Merge branch release-2016
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 7 Dec 2016 04:16:48 +0000 (15:16 +1100)
committerMark Abraham <mark.j.abraham@gmail.com>
Wed, 7 Dec 2016 04:17:43 +0000 (15:17 +1100)
Ignored fix to zlib management for GMX_EXTERNAL_TNG=on because that
was already a feature of the refactoring of TNG management in master
branch.

Change-Id: I8bc7ce196fb0d64685c6957b5055d73ff093d864

1  2 
src/gromacs/gmxana/gmx_trjconv.cpp
src/gromacs/selection/compiler.cpp
src/gromacs/selection/sm_simple.cpp
src/gromacs/selection/tests/selectioncollection.cpp
src/gromacs/tools/dump.cpp
src/programs/mdrun/membed.cpp

index a28040b72f782cae6057b239e927bb99fadc441d,aa00fe498f620ee098ab0cad1109b3c9094cad46..cf975601f976e91a632a23dfce5570a09025cef1
@@@ -861,7 -861,7 +861,7 @@@ int gmx_trjconv(int argc, char *argv[]
      FILE             *out    = NULL;
      t_trxstatus      *trxout = NULL;
      t_trxstatus      *trxin;
-     int               ftp, ftpin = 0, file_nr;
+     int               file_nr;
      t_trxframe        fr, frout;
      int               flags;
      rvec             *xmem  = NULL, *vmem = NULL, *fmem = NULL;
  
          /* Determine output type */
          out_file = opt2fn("-o", NFILE, fnm);
-         ftp      = fn2ftp(out_file);
+         int ftp  = fn2ftp(out_file);
          fprintf(stderr, "Will write %s: %s\n", ftp2ext(ftp), ftp2desc(ftp));
          bNeedPrec = (ftp == efXTC || ftp == efGRO);
+         int ftpin = fn2ftp(in_file);
          if (bVels)
          {
              /* check if velocities are possible in input and output files */
-             ftpin = fn2ftp(in_file);
              bVels = (ftp == efTRR || ftp == efGRO ||
                       ftp == efG96 || ftp == efTNG)
                  && (ftpin == efTRR || ftpin == efGRO ||
              /* get memory for stuff to go in .pdb file, and initialize
               * the pdbinfo structure part if the input has it.
               */
 -            init_t_atoms(&useatoms, atoms->nr, (atoms->pdbinfo != NULL));
 +            init_t_atoms(&useatoms, atoms->nr, atoms->havePdbInfo);
              sfree(useatoms.resinfo);
              useatoms.resinfo = atoms->resinfo;
              for (i = 0; (i < nout); i++)
              {
                  useatoms.atomname[i] = atoms->atomname[index[i]];
                  useatoms.atom[i]     = atoms->atom[index[i]];
 -                if (atoms->pdbinfo != NULL)
 +                if (atoms->havePdbInfo)
                  {
                      useatoms.pdbinfo[i]  = atoms->pdbinfo[index[i]];
                  }
index 217a4b71b52fbc566dbdc091adc0eb80839eaa74,a5f9239677051c28425d2705f7cc301287a68311..a35ac378a01d52dfc82ff246087b6ac29bf9b53e
@@@ -1829,7 -1829,7 +1829,7 @@@ store_param_val(const SelectionTreeElem
   * is prevented by using \ref SEL_METHODINIT and \ref SEL_OUTINIT flags.
   */
  static void
 -init_method(const SelectionTreeElementPointer &sel, t_topology *top, int isize)
 +init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int isize)
  {
      /* Find out whether there are any atom-valued parameters */
      bool bAtomVal                     = false;
@@@ -2281,6 -2281,7 +2281,7 @@@ analyze_static(gmx_sel_evaluate_
                  if (sel->v.type == POS_VALUE)
                  {
                      alloc_selection_pos_data(sel);
+                     gmx_ana_pos_copy(sel->v.u.p, sel->child->v.u.p, true);
                  }
                  else
                  {
index 4af50ee16347c9c3f1f3bde89f02d89b9c784ac7,ca384efd8144d882ea083bb9dadc4c7f08bf3733..60910d1cbe43b604284636459c9c68f22b22d41b
  #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.
@@@ -205,6 -196,28 +205,28 @@@ static const char *const help_atomname[
      "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,
@@@ -259,6 -272,7 +281,7 @@@ gmx_ana_selmethod_t sm_resnr = 
      NULL,
      &evaluate_resnr,
      NULL,
+     {NULL, helptitle_resindex, asize(help_resindex), help_resindex}
  };
  
  /** Selection method data for \p resindex selection keyword. */
@@@ -273,6 -287,7 +296,7 @@@ gmx_ana_selmethod_t sm_resindex = 
      NULL,
      &evaluate_resindex,
      NULL,
+     {NULL, helptitle_resindex, asize(help_resindex), help_resindex}
  };
  
  /** Selection method data for \p molindex selection keyword. */
@@@ -377,7 -392,7 +401,7 @@@ gmx_ana_selmethod_t sm_chain = 
  
  /** 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,
@@@ -395,7 -410,7 +419,7 @@@ gmx_ana_selmethod_t sm_charge = 
      0, NULL,
      NULL,
      NULL,
 -    NULL,
 +    &check_charge,
      NULL,
      NULL,
      NULL,
@@@ -494,7 -509,7 +518,7 @@@ gmx_ana_selmethod_t sm_z = 
   * 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;
      }
  }
  
@@@ -879,7 -898,7 +903,7 @@@ evaluate_coord(real out[], gmx_ana_pos_
   * 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();
index 2d89ecc2d1ac6be70b559d390358f0f167aa58e8,34f59aabcdd32885d0c449e4861232fde402de6d..c8c3a75c4a63151845f1ba538f8bc78e86e75bad
@@@ -91,6 -91,7 +91,6 @@@ class SelectionCollectionTest : public 
          gmx::test::TopologyManager  topManager_;
          gmx::SelectionCollection    sc_;
          gmx::SelectionList          sel_;
 -        t_topology                 *top_;
          gmx_ana_indexgrps_t        *grps_;
  };
  
@@@ -107,7 -108,7 +107,7 @@@ GMX_TEST_OPTIONS(SelectionCollectionTes
  #endif
  
  SelectionCollectionTest::SelectionCollectionTest()
 -    : top_(NULL), grps_(NULL)
 +    : grps_(NULL)
  {
      topManager_.requestFrame();
      sc_.setDebugLevel(s_debugLevel);
@@@ -133,7 -134,9 +133,7 @@@ SelectionCollectionTest::loadTopology(c
  void
  SelectionCollectionTest::setTopology()
  {
 -    top_   = topManager_.topology();
 -
 -    ASSERT_NO_THROW_GMX(sc_.setTopology(top_, -1));
 +    ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1));
  }
  
  void
@@@ -420,58 -423,26 +420,58 @@@ SelectionCollectionDataTest::runTest
  
  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(
@@@ -671,7 -642,7 +671,7 @@@ TEST_F(SelectionCollectionTest, Handles
  {
      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);
@@@ -882,9 -853,8 +882,9 @@@ TEST_F(SelectionCollectionDataTest, Han
          "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());
  }
  
@@@ -915,10 -885,9 +915,10 @@@ TEST_F(SelectionCollectionDataTest, Han
          "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());
  }
  
@@@ -937,15 -906,11 +937,15 @@@ TEST_F(SelectionCollectionDataTest, Han
          "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());
  }
  
@@@ -955,17 -920,13 +955,17 @@@ TEST_F(SelectionCollectionDataTest, Han
          "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());
  }
  
@@@ -1154,16 -1115,12 +1154,16 @@@ TEST_F(SelectionCollectionDataTest, Com
      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());
@@@ -1332,14 -1289,11 +1332,14 @@@ TEST_F(SelectionCollectionDataTest, Han
          "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());
  }
  
@@@ -1532,6 -1486,18 +1532,18 @@@ TEST_F(SelectionCollectionDataTest, Han
  }
  
  
+ 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[] = {
index 1e9da4acfd4cc87d299cd1c7adf3efb7b3692b3d,9ddd8ec035d0cbc1151c6b14d1337caba69eecac..17196243034a9236066579cf80beb25999c4a83a
@@@ -56,7 -56,6 +56,7 @@@
  #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)
@@@ -353,6 -346,7 +353,7 @@@ static void list_tng(const char gmx_unu
      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
  }
@@@ -626,11 -620,9 +627,11 @@@ int gmx_dump(int argc, char *argv[]
      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))
index c57dc73c3234dcc05ec1900d4d604081c50381bc,50feee655d4e9e66f98eb854ca998dfddbbed99c..ce15054cf88be6b169668a73a088d8b695b5f74d
@@@ -50,7 -50,6 +50,7 @@@
  #include "gromacs/mdtypes/state.h"
  #include "gromacs/pbcutil/pbc.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/cstringutil.h"
@@@ -107,15 -106,18 +107,15 @@@ static int get_mol_id(int at, gmx_mtop_
      int                   mol_id = 0;
      int                   i;
      int                   atnr_mol;
 -    gmx_mtop_atomlookup_t alook;
  
 -    alook = gmx_mtop_atomlookup_settle_init(mtop);
 -    gmx_mtop_atomnr_to_molblock_ind(alook, at, block, &mol_id, &atnr_mol);
 +    *block = 0;
 +    mtopGetMolblockIndex(mtop, at, block, &mol_id, &atnr_mol);
      for (i = 0; i < *block; i++)
      {
          mol_id += mtop->molblock[i].nmol;
      }
      *type = mtop->molblock[*block].type;
  
 -    gmx_mtop_atomlookup_destroy(alook);
 -
      return mol_id;
  }
  
@@@ -719,8 -721,9 +719,8 @@@ static void rm_group(gmx_groups_t *grou
      mtop->mols.index = new_mols;
      mtop->natoms    -= n;
      state->natoms   -= n;
 -    state->nalloc    = state->natoms;
 -    snew(x_tmp, state->nalloc);
 -    snew(v_tmp, state->nalloc);
 +    snew(x_tmp, state->natoms);
 +    snew(v_tmp, state->natoms);
  
      for (i = 0; i < egcNR; i++)
      {
              }
          }
      }
 -    sfree(state->x);
 -    state->x = x_tmp;
 -    sfree(state->v);
 -    state->v = v_tmp;
 +    for (int i = 0; i < state->natoms; i++)
 +    {
 +        copy_rvec(x_tmp[i], state->x[i]);
 +    }
 +    sfree(x_tmp);
 +    for (int i = 0; i < state->natoms; i++)
 +    {
 +        copy_rvec(v_tmp[i], state->v[i]);
 +    }
 +    sfree(v_tmp);
  
      for (i = 0; i < egcNR; i++)
      {
@@@ -1116,7 -1113,7 +1116,7 @@@ gmx_membed_t *init_membed(FILE *fplog, 
          if (xy_fac < min_xy_init)
          {
              warn++;
-             fprintf(stderr, "\nWarning %d:\nThe initial size of %s is probably too smal.\n\n", warn, ins);
+             fprintf(stderr, "\nWarning %d:\nThe initial size of %s is probably too small.\n\n", warn, ins);
          }
  
          if (it_xy < min_it_xy)
          /* Check that moleculetypes in insertion group are not part of the rest of the system */
          check_types(ins_at, rest_at, mtop);
  
 -        init_mem_at(mem_p, mtop, state->x, state->box, pos_ins);
 +        init_mem_at(mem_p, mtop, as_rvec_array(state->x.data()), state->box, pos_ins);
  
 -        prot_area = est_prot_area(pos_ins, state->x, ins_at, mem_p);
 +        prot_area = est_prot_area(pos_ins, as_rvec_array(state->x.data()), ins_at, mem_p);
          if ( (prot_area > prot_vs_box) && ( (state->box[XX][XX]*state->box[YY][YY]-state->box[XX][YY]*state->box[YY][XX]) < box_vs_prot) )
          {
              warn++;
  
          /* resize the protein by xy and by z if necessary*/
          snew(r_ins, ins_at->nr);
 -        init_resize(ins_at, r_ins, pos_ins, mem_p, state->x, bALLOW_ASYMMETRY);
 +        init_resize(ins_at, r_ins, pos_ins, mem_p, as_rvec_array(state->x.data()), bALLOW_ASYMMETRY);
          membed->fac[0] = membed->fac[1] = xy_fac;
          membed->fac[2] = z_fac;
  
          membed->xy_step = (xy_max-xy_fac)/(double)(it_xy);
          membed->z_step  = (z_max-z_fac)/(double)(it_z-1);
  
 -        resize(r_ins, state->x, pos_ins, membed->fac);
 +        resize(r_ins, as_rvec_array(state->x.data()), pos_ins, membed->fac);
  
          /* remove overlapping lipids and water from the membrane box*/
          /*mark molecules to be removed*/
          set_pbc(pbc, inputrec->ePBC, state->box);
  
          snew(rm_p, 1);
 -        lip_rm = gen_rm_list(rm_p, ins_at, rest_at, pbc, mtop, state->x, mem_p, pos_ins,
 +        lip_rm = gen_rm_list(rm_p, ins_at, rest_at, pbc, mtop, as_rvec_array(state->x.data()), mem_p, pos_ins,
                               probe_rad, low_up_rm, bALLOW_ASYMMETRY);
          lip_rm -= low_up_rm;