3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
44 #include "gmx_fatal.h"
58 #include "mtop_util.h"
59 #include "gmx_statistics.h"
61 static real minthird
=-1.0/3.0,minsixth
=-1.0/6.0;
69 static double mypow(double x
,double y
)
77 static int *select_it(int nre
,char *nm
[],int *nset
)
84 if ((getenv("VERBOSE")) != NULL
)
87 fprintf(stderr
,"Select the terms you want from the following list\n");
88 fprintf(stderr
,"End your selection with 0\n");
92 for(j
=0; (j
<4) && (k
<nre
); j
++,k
++)
93 fprintf(stderr
," %3d=%14s",k
+1,nm
[k
]);
100 if(1 != scanf("%d",&n
))
102 gmx_fatal(FARGS
,"Error reading user input");
104 if ((n
>0) && (n
<=nre
))
109 for(i
=(*nset
)=0; (i
<nre
); i
++)
118 static int strcount(const char *s1
,const char *s2
)
121 while (s1
&& s2
&& (toupper(s1
[n
]) == toupper(s2
[n
])))
126 static void chomp(char *buf
)
128 int len
= strlen(buf
);
130 while ((len
> 0) && (buf
[len
-1] == '\n')) {
136 static int *select_by_name(int nre
,gmx_enxnm_t
*nm
,int *nset
)
139 int n
,k
,kk
,j
,i
,nmatch
,nind
,nss
;
141 bool bEOF
,bVerbose
= TRUE
,bLong
=FALSE
;
142 char *ptr
,buf
[STRLEN
];
143 const char *fm4
="%3d %-14s";
144 const char *fm2
="%3d %-34s";
147 if ((getenv("VERBOSE")) != NULL
)
150 fprintf(stderr
,"\n");
151 fprintf(stderr
,"Select the terms you want from the following list by\n");
152 fprintf(stderr
,"selecting either (part of) the name or the number or a combination.\n");
153 fprintf(stderr
,"End your selection with an empty line or a zero.\n");
154 fprintf(stderr
,"-------------------------------------------------------------------\n");
158 for(k
=0; k
<nre
; k
++) {
159 newnm
[k
] = strdup(nm
[k
].name
);
160 /* Insert dashes in all the names */
161 while ((ptr
= strchr(newnm
[k
],' ')) != NULL
) {
167 fprintf(stderr
,"\n");
170 for(kk
=k
; kk
<k
+4; kk
++) {
171 if (kk
< nre
&& strlen(nm
[kk
].name
) > 14) {
179 fprintf(stderr
,fm4
,k
+1,newnm
[k
]);
185 fprintf(stderr
,fm2
,k
+1,newnm
[k
]);
194 fprintf(stderr
,"\n\n");
200 while (!bEOF
&& (fgets2(buf
,STRLEN
-1,stdin
))) {
201 /* Remove newlines */
207 /* Empty line means end of input */
208 bEOF
= (strlen(buf
) == 0);
213 /* First try to read an integer */
214 nss
= sscanf(ptr
,"%d",&nind
);
216 /* Zero means end of input */
219 } else if ((1<=nind
) && (nind
<=nre
)) {
222 fprintf(stderr
,"number %d is out of range\n",nind
);
226 /* Now try to read a string */
229 for(nind
=0; nind
<nre
; nind
++) {
230 if (strcasecmp(newnm
[nind
],ptr
) == 0) {
238 for(nind
=0; nind
<nre
; nind
++) {
239 if (strncasecmp(newnm
[nind
],ptr
,i
) == 0) {
245 fprintf(stderr
,"String '%s' does not match anything\n",ptr
);
250 /* Look for the first space, and remove spaces from there */
251 if ((ptr
= strchr(ptr
,' ')) != NULL
) {
254 } while (!bEOF
&& (ptr
&& (strlen(ptr
) > 0)));
259 for(i
=(*nset
)=0; (i
<nre
); i
++)
266 gmx_fatal(FARGS
,"No energy terms selected");
268 for(i
=0; (i
<nre
); i
++)
275 static void get_orires_parms(const char *topnm
,
276 int *nor
,int *nex
,int **label
,real
**obs
)
287 read_tpx(topnm
,&ir
,box
,&natoms
,NULL
,NULL
,NULL
,&mtop
);
288 top
= gmx_mtop_generate_local_top(&mtop
,&ir
);
290 ip
= top
->idef
.iparams
;
291 iatom
= top
->idef
.il
[F_ORIRES
].iatoms
;
293 /* Count how many distance restraint there are... */
294 nb
= top
->idef
.il
[F_ORIRES
].nr
;
296 gmx_fatal(FARGS
,"No orientation restraints in topology!\n");
302 for(i
=0; i
<nb
; i
+=3) {
303 (*label
)[i
/3] = ip
[iatom
[i
]].orires
.label
;
304 (*obs
)[i
/3] = ip
[iatom
[i
]].orires
.obs
;
305 if (ip
[iatom
[i
]].orires
.ex
>= *nex
)
306 *nex
= ip
[iatom
[i
]].orires
.ex
+1;
308 fprintf(stderr
,"Found %d orientation restraints with %d experiments",
312 static int get_bounds(const char *topnm
,
313 real
**bounds
,int **index
,int **dr_pair
,int *npairs
,
314 gmx_mtop_t
*mtop
,gmx_localtop_t
**ltop
,t_inputrec
*ir
)
317 t_functype
*functype
;
319 int natoms
,i
,j
,k
,type
,ftype
,natom
;
327 read_tpx(topnm
,ir
,box
,&natoms
,NULL
,NULL
,NULL
,mtop
);
329 top
= gmx_mtop_generate_local_top(mtop
,ir
);
332 functype
= top
->idef
.functype
;
333 ip
= top
->idef
.iparams
;
335 /* Count how many distance restraint there are... */
336 nb
=top
->idef
.il
[F_DISRES
].nr
;
338 gmx_fatal(FARGS
,"No distance restraints in topology!\n");
340 /* Allocate memory */
345 /* Fill the bound array */
347 for(i
=0; (i
<top
->idef
.ntypes
); i
++) {
349 if (ftype
== F_DISRES
) {
351 label1
= ip
[i
].disres
.label
;
352 b
[nb
] = ip
[i
].disres
.up1
;
359 /* Fill the index array */
361 disres
= &(top
->idef
.il
[F_DISRES
]);
362 iatom
= disres
->iatoms
;
363 for(i
=j
=k
=0; (i
<disres
->nr
); ) {
365 ftype
= top
->idef
.functype
[type
];
366 natom
= interaction_function
[ftype
].nratoms
+1;
367 if (label1
!= top
->idef
.iparams
[type
].disres
.label
) {
369 label1
= top
->idef
.iparams
[type
].disres
.label
;
378 gmx_incons("get_bounds for distance restraints");
386 static void calc_violations(real rt
[],real rav3
[],int nb
,int index
[],
387 real bounds
[],real
*viol
,double *st
,double *sa
)
389 const real sixth
=1.0/6.0;
391 double rsum
,rav
,sumaver
,sumt
;
395 for(i
=0; (i
<nb
); i
++) {
398 for(j
=index
[i
]; (j
<index
[i
+1]); j
++) {
400 viol
[j
] += mypow(rt
[j
],-3.0);
402 rsum
+= mypow(rt
[j
],-6);
404 rsum
= max(0.0,mypow(rsum
,-sixth
)-bounds
[i
]);
405 rav
= max(0.0,mypow(rav
, -sixth
)-bounds
[i
]);
414 static void analyse_disre(const char *voutfn
, int nframes
,
415 real violaver
[], real bounds
[], int index
[],
416 int pair
[], int nbounds
,
417 const output_env_t oenv
)
420 double sum
,sumt
,sumaver
;
423 /* Subtract bounds from distances, to calculate violations */
424 calc_violations(violaver
,violaver
,
425 nbounds
,pair
,bounds
,NULL
,&sumt
,&sumaver
);
428 fprintf(stdout
,"\nSum of violations averaged over simulation: %g nm\n",
430 fprintf(stdout
,"Largest violation averaged over simulation: %g nm\n\n",
433 vout
=xvgropen(voutfn
,"r\\S-3\\N average violations","DR Index","nm",
437 for(i
=0; (i
<nbounds
); i
++) {
438 /* Do ensemble averaging */
440 for(j
=pair
[i
]; (j
<pair
[i
+1]); j
++)
441 sumaver
+= sqr(violaver
[j
]/nframes
);
442 sumaver
= max(0.0,mypow(sumaver
,minsixth
)-bounds
[i
]);
445 sum
= max(sum
,sumaver
);
446 fprintf(vout
,"%10d %10.5e\n",index
[i
],sumaver
);
449 for(j
=0; (j
<dr
.ndr
); j
++)
450 fprintf(vout
,"%10d %10.5e\n",j
,mypow(violaver
[j
]/nframes
,minthird
));
454 fprintf(stdout
,"\nSum of violations averaged over simulation: %g nm\n",
456 fprintf(stdout
,"Largest violation averaged over simulation: %g nm\n\n",sum
);
458 do_view(oenv
,voutfn
,"-graphtype bar");
461 static void einstein_visco(const char *fn
,const char *fni
,int nsets
,
462 int nframes
,real
**sum
,
463 real V
,real T
,int nsteps
,double time
[],
464 const output_env_t oenv
)
467 double av
[4],avold
[4];
474 dt
= (time
[1]-time
[0]);
477 for(i
=0; i
<=nsets
; i
++)
479 fp0
=xvgropen(fni
,"Shear viscosity integral",
480 "Time (ps)","(kg m\\S-1\\N s\\S-1\\N ps)",oenv
);
481 fp1
=xvgropen(fn
,"Shear viscosity using Einstein relation",
482 "Time (ps)","(kg m\\S-1\\N s\\S-1\\N)",oenv
);
483 for(i
=1; i
<nf4
; i
++) {
484 fac
= dt
*nframes
/nsteps
;
485 for(m
=0; m
<=nsets
; m
++)
487 for(j
=0; j
<nframes
-i
; j
++) {
488 for(m
=0; m
<nsets
; m
++) {
489 di
= sqr(fac
*(sum
[m
][j
+i
]-sum
[m
][j
]));
492 av
[nsets
] += di
/nsets
;
495 /* Convert to SI for the viscosity */
496 fac
= (V
*NANO
*NANO
*NANO
*PICO
*1e10
)/(2*BOLTZMANN
*T
)/(nframes
-i
);
497 fprintf(fp0
,"%10g",time
[i
]-time
[0]);
498 for(m
=0; (m
<=nsets
); m
++) {
500 fprintf(fp0
," %10g",av
[m
]);
503 fprintf(fp1
,"%10g",0.5*(time
[i
]+time
[i
-1])-time
[0]);
504 for(m
=0; (m
<=nsets
); m
++) {
505 fprintf(fp1
," %10g",(av
[m
]-avold
[m
])/dt
);
514 static void analyse_ener(bool bCorr
,const char *corrfn
,
515 bool bFee
,bool bSum
,bool bFluct
,
516 bool bVisco
,const char *visfn
,int nmol
,int ndf
,
517 gmx_large_int_t start_step
,double start_t
,
518 gmx_large_int_t step
,double t
,
519 double time
[], real reftemp
,
520 gmx_large_int_t ee_nsum
,
521 t_energy ee_sum
[],enersum_t
*enersum
,
522 int nset
,int set
[],int nenergy
,real
**eneset
,
524 char **leg
,gmx_enxnm_t
*enm
,
525 real Vaver
,real ezero
, const output_env_t oenv
)
528 /* Check out the printed manual for equations! */
529 double Dt
,aver
,avertot
,stddev
,delta_t
,totaldrift
;
531 real xxx
,integral
,intBulk
;
532 real sfrac
,oldfrac
,diffsum
,diffav
,fstep
,pr_aver
,pr_stddev
,fluct2
;
533 double beta
=0,expE
,expEtot
,*fee
=NULL
;
534 gmx_large_int_t nsteps
;
535 int nexact
,nnotexact
,iset
;
537 real Temp
=-1,Pres
=-1,VarV
=-1,VarT
=-1;
543 nsteps
= step
- start_step
+ 1;
545 fprintf(stdout
,"Not enough steps (%s) for statistics\n",
546 gmx_step_str(nsteps
,buf
));
549 /* Calculate the time difference */
550 delta_t
= t
- start_t
;
552 fprintf(stdout
,"\nStatistics over %s steps [ %.4f thru %.4f ps ], %d data sets\n",
553 gmx_step_str(nsteps
,buf
),start_t
,t
,nset
);
561 for(i
=0; (i
<nset
); i
++) {
562 if (ee_sum
[set
[i
]].esum
!= 0) {
570 if (nnotexact
== 0) {
571 fprintf(stdout
,"All averages are over %s frames\n",
572 gmx_step_str(ee_nsum
,buf
));
573 } else if (nexact
== 0 || ee_nsum
== enersum
->nframes
) {
574 fprintf(stdout
,"All averages are over %d frames\n",enersum
->nframes
);
576 fprintf(stdout
,"The term%s",nnotexact
==1 ? "" : "s");
577 for(i
=0; (i
<nset
); i
++) {
578 if (ee_sum
[set
[i
]].esum
== 0) {
579 fprintf(stdout
," '%s'",leg
[i
]);
582 fprintf(stdout
," %s averaged over %d frames\n",
583 nnotexact
==1 ? "is" : "are",enersum
->nframes
);
584 fprintf(stdout
,"All other averages are over %s frames\n",
585 gmx_step_str(ee_nsum
,buf
));
587 fprintf(stdout
,"\n");
589 fprintf(stdout
,"%-24s %10s %10s %10s %10s",
590 "Energy","Average","RMSD","Fluct.","Tot-Drift");
592 fprintf(stdout
," %10s\n","-kT ln<e^(E/kT)>");
594 fprintf(stdout
,"\n");
595 fprintf(stdout
,"-------------------------------------------------------------------------------\n");
597 /* Initiate locals, only used with -sum */
601 beta
= 1.0/(BOLTZ
*reftemp
);
604 for(i
=0; (i
<nset
); i
++) {
606 if (ee_nsum
> 0 && ee_sum
[iset
].esum
!= 0) {
607 /* We have exact sums over all the MD steps */
608 aver
= ee_sum
[iset
].esum
/ee_nsum
;
609 stddev
= sqrt(ee_sum
[iset
].eav
/ee_nsum
);
611 /* We only have data at energy file frame steps */
612 aver
= enersum
->sum
[i
]/enersum
->nframes
;
613 if (enersum
->nframes
> 1) {
614 stddev
= sqrt(enersum
->sum2
[i
]/enersum
->nframes
- aver
*aver
);
624 for(j
=0; (j
<nenergy
); j
++) {
625 expE
+= exp(beta
*(eneset
[i
][j
]-aver
)/nmol
);
628 expEtot
+=expE
/nenergy
;
630 fee
[i
] = log(expE
/nenergy
)/beta
+ aver
/nmol
;
632 if (strstr(leg
[i
],"empera") != NULL
) {
635 } else if (strstr(leg
[i
],"olum") != NULL
) {
638 } else if (strstr(leg
[i
],"essure") != NULL
) {
642 for (j
=0; (j
<= F_ETOT
); j
++)
644 (strcasecmp(interaction_function
[j
].longname
,leg
[i
]) == 0);
646 pr_aver
= aver
/nmol
-ezero
;
647 pr_stddev
= stddev
/nmol
;
654 lsq_y_ax_b_xdouble(nenergy
,time
,eneset
[i
],&a
,&b
,&r
,&chi2
);
655 totaldrift
= a
* delta_t
;
659 fluct2
= sqr(pr_stddev
) - sqr(totaldrift
)/12;
662 fprintf(stdout
,"%-24s %10g %10g %10g %10g",
663 leg
[i
],pr_aver
,pr_stddev
,sqrt(fluct2
),totaldrift
);
665 fprintf(stdout
," %10g",fee
[i
]);
667 fprintf(stdout
," (%s)\n",enm
[set
[i
]].unit
);
670 for(j
=0; (j
<nenergy
); j
++)
671 eneset
[i
][j
] -= aver
;
675 fprintf(stdout
,"%-24s %10g %10s %10s %10s %10s",
676 "Total",avertot
/nmol
,"--","--","--","--");
677 /* pr_aver,pr_stddev,a,totaldrift */
679 fprintf(stdout
," %10g %10g\n",
680 log(expEtot
)/beta
+ avertot
/nmol
,log(expEtot
)/beta
);
682 fprintf(stdout
,"\n");
687 factor
= nmol
*ndf
*VarT
/(3.0*sqr(Temp
));
688 fprintf(stdout
,"Heat Capacity Cv: %10g J/mol K (factor = %g)\n",
689 1000*BOLTZ
/(2.0/3.0 - factor
),factor
);
691 if ((VarV
!= -1) && (Temp
!= -1)) {
692 real tmp
= VarV
/(Vaver
*BOLTZ
*Temp
*PRESFAC
);
694 fprintf(stdout
,"Isothermal Compressibility: %10g /%s\n",
696 fprintf(stdout
,"Adiabatic bulk modulus: %10g %s\n",
697 1.0/tmp
,unit_pres_bar
);
699 /* Do correlation function */
700 Dt
= delta_t
/nenergy
;
702 char *leg
[] = { "Shear", "Bulk" };
705 /* Assume pressure tensor is in Pxx Pxy Pxz Pyx Pyy Pyz Pzx Pzy Pzz */
707 /* Symmetrise tensor! (and store in first three elements)
708 * And subtract average pressure!
710 for(i
=0; (i
<nenergy
); i
++) {
711 eneset
[0][i
] = 0.5*(eneset
[1][i
]+eneset
[3][i
]);
712 eneset
[1][i
] = 0.5*(eneset
[2][i
]+eneset
[6][i
]);
713 eneset
[2][i
] = 0.5*(eneset
[5][i
]+eneset
[7][i
]);
714 eneset
[11][i
] -= Pres
;
715 enesum
[0][i
] = 0.5*(enesum
[1][i
]+enesum
[3][i
]);
716 enesum
[1][i
] = 0.5*(enesum
[2][i
]+enesum
[6][i
]);
717 enesum
[2][i
] = 0.5*(enesum
[5][i
]+enesum
[7][i
]);
720 einstein_visco("evisco.xvg","eviscoi.xvg",
721 3,nenergy
,enesum
,Vaver
,Temp
,nsteps
,time
,oenv
);
723 /*do_autocorr(corrfn,buf,nenergy,3,eneset,Dt,eacNormal,TRUE);*/
724 /* Do it for shear viscosity */
725 strcpy(buf
,"Shear Viscosity");
726 low_do_autocorr(corrfn
,oenv
,buf
,nenergy
,3,(nenergy
+1)/2,eneset
,Dt
,
727 eacNormal
,1,TRUE
,FALSE
,FALSE
,0.0,0.0,0,1);
729 /* Now for bulk viscosity */
730 strcpy(buf
,"Bulk Viscosity");
731 low_do_autocorr(corrfn
,oenv
,buf
,nenergy
,1,(nenergy
+1)/2,&(eneset
[11]),Dt
,
732 eacNormal
,1,TRUE
,FALSE
,FALSE
,0.0,0.0,0,1);
734 factor
= (Vaver
*1e-26/(BOLTZMANN
*Temp
))*Dt
;
735 fp
=xvgropen(visfn
,buf
,"Time (ps)","\\8h\\4 (cp)",oenv
);
736 xvgr_legend(fp
,asize(leg
),leg
,oenv
);
738 /* Use trapezium rule for integration */
741 for(i
=1; (i
<nenergy
/2); i
++) {
742 integral
+= 0.5*(eneset
[0][i
-1] + eneset
[0][i
])*factor
;
743 intBulk
+= 0.5*(eneset
[11][i
-1] + eneset
[11][i
])*factor
;
744 fprintf(fp
,"%10g %10g %10g\n",(i
*Dt
),integral
,intBulk
);
750 strcpy(buf
,"Autocorrelation of Energy Fluctuations");
752 strcpy(buf
,"Energy Autocorrelation");
753 do_autocorr(corrfn
,oenv
,buf
,nenergy
,
755 bSum
? &(eneset
[nset
-1]) : eneset
,
756 (delta_t
/nenergy
),eacNormal
,FALSE
);
761 static void print_time(FILE *fp
,double t
)
763 fprintf(fp
,"%12.6f",t
);
766 static void print1(FILE *fp
,bool bDp
,real e
)
769 fprintf(fp
," %16.12f",e
);
771 fprintf(fp
," %10.6f",e
);
775 static void fec(const char *ene2fn
, const char *runavgfn
,
776 real reftemp
, int nset
, int set
[], char *leg
[],
777 int nenergy
, real
**eneset
, double time
[],
778 const output_env_t oenv
)
780 char *ravgleg
[] = { "\\8D\\4E = E\\sB\\N-E\\sA\\N",
781 "<e\\S-\\8D\\4E/kT\\N>\\s0..t\\N" };
784 int nre
,timecheck
,step
,nenergy2
,maxenergy
;
790 gmx_enxnm_t
*enm
=NULL
;
794 /* read second energy file */
797 enx
= open_enx(ene2fn
,"r");
798 do_enxnms(enx
,&(fr
->nre
),&enm
);
800 snew(eneset2
,nset
+1);
805 /* This loop searches for the first frame (when -b option is given),
806 * or when this has been found it reads just one energy frame
809 bCont
= do_enx(enx
,fr
);
812 timecheck
= check_times(fr
->t
);
814 } while (bCont
&& (timecheck
< 0));
816 /* Store energies for analysis afterwards... */
817 if ((timecheck
== 0) && bCont
) {
819 if ( nenergy2
>= maxenergy
) {
821 for(i
=0; i
<=nset
; i
++)
822 srenew(eneset2
[i
],maxenergy
);
824 if (fr
->t
!= time
[nenergy2
])
825 fprintf(stderr
,"\nWARNING time mismatch %g!=%g at frame %s\n",
826 fr
->t
, time
[nenergy2
], gmx_step_str(fr
->step
,buf
));
827 for(i
=0; i
<nset
; i
++)
828 eneset2
[i
][nenergy2
] = fr
->ener
[set
[i
]].e
;
832 } while (bCont
&& (timecheck
== 0));
835 if(nenergy
!=nenergy2
)
836 fprintf(stderr
,"\nWARNING file length mismatch %d!=%d\n",nenergy
,nenergy2
);
837 nenergy
=min(nenergy
,nenergy2
);
839 /* calculate fe difference dF = -kT ln < exp(-(E_B-E_A)/kT) >_A */
842 fp
=xvgropen(runavgfn
,"Running average free energy difference",
843 "Time (" unit_time
")","\\8D\\4E (" unit_energy
")",oenv
);
844 xvgr_legend(fp
,asize(ravgleg
),ravgleg
,oenv
);
846 fprintf(stdout
,"\n%-24s %10s\n",
847 "Energy","dF = -kT ln < exp(-(EB-EA)/kT) >A");
849 beta
= 1.0/(BOLTZ
*reftemp
);
850 for(i
=0; i
<nset
; i
++) {
851 if (strcasecmp(leg
[i
],enm
[set
[i
]].name
)!=0)
852 fprintf(stderr
,"\nWARNING energy set name mismatch %s!=%s\n",
853 leg
[i
],enm
[set
[i
]].name
);
854 for(j
=0; j
<nenergy
; j
++) {
855 dE
= eneset2
[i
][j
]-eneset
[i
][j
];
856 sum
+= exp(-dE
*beta
);
858 fprintf(fp
,"%10g %10g %10g\n",
859 time
[j
], dE
, -BOLTZ
*reftemp
*log(sum
/(j
+1)) );
861 aver
= -BOLTZ
*reftemp
*log(sum
/nenergy
);
862 fprintf(stdout
,"%-24s %10g\n",leg
[i
],aver
);
868 int gmx_energy(int argc
,char *argv
[])
870 const char *desc
[] = {
872 "g_energy extracts energy components or distance restraint",
873 "data from an energy file. The user is prompted to interactively",
874 "select the energy terms she wants.[PAR]",
876 "Average and RMSD are calculated with full precision from the",
877 "simulation (see printed manual). Drift is calculated by performing",
878 "a LSQ fit of the data to a straight line. The reported total drift",
879 "is the difference of the fit at the first and last point.",
880 "The term fluctuation gives the RMSD around the LSQ fit.[PAR]",
882 "When the [TT]-viol[tt] option is set, the time averaged",
883 "violations are plotted and the running time-averaged and",
884 "instantaneous sum of violations are recalculated. Additionally",
885 "running time-averaged and instantaneous distances between",
886 "selected pairs can be plotted with the [TT]-pairs[tt] option.[PAR]",
888 "Options [TT]-ora[tt], [TT]-ort[tt], [TT]-oda[tt], [TT]-odr[tt] and",
889 "[TT]-odt[tt] are used for analyzing orientation restraint data.",
890 "The first two options plot the orientation, the last three the",
891 "deviations of the orientations from the experimental values.",
892 "The options that end on an 'a' plot the average over time",
893 "as a function of restraint. The options that end on a 't'",
894 "prompt the user for restraint label numbers and plot the data",
895 "as a function of time. Option [TT]-odr[tt] plots the RMS",
896 "deviation as a function of restraint.",
897 "When the run used time or ensemble averaged orientation restraints,",
898 "option [TT]-orinst[tt] can be used to analyse the instantaneous,",
899 "not ensemble-averaged orientations and deviations instead of",
900 "the time and ensemble averages.[PAR]",
902 "Option [TT]-oten[tt] plots the eigenvalues of the molecular order",
903 "tensor for each orientation restraint experiment. With option",
904 "[TT]-ovec[tt] also the eigenvectors are plotted.[PAR]",
906 "With [TT]-fee[tt] an estimate is calculated for the free-energy",
907 "difference with an ideal gas state: [BR]",
908 " Delta A = A(N,V,T) - A_idgas(N,V,T) = kT ln < e^(Upot/kT) >[BR]",
909 " Delta G = G(N,p,T) - G_idgas(N,p,T) = kT ln < e^(Upot/kT) >[BR]",
910 "where k is Boltzmann's constant, T is set by [TT]-fetemp[tt] and"
911 "the average is over the ensemble (or time in a trajectory).",
912 "Note that this is in principle",
913 "only correct when averaging over the whole (Boltzmann) ensemble",
914 "and using the potential energy. This also allows for an entropy",
915 "estimate using:[BR]",
916 " Delta S(N,V,T) = S(N,V,T) - S_idgas(N,V,T) = (<Upot> - Delta A)/T[BR]",
917 " Delta S(N,p,T) = S(N,p,T) - S_idgas(N,p,T) = (<Upot> + pV - Delta G)/T",
920 "When a second energy file is specified ([TT]-f2[tt]), a free energy",
921 "difference is calculated dF = -kT ln < e ^ -(EB-EA)/kT >A ,",
922 "where EA and EB are the energies from the first and second energy",
923 "files, and the average is over the ensemble A. [BB]NOTE[bb] that",
924 "the energies must both be calculated from the same trajectory."
927 static bool bSum
=FALSE
,bFee
=FALSE
,bAll
=FALSE
,bFluct
=FALSE
;
928 static bool bDp
=FALSE
,bMutot
=FALSE
,bOrinst
=FALSE
,bOvec
=FALSE
;
929 static int skip
=0,nmol
=1,ndf
=3;
930 static real reftemp
=300.0,ezero
=0;
932 { "-fee", FALSE
, etBOOL
, {&bFee
},
933 "Do a free energy estimate" },
934 { "-fetemp", FALSE
, etREAL
,{&reftemp
},
935 "Reference temperature for free energy calculation" },
936 { "-zero", FALSE
, etREAL
, {&ezero
},
937 "Subtract a zero-point energy" },
938 { "-sum", FALSE
, etBOOL
, {&bSum
},
939 "Sum the energy terms selected rather than display them all" },
940 { "-dp", FALSE
, etBOOL
, {&bDp
},
941 "Print energies in high precision" },
942 { "-mutot",FALSE
, etBOOL
, {&bMutot
},
943 "Compute the total dipole moment from the components" },
944 { "-skip", FALSE
, etINT
, {&skip
},
945 "Skip number of frames between data points" },
946 { "-aver", FALSE
, etBOOL
, {&bAll
},
947 "Print also the X1,t and sigma1,t, only if only 1 energy is requested" },
948 { "-nmol", FALSE
, etINT
, {&nmol
},
949 "Number of molecules in your sample: the energies are divided by this number" },
950 { "-ndf", FALSE
, etINT
, {&ndf
},
951 "Number of degrees of freedom per molecule. Necessary for calculating the heat capacity" },
952 { "-fluc", FALSE
, etBOOL
, {&bFluct
},
953 "Calculate autocorrelation of energy fluctuations rather than energy itself" },
954 { "-orinst", FALSE
, etBOOL
, {&bOrinst
},
955 "Analyse instantaneous orientation data" },
956 { "-ovec", FALSE
, etBOOL
, {&bOvec
},
957 "Also plot the eigenvectors with -oten" }
963 static const char *setnm
[] = {
964 "Pres-XX", "Pres-XY", "Pres-XZ", "Pres-YX", "Pres-YY",
965 "Pres-YZ", "Pres-ZX", "Pres-ZY", "Pres-ZZ", "Temperature",
969 FILE *out
,*fp_pairs
=NULL
,*fort
=NULL
,*fodt
=NULL
,*foten
=NULL
;
974 gmx_localtop_t
*top
=NULL
;
976 t_energy
*ee_sum
,**ee
;
978 gmx_enxnm_t
*enm
=NULL
;
979 t_enxframe
*frame
,*fr
=NULL
;
982 int nre
,teller
,teller_disre
;
983 gmx_large_int_t start_step
,ee_nsteps
,ee_nsum
;
984 int nor
=0,nex
=0,norfr
=0,enx_i
=0;
986 real
*bounds
=NULL
,*violaver
=NULL
,*oobs
=NULL
,*orient
=NULL
,*odrms
=NULL
;
987 int *index
=NULL
,*pair
=NULL
,norsel
=0,*orsel
=NULL
,*or_label
=NULL
;
988 int nbounds
=0,npairs
;
989 bool bDisRe
,bDRAll
,bORA
,bORT
,bODA
,bODR
,bODT
,bORIRE
,bOTEN
;
990 bool bFoundStart
,bCont
,bEDR
,bVisco
;
991 double sum
,sumaver
,sumt
,ener
,dbl
;
993 real
**eneset
=NULL
, **enesum
=NULL
,Vaver
;
994 int *set
=NULL
,i
,j
,k
,nset
,sss
,nenergy
;
995 char **pairleg
,**odtleg
,**otenleg
;
998 char *anm_j
,*anm_k
,*resnm_j
,*resnm_k
;
1000 const char *orinst_sub
= "@ subtitle \"instantaneous\"\n";
1004 { efEDR
, "-f", NULL
, ffREAD
},
1005 { efEDR
, "-f2", NULL
, ffOPTRD
},
1006 { efTPX
, "-s", NULL
, ffOPTRD
},
1007 { efXVG
, "-o", "energy", ffWRITE
},
1008 { efXVG
, "-viol", "violaver",ffOPTWR
},
1009 { efXVG
, "-pairs","pairs", ffOPTWR
},
1010 { efXVG
, "-ora", "orienta", ffOPTWR
},
1011 { efXVG
, "-ort", "orientt", ffOPTWR
},
1012 { efXVG
, "-oda", "orideva", ffOPTWR
},
1013 { efXVG
, "-odr", "oridevr", ffOPTWR
},
1014 { efXVG
, "-odt", "oridevt", ffOPTWR
},
1015 { efXVG
, "-oten", "oriten", ffOPTWR
},
1016 { efXVG
, "-corr", "enecorr", ffOPTWR
},
1017 { efXVG
, "-vis", "visco", ffOPTWR
},
1018 { efXVG
, "-ravg", "runavgdf",ffOPTWR
}
1020 #define NFILE asize(fnm)
1024 CopyRight(stderr
,argv
[0]);
1026 ppa
= add_acf_pargs(&npargs
,pa
);
1027 parse_common_args(&argc
,argv
,
1028 PCA_CAN_VIEW
| PCA_CAN_BEGIN
| PCA_CAN_END
| PCA_BE_NICE
,
1029 NFILE
,fnm
,npargs
,ppa
,asize(desc
),desc
,0,NULL
,&oenv
);
1031 bDRAll
= opt2bSet("-pairs",NFILE
,fnm
);
1032 bDisRe
= opt2bSet("-viol",NFILE
,fnm
) || bDRAll
;
1033 bORA
= opt2bSet("-ora",NFILE
,fnm
);
1034 bORT
= opt2bSet("-ort",NFILE
,fnm
);
1035 bODA
= opt2bSet("-oda",NFILE
,fnm
);
1036 bODR
= opt2bSet("-odr",NFILE
,fnm
);
1037 bODT
= opt2bSet("-odt",NFILE
,fnm
);
1038 bORIRE
= bORA
|| bORT
|| bODA
|| bODR
|| bODT
;
1039 bOTEN
= opt2bSet("-oten",NFILE
,fnm
);
1044 fp
= open_enx(ftp2fn(efEDR
,NFILE
,fnm
),"r");
1045 do_enxnms(fp
,&nre
,&enm
);
1047 /* Initiate energies and set them to zero */
1049 enersum
.nframes
= 0;
1050 snew(enersum
.sum
,nre
);
1051 snew(enersum
.sum2
,nre
);
1055 bVisco
= opt2bSet("-vis",NFILE
,fnm
);
1061 /* This is nasty code... To extract Pres tensor, Volume and Temperature */
1062 for(j
=0; j
<nset
; j
++) {
1063 for(i
=0; i
<nre
; i
++) {
1064 if (strstr(enm
[i
].name
,setnm
[j
])) {
1070 if (strcasecmp(setnm
[j
],"Volume")==0) {
1071 printf("Enter the box volume (" unit_volume
"): ");
1072 if(1 != scanf("%lf",&dbl
))
1074 gmx_fatal(FARGS
,"Error reading user input");
1078 gmx_fatal(FARGS
,"Could not find term %s for viscosity calculation",
1084 set
=select_by_name(nre
,enm
,&nset
);
1086 /* Print all the different units once */
1087 sprintf(buf
,"(%s)",enm
[set
[0]].unit
);
1088 for(i
=1; i
<nset
; i
++) {
1089 for(j
=0; j
<i
; j
++) {
1090 if (strcmp(enm
[set
[i
]].unit
,enm
[set
[j
]].unit
) == 0) {
1096 strcat(buf
,enm
[set
[i
]].unit
);
1100 out
=xvgropen(opt2fn("-o",NFILE
,fnm
),"Gromacs Energies","Time (ps)",buf
,
1104 for(i
=0; (i
<nset
); i
++)
1105 leg
[i
] = enm
[set
[i
]].name
;
1107 leg
[nset
]=strdup("Sum");
1108 xvgr_legend(out
,nset
+1,leg
,oenv
);
1111 xvgr_legend(out
,nset
,leg
,oenv
);
1113 snew(eneset
,nset
+1);
1115 snew(enesum
,nset
+1);
1118 if (bORIRE
|| bOTEN
)
1119 get_orires_parms(ftp2fn(efTPX
,NFILE
,fnm
),&nor
,&nex
,&or_label
,&oobs
);
1132 fprintf(stderr
,"Select the orientation restraint labels you want (-1 is all)\n");
1133 fprintf(stderr
,"End your selection with 0\n");
1139 if(1 != scanf("%d",&(orsel
[j
])))
1141 gmx_fatal(FARGS
,"Error reading user input");
1143 } while (orsel
[j
] > 0);
1144 if (orsel
[0] == -1) {
1145 fprintf(stderr
,"Selecting all %d orientation restraints\n",nor
);
1148 for(i
=0; i
<nor
; i
++)
1151 /* Build the selection */
1153 for(i
=0; i
<j
; i
++) {
1154 for(k
=0; k
<nor
; k
++)
1155 if (or_label
[k
] == orsel
[i
]) {
1161 fprintf(stderr
,"Orientation restraint label %d not found\n",
1165 snew(odtleg
,norsel
);
1166 for(i
=0; i
<norsel
; i
++) {
1167 snew(odtleg
[i
],256);
1168 sprintf(odtleg
[i
],"%d",or_label
[orsel
[i
]]);
1171 fort
=xvgropen(opt2fn("-ort",NFILE
,fnm
), "Calculated orientations",
1172 "Time (ps)","",oenv
);
1174 fprintf(fort
,"%s",orinst_sub
);
1175 xvgr_legend(fort
,norsel
,odtleg
,oenv
);
1178 fodt
=xvgropen(opt2fn("-odt",NFILE
,fnm
),
1179 "Orientation restraint deviation",
1180 "Time (ps)","",oenv
);
1182 fprintf(fodt
,"%s",orinst_sub
);
1183 xvgr_legend(fodt
,norsel
,odtleg
,oenv
);
1188 foten
=xvgropen(opt2fn("-oten",NFILE
,fnm
),
1189 "Order tensor","Time (ps)","",oenv
);
1190 snew(otenleg
,bOvec
? nex
*12 : nex
*3);
1191 for(i
=0; i
<nex
; i
++) {
1192 for(j
=0; j
<3; j
++) {
1193 sprintf(buf
,"eig%d",j
+1);
1194 otenleg
[(bOvec
? 12 : 3)*i
+j
] = strdup(buf
);
1197 for(j
=0; j
<9; j
++) {
1198 sprintf(buf
,"vec%d%s",j
/3+1,j
%3==0 ? "x" : (j
%3==1 ? "y" : "z"));
1199 otenleg
[12*i
+3+j
] = strdup(buf
);
1203 xvgr_legend(foten
,bOvec
? nex
*12 : nex
*3,otenleg
,oenv
);
1207 nbounds
=get_bounds(ftp2fn(efTPX
,NFILE
,fnm
),&bounds
,&index
,&pair
,&npairs
,
1209 snew(violaver
,npairs
);
1210 out
=xvgropen(opt2fn("-o",NFILE
,fnm
),"Sum of Violations",
1211 "Time (ps)","nm",oenv
);
1212 xvgr_legend(out
,2,drleg
,oenv
);
1214 fp_pairs
=xvgropen(opt2fn("-pairs",NFILE
,fnm
),"Pair Distances",
1215 "Time (ps)","Distance (nm)",oenv
);
1216 if (get_print_xvgr_codes(oenv
))
1217 fprintf(fp_pairs
,"@ subtitle \"averaged (tau=%g) and instantaneous\"\n",
1222 /* Initiate counters */
1225 bFoundStart
= FALSE
;
1231 /* This loop searches for the first frame (when -b option is given),
1232 * or when this has been found it reads just one energy frame
1235 bCont
= do_enx(fp
,&(frame
[NEXT
]));
1238 timecheck
= check_times(frame
[NEXT
].t
);
1240 } while (bCont
&& (timecheck
< 0));
1242 if ((timecheck
== 0) && bCont
) {
1243 /* We read a valid frame, so we can use it */
1244 fr
= &(frame
[NEXT
]);
1247 /* The frame contains energies, so update cur */
1252 /* Initiate the previous step data */
1253 start_step
= fr
->step
;
1255 /* Initiate the energy sums */
1256 for(i
=0; i
<fr
->nre
; i
++) {
1257 ee_sum
[i
].esum
= fr
->ener
[i
].e
;
1264 if (fr
->step
- start_step
+ 1 == ee_nsteps
+ fr
->nsteps
) {
1265 if (fr
->nsum
<= 1) {
1266 /* We have a sum of a single frame:
1267 * add the energy to the sums.
1269 for(i
=0; i
<fr
->nre
; i
++) {
1271 dsqr(ee_sum
[i
].esum
/ee_nsum
- (ee_sum
[i
].esum
+ fr
->ener
[i
].e
)/(ee_nsum
+ 1))*
1272 ee_nsum
*(ee_nsum
+ 1);
1273 ee_sum
[i
].esum
+= fr
->ener
[i
].e
;
1277 /* Add the sums to the total */
1278 for(i
=0; i
<fr
->nre
; i
++) {
1281 dsqr(ee_sum
[i
].esum
/ee_nsum
- (ee_sum
[i
].esum
+ fr
->ener
[i
].esum
)/(ee_nsum
+ fr
->nsum
))*
1282 ee_nsum
*(ee_nsum
+ fr
->nsum
)/(double)fr
->nsum
;
1283 ee_sum
[i
].esum
+= fr
->ener
[i
].esum
;
1285 ee_nsum
+= fr
->nsum
;
1288 /* The interval does not match fr->nsteps:
1289 * can not do exact averages.
1293 ee_nsteps
= fr
->step
- start_step
+ 1;
1298 * Define distance restraint legends. Can only be done after
1299 * the first frame has been read... (Then we know how many there are)
1301 if (bDisRe
&& bDRAll
&& !leg
&& (fr
->ndisre
> 0)) {
1305 fa
= top
->idef
.il
[F_DISRES
].iatoms
;
1306 ip
= top
->idef
.iparams
;
1308 if (fr
->ndisre
!= top
->idef
.il
[F_DISRES
].nr
/3)
1309 gmx_fatal(FARGS
,"Number of disre pairs in the energy file (%d) does not match the number in the run input file (%d)\n",
1310 fr
->ndisre
,top
->idef
.il
[F_DISRES
].nr
/3);
1312 snew(pairleg
,fr
->ndisre
);
1313 for(i
=0; i
<fr
->ndisre
; i
++) {
1314 snew(pairleg
[i
],30);
1317 gmx_mtop_atominfo_global(&mtop
,j
,&anm_j
,&resnr_j
,&resnm_j
);
1318 gmx_mtop_atominfo_global(&mtop
,k
,&anm_k
,&resnr_k
,&resnm_k
);
1319 sprintf(pairleg
[i
],"%d %s %d %s (%d)",
1320 resnr_j
+1,anm_j
,resnr_k
+1,anm_k
,
1321 ip
[fa
[3*i
]].disres
.label
);
1323 set
=select_it(fr
->ndisre
,pairleg
,&nset
);
1325 for(i
=0; (i
<nset
); i
++) {
1327 sprintf(leg
[2*i
], "a %s",pairleg
[set
[i
]]);
1328 snew(leg
[2*i
+1],32);
1329 sprintf(leg
[2*i
+1],"i %s",pairleg
[set
[i
]]);
1331 xvgr_legend(fp_pairs
,2*nset
,leg
,oenv
);
1335 * Store energies for analysis afterwards...
1337 if (!bDisRe
&& (fr
->nre
> 0)) {
1338 if ((nenergy
% 1000) == 0) {
1339 srenew(time
,nenergy
+1000);
1340 for(i
=0; (i
<=nset
); i
++) {
1341 srenew(eneset
[i
],nenergy
+1000);
1343 srenew(enesum
[i
],nenergy
+1000);
1346 time
[nenergy
] = fr
->t
;
1348 for(i
=0; (i
<nset
); i
++) {
1349 ener
= fr
->ener
[set
[i
]].e
;
1350 eneset
[i
][nenergy
] = ener
;
1353 enesum
[i
][nenergy
] = fr
->ener
[set
[i
]].esum
;
1355 /* Sum the actual frame energies,
1356 * for in case we do not have exact sums in the energy file.
1358 enersum
.sum
[i
] += ener
;
1359 enersum
.sum2
[i
] += ener
*ener
;
1362 eneset
[nset
][nenergy
] = sum
;
1368 * Printing time, only when we do not want to skip frames
1370 if (!skip
|| teller
% skip
== 0) {
1372 /*******************************************
1373 * D I S T A N C E R E S T R A I N T S
1374 *******************************************/
1375 if (fr
->ndisre
> 0) {
1376 print_time(out
,fr
->t
);
1377 if (violaver
== NULL
)
1378 snew(violaver
,fr
->ndisre
);
1380 /* Subtract bounds from distances, to calculate violations */
1381 calc_violations(fr
->disre_rt
,fr
->disre_rm3tav
,
1382 nbounds
,pair
,bounds
,violaver
,&sumt
,&sumaver
);
1384 fprintf(out
," %8.4f %8.4f\n",sumaver
,sumt
);
1386 print_time(fp_pairs
,fr
->t
);
1387 for(i
=0; (i
<nset
); i
++) {
1389 fprintf(fp_pairs
," %8.4f",
1390 mypow(fr
->disre_rm3tav
[sss
],minthird
));
1391 fprintf(fp_pairs
," %8.4f",
1394 fprintf(fp_pairs
,"\n");
1399 /*******************************************
1401 *******************************************/
1404 print_time(out
,fr
->t
);
1406 print1(out
,bDp
,(eneset
[nset
][nenergy
-1])/nmol
-ezero
);
1407 else if ((nset
== 1) && bAll
) {
1408 print1(out
,bDp
,fr
->ener
[set
[0]].e
);
1409 print1(out
,bDp
,fr
->ener
[set
[0]].esum
);
1410 print1(out
,bDp
,fr
->ener
[set
[0]].eav
);
1412 else for(i
=0; (i
<nset
); i
++)
1413 print1(out
,bDp
,(fr
->ener
[set
[i
]].e
)/nmol
-ezero
);
1417 if (bORIRE
&& fr
->nblock
>enx_i
&& fr
->nr
[enx_i
]>0) {
1418 if (fr
->nr
[enx_i
] != nor
)
1419 gmx_fatal(FARGS
,"Number of orientation restraints in energy file (%d) does not match with the topology (%d)",fr
->nr
[enx_i
],nor
);
1421 for(i
=0; i
<nor
; i
++)
1422 orient
[i
] += fr
->block
[enx_i
][i
];
1424 for(i
=0; i
<nor
; i
++)
1425 odrms
[i
] += sqr(fr
->block
[enx_i
][i
]-oobs
[i
]);
1427 fprintf(fort
," %10f",fr
->t
);
1428 for(i
=0; i
<norsel
; i
++)
1429 fprintf(fort
," %g",fr
->block
[enx_i
][orsel
[i
]]);
1433 fprintf(fodt
," %10f",fr
->t
);
1434 for(i
=0; i
<norsel
; i
++)
1435 fprintf(fodt
," %g",fr
->block
[enx_i
][orsel
[i
]]-oobs
[orsel
[i
]]);
1440 if (bOTEN
&& fr
->nblock
>enxORT
) {
1441 if (fr
->nr
[enxORT
] != nex
*12)
1442 gmx_fatal(FARGS
,"Number of orientation experiments in energy file (%g) does not match with the topology (%d)",fr
->nr
[enxORT
]/12,nex
);
1443 fprintf(foten
," %10f",fr
->t
);
1444 for(i
=0; i
<nex
; i
++)
1445 for(j
=0; j
<(bOvec
?12:3); j
++)
1446 fprintf(foten
," %g",fr
->block
[enxORT
][i
*12+j
]);
1447 fprintf(foten
,"\n");
1452 } while (bCont
&& (timecheck
== 0));
1454 fprintf(stderr
,"\n");
1467 out
= xvgropen(opt2fn("-ora",NFILE
,fnm
),
1468 "Average calculated orientations",
1469 "Restraint label","",oenv
);
1471 fprintf(out
,"%s",orinst_sub
);
1472 for(i
=0; i
<nor
; i
++)
1473 fprintf(out
,"%5d %g\n",or_label
[i
],orient
[i
]/norfr
);
1477 out
= xvgropen(opt2fn("-oda",NFILE
,fnm
),
1478 "Average restraint deviation",
1479 "Restraint label","",oenv
);
1481 fprintf(out
,"%s",orinst_sub
);
1482 for(i
=0; i
<nor
; i
++)
1483 fprintf(out
,"%5d %g\n",or_label
[i
],orient
[i
]/norfr
-oobs
[i
]);
1487 out
= xvgropen(opt2fn("-odr",NFILE
,fnm
),
1488 "RMS orientation restraint deviations",
1489 "Restraint label","",oenv
);
1491 fprintf(out
,"%s",orinst_sub
);
1492 for(i
=0; i
<nor
; i
++)
1493 fprintf(out
,"%5d %g\n",or_label
[i
],sqrt(odrms
[i
]/norfr
));
1500 analyse_disre(opt2fn("-viol",NFILE
,fnm
),
1501 teller_disre
,violaver
,bounds
,index
,pair
,nbounds
,oenv
);
1503 analyse_ener(opt2bSet("-corr",NFILE
,fnm
),opt2fn("-corr",NFILE
,fnm
),
1504 bFee
,bSum
,bFluct
,bVisco
,opt2fn("-vis",NFILE
,fnm
),
1505 nmol
,ndf
,start_step
,start_t
,frame
[cur
].step
,frame
[cur
].t
,
1506 time
,reftemp
,ee_nsum
,ee_sum
,&enersum
,
1507 nset
,set
,nenergy
,eneset
,enesum
,leg
,enm
,Vaver
,ezero
,oenv
);
1509 if (opt2bSet("-f2",NFILE
,fnm
)) {
1510 fec(opt2fn("-f2",NFILE
,fnm
), opt2fn("-ravg",NFILE
,fnm
),
1511 reftemp
, nset
, set
, leg
, nenergy
, eneset
, time
,oenv
);
1515 const char *nxy
= "-nxy";
1517 do_view(oenv
,opt2fn("-o",NFILE
,fnm
),nxy
);
1518 do_view(oenv
,opt2fn_null("-ravg",NFILE
,fnm
),nxy
);
1519 do_view(oenv
,opt2fn_null("-ora",NFILE
,fnm
),nxy
);
1520 do_view(oenv
,opt2fn_null("-ort",NFILE
,fnm
),nxy
);
1521 do_view(oenv
,opt2fn_null("-oda",NFILE
,fnm
),nxy
);
1522 do_view(oenv
,opt2fn_null("-odr",NFILE
,fnm
),nxy
);
1523 do_view(oenv
,opt2fn_null("-odt",NFILE
,fnm
),nxy
);
1524 do_view(oenv
,opt2fn_null("-oten",NFILE
,fnm
),nxy
);