2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
50 #include "gmx_fatal.h"
52 #define XTC_MAGIC 1995
55 static int xdr_r2f(XDR *xdrs,real *r,gmx_bool bRead)
63 ret = xdr_float(xdrs,&f);
69 return xdr_float(xdrs,(float *)r);
74 t_fileio *open_xtc(const char *fn,const char *mode)
76 return gmx_fio_open(fn,mode);
79 void close_xtc(t_fileio *fio)
84 static void check_xtc_magic(int magic)
86 if (magic != XTC_MAGIC)
87 gmx_fatal(FARGS,"Magic Number Error in XTC file (read %d, should be %d)",
91 int xtc_check(const char *str,gmx_bool bResult,const char *file,int line)
95 fprintf(debug,"\nXTC error: read/write of %s failed, "
96 "source file %s, line %d\n",str,file,line);
102 void xtc_check_fat_err(const char *str,gmx_bool bResult,const char *file,int line)
105 gmx_fatal(FARGS,"XTC read/write of %s failed, "
106 "source file %s, line %d\n",str,file,line);
110 static int xtc_header(XDR *xd,int *magic,int *natoms,int *step,real *time,
111 gmx_bool bRead,gmx_bool *bOK)
115 if (xdr_int(xd,magic) == 0)
117 result=XTC_CHECK("natoms", xdr_int(xd,natoms)); /* number of atoms */
119 result=XTC_CHECK("step", xdr_int(xd,step)); /* frame number */
121 result=XTC_CHECK("time", xdr_r2f(xd,time,bRead)); /* time */
127 static int xtc_coord(XDR *xd,int *natoms,matrix box,rvec *x,real *prec, gmx_bool bRead)
137 for(i=0; ((i<DIM) && result); i++)
138 for(j=0; ((j<DIM) && result); j++)
139 result=XTC_CHECK("box",xdr_r2f(xd,&(box[i][j]),bRead));
145 /* allocate temp. single-precision array */
146 snew(ftmp,(*natoms)*DIM);
148 /* Copy data to temp. array if writing */
151 for(i=0; (i<*natoms); i++)
153 ftmp[DIM*i+XX]=x[i][XX];
154 ftmp[DIM*i+YY]=x[i][YY];
155 ftmp[DIM*i+ZZ]=x[i][ZZ];
159 result=XTC_CHECK("x",xdr3dfcoord(xd,ftmp,natoms,&fprec));
161 /* Copy from temp. array if reading */
164 for(i=0; (i<*natoms); i++)
166 x[i][XX] = ftmp[DIM*i+XX];
167 x[i][YY] = ftmp[DIM*i+YY];
168 x[i][ZZ] = ftmp[DIM*i+ZZ];
174 result=XTC_CHECK("x",xdr3dfcoord(xd,x[0],natoms,prec));
182 int write_xtc(t_fileio *fio,
183 int natoms,int step,real time,
184 matrix box,rvec *x,real prec)
186 int magic_number = XTC_MAGIC;
191 xd = gmx_fio_getxdr(fio);
192 /* write magic number and xtc identidier */
193 if (xtc_header(xd,&magic_number,&natoms,&step,&time,FALSE,&bDum) == 0)
199 bOK = xtc_coord(xd,&natoms,box,x,&prec,FALSE); /* bOK will be 1 if writing went well */
203 if(gmx_fio_flush(fio) !=0)
208 return bOK; /* 0 if bad, 1 if writing went well */
211 int read_first_xtc(t_fileio *fio,int *natoms,int *step,real *time,
212 matrix box,rvec **x,real *prec,gmx_bool *bOK)
218 xd = gmx_fio_getxdr(fio);
220 /* read header and malloc x */
221 if ( !xtc_header(xd,&magic,natoms,step,time,TRUE,bOK))
224 /* Check magic number */
225 check_xtc_magic(magic);
229 *bOK=xtc_coord(xd,natoms,box,*x,prec,TRUE);
234 int read_next_xtc(t_fileio* fio,
235 int natoms,int *step,real *time,
236 matrix box,rvec *x,real *prec,gmx_bool *bOK)
243 xd = gmx_fio_getxdr(fio);
246 if (!xtc_header(xd,&magic,&n,step,time,TRUE,bOK))
249 /* Check magic number */
250 check_xtc_magic(magic);
253 gmx_fatal(FARGS, "Frame contains more atoms (%d) than expected (%d)",
257 *bOK=xtc_coord(xd,&natoms,box,x,prec,TRUE);