4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Great Red Owns Many ACres of Sand
40 void free_enxframe(t_enxframe
*fr
)
50 for(b
=0; b
<fr
->nblock
; b
++)
57 static void wr_ener_nms(FILE *out
,int nre
,char *nms
[])
61 fprintf(out
,"%d\n",nre
);
62 for(i
=0; (i
<nre
); i
++)
63 fprintf(out
,"%s\n",nms
[i
]);
66 static void rd_ener_nms(FILE *in
,int *nre
,char ***nm
)
72 if (sscanf(line
,"%d",nre
) == 0) {
77 for(i
=0; (i
< (*nre
)); i
++) {
80 (*nm
)[i
]=strdup(line
);
84 static void edr_nms(int fp
,int *nre
,char ***nms
)
87 bool bRead
= fio_getread(fp
);
95 if (!xdr_int(xdr
,nre
)) {
102 for(i
=0; i
<*nre
; i
++) {
103 if (bRead
&& NM
[i
]) {
107 xdr_string(xdr
,&(NM
[i
]),STRLEN
);
112 static bool do_eheader(int fp
,t_enxframe
*fr
,bool *bOK
)
115 bool bRead
= fio_getread(fp
);
119 if (!do_real(fr
->t
)) return FALSE
;
120 if (!do_int (fr
->step
)) *bOK
= FALSE
;
121 if (!do_int (fr
->nre
)) *bOK
= FALSE
;
122 if (!do_int (fr
->ndisre
)) *bOK
= FALSE
;
123 if (!do_int (fr
->nblock
)) *bOK
= FALSE
;
124 if (bRead
&& fr
->nblock
>70) {
125 /* Temporary fix for intermediate file version, only used by B. Hess */
126 tempfix_nr
= fr
->nblock
;
129 if (bRead
&& fr
->nblock
>fr
->nr_alloc
) {
130 srenew(fr
->nr
,fr
->nblock
);
131 srenew(fr
->b_alloc
,fr
->nblock
);
132 srenew(fr
->block
,fr
->nblock
);
133 for(i
=fr
->nr_alloc
; i
<fr
->nblock
; i
++) {
137 fr
->nr_alloc
= fr
->nblock
;
140 fr
->nr
[0] = tempfix_nr
;
142 for(block
=0; block
<fr
->nblock
; block
++)
143 if (!do_int (fr
->nr
[block
]))
146 if (!do_int (fr
->e_size
)) *bOK
= FALSE
;
147 if (!do_int (fr
->d_size
)) *bOK
= FALSE
;
148 /* Do a dummy int to keep the format compatible with the old code */
149 if (!do_int (dum
)) *bOK
= FALSE
;
154 void do_enxnms(int fp
,int *nre
,char ***nms
)
158 bRead
= fio_getread(fp
);
159 if (fio_getftp(fp
) == efEDR
) {
164 rd_ener_nms(fio_getfp(fp
),nre
,nms
);
166 wr_ener_nms(fio_getfp(fp
),*nre
,*nms
);
169 void close_enx(int fp
)
174 static bool empty_file(char *fn
)
181 fread(&dum
,sizeof(dum
),1,fp
);
190 int open_enx(char *fn
,char *mode
)
198 fp
=fio_open(fn
,mode
);
200 fio_setprecision(fp
,FALSE
);
201 do_enxnms(fp
,&nre
,&nm
);
203 do_eheader(fp
,fr
,&bDum
);
205 /* Now check whether this file is in single precision */
206 if (((fr
->e_size
&& (fr
->nre
== nre
) &&
207 (nre
*4*sizeof(float) == fr
->e_size
)) ||
209 (fr
->ndisre
*sizeof(float)*2+sizeof(int) == fr
->d_size
)))){
210 fprintf(stderr
,"Opened %s as single precision energy file\n",fn
);
211 for(i
=0; (i
<nre
); i
++)
218 fio_setprecision(fp
,TRUE
);
219 do_enxnms(fp
,&nre
,&nm
);
220 do_eheader(fp
,fr
,&bDum
);
221 if (((fr
->e_size
&& (fr
->nre
== nre
) &&
222 (nre
*4*sizeof(double) == fr
->e_size
)) ||
224 (fr
->ndisre
*sizeof(double)*2+sizeof(int) == fr
->d_size
))))
225 fprintf(stderr
,"Opened %s as double precision energy file\n",fn
);
228 fatal_error(0,"File %s is empty",fn
);
230 fatal_error(0,"Energy file %s not recognized, maybe different CPU?",
233 for(i
=0; (i
<nre
); i
++)
242 fp
= fio_open(fn
,mode
);
249 bool do_enx(int fp
,t_enxframe
*fr
)
252 bool bRead
,bOK
,bOK1
,bSane
;
256 bRead
= fio_getread(fp
);
258 fr
->e_size
= fr
->nre
*sizeof(fr
->ener
[0].e
)*4;
259 fr
->d_size
= fr
->ndisre
*(sizeof(fr
->rav
[0]) +
264 if (!do_eheader(fp
,fr
,&bOK
)) {
266 fprintf(stderr
,"\rLast frame read %d ",framenr
-1);
268 fprintf(stderr
,"\nWARNING: Incomplete frame: nr %6d time %8.3f\n",
274 if ( ( framenr
<10 ) || ( framenr
%10 == 0) )
275 fprintf(stderr
,"\rReading frame %6d time %8.3f ",framenr
,fr
->t
);
278 /* Check sanity of this header */
279 bSane
= (fr
->nre
> 0 || fr
->ndisre
> 0);
280 for(block
=0; block
<fr
->nblock
; block
++)
281 bSane
= bSane
|| (fr
->nr
[block
] > 0);
282 if (!((fr
->step
>= 0) && bSane
)) {
283 fprintf(stderr
,"\nWARNING: there may be something wrong with energy file %s\n",
285 fprintf(stderr
,"Found: step=%d, nre=%d, ndisre=%d, nblock=%d, time=%g.\n"
286 "Trying to skip frame expect a crash though\n",
287 fr
->step
,fr
->nre
,fr
->ndisre
,fr
->nblock
,fr
->t
);
289 if (bRead
&& fr
->nre
>fr
->e_alloc
) {
290 srenew(fr
->ener
,fr
->nre
);
291 fr
->e_alloc
= fr
->nre
;
293 for(i
=0; i
<fr
->nre
; i
++) {
294 bOK
= bOK
&& do_real(fr
->ener
[i
].e
);
296 tmp1
= fr
->ener
[i
].eav
;
297 if((tmp1
/(fr
->step
+1))<GMX_REAL_EPS
)
299 bOK
= bOK
&& do_real(tmp1
);
300 fr
->ener
[i
].eav
= tmp1
;
302 /* This is to save only in single precision (unless compiled in DP) */
303 tmp2
= fr
->ener
[i
].esum
;
304 bOK
= bOK
&& do_real(tmp2
);
305 fr
->ener
[i
].esum
= tmp2
;
307 bOK
= bOK
&& do_real(fr
->ener
[i
].e2sum
);
310 if (bRead
&& fr
->ndisre
>fr
->d_alloc
) {
311 srenew(fr
->rav
,fr
->ndisre
);
312 srenew(fr
->rt
,fr
->ndisre
);
313 fr
->d_alloc
= fr
->ndisre
;
315 ndo_real(fr
->rav
,fr
->ndisre
,bOK1
);
317 ndo_real(fr
->rt
,fr
->ndisre
,bOK1
);
320 for(block
=0; block
<fr
->nblock
; block
++) {
321 if (bRead
&& fr
->nr
[block
]>fr
->b_alloc
[block
]) {
322 srenew(fr
->block
[block
],fr
->nr
[block
]);
323 fr
->b_alloc
[block
] = fr
->nr
[block
];
325 ndo_real(fr
->block
[block
],fr
->nr
[block
],bOK1
);
330 fprintf(stderr
,"\nLast frame read %d ",
332 fprintf(stderr
,"\nWARNING: Incomplete frame: nr %6d time %8.3f \n",
335 fatal_error(-1,"could not write energies");