Split g96 I/O routines from confio.cpp
authorTeemu Murtola <teemu.murtola@gmail.com>
Wed, 22 Jul 2015 17:45:41 +0000 (20:45 +0300)
committerTeemu Murtola <teemu.murtola@gmail.com>
Wed, 22 Jul 2015 18:30:38 +0000 (21:30 +0300)
Move routines to read/write g96 files to g96io.*.
Ideally, these would be internal to the fileio/ module, but trjconv
has some ugliness.

Silence a pedantic clang warning that makes it impossible to minimize
header dependencies for mixed C/C++ code, and where problems would
anyways trigger as compilation failures in C code.

Change-Id: I20a88234bec8527f8fd41a614fb37e3144eb7532

cmake/gmxCFlags.cmake
src/gromacs/fileio/confio.cpp
src/gromacs/fileio/confio.h
src/gromacs/fileio/g96io.cpp [new file with mode: 0644]
src/gromacs/fileio/g96io.h [new file with mode: 0644]
src/gromacs/fileio/trxio.cpp
src/gromacs/gmxana/gmx_trjconv.c
src/gromacs/topology/mtop_util.h

index 3e8644e843b4065f1eedd0932c65409db7b89586..6ef7b48c447fbb6d9de4a3a1cc12d0da52475f44 100644 (file)
@@ -314,6 +314,8 @@ MACRO(gmx_c_flags)
         if(NOT GMX_OPENMP)
             GMX_TEST_CXXFLAG(CXXFLAGS_PRAGMA "-Wno-unknown-pragmas" GMXC_CXXFLAGS)
         endif()
+        # Once we get rid of most extern "C" declarations, this can hopefully go away.
+        GMX_TEST_CXXFLAG(CXXFLAGS_WARN_PEDANTIC "-Wno-return-type-c-linkage" GMXC_CXXFLAGS)
         GMX_TEST_CXXFLAG(CXXFLAGS_WARN "-Wall -Wno-unused-function" GMXC_CXXFLAGS)
         GMX_TEST_CXXFLAG(CXXFLAGS_WARN_EXTRA "-Wextra -Wno-missing-field-initializers -Wpointer-arith" GMXC_CXXFLAGS)
     endif()
index a7d9fdaa5d483d4eaf70282fc4927d6c4cec8096..b9844ba9671bec3b1fd5a29134099ae3db9e189b 100644 (file)
 #include <algorithm>
 
 #include "gromacs/fileio/filenm.h"
+#include "gromacs/fileio/g96io.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/fileio/pdbio.h"
 #include "gromacs/fileio/tpxio.h"
 #include "gromacs/fileio/trx.h"
 #include "gromacs/fileio/trxio.h"
-#include "gromacs/fileio/xdrf.h"
 #include "gromacs/legacyheaders/copyrite.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/legacyheaders/typedefs.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/topology/atomprop.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/block.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/symtab.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
 #include "gromacs/utility/smalloc.h"
 
-#define CHAR_SHIFT 24
-
-static int read_g96_pos(char line[], t_symtab *symtab,
-                        FILE *fp, const char *infile,
-                        t_trxframe *fr)
-{
-    t_atoms   *atoms;
-    gmx_bool   bEnd;
-    int        nwanted, natoms, atnr, resnr = 0, oldres, newres, shift;
-    char       anm[STRLEN], resnm[STRLEN];
-    char       c1, c2;
-    double     db1, db2, db3;
-
-    nwanted = fr->natoms;
-
-    atoms = fr->atoms;
-
-    natoms = 0;
-
-    if (fr->bX)
-    {
-        if (fr->bAtoms)
-        {
-            shift = CHAR_SHIFT;
-        }
-        else
-        {
-            shift = 0;
-        }
-        newres  = -1;
-        oldres  = -666; /* Unlikely number for the first residue! */
-        bEnd    = FALSE;
-        while (!bEnd && fgets2(line, STRLEN, fp))
-        {
-            bEnd = (std::strncmp(line, "END", 3) == 0);
-            if (!bEnd  && (line[0] != '#'))
-            {
-                if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
-                {
-                    gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n",
-                              natoms+1, infile);
-                }
-                if ((nwanted != -1) && (natoms >= nwanted))
-                {
-                    gmx_fatal(FARGS,
-                              "Found more coordinates (%d) in %s than expected %d\n",
-                              natoms, infile, nwanted);
-                }
-                if (atoms)
-                {
-                    if (fr->bAtoms &&
-                        (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr)
-                         != 6))
-                    {
-                        if (oldres >= 0)
-                        {
-                            resnr = oldres;
-                        }
-                        else
-                        {
-                            resnr    = 1;
-                            strncpy(resnm, "???", sizeof(resnm)-1);
-                        }
-                        strncpy(anm, "???", sizeof(anm)-1);
-                    }
-                    atoms->atomname[natoms] = put_symtab(symtab, anm);
-                    if (resnr != oldres)
-                    {
-                        oldres = resnr;
-                        newres++;
-                        if (newres >= atoms->nr)
-                        {
-                            gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
-                                      infile, atoms->nr);
-                        }
-                        atoms->atom[natoms].resind = newres;
-                        if (newres+1 > atoms->nres)
-                        {
-                            atoms->nres = newres+1;
-                        }
-                        t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' ');
-                    }
-                    else
-                    {
-                        atoms->atom[natoms].resind = newres;
-                    }
-                }
-                if (fr->x)
-                {
-                    fr->x[natoms][0] = db1;
-                    fr->x[natoms][1] = db2;
-                    fr->x[natoms][2] = db3;
-                }
-                natoms++;
-            }
-        }
-        if ((nwanted != -1) && natoms != nwanted)
-        {
-            fprintf(stderr,
-                    "Warning: found less coordinates (%d) in %s than expected %d\n",
-                    natoms, infile, nwanted);
-        }
-    }
-
-    fr->natoms = natoms;
-
-    return natoms;
-}
-
-static int read_g96_vel(char line[], FILE *fp, const char *infile,
-                        t_trxframe *fr)
-{
-    gmx_bool   bEnd;
-    int        nwanted, natoms = -1, shift;
-    double     db1, db2, db3;
-
-    nwanted = fr->natoms;
-
-    if (fr->v && fr->bV)
-    {
-        if (strcmp(line, "VELOCITYRED") == 0)
-        {
-            shift = 0;
-        }
-        else
-        {
-            shift = CHAR_SHIFT;
-        }
-        natoms = 0;
-        bEnd   = FALSE;
-        while (!bEnd && fgets2(line, STRLEN, fp))
-        {
-            bEnd = (strncmp(line, "END", 3) == 0);
-            if (!bEnd && (line[0] != '#'))
-            {
-                if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
-                {
-                    gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s",
-                              natoms+1, infile);
-                }
-                if ((nwanted != -1) && (natoms >= nwanted))
-                {
-                    gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n",
-                              natoms, infile, nwanted);
-                }
-                if (fr->v)
-                {
-                    fr->v[natoms][0] = db1;
-                    fr->v[natoms][1] = db2;
-                    fr->v[natoms][2] = db3;
-                }
-                natoms++;
-            }
-        }
-        if ((nwanted != -1) && (natoms != nwanted))
-        {
-            fprintf(stderr,
-                    "Warning: found less velocities (%d) in %s than expected %d\n",
-                    natoms, infile, nwanted);
-        }
-    }
-
-    return natoms;
-}
-
-int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line)
-{
-    t_symtab  *symtab = NULL;
-    gmx_bool   bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished;
-    int        natoms, nbp;
-    double     db1, db2, db3, db4, db5, db6, db7, db8, db9;
-
-    bAtStart = (ftell(fp) == 0);
-
-    clear_trxframe(fr, FALSE);
-
-    if (!symtab)
-    {
-        snew(symtab, 1);
-        open_symtab(symtab);
-    }
-
-    natoms = 0;
-
-    if (bAtStart)
-    {
-        while (!fr->bTitle && fgets2(line, STRLEN, fp))
-        {
-            fr->bTitle = (std::strcmp(line, "TITLE") == 0);
-        }
-        if (fr->title == NULL)
-        {
-            fgets2(line, STRLEN, fp);
-            fr->title = gmx_strdup(line);
-        }
-        bEnd = FALSE;
-        while (!bEnd && fgets2(line, STRLEN, fp))
-        {
-            bEnd = (std::strcmp(line, "END") == 0);
-        }
-        fgets2(line, STRLEN, fp);
-    }
-
-    /* Do not get a line if we are not at the start of the file, *
-     * because without a parameter file we don't know what is in *
-     * the trajectory and we have already read the line in the   *
-     * previous call (VERY DIRTY).                               */
-    bFinished = FALSE;
-    do
-    {
-        bTime  = (std::strcmp(line, "TIMESTEP") == 0);
-        bAtoms = (std::strcmp(line, "POSITION") == 0);
-        bPos   = (bAtoms || (strcmp(line, "POSITIONRED") == 0));
-        bVel   = (std::strncmp(line, "VELOCITY", 8) == 0);
-        bBox   = (std::strcmp(line, "BOX") == 0);
-        if (bTime)
-        {
-            if (!fr->bTime && !fr->bX)
-            {
-                fr->bStep = bTime;
-                fr->bTime = bTime;
-                do
-                {
-                    bFinished = (fgets2(line, STRLEN, fp) == NULL);
-                }
-                while (!bFinished && (line[0] == '#'));
-                sscanf(line, "%15d%15lf", &(fr->step), &db1);
-                fr->time = db1;
-            }
-            else
-            {
-                bFinished = TRUE;
-            }
-        }
-        if (bPos)
-        {
-            if (!fr->bX)
-            {
-                fr->bAtoms = bAtoms;
-                fr->bX     = bPos;
-                natoms     = read_g96_pos(line, symtab, fp, infile, fr);
-            }
-            else
-            {
-                bFinished = TRUE;
-            }
-        }
-        if (fr->v && bVel)
-        {
-            fr->bV = bVel;
-            natoms = read_g96_vel(line, fp, infile, fr);
-        }
-        if (bBox)
-        {
-            fr->bBox = bBox;
-            clear_mat(fr->box);
-            bEnd = FALSE;
-            while (!bEnd && fgets2(line, STRLEN, fp))
-            {
-                bEnd = (strncmp(line, "END", 3) == 0);
-                if (!bEnd && (line[0] != '#'))
-                {
-                    nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
-                                 &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9);
-                    if (nbp < 3)
-                    {
-                        gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
-                    }
-                    fr->box[XX][XX] = db1;
-                    fr->box[YY][YY] = db2;
-                    fr->box[ZZ][ZZ] = db3;
-                    if (nbp == 9)
-                    {
-                        fr->box[XX][YY] = db4;
-                        fr->box[XX][ZZ] = db5;
-                        fr->box[YY][XX] = db6;
-                        fr->box[YY][ZZ] = db7;
-                        fr->box[ZZ][XX] = db8;
-                        fr->box[ZZ][YY] = db9;
-                    }
-                }
-            }
-            bFinished = TRUE;
-        }
-    }
-    while (!bFinished && fgets2(line, STRLEN, fp));
-
-    free_symtab(symtab);
-
-    fr->natoms = natoms;
-
-    return natoms;
-}
-
-void write_g96_conf(FILE *out, t_trxframe *fr,
-                    int nindex, const atom_id *index)
-{
-    t_atoms *atoms;
-    int      nout, i, a;
-
-    atoms = fr->atoms;
-
-    if (index)
-    {
-        nout = nindex;
-    }
-    else
-    {
-        nout = fr->natoms;
-    }
-
-    if (fr->bTitle)
-    {
-        fprintf(out, "TITLE\n%s\nEND\n", fr->title);
-    }
-    if (fr->bStep || fr->bTime)
-    {
-        /* Officially the time format is %15.9, which is not enough for 10 ns */
-        fprintf(out, "TIMESTEP\n%15d%15.6f\nEND\n", fr->step, fr->time);
-    }
-    if (fr->bX)
-    {
-        if (fr->bAtoms)
-        {
-            fprintf(out, "POSITION\n");
-            for (i = 0; i < nout; i++)
-            {
-                if (index)
-                {
-                    a = index[i];
-                }
-                else
-                {
-                    a = i;
-                }
-                fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
-                        (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
-                        *atoms->resinfo[atoms->atom[a].resind].name,
-                        *atoms->atomname[a], (i+1) % 10000000,
-                        fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
-            }
-        }
-        else
-        {
-            fprintf(out, "POSITIONRED\n");
-            for (i = 0; i < nout; i++)
-            {
-                if (index)
-                {
-                    a = index[i];
-                }
-                else
-                {
-                    a = i;
-                }
-                fprintf(out, "%15.9f%15.9f%15.9f\n",
-                        fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
-            }
-        }
-        fprintf(out, "END\n");
-    }
-    if (fr->bV)
-    {
-        if (fr->bAtoms)
-        {
-            fprintf(out, "VELOCITY\n");
-            for (i = 0; i < nout; i++)
-            {
-                if (index)
-                {
-                    a = index[i];
-                }
-                else
-                {
-                    a = i;
-                }
-                fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
-                        (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
-                        *atoms->resinfo[atoms->atom[a].resind].name,
-                        *atoms->atomname[a], (i+1) % 10000000,
-                        fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
-            }
-        }
-        else
-        {
-            fprintf(out, "VELOCITYRED\n");
-            for (i = 0; i < nout; i++)
-            {
-                if (index)
-                {
-                    a = index[i];
-                }
-                else
-                {
-                    a = i;
-                }
-                fprintf(out, "%15.9f%15.9f%15.9f\n",
-                        fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
-            }
-        }
-        fprintf(out, "END\n");
-    }
-    if (fr->bBox)
-    {
-        fprintf(out, "BOX\n");
-        fprintf(out, "%15.9f%15.9f%15.9f",
-                fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]);
-        if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
-            fr->box[YY][ZZ] || fr->box[ZZ][XX] || fr->box[ZZ][YY])
-        {
-            fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
-                    fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX],
-                    fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
-        }
-        fprintf(out, "\n");
-        fprintf(out, "END\n");
-    }
-}
-
 static int get_espresso_word(FILE *fp, char word[])
 {
     int  ret, nc, i;
@@ -940,7 +520,7 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title,
     char      *p1, *p2, *p3;
 
     newres  = -1;
-    oldres  = NOTSET; /* Unlikely number for the first residue! */
+    oldres  = -12345; /* Unlikely number for the first residue! */
     ddist   = 0;
 
     /* Read the title and number of atoms */
index f27b1b648b45f696eb1a583d2764c00b1624e560..194c514e515b85484139b4c9b887559ed4cfc496 100644 (file)
@@ -34,7 +34,6 @@
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-
 #ifndef GMX_FILEIO_CONFIO_H
 #define GMX_FILEIO_CONFIO_H
 
@@ -54,20 +53,6 @@ struct gmx_mtop_t;
 struct t_atoms;
 struct t_topology;
 
-int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line);
-/* read a Gromos96 coordinate or trajectory file,                       *
- * returns the number of atoms                                          *
- * sets what's in the frame in info                                     *
- * read from fp, infile is only needed for error messages               *
- * nwanted is the number of wanted coordinates,                         *
- * set this to -1 if you want to know the number of atoms in the file   *
- * title, atoms, x, v can all be NULL, in which case they won't be read *
- * line holds the previous line for trajectory reading                  */
-
-void write_g96_conf(FILE *out, t_trxframe *fr, int nindex, const atom_id *index);
-/* write a Gromos96 coordinate file or trajectory frame *
- * index can be NULL                                    */
-
 gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr);
 int gro_first_x_or_v(FILE *status, t_trxframe *fr);
 /* read first/next x and/or v frame from gro file */
diff --git a/src/gromacs/fileio/g96io.cpp b/src/gromacs/fileio/g96io.cpp
new file mode 100644 (file)
index 0000000..d7404c4
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#include "gmxpre.h"
+
+#include "g96io.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include "gromacs/fileio/trx.h"
+#include "gromacs/fileio/trxio.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/topology/atoms.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/smalloc.h"
+
+#define CHAR_SHIFT 24
+
+static int read_g96_pos(char line[], t_symtab *symtab,
+                        FILE *fp, const char *infile,
+                        t_trxframe *fr)
+{
+    t_atoms   *atoms;
+    gmx_bool   bEnd;
+    int        nwanted, natoms, atnr, resnr = 0, oldres, newres, shift;
+    char       anm[STRLEN], resnm[STRLEN];
+    char       c1, c2;
+    double     db1, db2, db3;
+
+    nwanted = fr->natoms;
+
+    atoms = fr->atoms;
+
+    natoms = 0;
+
+    if (fr->bX)
+    {
+        if (fr->bAtoms)
+        {
+            shift = CHAR_SHIFT;
+        }
+        else
+        {
+            shift = 0;
+        }
+        newres  = -1;
+        oldres  = -666; /* Unlikely number for the first residue! */
+        bEnd    = FALSE;
+        while (!bEnd && fgets2(line, STRLEN, fp))
+        {
+            bEnd = (std::strncmp(line, "END", 3) == 0);
+            if (!bEnd  && (line[0] != '#'))
+            {
+                if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
+                {
+                    gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n",
+                              natoms+1, infile);
+                }
+                if ((nwanted != -1) && (natoms >= nwanted))
+                {
+                    gmx_fatal(FARGS,
+                              "Found more coordinates (%d) in %s than expected %d\n",
+                              natoms, infile, nwanted);
+                }
+                if (atoms)
+                {
+                    if (fr->bAtoms &&
+                        (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr)
+                         != 6))
+                    {
+                        if (oldres >= 0)
+                        {
+                            resnr = oldres;
+                        }
+                        else
+                        {
+                            resnr    = 1;
+                            strncpy(resnm, "???", sizeof(resnm)-1);
+                        }
+                        strncpy(anm, "???", sizeof(anm)-1);
+                    }
+                    atoms->atomname[natoms] = put_symtab(symtab, anm);
+                    if (resnr != oldres)
+                    {
+                        oldres = resnr;
+                        newres++;
+                        if (newres >= atoms->nr)
+                        {
+                            gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
+                                      infile, atoms->nr);
+                        }
+                        atoms->atom[natoms].resind = newres;
+                        if (newres+1 > atoms->nres)
+                        {
+                            atoms->nres = newres+1;
+                        }
+                        t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' ');
+                    }
+                    else
+                    {
+                        atoms->atom[natoms].resind = newres;
+                    }
+                }
+                if (fr->x)
+                {
+                    fr->x[natoms][0] = db1;
+                    fr->x[natoms][1] = db2;
+                    fr->x[natoms][2] = db3;
+                }
+                natoms++;
+            }
+        }
+        if ((nwanted != -1) && natoms != nwanted)
+        {
+            fprintf(stderr,
+                    "Warning: found less coordinates (%d) in %s than expected %d\n",
+                    natoms, infile, nwanted);
+        }
+    }
+
+    fr->natoms = natoms;
+
+    return natoms;
+}
+
+static int read_g96_vel(char line[], FILE *fp, const char *infile,
+                        t_trxframe *fr)
+{
+    gmx_bool   bEnd;
+    int        nwanted, natoms = -1, shift;
+    double     db1, db2, db3;
+
+    nwanted = fr->natoms;
+
+    if (fr->v && fr->bV)
+    {
+        if (strcmp(line, "VELOCITYRED") == 0)
+        {
+            shift = 0;
+        }
+        else
+        {
+            shift = CHAR_SHIFT;
+        }
+        natoms = 0;
+        bEnd   = FALSE;
+        while (!bEnd && fgets2(line, STRLEN, fp))
+        {
+            bEnd = (strncmp(line, "END", 3) == 0);
+            if (!bEnd && (line[0] != '#'))
+            {
+                if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3)
+                {
+                    gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s",
+                              natoms+1, infile);
+                }
+                if ((nwanted != -1) && (natoms >= nwanted))
+                {
+                    gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n",
+                              natoms, infile, nwanted);
+                }
+                if (fr->v)
+                {
+                    fr->v[natoms][0] = db1;
+                    fr->v[natoms][1] = db2;
+                    fr->v[natoms][2] = db3;
+                }
+                natoms++;
+            }
+        }
+        if ((nwanted != -1) && (natoms != nwanted))
+        {
+            fprintf(stderr,
+                    "Warning: found less velocities (%d) in %s than expected %d\n",
+                    natoms, infile, nwanted);
+        }
+    }
+
+    return natoms;
+}
+
+int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line)
+{
+    t_symtab  *symtab = NULL;
+    gmx_bool   bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished;
+    int        natoms, nbp;
+    double     db1, db2, db3, db4, db5, db6, db7, db8, db9;
+
+    bAtStart = (ftell(fp) == 0);
+
+    clear_trxframe(fr, FALSE);
+
+    if (!symtab)
+    {
+        snew(symtab, 1);
+        open_symtab(symtab);
+    }
+
+    natoms = 0;
+
+    if (bAtStart)
+    {
+        while (!fr->bTitle && fgets2(line, STRLEN, fp))
+        {
+            fr->bTitle = (std::strcmp(line, "TITLE") == 0);
+        }
+        if (fr->title == NULL)
+        {
+            fgets2(line, STRLEN, fp);
+            fr->title = gmx_strdup(line);
+        }
+        bEnd = FALSE;
+        while (!bEnd && fgets2(line, STRLEN, fp))
+        {
+            bEnd = (std::strcmp(line, "END") == 0);
+        }
+        fgets2(line, STRLEN, fp);
+    }
+
+    /* Do not get a line if we are not at the start of the file, *
+     * because without a parameter file we don't know what is in *
+     * the trajectory and we have already read the line in the   *
+     * previous call (VERY DIRTY).                               */
+    bFinished = FALSE;
+    do
+    {
+        bTime  = (std::strcmp(line, "TIMESTEP") == 0);
+        bAtoms = (std::strcmp(line, "POSITION") == 0);
+        bPos   = (bAtoms || (strcmp(line, "POSITIONRED") == 0));
+        bVel   = (std::strncmp(line, "VELOCITY", 8) == 0);
+        bBox   = (std::strcmp(line, "BOX") == 0);
+        if (bTime)
+        {
+            if (!fr->bTime && !fr->bX)
+            {
+                fr->bStep = bTime;
+                fr->bTime = bTime;
+                do
+                {
+                    bFinished = (fgets2(line, STRLEN, fp) == NULL);
+                }
+                while (!bFinished && (line[0] == '#'));
+                sscanf(line, "%15d%15lf", &(fr->step), &db1);
+                fr->time = db1;
+            }
+            else
+            {
+                bFinished = TRUE;
+            }
+        }
+        if (bPos)
+        {
+            if (!fr->bX)
+            {
+                fr->bAtoms = bAtoms;
+                fr->bX     = bPos;
+                natoms     = read_g96_pos(line, symtab, fp, infile, fr);
+            }
+            else
+            {
+                bFinished = TRUE;
+            }
+        }
+        if (fr->v && bVel)
+        {
+            fr->bV = bVel;
+            natoms = read_g96_vel(line, fp, infile, fr);
+        }
+        if (bBox)
+        {
+            fr->bBox = bBox;
+            clear_mat(fr->box);
+            bEnd = FALSE;
+            while (!bEnd && fgets2(line, STRLEN, fp))
+            {
+                bEnd = (strncmp(line, "END", 3) == 0);
+                if (!bEnd && (line[0] != '#'))
+                {
+                    nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
+                                 &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9);
+                    if (nbp < 3)
+                    {
+                        gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile);
+                    }
+                    fr->box[XX][XX] = db1;
+                    fr->box[YY][YY] = db2;
+                    fr->box[ZZ][ZZ] = db3;
+                    if (nbp == 9)
+                    {
+                        fr->box[XX][YY] = db4;
+                        fr->box[XX][ZZ] = db5;
+                        fr->box[YY][XX] = db6;
+                        fr->box[YY][ZZ] = db7;
+                        fr->box[ZZ][XX] = db8;
+                        fr->box[ZZ][YY] = db9;
+                    }
+                }
+            }
+            bFinished = TRUE;
+        }
+    }
+    while (!bFinished && fgets2(line, STRLEN, fp));
+
+    free_symtab(symtab);
+
+    fr->natoms = natoms;
+
+    return natoms;
+}
+
+void write_g96_conf(FILE *out, t_trxframe *fr,
+                    int nindex, const atom_id *index)
+{
+    t_atoms *atoms;
+    int      nout, i, a;
+
+    atoms = fr->atoms;
+
+    if (index)
+    {
+        nout = nindex;
+    }
+    else
+    {
+        nout = fr->natoms;
+    }
+
+    if (fr->bTitle)
+    {
+        fprintf(out, "TITLE\n%s\nEND\n", fr->title);
+    }
+    if (fr->bStep || fr->bTime)
+    {
+        /* Officially the time format is %15.9, which is not enough for 10 ns */
+        fprintf(out, "TIMESTEP\n%15d%15.6f\nEND\n", fr->step, fr->time);
+    }
+    if (fr->bX)
+    {
+        if (fr->bAtoms)
+        {
+            fprintf(out, "POSITION\n");
+            for (i = 0; i < nout; i++)
+            {
+                if (index)
+                {
+                    a = index[i];
+                }
+                else
+                {
+                    a = i;
+                }
+                fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+                        (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
+                        *atoms->resinfo[atoms->atom[a].resind].name,
+                        *atoms->atomname[a], (i+1) % 10000000,
+                        fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
+            }
+        }
+        else
+        {
+            fprintf(out, "POSITIONRED\n");
+            for (i = 0; i < nout; i++)
+            {
+                if (index)
+                {
+                    a = index[i];
+                }
+                else
+                {
+                    a = i;
+                }
+                fprintf(out, "%15.9f%15.9f%15.9f\n",
+                        fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]);
+            }
+        }
+        fprintf(out, "END\n");
+    }
+    if (fr->bV)
+    {
+        if (fr->bAtoms)
+        {
+            fprintf(out, "VELOCITY\n");
+            for (i = 0; i < nout; i++)
+            {
+                if (index)
+                {
+                    a = index[i];
+                }
+                else
+                {
+                    a = i;
+                }
+                fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
+                        (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
+                        *atoms->resinfo[atoms->atom[a].resind].name,
+                        *atoms->atomname[a], (i+1) % 10000000,
+                        fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
+            }
+        }
+        else
+        {
+            fprintf(out, "VELOCITYRED\n");
+            for (i = 0; i < nout; i++)
+            {
+                if (index)
+                {
+                    a = index[i];
+                }
+                else
+                {
+                    a = i;
+                }
+                fprintf(out, "%15.9f%15.9f%15.9f\n",
+                        fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]);
+            }
+        }
+        fprintf(out, "END\n");
+    }
+    if (fr->bBox)
+    {
+        fprintf(out, "BOX\n");
+        fprintf(out, "%15.9f%15.9f%15.9f",
+                fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]);
+        if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
+            fr->box[YY][ZZ] || fr->box[ZZ][XX] || fr->box[ZZ][YY])
+        {
+            fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
+                    fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX],
+                    fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]);
+        }
+        fprintf(out, "\n");
+        fprintf(out, "END\n");
+    }
+}
diff --git a/src/gromacs/fileio/g96io.h b/src/gromacs/fileio/g96io.h
new file mode 100644 (file)
index 0000000..c936883
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_FILEIO_G96IO_H
+#define GMX_FILEIO_G96IO_H
+
+#include <stdio.h>
+
+#include "gromacs/legacyheaders/types/simple.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct t_trxframe;
+
+int read_g96_conf(FILE *fp, const char *infile, struct t_trxframe *fr, char *line);
+/* read a Gromos96 coordinate or trajectory file,                       *
+ * returns the number of atoms                                          *
+ * sets what's in the frame in info                                     *
+ * read from fp, infile is only needed for error messages               *
+ * nwanted is the number of wanted coordinates,                         *
+ * set this to -1 if you want to know the number of atoms in the file   *
+ * title, atoms, x, v can all be NULL, in which case they won't be read *
+ * line holds the previous line for trajectory reading                  */
+
+void write_g96_conf(FILE *out, struct t_trxframe *fr, int nindex, const atom_id *index);
+/* write a Gromos96 coordinate file or trajectory frame *
+ * index can be NULL                                    */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 86b52201aff8e5e91950312ec75eb0625bdb53b6..addaed90d829404e5feee305eb1050dfd11bbb1c 100644 (file)
@@ -44,6 +44,7 @@
 #include <cmath>
 
 #include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/g96io.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/fileio/gmxfio-xdr.h"
 #include "gromacs/fileio/pdbio.h"
index 26ba84944cdd64e9027bec5522a70f9284bff803..eb83b301d410bd91d1353c431064655169607a4a 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "gromacs/commandline/pargs.h"
 #include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/g96io.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/fileio/pdbio.h"
 #include "gromacs/fileio/tngio_for_tools.h"
index 308476ea764b87d249d83d201d3b0f2d56982bb8..e5ec0c205380cb3f4154b07a4cd916084b25093b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 #include "gromacs/legacyheaders/types/inputrec.h"
 #include "gromacs/utility/basedefinitions.h"
 
+/* Ugly hack to convince some compilers that returning t_topology (or other
+ * structs) from an extern "C" function is OK; can probably go when the extern
+ * "C" blocks go.
+ */
+#include "gromacs/topology/topology.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif