Use gmx_mtop_t in selections, part 2
authorTeemu Murtola <teemu.murtola@gmail.com>
Tue, 21 Jun 2016 18:42:59 +0000 (21:42 +0300)
committerBerk Hess <hess@kth.se>
Thu, 13 Oct 2016 20:56:43 +0000 (22:56 +0200)
Use gmx_mtop_t throughout low-level selection routines, i.e.,
centerofmass.cpp, poscalc.cpp, and indexutil.cpp.  Adapt test code,
which is now using gmx_mtop_t throughout as well.

In places where gmx_mtop_t is actually accessed, the changes are as
local as possible.  In most cases, some additional restructuring could
give better performance and/or much clearer code, but that is outside
the scope of this change.

Part of #1862.

Change-Id: Icc99432bddec04a325aef733df56571d709130fb

24 files changed:
src/gromacs/domdec/domdec.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/selection/centerofmass.cpp
src/gromacs/selection/centerofmass.h
src/gromacs/selection/indexutil.cpp
src/gromacs/selection/indexutil.h
src/gromacs/selection/poscalc.cpp
src/gromacs/selection/poscalc.h
src/gromacs/selection/selection.cpp
src/gromacs/selection/selection.h
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/tests/indexutil.cpp
src/gromacs/selection/tests/poscalc.cpp
src/gromacs/selection/tests/selectioncollection.cpp
src/gromacs/selection/tests/selectionoption.cpp
src/gromacs/selection/tests/toputils.cpp
src/gromacs/selection/tests/toputils.h
src/gromacs/topology/topology.cpp
src/gromacs/topology/topology.h
src/gromacs/trajectoryanalysis/analysissettings.h
src/gromacs/trajectoryanalysis/modules/pairdist.cpp
src/gromacs/trajectoryanalysis/modules/rdf.cpp
src/gromacs/trajectoryanalysis/modules/sasa.cpp

index 1a3cbe0303bc641dd67e7f126d966bbf3688191f..e1c020808d36743150df0413cc71fd518d302cbf 100644 (file)
@@ -1774,7 +1774,7 @@ void write_dd_pdb(const char *fn, gmx_int64_t step, const char *title,
     for (i = 0; i < natoms; i++)
     {
         ii = dd->gatindex[i];
-        mtopGetAtomAndResidueName(mtop, ii, &molb, &atomname, &resnr, &resname, NULL);
+        mtopGetAtomAndResidueName(mtop, ii, &molb, &atomname, &resnr, &resname, nullptr);
         if (i < dd->comm->nat[ddnatZONE])
         {
             c = 0;
index 2ecc85a4b14643ec0407aec4f62433d69c603510..d507bac7ef809b1b84c24186282d3fb7e764d844 100644 (file)
@@ -2483,8 +2483,8 @@ int gmx_energy(int argc, char *argv[])
                     snew(pairleg[i], 30);
                     j = fa[3*i+1];
                     k = fa[3*i+2];
-                    mtopGetAtomAndResidueName(&mtop, j, &molb, &anm_j, &resnr_j, &resnm_j, NULL);
-                    mtopGetAtomAndResidueName(&mtop, k, &molb, &anm_k, &resnr_k, &resnm_k, NULL);
+                    mtopGetAtomAndResidueName(&mtop, j, &molb, &anm_j, &resnr_j, &resnm_j, nullptr);
+                    mtopGetAtomAndResidueName(&mtop, k, &molb, &anm_k, &resnr_k, &resnm_k, nullptr);
                     sprintf(pairleg[i], "%d %s %d %s (%d)",
                             resnr_j, anm_j, resnr_k, anm_k,
                             ip[fa[3*i]].disres.label);
index a4b9f1e9a158d7b2c24d93cfdbc74a81485afba2..715d8b4e1a5c55a35b1aee6e39f95b5831fa6149 100644 (file)
@@ -223,7 +223,7 @@ static void write_constr_pdb(const char *fn, const char *title,
         {
             ii = i;
         }
-        mtopGetAtomAndResidueName(mtop, ii, &molb, &anm, &resnr, &resnm, NULL);
+        mtopGetAtomAndResidueName(mtop, ii, &molb, &anm, &resnr, &resnm, nullptr);
         gmx_fprintf_pdb_atomline(out, epdbATOM, ii+1, anm, ' ', resnm, ' ', resnr, ' ',
                                  10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, 0.0, "");
     }
index 64afbfcc026bbc92bbfad3ac29a20863b0f6dbb5..059ff4b3486476d92ed3d8473f59ff063971052c 100644 (file)
 #include "gromacs/math/vec.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/topology/block.h"
+#include "gromacs/topology/mtop_lookup.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/utility/gmxassert.h"
 
 void
-gmx_calc_cog(const t_topology * /* top */, rvec x[], int nrefat, const int index[], rvec xout)
+gmx_calc_cog(const gmx_mtop_t * /* top */, rvec x[], int nrefat, const int index[], rvec xout)
 {
     int                 m, ai;
 
@@ -74,20 +75,18 @@ gmx_calc_cog(const t_topology * /* top */, rvec x[], int nrefat, const int index
  * mass are calculated, and hence a topology with masses is required.
  */
 void
-gmx_calc_com(const t_topology *top, rvec x[], int nrefat, const int index[], rvec xout)
+gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout)
 {
-    int                 m, j, ai;
-    real                mass, mtot;
-
-    GMX_RELEASE_ASSERT(top != nullptr && top->atoms.haveMass,
+    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                        "No masses available while mass weighting was requested");
     clear_rvec(xout);
-    mtot = 0;
-    for (m = 0; m < nrefat; ++m)
+    real mtot = 0;
+    int  molb = 0;
+    for (int m = 0; m < nrefat; ++m)
     {
-        ai   = index[m];
-        mass = top->atoms.atom[ai].m;
-        for (j = 0; j < DIM; ++j)
+        const int  ai   = index[m];
+        const real mass = mtopGetAtomMass(top, ai, &molb);
+        for (int j = 0; j < DIM; ++j)
         {
             xout[j] += mass * x[ai][j];
         }
@@ -104,20 +103,18 @@ gmx_calc_com(const t_topology *top, rvec x[], int nrefat, const int index[], rve
  * \param[out] fout   Force on the COG position for the indexed atoms.
  */
 void
-gmx_calc_cog_f(const t_topology *top, rvec f[], int nrefat, const int index[], rvec fout)
+gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout)
 {
-    int                 m, j, ai;
-    real                mass, mtot;
-
-    GMX_RELEASE_ASSERT(top != nullptr && top->atoms.haveMass,
+    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                        "No masses available while mass weighting was requested");
     clear_rvec(fout);
-    mtot = 0;
-    for (m = 0; m < nrefat; ++m)
+    real mtot = 0;
+    int  molb = 0;
+    for (int m = 0; m < nrefat; ++m)
     {
-        ai   = index[m];
-        mass = top->atoms.atom[ai].m;
-        for (j = 0; j < DIM; ++j)
+        const int  ai   = index[m];
+        const real mass = mtopGetAtomMass(top, ai, &molb);
+        for (int j = 0; j < DIM; ++j)
         {
             fout[j] += f[ai][j] / mass;
         }
@@ -127,7 +124,7 @@ gmx_calc_cog_f(const t_topology *top, rvec f[], int nrefat, const int index[], r
 }
 
 void
-gmx_calc_com_f(const t_topology * /* top */, rvec f[], int nrefat, const int index[], rvec fout)
+gmx_calc_com_f(const gmx_mtop_t * /* top */, rvec f[], int nrefat, const int index[], rvec fout)
 {
     clear_rvec(fout);
     for (int m = 0; m < nrefat; ++m)
@@ -151,7 +148,7 @@ gmx_calc_com_f(const t_topology * /* top */, rvec f[], int nrefat, const int ind
  * Other parameters are passed unmodified to these functions.
  */
 void
-gmx_calc_comg(const t_topology *top, rvec x[], int nrefat, const int index[],
+gmx_calc_comg(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[],
               bool bMass, rvec xout)
 {
     if (bMass)
@@ -178,7 +175,7 @@ gmx_calc_comg(const t_topology *top, rvec x[], int nrefat, const int index[],
  * Other parameters are passed unmodified to these functions.
  */
 void
-gmx_calc_comg_f(const t_topology *top, rvec f[], int nrefat, const int index[],
+gmx_calc_comg_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[],
                 bool bMass, rvec fout)
 {
     if (bMass)
@@ -203,7 +200,7 @@ gmx_calc_comg_f(const t_topology *top, rvec f[], int nrefat, const int index[],
  * Works exactly as gmx_calc_com_pbc(), but calculates the center of geometry.
  */
 void
-gmx_calc_cog_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                  int nrefat, const int index[], rvec xout)
 {
     const real          tol = 1e-4;
@@ -258,25 +255,20 @@ gmx_calc_cog_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
  * Modified from src/tools/gmx_sorient.c in Gromacs distribution.
  */
 void
-gmx_calc_com_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                  int nrefat, const int index[], rvec xout)
 {
-    const real          tol = 1e-4;
-    bool                bChanged;
-    int                 m, j, ai, iter;
-    real                mass, mtot;
-    rvec                dx, xtest;
-
-    GMX_RELEASE_ASSERT(top != nullptr && top->atoms.haveMass,
+    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                        "No masses available while mass weighting was requested");
     /* First simple calculation */
     clear_rvec(xout);
-    mtot = 0;
-    for (m = 0; m < nrefat; ++m)
+    real mtot = 0;
+    int  molb = 0;
+    for (int m = 0; m < nrefat; ++m)
     {
-        ai   = index[m];
-        mass = top->atoms.atom[ai].m;
-        for (j = 0; j < DIM; ++j)
+        const int  ai   = index[m];
+        const real mass = mtopGetAtomMass(top, ai, &molb);
+        for (int j = 0; j < DIM; ++j)
         {
             xout[j] += mass * x[ai][j];
         }
@@ -286,17 +278,20 @@ gmx_calc_com_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
     /* Now check if any atom is more than half the box from the COM */
     if (pbc)
     {
-        iter = 0;
+        const real tol  = 1e-4;
+        bool       bChanged;
         do
         {
             bChanged = false;
-            for (m = 0; m < nrefat; ++m)
+            molb     = 0;
+            for (int m = 0; m < nrefat; ++m)
             {
-                ai   = index[m];
-                mass = top->atoms.atom[ai].m / mtot;
+                rvec       dx, xtest;
+                const int  ai   = index[m];
+                const real mass = mtopGetAtomMass(top, ai, &molb) / mtot;
                 pbc_dx(pbc, x[ai], xout, dx);
                 rvec_add(xout, dx, xtest);
-                for (j = 0; j < DIM; ++j)
+                for (int j = 0; j < DIM; ++j)
                 {
                     if (fabs(xtest[j] - x[ai][j]) > tol)
                     {
@@ -307,7 +302,6 @@ gmx_calc_com_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
                     }
                 }
             }
-            iter++;
         }
         while (bChanged);
     }
@@ -328,7 +322,7 @@ gmx_calc_com_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
  * Other parameters are passed unmodified to these functions.
  */
 void
-gmx_calc_comg_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                   int nrefat, const int index[], bool bMass, rvec xout)
 {
     if (bMass)
@@ -343,7 +337,7 @@ gmx_calc_comg_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
 
 
 void
-gmx_calc_cog_block(const t_topology * /* top */, rvec x[], const t_block *block, const int index[],
+gmx_calc_cog_block(const gmx_mtop_t * /* top */, rvec x[], const t_block *block, const int index[],
                    rvec xout[])
 {
     int                 b, i, ai;
@@ -372,24 +366,22 @@ gmx_calc_cog_block(const t_topology * /* top */, rvec x[], const t_block *block,
  * mass are calculated, and hence a topology with masses is required.
  */
 void
-gmx_calc_com_block(const t_topology *top, rvec x[], const t_block *block, const int index[],
+gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const int index[],
                    rvec xout[])
 {
-    int                 b, i, ai, d;
-    rvec                xb;
-    real                mass, mtot;
-
-    GMX_RELEASE_ASSERT(top != nullptr && top->atoms.haveMass,
+    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                        "No masses available while mass weighting was requested");
-    for (b = 0; b < block->nr; ++b)
+    int molb = 0;
+    for (int b = 0; b < block->nr; ++b)
     {
+        rvec xb;
         clear_rvec(xb);
-        mtot = 0;
-        for (i = block->index[b]; i < block->index[b+1]; ++i)
+        real mtot = 0;
+        for (int i = block->index[b]; i < block->index[b+1]; ++i)
         {
-            ai   = index[i];
-            mass = top->atoms.atom[ai].m;
-            for (d = 0; d < DIM; ++d)
+            const int  ai   = index[i];
+            const real mass = mtopGetAtomMass(top, ai, &molb);
+            for (int d = 0; d < DIM; ++d)
             {
                 xb[d] += mass * x[ai][d];
             }
@@ -407,24 +399,22 @@ gmx_calc_com_block(const t_topology *top, rvec x[], const t_block *block, const
  * \param[out] fout  \p block->nr Forces on COG positions.
  */
 void
-gmx_calc_cog_f_block(const t_topology *top, rvec f[], const t_block *block, const int index[],
+gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, const int index[],
                      rvec fout[])
 {
-    int                 b, i, ai, d;
-    rvec                fb;
-    real                mass, mtot;
-
-    GMX_RELEASE_ASSERT(top != nullptr && top->atoms.haveMass,
+    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                        "No masses available while mass weighting was requested");
-    for (b = 0; b < block->nr; ++b)
+    int molb = 0;
+    for (int b = 0; b < block->nr; ++b)
     {
+        rvec fb;
         clear_rvec(fb);
-        mtot = 0;
-        for (i = block->index[b]; i < block->index[b+1]; ++i)
+        real mtot = 0;
+        for (int i = block->index[b]; i < block->index[b+1]; ++i)
         {
-            ai   = index[i];
-            mass = top->atoms.atom[ai].m;
-            for (d = 0; d < DIM; ++d)
+            const int  ai   = index[i];
+            const real mass = mtopGetAtomMass(top, ai, &molb);
+            for (int d = 0; d < DIM; ++d)
             {
                 fb[d] += f[ai][d] / mass;
             }
@@ -435,7 +425,7 @@ gmx_calc_cog_f_block(const t_topology *top, rvec f[], const t_block *block, cons
 }
 
 void
-gmx_calc_com_f_block(const t_topology * /* top */, rvec f[], const t_block *block, const int index[],
+gmx_calc_com_f_block(const gmx_mtop_t * /* top */, rvec f[], const t_block *block, const int index[],
                      rvec fout[])
 {
     for (int b = 0; b < block->nr; ++b)
@@ -465,7 +455,7 @@ gmx_calc_com_f_block(const t_topology * /* top */, rvec f[], const t_block *bloc
  * Other parameters are passed unmodified to these functions.
  */
 void
-gmx_calc_comg_block(const t_topology *top, rvec x[], const t_block *block, const int index[],
+gmx_calc_comg_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const int index[],
                     bool bMass, rvec xout[])
 {
     if (bMass)
@@ -492,7 +482,7 @@ gmx_calc_comg_block(const t_topology *top, rvec x[], const t_block *block, const
  * Other parameters are passed unmodified to these functions.
  */
 void
-gmx_calc_comg_f_block(const t_topology *top, rvec f[], const t_block *block, const int index[],
+gmx_calc_comg_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, const int index[],
                       bool bMass, rvec fout[])
 {
     if (bMass)
@@ -524,7 +514,7 @@ gmx_calc_comg_f_block(const t_topology *top, rvec f[], const t_block *block, con
  * crashes.
  */
 void
-gmx_calc_comg_blocka(const t_topology *top, rvec x[], const t_blocka *block,
+gmx_calc_comg_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block,
                      bool bMass, rvec xout[])
 {
     /* TODO: It would probably be better to do this without the type cast */
@@ -550,7 +540,7 @@ gmx_calc_comg_blocka(const t_topology *top, rvec x[], const t_blocka *block,
  * crashes.
  */
 void
-gmx_calc_comg_f_blocka(const t_topology *top, rvec f[], const t_blocka *block,
+gmx_calc_comg_f_blocka(const gmx_mtop_t *top, rvec f[], const t_blocka *block,
                        bool bMass, rvec fout[])
 {
     /* TODO: It would probably be better to do this without the type cast */
index 6b2054ad1ddfb548b0606c8c9a78fb601b7e6b31..12b92b4b92ba6d2efed9308af0b30e99111b2a57 100644 (file)
 
 #include "gromacs/math/vectypes.h"
 
+struct gmx_mtop_t;
 struct t_block;
 struct t_blocka;
 struct t_pbc;
-struct t_topology;
 
 /*! \brief
  * Calculate a single center of geometry.
@@ -91,13 +91,13 @@ struct t_topology;
  * \param[out] xout   COG position for the indexed atoms.
  */
 void
-gmx_calc_cog(const t_topology *top, rvec x[], int nrefat, const int index[], rvec xout);
+gmx_calc_cog(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout);
 /** Calculate a single center of mass. */
 void
-gmx_calc_com(const t_topology *top, rvec x[], int nrefat, const int index[], rvec xout);
+gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout);
 /** Calculate force on a single center of geometry. */
 void
-gmx_calc_cog_f(const t_topology *top, rvec f[], int nrefat, const int index[], rvec fout);
+gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout);
 /*! \brief
  * Calculate force on a single center of mass.
  *
@@ -108,27 +108,27 @@ gmx_calc_cog_f(const t_topology *top, rvec f[], int nrefat, const int index[], r
  * \param[out] fout   Force on the COM position for the indexed atoms.
  */
 void
-gmx_calc_com_f(const t_topology *top, rvec f[], int nrefat, const int index[], rvec fout);
+gmx_calc_com_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout);
 /** Calculate a single center of mass/geometry. */
 void
-gmx_calc_comg(const t_topology *top, rvec x[], int nrefat, const int index[],
+gmx_calc_comg(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[],
               bool bMass, rvec xout);
 /** Calculate force on a single center of mass/geometry. */
 void
-gmx_calc_comg_f(const t_topology *top, rvec f[], int nrefat, const int index[],
+gmx_calc_comg_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[],
                 bool bMass, rvec fout);
 
 /** Calculate a single center of geometry iteratively, taking PBC into account. */
 void
-gmx_calc_cog_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                  int nrefat, const int index[], rvec xout);
 /** Calculate a single center of mass iteratively, taking PBC into account. */
 void
-gmx_calc_com_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                  int nrefat, const int index[], rvec xout);
 /** Calculate a single center of mass/geometry iteratively with PBC. */
 void
-gmx_calc_comg_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
+gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                   int nrefat, const int index[], bool bMass, rvec xout);
 
 /*! \brief
@@ -141,15 +141,15 @@ gmx_calc_comg_pbc(const t_topology *top, rvec x[], const t_pbc *pbc,
  * \param[out] xout  \p block->nr COG positions.
  */
 void
-gmx_calc_cog_block(const t_topology *top, rvec x[], const t_block *block,
+gmx_calc_cog_block(const gmx_mtop_t *top, rvec x[], const t_block *block,
                    const int index[], rvec xout[]);
 /** Calculate centers of mass for a blocked index. */
 void
-gmx_calc_com_block(const t_topology *top, rvec x[], const t_block *block,
+gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block,
                    const int index[], rvec xout[]);
 /** Calculate forces on centers of geometry for a blocked index. */
 void
-gmx_calc_cog_f_block(const t_topology *top, rvec f[], const t_block *block,
+gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block,
                      const int index[], rvec fout[]);
 /*! \brief
  * Calculate forces on centers of mass for a blocked index.
@@ -161,23 +161,23 @@ gmx_calc_cog_f_block(const t_topology *top, rvec f[], const t_block *block,
  * \param[out] fout  \p block->nr Forces on COM positions.
  */
 void
-gmx_calc_com_f_block(const t_topology *top, rvec f[], const t_block *block,
+gmx_calc_com_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block,
                      const int index[], rvec fout[]);
 /** Calculate centers of mass/geometry for a blocked index. */
 void
-gmx_calc_comg_block(const t_topology *top, rvec x[], const t_block *block,
+gmx_calc_comg_block(const gmx_mtop_t *top, rvec x[], const t_block *block,
                     const int index[], bool bMass, rvec xout[]);
 /** Calculate forces on centers of mass/geometry for a blocked index. */
 void
-gmx_calc_comg_f_block(const t_topology *top, rvec f[], const t_block *block,
+gmx_calc_comg_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block,
                       const int index[], bool bMass, rvec fout[]);
 /** Calculate centers of mass/geometry for a set of blocks; */
 void
-gmx_calc_comg_blocka(const t_topology *top, rvec x[], const t_blocka *block,
+gmx_calc_comg_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block,
                      bool bMass, rvec xout[]);
 /** Calculate forces on centers of mass/geometry for a set of blocks; */
 void
-gmx_calc_comg_f_blocka(const t_topology *top, rvec x[], const t_blocka *block,
+gmx_calc_comg_f_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block,
                        bool bMass, rvec xout[]);
 
 #endif
index 50404b4e9d2c6612108045758ed4b88622c352c4..210d52d97bceb0f5afa9379c2836e8fa75a09c12 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "gromacs/topology/block.h"
 #include "gromacs/topology/index.h"
+#include "gromacs/topology/mtop_lookup.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/utility/exceptions.h"
@@ -795,7 +796,7 @@ gmx_ana_index_merge(gmx_ana_index_t *dest,
  * \ingroup module_selection
  */
 static bool
-next_group_index(int atomIndex, t_topology *top, e_index_t type, int *id)
+next_group_index(int atomIndex, const gmx_mtop_t *top, e_index_t type, int *id)
 {
     int prev = *id;
     switch (type)
@@ -804,8 +805,12 @@ next_group_index(int atomIndex, t_topology *top, e_index_t type, int *id)
             *id = atomIndex;
             break;
         case INDEX_RES:
-            *id = top->atoms.atom[atomIndex].resind;
+        {
+            int resind, molb = 0;
+            mtopGetAtomAndResidueName(top, atomIndex, &molb, nullptr, nullptr, nullptr, &resind);
+            *id = resind;
             break;
+        }
         case INDEX_MOL:
             if (*id >= 0 && top->mols.index[*id] > atomIndex)
             {
@@ -842,7 +847,7 @@ next_group_index(int atomIndex, t_topology *top, e_index_t type, int *id)
  * \p g should be sorted.
  */
 void
-gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
+gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g,
                          e_index_t type, bool bComplete)
 {
     if (type == INDEX_UNKNOWN)
@@ -879,10 +884,10 @@ gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
         t->nra = 0;
         /* We may allocate some extra memory here because we don't know in
          * advance how much will be needed. */
-        if (t->nalloc_a < top->atoms.nr)
+        if (t->nalloc_a < top->natoms)
         {
-            srenew(t->a, top->atoms.nr);
-            t->nalloc_a = top->atoms.nr;
+            srenew(t->a, top->natoms);
+            t->nalloc_a = top->natoms;
         }
     }
     else
@@ -906,13 +911,14 @@ gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
     }
     /* Clear counters */
     t->nr  = 0;
-    int j  = 0; /* j is used by residue completion for the first atom not stored */
-    int id = -1;
+    int id   = -1;
+    int molb = 0;
     for (int i = 0; i < g->isize; ++i)
     {
+        const int ai = g->index[i];
         /* Find the ID number of the atom/residue/molecule corresponding to
          * the atom. */
-        if (next_group_index(g->index[i], top, type, &id))
+        if (next_group_index(ai, top, type, &id))
         {
             /* If this is the first atom in a new block, initialize the block. */
             if (bComplete)
@@ -923,19 +929,34 @@ gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
                 switch (type)
                 {
                     case INDEX_RES:
-                        while (top->atoms.atom[j].resind != id)
+                    {
+                        int            molnr, atnr_mol;
+                        mtopGetMolblockIndex(top, ai, &molb, &molnr, &atnr_mol);
+                        const t_atoms &mol_atoms = top->moltype[top->molblock[molb].type].atoms;
+                        int            last_atom = atnr_mol + 1;
+                        while (last_atom < mol_atoms.nr
+                               && mol_atoms.atom[last_atom].resind == id)
+                        {
+                            ++last_atom;
+                        }
+                        int first_atom = atnr_mol - 1;
+                        while (first_atom >= 0
+                               && mol_atoms.atom[first_atom].resind == id)
                         {
-                            ++j;
+                            --first_atom;
                         }
-                        while (j < top->atoms.nr && top->atoms.atom[j].resind == id)
+                        int first_mol_atom = top->molblock[molb].globalAtomStart;
+                        first_mol_atom += molnr*top->molblock[molb].natoms_mol;
+                        first_atom      = first_mol_atom + first_atom + 1;
+                        last_atom       = first_mol_atom + last_atom - 1;
+                        for (int j = first_atom; j <= last_atom; ++j)
                         {
                             t->a[t->nra++] = j;
-                            ++j;
                         }
                         break;
-
+                    }
                     case INDEX_MOL:
-                        for (j = top->mols.index[id]; j < top->mols.index[id+1]; ++j)
+                        for (int j = top->mols.index[id]; j < top->mols.index[id+1]; ++j)
                         {
                             t->a[t->nra++] = j;
                         }
@@ -974,7 +995,7 @@ gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
  * The atoms in \p g are assumed to be sorted.
  */
 bool
-gmx_ana_index_has_full_blocks(gmx_ana_index_t *g, t_block *b)
+gmx_ana_index_has_full_blocks(const gmx_ana_index_t *g, const t_block *b)
 {
     int  i, j, bi;
 
@@ -1047,6 +1068,29 @@ gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b)
     return true;
 }
 
+/*!
+ * \brief Returns if an atom is at a residue boundary.
+ *
+ * \param[in]     top   Topology data.
+ * \param[in]     a     Atom index to check, should be -1 <= \p a < top->natoms.
+ * \param[in,out] molb  The molecule block of atom a
+ * \returns       true if atoms \p a and \p a + 1 are in different residues, false otherwise.
+ */
+static bool is_at_residue_boundary(const gmx_mtop_t *top, int a, int *molb)
+{
+    if (a == -1 || a + 1 == top->natoms)
+    {
+        return true;
+    }
+    int resindA;
+    mtopGetAtomAndResidueName(top, a, molb,
+                              nullptr, nullptr, nullptr, &resindA);
+    int resindAPlusOne;
+    mtopGetAtomAndResidueName(top, a + 1, molb,
+                              nullptr, nullptr, nullptr, &resindAPlusOne);
+    return resindAPlusOne != resindA;
+}
+
 /*!
  * \param[in] g     Index group to check.
  * \param[in] type  Block data to check against.
@@ -1062,8 +1106,13 @@ gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b)
  */
 bool
 gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type,
-                                 t_topology *top)
+                                 const gmx_mtop_t *top)
 {
+    if (g->isize == 0)
+    {
+        return true;
+    }
+
     // TODO: Consider whether unsorted groups need to be supported better.
     switch (type)
     {
@@ -1076,30 +1125,28 @@ gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type,
 
         case INDEX_RES:
         {
-            int      i, ai;
-            int      id, prev;
-
-            prev = -1;
-            for (i = 0; i < g->isize; ++i)
+            int molb  = 0;
+            int aPrev = -1;
+            for (int i = 0; i < g->isize; ++i)
             {
-                ai = g->index[i];
-                id = top->atoms.atom[ai].resind;
-                if (id != prev)
+                const int a = g->index[i];
+                // Check if a is consecutive or on a residue boundary
+                if (a != aPrev + 1)
                 {
-                    if (ai > 0 && top->atoms.atom[ai-1].resind == id)
+                    if (!is_at_residue_boundary(top, aPrev, &molb))
                     {
                         return false;
                     }
-                    if (i > 0 && g->index[i-1] < top->atoms.nr - 1
-                        && top->atoms.atom[g->index[i-1]+1].resind == prev)
+                    if (!is_at_residue_boundary(top, a - 1, &molb))
                     {
                         return false;
                     }
                 }
-                prev = id;
+                aPrev = a;
             }
-            if (g->index[i-1] < top->atoms.nr - 1
-                && top->atoms.atom[g->index[i-1]+1].resind == prev)
+            GMX_ASSERT(g->isize > 0, "We return above when isize=0");
+            const int a = g->index[g->isize - 1];
+            if (!is_at_residue_boundary(top, a, &molb))
             {
                 return false;
             }
@@ -1180,7 +1227,7 @@ gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize)
  */
 void
 gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
-                      t_topology *top, e_index_t type)
+                      const gmx_mtop_t *top, e_index_t type)
 {
     m->type   = type;
     gmx_ana_index_make_block(&m->b, top, g, type, false);
@@ -1202,7 +1249,7 @@ gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
 }
 
 int
-gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, t_topology *top,
+gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top,
                                   e_index_t type)
 {
     GMX_RELEASE_ASSERT(m->bStatic,
index 40b7bb9b7e6d7b70210b25351869cc1f146e1447..83de646fef75fc555b8e83c5ea72a81816100367 100644 (file)
@@ -73,7 +73,6 @@ class TextWriter;
 }
 
 struct gmx_mtop_t;
-struct t_topology;
 
 /** Stores a set of index groups. */
 struct gmx_ana_indexgrps_t;
@@ -328,17 +327,18 @@ gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2,
 /*@{*/
 /** Partition a group based on topology information. */
 void
-gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
+gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g,
                          e_index_t type, bool bComplete);
 /** Checks whether a group consists of full blocks. */
 bool
-gmx_ana_index_has_full_blocks(gmx_ana_index_t *g, t_block *b);
+gmx_ana_index_has_full_blocks(const gmx_ana_index_t *g, const t_block *b);
 /** Checks whether a group consists of full blocks. */
 bool
 gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b);
 /** Checks whether a group consists of full residues/molecules. */
 bool
-gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, t_topology *top);
+gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type,
+                                 const gmx_mtop_t *top);
 
 /** Initializes an empty index group mapping. */
 void
@@ -349,7 +349,7 @@ gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize);
 /** Initializes an index group mapping. */
 void
 gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
-                      t_topology *top, e_index_t type);
+                      const gmx_mtop_t *top, e_index_t type);
 /*! \brief
  * Initializes `orgid` entries based on topology grouping.
  *
@@ -375,7 +375,7 @@ gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
  * Strong exception safety guarantee.
  */
 int
-gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, t_topology *top,
+gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top,
                                   e_index_t type);
 /** Sets an index group mapping to be static. */
 void
index 02db22278c036556a78115aacc32f9385f885499..68ad13a2ace85fc7857a83d74067b26d77f4034f 100644 (file)
@@ -151,7 +151,7 @@ class PositionCalculationCollection::Impl
          * Can be NULL if none of the calculations require topology data or if
          * setTopology() has not been called.
          */
-        t_topology               *top_;
+        const gmx_mtop_t         *top_;
         //! Pointer to the first data structure.
         gmx_ana_poscalc_t        *first_;
         //! Pointer to the last data structure.
@@ -471,7 +471,7 @@ PositionCalculationCollection::~PositionCalculationCollection()
 }
 
 void
-PositionCalculationCollection::setTopology(t_topology *top)
+PositionCalculationCollection::setTopology(const gmx_mtop_t *top)
 {
     impl_->top_ = top;
 }
@@ -736,7 +736,7 @@ void PositionCalculationCollection::initFrame(const t_trxframe *fr)
 static void
 set_poscalc_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g, bool bBase)
 {
-    t_topology *top = pc->coll->top_;
+    const gmx_mtop_t *top = pc->coll->top_;
     gmx_ana_index_make_block(&pc->b, top, g, pc->itype, pc->flags & POS_COMPLWHOLE);
     /* Set the type to POS_ATOM if the calculation in fact is such. */
     if (pc->b.nr == pc->b.nra)
@@ -1331,7 +1331,7 @@ gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p,
             }
         }
         gmx::ConstArrayRef<int> index = pc->coll->getFrameIndices(pc->b.nra, pc->b.a);
-        const t_topology       *top   = pc->coll->top_;
+        const gmx_mtop_t       *top   = pc->coll->top_;
         const bool              bMass = pc->flags & POS_MASS;
         switch (pc->type)
         {
index a0c2590e5dd2a56fa4ae3dfc3715e39cbaca21d4..e37628dea0fb28efeedde4accbb33cc37152853d 100644 (file)
@@ -131,8 +131,8 @@ struct gmx_ana_poscalc_t;
 
 struct gmx_ana_index_t;
 struct gmx_ana_pos_t;
+struct gmx_mtop_t;
 struct t_pbc;
-struct t_topology;
 struct t_trxframe;
 
 namespace gmx
@@ -253,7 +253,7 @@ class PositionCalculationCollection
          *
          * Does not throw.
          */
-        void setTopology(t_topology *top);
+        void setTopology(const gmx_mtop_t *top);
         /*! \brief
          * Prints information about calculations.
          *
index 0b642b5ba9c66d2d0651d6c500966bb486a2f321..0b2f337be4dfb4b94c0b7b452c7b8212e2685193 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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.
@@ -289,7 +289,7 @@ Selection::setOriginalId(int i, int id)
 
 
 int
-Selection::initOriginalIdsToGroup(t_topology *top, e_index_t type)
+Selection::initOriginalIdsToGroup(const gmx_mtop_t *top, e_index_t type)
 {
     try
     {
index 47d8a40e45abdbe952ab982690c64653fa78b1a9..c9f619ee3b9a0d9202989f0abfb4e1d56c0a93ad 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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.
@@ -52,6 +52,7 @@
 #include "gromacs/utility/classhelpers.h"
 #include "gromacs/utility/gmxassert.h"
 
+struct gmx_mtop_t;
 struct t_topology;
 
 namespace gmx
@@ -532,7 +533,7 @@ class Selection
          * \see setOriginalId()
          * \see SelectionPosition::mappedId()
          */
-        int initOriginalIdsToGroup(t_topology *top, e_index_t type);
+        int initOriginalIdsToGroup(const gmx_mtop_t *top, e_index_t type);
 
         /*! \brief
          * Prints out one-line description of the selection.
index f3b0d42e9876d1ea3cc2b642f37c3db652c830b0..5ae0f85ca1aa4871c4edd323222543d685f466f1 100644 (file)
@@ -643,13 +643,13 @@ SelectionCollection::setTopology(gmx_mtop_t *top, int natoms)
     {
         snew(sc->top, 1);
         *sc->top = gmx_mtop_t_to_t_topology(top, false);
-        sc->pcc.setTopology(sc->top);
         checkTopologyProperties(sc->top, requiredTopologyProperties());
     }
     else
     {
         checkTopologyProperties(nullptr, requiredTopologyProperties());
     }
+    sc->pcc.setTopology(top);
 }
 
 
index ffd884fe591837cbd5bdaa4c1b4bbe302dabfff2..70bb817208ea4a62f32df42baec8319f16338b29 100644 (file)
@@ -296,7 +296,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteResiduesPositive)
 
     topManager_.initAtoms(15);
     topManager_.initUniformResidues(3);
-    t_topology *top = topManager_.topology();
+    gmx_mtop_t *top = topManager_.topology();
 
     setGroup(group1);
     EXPECT_TRUE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top));
@@ -310,10 +310,11 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteResiduesNegative)
     const int group1[] = { 3, 4, 5, 6, 7, 8, 12, 13 };
     const int group2[] = { 3, 4, 5, 6, 7, 12, 13, 14 };
     const int group3[] = { 4, 5, 6, 7, 8, 12, 13, 14 };
+    const int group4[] = { 3, 4, 5, 6, 8, 12, 13, 14 };
 
     topManager_.initAtoms(18);
     topManager_.initUniformResidues(3);
-    t_topology *top = topManager_.topology();
+    gmx_mtop_t *top = topManager_.topology();
 
     setGroup(group1);
     EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top));
@@ -323,6 +324,9 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteResiduesNegative)
 
     setGroup(group3);
     EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top));
+
+    setGroup(group4);
+    EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top));
 }
 
 TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesPositive)
@@ -331,7 +335,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesPositive)
 
     topManager_.initAtoms(15);
     topManager_.initUniformMolecules(3);
-    t_topology *top = topManager_.topology();
+    gmx_mtop_t *top = topManager_.topology();
 
     setGroup(group);
     EXPECT_TRUE(gmx_ana_index_has_complete_elems(&g_, INDEX_MOL, top));
@@ -345,7 +349,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesNegative)
 
     topManager_.initAtoms(18);
     topManager_.initUniformMolecules(3);
-    t_topology *top = topManager_.topology();
+    gmx_mtop_t *top = topManager_.topology();
 
     setGroup(group1);
     EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_MOL, top));
index 74f4f171d7b6a83ffd4517bd84abcd47cb485f74..4b28450eea924596a469e5ab55da3fc359b70f67 100644 (file)
@@ -157,12 +157,12 @@ PositionCalculationTest::~PositionCalculationTest()
 
 void PositionCalculationTest::generateCoordinates()
 {
-    t_topology *top   = topManager_.topology();
+    t_atoms    &atoms = topManager_.atoms();
     t_trxframe *frame = topManager_.frame();
-    for (int i = 0; i < top->atoms.nr; ++i)
+    for (int i = 0; i < atoms.nr; ++i)
     {
         frame->x[i][XX] = i;
-        frame->x[i][YY] = top->atoms.atom[i].resind;
+        frame->x[i][YY] = atoms.atom[i].resind;
         frame->x[i][ZZ] = 0.0;
         if (frame->bV)
         {
index 6537a33b139a7c0eb9e72bda730a8e958183b9fd..2d89ecc2d1ac6be70b559d390358f0f167aa58e8 100644 (file)
@@ -133,7 +133,7 @@ SelectionCollectionTest::loadTopology(const char *filename)
 void
 SelectionCollectionTest::setTopology()
 {
-    ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.mtop(), -1));
+    ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1));
 }
 
 void
@@ -875,15 +875,16 @@ TEST_F(SelectionCollectionDataTest, HandlesResIndex)
     runTest("simple.pdb", selections);
 }
 
-TEST_F(SelectionCollectionDataTest, DISABLED_HandlesMolIndex)
+TEST_F(SelectionCollectionDataTest, HandlesMolIndex)
 {
     static const char * const selections[] = {
         "molindex 1 4",
         "molecule 2 3 5"
     };
     ASSERT_NO_FATAL_FAILURE(runParser(selections));
-    ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
+    ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
     topManager_.initUniformMolecules(3);
+    ASSERT_NO_FATAL_FAILURE(setTopology());
     ASSERT_NO_FATAL_FAILURE(runCompiler());
 }
 
index ddfc83b723abf73ce491238804697ce490bfe698..d6d6e7053fc6b5ba966b7f0daabdbc0907e34896 100644 (file)
@@ -94,7 +94,7 @@ void SelectionOptionTestBase::loadTopology(const char *filename)
 {
     topManager_.loadTopology(filename);
 
-    ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.mtop(), -1));
+    ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1));
 }
 
 
index 3a33ae9331e5cf5889ccb6a814c0f44ef9a56469..224df3a17b2fad52dbc4d30d18bc1c7a506bce10 100644 (file)
@@ -51,6 +51,7 @@
 #include "gromacs/fileio/trxio.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/topology/atoms.h"
+#include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/trajectory/trajectoryframe.h"
 #include "gromacs/utility/arrayref.h"
@@ -66,7 +67,7 @@ namespace test
 {
 
 TopologyManager::TopologyManager()
-    : mtop_(nullptr), top_(nullptr), frame_(nullptr)
+    : mtop_(nullptr), frame_(nullptr)
 {
 }
 
@@ -77,11 +78,6 @@ TopologyManager::~TopologyManager()
         done_mtop(mtop_, TRUE);
         sfree(mtop_);
     }
-    else if (top_ != nullptr)
-    {
-        done_top(top_);
-    }
-    sfree(top_);
 
     if (frame_ != nullptr)
     {
@@ -100,7 +96,7 @@ TopologyManager::~TopologyManager()
 
 void TopologyManager::requestFrame()
 {
-    GMX_RELEASE_ASSERT(top_ == NULL,
+    GMX_RELEASE_ASSERT(mtop_ == NULL,
                        "Frame must be requested before initializing topology");
     if (frame_ == NULL)
     {
@@ -159,14 +155,26 @@ void TopologyManager::loadTopology(const char *filename)
 
 void TopologyManager::initAtoms(int count)
 {
-    GMX_RELEASE_ASSERT(top_ == NULL, "Topology initialized more than once");
-    snew(top_, 1);
-    init_t_atoms(&top_->atoms, count, FALSE);
+    GMX_RELEASE_ASSERT(mtop_ == NULL, "Topology initialized more than once");
+    snew(mtop_, 1);
+    mtop_->nmoltype = 1;
+    snew(mtop_->moltype, 1);
+    init_t_atoms(&mtop_->moltype[0].atoms, count, FALSE);
+    mtop_->nmolblock = 1;
+    snew(mtop_->molblock, 1);
+    mtop_->molblock[0].type            = 0;
+    mtop_->molblock[0].nmol            = 1;
+    mtop_->molblock[0].natoms_mol      = count;
+    mtop_->natoms                      = count;
+    mtop_->maxres_renum                = 0;
+    gmx_mtop_finalize(mtop_);
+    GMX_RELEASE_ASSERT(mtop_->maxres_renum == 0, "maxres_renum in mtop can be modified by an env.var., that is not supported in this test");
+    t_atoms &atoms = this->atoms();
     for (int i = 0; i < count; ++i)
     {
-        top_->atoms.atom[i].m = (i % 3 == 0 ? 2.0 : 1.0);
+        atoms.atom[i].m = (i % 3 == 0 ? 2.0 : 1.0);
     }
-    top_->atoms.haveMass = TRUE;
+    atoms.haveMass = TRUE;
     if (frame_ != NULL)
     {
         frame_->natoms = count;
@@ -207,32 +215,33 @@ void TopologyManager::initAtomTypes(const ConstArrayRef<const char *> &types)
 
 void TopologyManager::initUniformResidues(int residueSize)
 {
-    GMX_RELEASE_ASSERT(top_ != NULL, "Topology not initialized");
-    int residueIndex = -1;
-    for (int i = 0; i < top_->atoms.nr; ++i)
+    GMX_RELEASE_ASSERT(mtop_ != NULL, "Topology not initialized");
+    t_atoms &atoms        = this->atoms();
+    int      residueIndex = -1;
+    for (int i = 0; i < atoms.nr; ++i)
     {
         if (i % residueSize == 0)
         {
             ++residueIndex;
         }
-        top_->atoms.atom[i].resind = residueIndex;
+        atoms.atom[i].resind = residueIndex;
     }
 }
 
 void TopologyManager::initUniformMolecules(int moleculeSize)
 {
-    GMX_RELEASE_ASSERT(top_ != NULL, "Topology not initialized");
+    GMX_RELEASE_ASSERT(mtop_ != NULL, "Topology not initialized");
     int index = 0;
-    top_->mols.nalloc_index = (top_->atoms.nr + moleculeSize - 1) / moleculeSize + 1;
-    snew(top_->mols.index, top_->mols.nalloc_index);
-    top_->mols.nr = 0;
-    while (index < top_->atoms.nr)
+    mtop_->mols.nalloc_index = (mtop_->natoms + moleculeSize - 1) / moleculeSize + 1;
+    snew(mtop_->mols.index, mtop_->mols.nalloc_index);
+    mtop_->mols.nr = 0;
+    while (index < mtop_->natoms)
     {
-        top_->mols.index[top_->mols.nr] = index;
-        ++top_->mols.nr;
+        mtop_->mols.index[mtop_->mols.nr] = index;
+        ++mtop_->mols.nr;
         index += moleculeSize;
     }
-    top_->mols.index[top_->mols.nr] = top_->atoms.nr;
+    mtop_->mols.index[mtop_->mols.nr] = mtop_->natoms;
 }
 
 void TopologyManager::initFrameIndices(const ConstArrayRef<int> &index)
index 2bd96e7a01c30f9beb0de0be61f841c73b460998..4b5b9dd3bcaf872da8a2e087c58694c8c16ef68a 100644 (file)
@@ -46,7 +46,6 @@
 
 struct gmx_mtop_t;
 struct t_atoms;
-struct t_topology;
 struct t_trxframe;
 
 namespace gmx
@@ -76,14 +75,12 @@ class TopologyManager
 
         void initFrameIndices(const ConstArrayRef<int> &index);
 
-        t_topology *topology() { return top_; }
-        gmx_mtop_t *mtop() { return mtop_; }
+        gmx_mtop_t *topology() { return mtop_; }
         t_atoms &atoms();
         t_trxframe *frame() { return frame_; }
 
     private:
         gmx_mtop_t             *mtop_;
-        t_topology             *top_;
         t_trxframe             *frame_;
         std::vector<char *>     atomtypes_;
 };
index a94f36ee5a5e80d81b97adbc96bb1111a7009d43..bc9dd15c0bacef2dfe26f5e7d8fe037d72d2efce 100644 (file)
@@ -168,6 +168,24 @@ void done_top(t_topology *top)
     done_blocka(&(top->excls));
 }
 
+bool gmx_mtop_has_masses(const gmx_mtop_t *mtop)
+{
+    if (mtop == nullptr)
+    {
+        return false;
+    }
+    return mtop->nmoltype == 0 || mtop->moltype[0].atoms.haveMass;
+}
+
+bool gmx_mtop_has_charges(const gmx_mtop_t *mtop)
+{
+    if (mtop == nullptr)
+    {
+        return false;
+    }
+    return mtop->nmoltype == 0 || mtop->moltype[0].atoms.haveCharge;
+}
+
 static void pr_grps(FILE *fp, const char *title, const t_grps grps[], char **grpname[])
 {
     int i, j;
index 6b36d1f66ba8a6f5cfcb481b75ba813b152237e5..15e380d6e022c90ba717e53a4375454cb6c0e48e 100644 (file)
@@ -150,6 +150,9 @@ void done_molblock(gmx_molblock_t *molb);
 void done_mtop(gmx_mtop_t *mtop, gmx_bool bDoneSymtab);
 void done_top(t_topology *top);
 
+bool gmx_mtop_has_masses(const gmx_mtop_t *mtop);
+bool gmx_mtop_has_charges(const gmx_mtop_t *mtop);
+
 void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop,
              gmx_bool bShowNumbers);
 void pr_top(FILE *fp, int indent, const char *title, const t_topology *top, gmx_bool bShowNumbers);
index b63486e7b33b82feb5d1cb13bdb3fd1665b2e7c9..0873d8a5a696ed5992f2e2d4c1222904716c6aeb 100644 (file)
@@ -258,6 +258,8 @@ class TopologyInformation
         //! Returns true if a full topology file was loaded.
         bool hasFullTopology() const { return bTop_; }
         //! Returns the loaded topology, or NULL if not loaded.
+        const gmx_mtop_t *mtop() const { return mtop_; }
+        //! Returns the loaded topology, or NULL if not loaded.
         t_topology *topology() const;
         //! Returns the ePBC field from the topology.
         int ePBC() const { return ePBC_; }
index 3091cb4451f299c3891add4012e9a8315eecc36d..72f7417944a668ea8f288687e54a364af529ae7b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016, 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.
@@ -238,7 +238,7 @@ PairDistance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings
 }
 
 //! Helper function to initialize the grouping for a selection.
-int initSelectionGroups(Selection *sel, t_topology *top, int type)
+int initSelectionGroups(Selection *sel, const gmx_mtop_t *top, int type)
 {
     e_index_t indexType = INDEX_UNKNOWN;
     switch (type)
@@ -256,14 +256,14 @@ void
 PairDistance::initAnalysis(const TrajectoryAnalysisSettings &settings,
                            const TopologyInformation        &top)
 {
-    refGroupCount_ = initSelectionGroups(&refSel_, top.topology(), refGroupType_);
+    refGroupCount_ = initSelectionGroups(&refSel_, top.mtop(), refGroupType_);
 
     maxGroupCount_ = 0;
     distances_.setDataSetCount(sel_.size());
     for (size_t i = 0; i < sel_.size(); ++i)
     {
         const int selGroupCount
-            = initSelectionGroups(&sel_[i], top.topology(), selGroupType_);
+            = initSelectionGroups(&sel_[i], top.mtop(), selGroupType_);
         const int columnCount = refGroupCount_ * selGroupCount;
         maxGroupCount_ = std::max(maxGroupCount_, columnCount);
         distances_.setColumnCount(i, columnCount);
index 958a67b9c6cb071946a4882bf46400af88e29aeb..664682e0abeaecb92e262eef4ac6f76b5a7369e4 100644 (file)
@@ -358,7 +358,7 @@ Rdf::initAnalysis(const TrajectoryAnalysisSettings &settings,
             GMX_THROW(InconsistentInputError("-surf only works with -ref that consists of atoms"));
         }
         const e_index_t type = (surface_ == SurfaceType_Molecule ? INDEX_MOL : INDEX_RES);
-        surfaceGroupCount_ = refSel_.initOriginalIdsToGroup(top.topology(), type);
+        surfaceGroupCount_ = refSel_.initOriginalIdsToGroup(top.mtop(), type);
     }
 
     if (bExclusions_)
index bd440203e22708e8e4a20cd833bab1ae9150305d..20cbc4ab4c7d649a54274d8d7a139b36739bf3e7 100644 (file)
@@ -555,7 +555,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings,
         dgsFactor_.reserve(surfaceSel_.posCount());
     }
 
-    const int resCount = surfaceSel_.initOriginalIdsToGroup(top_, INDEX_RES);
+    const int resCount = surfaceSel_.initOriginalIdsToGroup(top.mtop(), INDEX_RES);
 
     // TODO: Not exception-safe, but nice solution would be to have a C++
     // atom properties class...