This is the release 1.0 version
[gromacs/libxdrfile.git] / src / xdrfile_trr.c
blob9256ae388d674c9def180564c93824735308f913
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 * $Id$
5 * Copyright (c) Erik Lindahl, David van der Spoel 2003,2004.
6 * Coordinate compression (c) by Frans van Hoesel.
8 * IN contrast to the rest of Gromacs, XDRFILE is distributed under the
9 * BSD license, so you can use it any way you wish, including closed source:
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
30 #include <stdlib.h>
31 #include <string.h>
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include "xdrfile.h"
38 #include "xdrfile_trr.h"
40 #define BUFSIZE 128
41 #define GROMACS_MAGIC 1993
43 typedef struct /* This struct describes the order and the */
44 /* sizes of the structs in a trjfile, sizes are given in bytes. */
46 bool bDouble; /* Double precision? */
47 int ir_size; /* Backward compatibility */
48 int e_size; /* Backward compatibility */
49 int box_size; /* Non zero if a box is present */
50 int vir_size; /* Backward compatibility */
51 int pres_size; /* Backward compatibility */
52 int top_size; /* Backward compatibility */
53 int sym_size; /* Backward compatibility */
54 int x_size; /* Non zero if coordinates are present */
55 int v_size; /* Non zero if velocities are present */
56 int f_size; /* Non zero if forces are present */
58 int natoms; /* The total number of atoms */
59 int step; /* Current step number */
60 int nre; /* Backward compatibility */
61 float tf; /* Current time */
62 float lambdaf; /* Current value of lambda */
63 double td; /* Current time */
64 double lambdad; /* Current value of lambda */
65 } t_trnheader;
67 static int nFloatSize(t_trnheader *sh,int *nflsz)
69 int nflsize=0;
71 if (sh->box_size)
72 nflsize = sh->box_size/(DIM*DIM);
73 else if (sh->x_size)
74 nflsize = sh->x_size/(sh->natoms*DIM);
75 else if (sh->v_size)
76 nflsize = sh->v_size/(sh->natoms*DIM);
77 else if (sh->f_size)
78 nflsize = sh->f_size/(sh->natoms*DIM);
79 else
80 return exdrHEADER;
82 if (((nflsize != sizeof(float)) && (nflsize != sizeof(double))))
83 return exdrHEADER;
85 *nflsz = nflsize;
87 return exdrOK;
90 static int do_trnheader(XDRFILE *xd,bool bRead,t_trnheader *sh)
92 int magic=GROMACS_MAGIC;
93 int nflsz,slen,result;
94 char *version = "GMX_trn_file";
95 char buf[BUFSIZE];
97 if (xdrfile_read_int(&magic,1,xd) != 1)
98 return exdrINT;
100 if (bRead)
102 if (xdrfile_read_int(&slen,1,xd) != 1)
103 return exdrINT;
104 if (slen != strlen(version)+1)
105 return exdrSTRING;
106 if (xdrfile_read_string(buf,BUFSIZE,xd) <= 0)
107 return exdrSTRING;
109 else
111 slen = strlen(version)+1;
112 if (xdrfile_read_int(&slen,1,xd) != 1)
113 return exdrINT;
114 if (xdrfile_write_string(version,xd) != (strlen(version)+1) )
115 return exdrSTRING;
117 if (xdrfile_read_int(&sh->ir_size,1,xd) != 1)
118 return exdrINT;
119 if (xdrfile_read_int(&sh->e_size,1,xd) != 1)
120 return exdrINT;
121 if (xdrfile_read_int(&sh->box_size,1,xd) != 1)
122 return exdrINT;
123 if (xdrfile_read_int(&sh->vir_size,1,xd) != 1)
124 return exdrINT;
125 if (xdrfile_read_int(&sh->pres_size,1,xd) != 1)
126 return exdrINT;
127 if (xdrfile_read_int(&sh->top_size,1,xd) != 1)
128 return exdrINT;
129 if (xdrfile_read_int(&sh->sym_size,1,xd) != 1)
130 return exdrINT;
131 if (xdrfile_read_int(&sh->x_size,1,xd) != 1)
132 return exdrINT;
133 if (xdrfile_read_int(&sh->v_size,1,xd) != 1)
134 return exdrINT;
135 if (xdrfile_read_int(&sh->f_size,1,xd) != 1)
136 return exdrINT;
137 if (xdrfile_read_int(&sh->natoms,1,xd) != 1)
138 return exdrINT;
140 if ((result = nFloatSize(sh,&nflsz)) != exdrOK)
141 return result;
142 sh->bDouble = (nflsz == sizeof(double));
144 if (xdrfile_read_int(&sh->step,1,xd) != 1)
145 return exdrINT;
146 if (xdrfile_read_int(&sh->nre,1,xd) != 1)
147 return exdrINT;
148 if (sh->bDouble)
150 if (xdrfile_read_double(&sh->td,1,xd) != 1)
151 return exdrDOUBLE;
152 sh->tf = sh->td;
153 if (xdrfile_read_double(&sh->lambdad,1,xd) != 1)
154 return exdrDOUBLE;
155 sh->lambdaf = sh->lambdad;
157 else
159 if (xdrfile_read_float(&sh->tf,1,xd) != 1)
160 return exdrFLOAT;
161 sh->td = sh->tf;
162 if (xdrfile_read_float(&sh->lambdaf,1,xd) != 1)
163 return exdrFLOAT;
164 sh->lambdad = sh->lambdaf;
167 return exdrOK;
170 static int do_htrn(XDRFILE *xd,bool bRead,t_trnheader *sh,
171 matrix box,rvec *x,rvec *v,rvec *f)
173 double pvd[DIM*DIM];
174 double *dx;
175 float pvf[DIM*DIM];
176 float *fx;
177 int i,j;
179 if (sh->bDouble)
181 if (sh->box_size != 0)
183 if (!bRead)
185 for(i=0; (i<DIM); i++)
186 for(j=0; (j<DIM); j++)
187 if (NULL != box)
189 pvd[i*DIM+j] = box[i][j];
192 if (xdrfile_read_double(pvd,DIM*DIM,xd) == DIM*DIM)
194 for(i=0; (i<DIM); i++)
195 for(j=0; (j<DIM); j++)
196 if (NULL != box)
198 box[i][j] = pvd[i*DIM+j];
201 else
202 return exdrDOUBLE;
205 if (sh->vir_size != 0)
207 if (xdrfile_read_double(pvd,DIM*DIM,xd) != DIM*DIM)
208 return exdrDOUBLE;
211 if (sh->pres_size!= 0)
213 if (xdrfile_read_double(pvd,DIM*DIM,xd) != DIM*DIM)
214 return exdrDOUBLE;
217 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
218 dx = calloc(sh->natoms*DIM,sizeof(dx[0]));
219 if (NULL == dx)
220 return exdrNOMEM;
222 if (sh->x_size != 0)
224 if (!bRead)
226 for(i=0; (i<sh->natoms); i++)
227 for(j=0; (j<DIM); j++)
228 if (NULL != x)
230 dx[i*DIM+j] = x[i][j];
233 if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
235 if (bRead)
237 for(i=0; (i<sh->natoms); i++)
238 for(j=0; (j<DIM); j++)
239 if (NULL != x)
241 x[i][j] = dx[i*DIM+j];
245 else
246 return exdrDOUBLE;
248 if (sh->v_size != 0)
250 if (!bRead)
252 for(i=0; (i<sh->natoms); i++)
253 for(j=0; (j<DIM); j++)
254 if (NULL != x)
256 dx[i*DIM+j] = v[i][j];
259 if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
261 for(i=0; (i<sh->natoms); i++)
262 for(j=0; (j<DIM); j++)
263 if (NULL != v)
265 v[i][j] = dx[i*DIM+j];
268 else
269 return exdrDOUBLE;
271 if (sh->f_size != 0)
273 if (!bRead)
275 for(i=0; (i<sh->natoms); i++)
276 for(j=0; (j<DIM); j++)
277 if (NULL != x)
279 dx[i*DIM+j] = f[i][j];
282 if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
284 for(i=0; (i<sh->natoms); i++)
286 for(j=0; (j<DIM); j++)
288 if (NULL != f)
290 f[i][j] = dx[i*DIM+j];
295 else
296 return exdrDOUBLE;
298 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
299 free(dx);
302 else
303 /* Float */
305 if (sh->box_size != 0)
307 if (!bRead)
309 for(i=0; (i<DIM); i++)
310 for(j=0; (j<DIM); j++)
311 if (NULL != box)
313 pvf[i*DIM+j] = box[i][j];
316 if (xdrfile_read_float(pvf,DIM*DIM,xd) == DIM*DIM)
318 for(i=0; (i<DIM); i++)
320 for(j=0; (j<DIM); j++)
322 if (NULL != box)
324 box[i][j] = pvf[i*DIM+j];
329 else
330 return exdrFLOAT;
333 if (sh->vir_size != 0)
335 if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM)
336 return exdrFLOAT;
339 if (sh->pres_size!= 0)
341 if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM)
342 return exdrFLOAT;
345 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
346 fx = calloc(sh->natoms*DIM,sizeof(fx[0]));
347 if (NULL == fx)
348 return exdrNOMEM;
350 if (sh->x_size != 0)
352 if (!bRead)
354 for(i=0; (i<sh->natoms); i++)
355 for(j=0; (j<DIM); j++)
356 if (NULL != x)
358 fx[i*DIM+j] = x[i][j];
361 if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
363 if (bRead)
365 for(i=0; (i<sh->natoms); i++)
366 for(j=0; (j<DIM); j++)
367 if (NULL != x)
368 x[i][j] = fx[i*DIM+j];
371 else
372 return exdrFLOAT;
374 if (sh->v_size != 0)
376 if (!bRead)
378 for(i=0; (i<sh->natoms); i++)
379 for(j=0; (j<DIM); j++)
380 if (NULL != x)
382 fx[i*DIM+j] = v[i][j];
385 if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
387 for(i=0; (i<sh->natoms); i++)
388 for(j=0; (j<DIM); j++)
389 if (NULL != v)
390 v[i][j] = fx[i*DIM+j];
392 else
393 return exdrFLOAT;
395 if (sh->f_size != 0)
397 if (!bRead)
399 for(i=0; (i<sh->natoms); i++)
400 for(j=0; (j<DIM); j++)
401 if (NULL != x)
403 fx[i*DIM+j] = f[i][j];
406 if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
408 for(i=0; (i<sh->natoms); i++)
409 for(j=0; (j<DIM); j++)
410 if (NULL != f)
411 f[i][j] = fx[i*DIM+j];
413 else
414 return exdrFLOAT;
416 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
417 free(fx);
420 return exdrOK;
423 static int do_trn(XDRFILE *xd,bool bRead,int *step,float *t,float *lambda,
424 matrix box,int *natoms,rvec *x,rvec *v,rvec *f)
426 t_trnheader *sh;
427 int result;
429 sh = calloc(1,sizeof(*sh));
431 if (!bRead) {
432 sh->box_size = (NULL != box) ? sizeof(matrix):0;
433 sh->x_size = ((NULL != x) ? (*natoms*sizeof(x[0])):0);
434 sh->v_size = ((NULL != v) ? (*natoms*sizeof(v[0])):0);
435 sh->f_size = ((NULL != f) ? (*natoms*sizeof(f[0])):0);
436 sh->natoms = *natoms;
437 sh->step = *step;
438 sh->nre = 0;
439 sh->td = *t;
440 sh->lambdad = *lambda;
441 sh->tf = *t;
442 sh->lambdaf = *lambda;
444 if ((result = do_trnheader(xd,bRead,sh)) != exdrOK)
445 return result;
446 if (bRead) {
447 *natoms = sh->natoms;
448 *step = sh->step;
449 *t = sh->td;
450 *lambda = sh->lambdad;
452 if ((result = do_htrn(xd,bRead,sh,box,x,v,f)) != exdrOK)
453 return result;
455 free(sh);
457 return exdrOK;
460 /************************************************************
462 * The following routines are the exported ones
464 ************************************************************/
466 int read_trr_natoms(char *fn,int *natoms)
468 XDRFILE *xd;
469 t_trnheader sh;
470 int result;
472 xd = xdrfile_open(fn,"r");
473 if (NULL == xd)
474 return exdrFILENOTFOUND;
475 if ((result = do_trnheader(xd,1,&sh)) != exdrOK)
476 return result;
477 xdrfile_close(xd);
478 *natoms = sh.natoms;
480 return exdrOK;
483 int write_trr(XDRFILE *xd,int natoms,int step,float t,float lambda,
484 matrix box,rvec *x,rvec *v,rvec *f)
486 return do_trn(xd,0,&step,&t,&lambda,box,&natoms,x,v,f);
489 int read_trr(XDRFILE *xd,int natoms,int *step,float *t,float *lambda,
490 matrix box,rvec *x,rvec *v,rvec *f)
492 return do_trn(xd,1,step,t,lambda,box,&natoms,x,v,f);