#include <cctype>
#include "gromacs/selection/position.h"
+#include "gromacs/topology/mtop_lookup.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/arraysize.h"
#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/gmxassert.h"
#include "selmethod.h"
/** Evaluates the \p all selection keyword. */
static void
-evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_all(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p none selection keyword. */
static void
-evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_none(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p atomnr selection keyword. */
static void
-evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_atomnr(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p resnr selection keyword. */
static void
-evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_resnr(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p resindex selection keyword. */
static void
-evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_resindex(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/*! \brief
* Checks whether molecule information is present in the topology.
* If molecule information is not found, also prints an error message.
*/
static void
-check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
+check_molecules(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
/** Evaluates the \p molindex selection keyword. */
static void
-evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_molindex(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p atomname selection keyword. */
static void
-evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_atomname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p pdbatomname selection keyword. */
static void
-evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_pdbatomname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/*! \brief
* Checks whether atom types are present in the topology.
* \param npar Not used.
* \param param Not used.
* \param data Not used.
- * \returns 0 if atom types are present in the topology, -1 otherwise.
- *
- * If the atom types are not found, also prints an error message.
*/
static void
-check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
+check_atomtype(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
/** Evaluates the \p atomtype selection keyword. */
static void
-evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_atomtype(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p insertcode selection keyword. */
static void
-evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_insertcode(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p chain selection keyword. */
static void
-evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_chain(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p mass selection keyword. */
static void
-evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_mass(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
+/*! \brief
+ * Checks whether charges are present in the topology.
+ *
+ * \param[in] top Topology structure.
+ * \param npar Not used.
+ * \param param Not used.
+ * \param data Not used.
+ */
+static void
+check_charge(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
/** Evaluates the \p charge selection keyword. */
static void
-evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_charge(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/*! \brief
* Checks whether PDB info is present in the topology.
* If PDB info is not found, also prints an error message.
*/
static void
-check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
+check_pdbinfo(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
/** Evaluates the \p altloc selection keyword. */
static void
-evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_altloc(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p occupancy selection keyword. */
static void
-evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_occupancy(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p betafactor selection keyword. */
static void
-evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_betafactor(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p resname selection keyword. */
static void
-evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_resname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p x selection keyword. */
static void
-evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_x(const gmx::SelMethodEvalContext &context,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p y selection keyword. */
static void
-evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_y(const gmx::SelMethodEvalContext &context,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
/** Evaluates the \p z selection keyword. */
static void
-evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+evaluate_z(const gmx::SelMethodEvalContext &context,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
//! Help title for atom name selection keywords.
"keywords."
};
+ //! Help title for residue index selection keywords.
+ static const char helptitle_resindex[] = "Selecting atoms by residue number";
+ //! Help text for residue index selection keywords.
+ static const char *const help_resindex[] = {
+ "::",
+ "",
+ " resnr",
+ " resid",
+ " resindex",
+ " residue",
+ "",
+ "[TT]resnr[tt] selects atoms using the residue numbering in the input",
+ "file. [TT]resid[tt] is synonym for this keyword for VMD compatibility.",
+ "",
+ "[TT]resindex N[tt] selects the [TT]N[tt]th residue starting from the",
+ "beginning of the input file. This is useful for uniquely identifying",
+ "residues if there are duplicate numbers in the input file (e.g., in",
+ "multiple chains).",
+ "[TT]residue[tt] is a synonym for [TT]resindex[tt]. This allows",
+ "[TT]same residue as[tt] to work as expected."
+ };
+
/** Selection method data for \p all selection keyword. */
gmx_ana_selmethod_t sm_all = {
"all", GROUP_VALUE, 0,
NULL,
&evaluate_resnr,
NULL,
+ {NULL, helptitle_resindex, asize(help_resindex), help_resindex}
};
/** Selection method data for \p resindex selection keyword. */
NULL,
&evaluate_resindex,
NULL,
+ {NULL, helptitle_resindex, asize(help_resindex), help_resindex}
};
/** Selection method data for \p molindex selection keyword. */
/** Selection method data for \p mass selection keyword. */
gmx_ana_selmethod_t sm_mass = {
- "mass", REAL_VALUE, SMETH_REQTOP,
+ "mass", REAL_VALUE, SMETH_REQMASS,
0, NULL,
NULL,
NULL,
0, NULL,
NULL,
NULL,
- NULL,
+ &check_charge,
NULL,
NULL,
NULL,
* Copies \p g to \p out->u.g.
*/
static void
-evaluate_all(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_all(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
gmx_ana_index_copy(out->u.g, g, false);
* Returns an empty \p out->u.g.
*/
static void
-evaluate_none(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_none(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void * /* data */)
{
out->u.g->isize = 0;
* Returns the indices for each atom in \p out->u.i.
*/
static void
-evaluate_atomnr(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_atomnr(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
int i;
* Returns the residue numbers for each atom in \p out->u.i.
*/
static void
-evaluate_resnr(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_resnr(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
- int resind;
-
- out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ out->nr = g->isize;
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- resind = top->atoms.atom[g->index[i]].resind;
- out->u.i[i] = top->atoms.resinfo[resind].nr;
+ mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
+ nullptr, &out->u.i[i], nullptr, nullptr);
}
}
* Returns the residue indices for each atom in \p out->u.i.
*/
static void
-evaluate_resindex(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_resindex(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
- out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ out->nr = g->isize;
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.i[i] = top->atoms.atom[g->index[i]].resind + 1;
+ int resind;
+ mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
+ nullptr, nullptr, nullptr, &resind);
+ out->u.i[i] = resind + 1;
}
}
static void
-check_molecules(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
+check_molecules(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
{
bool bOk;
* Returns the molecule indices for each atom in \p out->u.i.
*/
static void
-evaluate_molindex(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_molindex(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
int i, j;
out->nr = g->isize;
for (i = j = 0; i < g->isize; ++i)
{
- while (top->mols.index[j + 1] <= g->index[i])
+ while (context.top->mols.index[j + 1] <= g->index[i])
{
++j;
}
* Returns the atom name for each atom in \p out->u.s.
*/
static void
-evaluate_atomname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_atomname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.s[i] = *top->atoms.atomname[g->index[i]];
+ const char *atom_name;
+ mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
+ &atom_name, nullptr, nullptr, nullptr);
+ out->u.s[i] = const_cast<char *>(atom_name);
}
}
* Returns the PDB atom name for each atom in \p out->u.s.
*/
static void
-evaluate_pdbatomname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_pdbatomname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- char *s = top->atoms.pdbinfo[g->index[i]].atomnm;
+ const char *s = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).atomnm;
while (std::isspace(*s))
{
++s;
}
- out->u.s[i] = s;
+ out->u.s[i] = const_cast<char *>(s);
}
}
static void
-check_atomtype(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
+check_atomtype(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
{
- bool bOk;
-
- bOk = (top != NULL && top->atoms.atomtype != NULL);
- if (!bOk)
+ if (!gmx_mtop_has_atomtypes(top))
{
GMX_THROW(gmx::InconsistentInputError("Atom types not available in topology"));
}
* Segfaults if atom types are not found in the topology.
*/
static void
-evaluate_atomtype(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_atomtype(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.s[i] = *top->atoms.atomtype[g->index[i]];
+ int atomIndexInMolecule;
+ mtopGetMolblockIndex(context.top, g->index[i], &molb,
+ nullptr, &atomIndexInMolecule);
+ const gmx_moltype_t &moltype = context.top->moltype[context.top->molblock[molb].type];
+ out->u.s[i] = *moltype.atoms.atomtype[atomIndexInMolecule];
}
}
* Returns the residue name for each atom in \p out->u.s.
*/
static void
-evaluate_resname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_resname(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
- int resind;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- resind = top->atoms.atom[g->index[i]].resind;
- out->u.s[i] = *top->atoms.resinfo[resind].name;
+ out->u.s[i] = *mtopGetResidueInfo(context.top, g->index[i], &molb).name;
}
}
* Returns the insertion code for each atom in \p out->u.s.
*/
static void
-evaluate_insertcode(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_insertcode(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
- int resind;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- resind = top->atoms.atom[g->index[i]].resind;
- out->u.s[i][0] = top->atoms.resinfo[resind].ic;
+ out->u.s[i][0] = mtopGetResidueInfo(context.top, g->index[i], &molb).ic;
}
}
* Returns the chain for each atom in \p out->u.s.
*/
static void
-evaluate_chain(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_chain(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
- int resind;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- resind = top->atoms.atom[g->index[i]].resind;
- out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
+ out->u.s[i][0] = mtopGetResidueInfo(context.top, g->index[i], &molb).chainid;
}
}
* Returns the mass for each atom in \p out->u.r.
*/
static void
-evaluate_mass(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_mass(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
+ GMX_RELEASE_ASSERT(gmx_mtop_has_masses(context.top),
+ "Masses not available for evaluation");
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
+ {
+ out->u.r[i] = mtopGetAtomMass(context.top, g->index[i], &molb);
+ }
+}
+
+
+static void
+check_charge(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
+{
+ if (!gmx_mtop_has_charges(top))
{
- out->u.r[i] = top->atoms.atom[g->index[i]].m;
+ GMX_THROW(gmx::InconsistentInputError("Charges not available in topology"));
}
}
* Returns the charge for each atom in \p out->u.r.
*/
static void
-evaluate_charge(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_charge(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.r[i] = top->atoms.atom[g->index[i]].q;
+ out->u.r[i] = mtopGetAtomParameters(context.top, g->index[i], &molb).q;
}
}
static void
-check_pdbinfo(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
+check_pdbinfo(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
{
- bool bOk;
-
- bOk = (top != NULL && top->atoms.pdbinfo != NULL);
- if (!bOk)
+ if (!gmx_mtop_has_pdbinfo(top))
{
GMX_THROW(gmx::InconsistentInputError("PDB info not available in topology"));
}
* Returns the alternate location identifier for each atom in \p out->u.s.
*/
static void
-evaluate_altloc(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_altloc(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
+ out->u.s[i][0] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).altloc;
}
}
* Segfaults if PDB info is not found in the topology.
*/
static void
-evaluate_occupancy(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_occupancy(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
+ out->u.r[i] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).occup;
}
}
* Segfaults if PDB info is not found in the topology.
*/
static void
-evaluate_betafactor(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
+evaluate_betafactor(const gmx::SelMethodEvalContext &context,
gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
{
- int i;
-
out->nr = g->isize;
- for (i = 0; i < g->isize; ++i)
+ int molb = 0;
+ for (int i = 0; i < g->isize; ++i)
{
- out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
+ out->u.r[i] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).bfac;
}
}
* Returns the \p x coordinate for each position in \p out->u.r.
*/
static void
-evaluate_x(t_topology * /*top*/, t_trxframe * /*fr*/, t_pbc * /*pbc*/,
+evaluate_x(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
{
out->nr = pos->count();
* Returns the \p y coordinate for each position in \p out->u.r.
*/
static void
-evaluate_y(t_topology * /*top*/, t_trxframe * /*fr*/, t_pbc * /*pbc*/,
+evaluate_y(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
{
out->nr = pos->count();
* Returns the \p z coordinate for each position in \p out->u.r.
*/
static void
-evaluate_z(t_topology * /*top*/, t_trxframe * /*fr*/, t_pbc * /*pbc*/,
+evaluate_z(const gmx::SelMethodEvalContext & /*context*/,
gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
{
out->nr = pos->count();
gmx::test::TopologyManager topManager_;
gmx::SelectionCollection sc_;
gmx::SelectionList sel_;
- t_topology *top_;
gmx_ana_indexgrps_t *grps_;
};
#endif
SelectionCollectionTest::SelectionCollectionTest()
- : top_(NULL), grps_(NULL)
+ : grps_(NULL)
{
topManager_.requestFrame();
sc_.setDebugLevel(s_debugLevel);
void
SelectionCollectionTest::setTopology()
{
- top_ = topManager_.topology();
-
- ASSERT_NO_THROW_GMX(sc_.setTopology(top_, -1));
+ ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1));
}
void
TEST_F(SelectionCollectionTest, HandlesNoSelections)
{
- EXPECT_FALSE(sc_.requiresTopology());
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
EXPECT_NO_THROW_GMX(sc_.compile());
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
+}
+
+TEST_F(SelectionCollectionTest, HandlesNoSelectionsWithDefaultPositionType)
+{
+ EXPECT_NO_THROW_GMX(sc_.setOutputPosType("res_com"));
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsTopology);
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsMasses);
+ EXPECT_NO_THROW_GMX(sc_.setOutputPosType("res_cog"));
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsTopology);
+ EXPECT_FALSE(sc_.requiredTopologyProperties().needsMasses);
+ ASSERT_NO_THROW_GMX(sc_.parseFromString("atom of atomnr 1 to 10"));
+ ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
+ ASSERT_NO_THROW_GMX(sc_.compile());
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
}
TEST_F(SelectionCollectionTest, HandlesVelocityAndForceRequests)
{
ASSERT_NO_THROW_GMX(sel_ = sc_.parseFromString("atomnr 1 to 10; none"));
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
ASSERT_NO_FATAL_FAILURE(setAtomCount(10));
ASSERT_EQ(2U, sel_.size());
ASSERT_NO_THROW_GMX(sel_[0].setEvaluateVelocities(true));
ASSERT_NO_THROW_GMX(sel_[1].setEvaluateVelocities(true));
ASSERT_NO_THROW_GMX(sel_[0].setEvaluateForces(true));
ASSERT_NO_THROW_GMX(sel_[1].setEvaluateForces(true));
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
ASSERT_NO_THROW_GMX(sc_.compile());
+ EXPECT_FALSE(sc_.requiredTopologyProperties().hasAny());
EXPECT_TRUE(sel_[0].hasVelocities());
EXPECT_TRUE(sel_[1].hasVelocities());
EXPECT_TRUE(sel_[0].hasForces());
EXPECT_TRUE(sel_[1].hasForces());
}
+TEST_F(SelectionCollectionTest, HandlesForceRequestForCenterOfGeometry)
+{
+ ASSERT_NO_THROW_GMX(sel_ = sc_.parseFromString("res_cog of atomnr 1 to 10"));
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsTopology);
+ ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
+ ASSERT_EQ(1U, sel_.size());
+ ASSERT_NO_THROW_GMX(sel_[0].setEvaluateForces(true));
+ // In principle, the code could know here that the masses are required, but
+ // currently it only knows this after compilation.
+ ASSERT_NO_THROW_GMX(sc_.compile());
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsMasses);
+ EXPECT_TRUE(sel_[0].hasForces());
+}
+
TEST_F(SelectionCollectionTest, ParsesSelectionsFromFile)
{
ASSERT_NO_THROW_GMX(sel_ = sc_.parseFromFile(
{
const int index[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11 };
// Evaluating the positions will require atoms 1-3, 7-12.
- ASSERT_NO_THROW_GMX(sc_.parseFromString("whole_res_com of atomnr 2 7 11"));
+ ASSERT_NO_THROW_GMX(sc_.parseFromString("whole_res_cog of atomnr 2 7 11"));
ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
ASSERT_NO_THROW_GMX(sc_.compile());
topManager_.initFrameIndices(index);
"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());
}
"atomtype CA"
};
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
+ ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
const char *const types[] = { "CA", "SA", "SB" };
topManager_.initAtomTypes(types);
+ ASSERT_NO_FATAL_FAILURE(setTopology());
ASSERT_NO_FATAL_FAILURE(runCompiler());
}
"mass > 5"
};
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
- for (int i = 0; i < top_->atoms.nr; ++i)
+ EXPECT_TRUE(sc_.requiredTopologyProperties().needsMasses);
+ ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
+ t_atoms &atoms = topManager_.atoms();
+ for (int i = 0; i < atoms.nr; ++i)
{
- top_->atoms.atom[i].m = 1.0 + i;
+ atoms.atom[i].m = 1.0 + i;
}
+ atoms.haveMass = TRUE;
+ ASSERT_NO_FATAL_FAILURE(setTopology());
ASSERT_NO_FATAL_FAILURE(runCompiler());
}
"charge < 0.5"
};
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
- for (int i = 0; i < top_->atoms.nr; ++i)
+ ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
+ t_atoms &atoms = topManager_.atoms();
+ for (int i = 0; i < atoms.nr; ++i)
{
- top_->atoms.atom[i].q = i / 10.0;
+ atoms.atom[i].q = i / 10.0;
}
- //ensure exact representation of 0.5 is used, so the test is always reproducible
- top_->atoms.atom[5].q = 0.5;
+ // Ensure exact representation of 0.5 is used, so that the test is
+ // reproducible.
+ atoms.atom[5].q = 0.5;
+ atoms.haveCharge = TRUE;
+ ASSERT_NO_FATAL_FAILURE(setTopology());
ASSERT_NO_FATAL_FAILURE(runCompiler());
}
setFlags(TestFlags() | efTestEvaluation | efTestPositionAtoms
| efTestPositionMasses | efTestPositionCharges);
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
- for (int i = 0; i < top_->atoms.nr; ++i)
+ ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
+ t_atoms &atoms = topManager_.atoms();
+ for (int i = 0; i < atoms.nr; ++i)
{
- top_->atoms.atom[i].m = 1.0 + i / 100.0;
- top_->atoms.atom[i].q = -(1.0 + i / 100.0);
+ atoms.atom[i].m = 1.0 + i / 100.0;
+ atoms.atom[i].q = -(1.0 + i / 100.0);
}
+ atoms.haveMass = TRUE;
+ atoms.haveCharge = TRUE;
+ ASSERT_NO_FATAL_FAILURE(setTopology());
ASSERT_NO_FATAL_FAILURE(runCompiler());
ASSERT_NO_FATAL_FAILURE(runEvaluate());
ASSERT_NO_FATAL_FAILURE(runEvaluateFinal());
"charge {0.05 to -0.3 -0.05 to 0.55}"
};
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro"));
- for (int i = 0; i < top_->atoms.nr; ++i)
+ ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro"));
+ t_atoms &atoms = topManager_.atoms();
+ for (int i = 0; i < atoms.nr; ++i)
{
- top_->atoms.atom[i].q = i / 10.0 - 0.5;
+ atoms.atom[i].q = i / 10.0 - 0.5;
}
+ atoms.haveCharge = TRUE;
+ ASSERT_NO_FATAL_FAILURE(setTopology());
ASSERT_NO_FATAL_FAILURE(runCompiler());
}
}
+ TEST_F(SelectionCollectionDataTest, HandlesPositionVariableInModifier)
+ {
+ static const char * const selections[] = {
+ "foo = cog of resnr 1",
+ "cog of resnr 2 plus foo",
+ "cog of resnr 3 plus foo"
+ };
+ setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
+ runTest("simple.gro", selections);
+ }
+
+
TEST_F(SelectionCollectionDataTest, HandlesConstantPositionInVariable)
{
static const char * const selections[] = {
#include "gromacs/gmxpreprocess/gmxcpp.h"
#include "gromacs/linearalgebra/sparsematrix.h"
#include "gromacs/math/vecdump.h"
+#include "gromacs/mdrunutility/mdmodules.h"
#include "gromacs/mdtypes/forcerec.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/txtdump.h"
-static void list_tpx(const char *fn, gmx_bool bShowNumbers, const char *mdpfn,
- gmx_bool bSysTop)
+static void list_tpx(const char *fn,
+ gmx_bool bShowNumbers,
+ gmx_bool bShowParameters,
+ const char *mdpfn,
+ gmx_bool bSysTop)
{
FILE *gp;
int indent, i, j, **gcount, atot;
- t_state state;
- t_inputrec ir;
+ t_state state {};
+ t_inputrec *ir = nullptr;
t_tpxheader tpx;
gmx_mtop_t mtop;
gmx_groups_t *groups;
t_topology top;
read_tpxheader(fn, &tpx, TRUE);
-
+ gmx::MDModules mdModules;
+ if (tpx.bIr)
+ {
+ ir = mdModules.inputrec();
+ }
read_tpx_state(fn,
- tpx.bIr ? &ir : NULL,
+ ir,
&state,
tpx.bTop ? &mtop : NULL);
if (mdpfn && tpx.bIr)
{
gp = gmx_fio_fopen(mdpfn, "w");
- pr_inputrec(gp, 0, NULL, &(ir), TRUE);
+ pr_inputrec(gp, 0, NULL, ir, TRUE);
gmx_fio_fclose(gp);
}
{
if (bSysTop)
{
- top = gmx_mtop_t_to_t_topology(&mtop);
+ top = gmx_mtop_t_to_t_topology(&mtop, false);
}
if (available(stdout, &tpx, 0, fn))
{
indent = 0;
pr_title(stdout, indent, fn);
- pr_inputrec(stdout, 0, "inputrec", tpx.bIr ? &(ir) : NULL, FALSE);
+ pr_inputrec(stdout, 0, "inputrec", ir, FALSE);
pr_tpxheader(stdout, indent, "header", &(tpx));
if (!bSysTop)
{
- pr_mtop(stdout, indent, "topology", &(mtop), bShowNumbers);
+ pr_mtop(stdout, indent, "topology", &(mtop), bShowNumbers, bShowParameters);
}
else
{
- pr_top(stdout, indent, "topology", &(top), bShowNumbers);
+ pr_top(stdout, indent, "topology", &(top), bShowNumbers, bShowParameters);
}
pr_rvecs(stdout, indent, "box", tpx.bBox ? state.box : NULL, DIM);
pr_rvecs(stdout, indent, "svir_prev", tpx.bBox ? state.svir_prev : NULL, DIM);
pr_rvecs(stdout, indent, "fvir_prev", tpx.bBox ? state.fvir_prev : NULL, DIM);
/* leave nosehoover_xi in for now to match the tpr version */
- pr_doubles(stdout, indent, "nosehoover_xi", state.nosehoover_xi, state.ngtc);
+ pr_doubles(stdout, indent, "nosehoover_xi", state.nosehoover_xi.data(), state.ngtc);
/*pr_doubles(stdout,indent,"nosehoover_vxi",state.nosehoover_vxi,state.ngtc);*/
/*pr_doubles(stdout,indent,"therm_integral",state.therm_integral,state.ngtc);*/
- pr_rvecs(stdout, indent, "x", tpx.bX ? state.x : NULL, state.natoms);
- pr_rvecs(stdout, indent, "v", tpx.bV ? state.v : NULL, state.natoms);
+ pr_rvecs(stdout, indent, "x", tpx.bX ? as_rvec_array(state.x.data()) : NULL, state.natoms);
+ pr_rvecs(stdout, indent, "v", tpx.bV ? as_rvec_array(state.v.data()) : NULL, state.natoms);
}
groups = &mtop.groups;
}
sfree(gcount);
}
- done_state(&state);
}
static void list_top(const char *fn)
gmx_int64_t nframe = 0;
gmx_int64_t i, *block_ids = NULL, step, ndatablocks;
gmx_bool bOK;
+ real *values = NULL;
gmx_tng_open(fn, 'r', &tng);
gmx_print_tng_molecule_system(tng, stdout);
for (i = 0; i < ndatablocks; i++)
{
double frame_time;
- real prec, *values = NULL;
+ real prec;
gmx_int64_t n_values_per_frame, n_atoms;
char block_name[STRLEN];
{
sfree(block_ids);
}
-
+ sfree(values);
gmx_tng_close(&tng);
#endif
}
gmx_output_env_t *oenv;
/* Command line options */
static gmx_bool bShowNumbers = TRUE;
+ static gmx_bool bShowParams = FALSE;
static gmx_bool bSysTop = FALSE;
t_pargs pa[] = {
{ "-nr", FALSE, etBOOL, {&bShowNumbers}, "Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)" },
+ { "-param", FALSE, etBOOL, {&bShowParams}, "Show parameters for each bonded interaction (for comparing dumps, it is useful to combine this with -nonr)" },
{ "-sys", FALSE, etBOOL, {&bSysTop}, "List the atoms and bonded interactions for the whole system instead of for each molecule type" }
};
if (ftp2bSet(efTPR, NFILE, fnm))
{
- list_tpx(ftp2fn(efTPR, NFILE, fnm), bShowNumbers,
+ list_tpx(ftp2fn(efTPR, NFILE, fnm), bShowNumbers, bShowParams,
ftp2fn_null(efMDP, NFILE, fnm), bSysTop);
}
else if (ftp2bSet(efTRX, NFILE, fnm))