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 * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
44 #include "gromacs/fileio/trx.h"
45 #include "gromacs/fileio/trxio.h"
46 #include "gromacs/math/vec.h"
47 #include "gromacs/topology/atoms.h"
48 #include "gromacs/topology/symtab.h"
49 #include "gromacs/utility/cstringutil.h"
50 #include "gromacs/utility/fatalerror.h"
51 #include "gromacs/utility/smalloc.h"
55 static int read_g96_pos(char line[], t_symtab *symtab,
56 FILE *fp, const char *infile,
61 int nwanted, natoms, atnr, resnr = 0, oldres, newres, shift;
62 char anm[STRLEN], resnm[STRLEN];
83 oldres = -666; /* Unlikely number for the first residue! */
85 while (!bEnd && fgets2(line, STRLEN, fp))
87 bEnd = (std::strncmp(line, "END", 3) == 0);
88 if (!bEnd && (line[0] != '#'))
90 if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
92 gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n",
95 if ((nwanted != -1) && (natoms >= nwanted))
98 "Found more coordinates (%d) in %s than expected %d\n",
99 natoms, infile, nwanted);
104 (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr)
114 strncpy(resnm, "???", sizeof(resnm)-1);
116 strncpy(anm, "???", sizeof(anm)-1);
118 atoms->atomname[natoms] = put_symtab(symtab, anm);
123 if (newres >= atoms->nr)
125 gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
128 atoms->atom[natoms].resind = newres;
129 if (newres+1 > atoms->nres)
131 atoms->nres = newres+1;
133 t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' ');
137 atoms->atom[natoms].resind = newres;
142 fr->x[natoms][0] = db1;
143 fr->x[natoms][1] = db2;
144 fr->x[natoms][2] = db3;
149 if ((nwanted != -1) && natoms != nwanted)
152 "Warning: found less coordinates (%d) in %s than expected %d\n",
153 natoms, infile, nwanted);
162 static int read_g96_vel(char line[], FILE *fp, const char *infile,
166 int nwanted, natoms = -1, shift;
167 double db1, db2, db3;
169 nwanted = fr->natoms;
173 if (strcmp(line, "VELOCITYRED") == 0)
183 while (!bEnd && fgets2(line, STRLEN, fp))
185 bEnd = (strncmp(line, "END", 3) == 0);
186 if (!bEnd && (line[0] != '#'))
188 if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
190 gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s",
193 if ((nwanted != -1) && (natoms >= nwanted))
195 gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n",
196 natoms, infile, nwanted);
200 fr->v[natoms][0] = db1;
201 fr->v[natoms][1] = db2;
202 fr->v[natoms][2] = db3;
207 if ((nwanted != -1) && (natoms != nwanted))
210 "Warning: found less velocities (%d) in %s than expected %d\n",
211 natoms, infile, nwanted);
218 int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line)
220 t_symtab *symtab = NULL;
221 gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished;
223 double db1, db2, db3, db4, db5, db6, db7, db8, db9;
225 bAtStart = (ftell(fp) == 0);
227 clear_trxframe(fr, FALSE);
239 while (!fr->bTitle && fgets2(line, STRLEN, fp))
241 fr->bTitle = (std::strcmp(line, "TITLE") == 0);
243 if (fr->title == NULL)
245 fgets2(line, STRLEN, fp);
246 fr->title = gmx_strdup(line);
249 while (!bEnd && fgets2(line, STRLEN, fp))
251 bEnd = (std::strcmp(line, "END") == 0);
253 fgets2(line, STRLEN, fp);
256 /* Do not get a line if we are not at the start of the file, *
257 * because without a parameter file we don't know what is in *
258 * the trajectory and we have already read the line in the *
259 * previous call (VERY DIRTY). */
263 bTime = (std::strcmp(line, "TIMESTEP") == 0);
264 bAtoms = (std::strcmp(line, "POSITION") == 0);
265 bPos = (bAtoms || (strcmp(line, "POSITIONRED") == 0));
266 bVel = (std::strncmp(line, "VELOCITY", 8) == 0);
267 bBox = (std::strcmp(line, "BOX") == 0);
270 if (!fr->bTime && !fr->bX)
276 bFinished = (fgets2(line, STRLEN, fp) == NULL);
278 while (!bFinished && (line[0] == '#'));
279 sscanf(line, "%15d%15lf", &(fr->step), &db1);
293 natoms = read_g96_pos(line, symtab, fp, infile, fr);
303 natoms = read_g96_vel(line, fp, infile, fr);
310 while (!bEnd && fgets2(line, STRLEN, fp))
312 bEnd = (strncmp(line, "END", 3) == 0);
313 if (!bEnd && (line[0] != '#'))
315 nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
316 &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9);
319 gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
321 fr->box[XX][XX] = db1;
322 fr->box[YY][YY] = db2;
323 fr->box[ZZ][ZZ] = db3;
326 fr->box[XX][YY] = db4;
327 fr->box[XX][ZZ] = db5;
328 fr->box[YY][XX] = db6;
329 fr->box[YY][ZZ] = db7;
330 fr->box[ZZ][XX] = db8;
331 fr->box[ZZ][YY] = db9;
338 while (!bFinished && fgets2(line, STRLEN, fp));
347 void write_g96_conf(FILE *out, t_trxframe *fr,
348 int nindex, const atom_id *index)
366 fprintf(out, "TITLE\n%s\nEND\n", fr->title);
368 if (fr->bStep || fr->bTime)
370 /* Officially the time format is %15.9, which is not enough for 10 ns */
371 fprintf(out, "TIMESTEP\n%15d%15.6f\nEND\n", fr->step, fr->time);
377 fprintf(out, "POSITION\n");
378 for (i = 0; i < nout; i++)
388 fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
389 (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
390 *atoms->resinfo[atoms->atom[a].resind].name,
391 *atoms->atomname[a], (i+1) % 10000000,
392 fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
397 fprintf(out, "POSITIONRED\n");
398 for (i = 0; i < nout; i++)
408 fprintf(out, "%15.9f%15.9f%15.9f\n",
409 fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
412 fprintf(out, "END\n");
418 fprintf(out, "VELOCITY\n");
419 for (i = 0; i < nout; i++)
429 fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
430 (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
431 *atoms->resinfo[atoms->atom[a].resind].name,
432 *atoms->atomname[a], (i+1) % 10000000,
433 fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
438 fprintf(out, "VELOCITYRED\n");
439 for (i = 0; i < nout; i++)
449 fprintf(out, "%15.9f%15.9f%15.9f\n",
450 fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
453 fprintf(out, "END\n");
457 fprintf(out, "BOX\n");
458 fprintf(out, "%15.9f%15.9f%15.9f",
459 fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]);
460 if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
461 fr->box[YY][ZZ] || fr->box[ZZ][XX] || fr->box[ZZ][YY])
463 fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
464 fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX],
465 fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
468 fprintf(out, "END\n");