Add pdbname selection keyword.
authorTeemu Murtola <teemu.murtola@gmail.com>
Mon, 24 Sep 2012 04:48:01 +0000 (07:48 +0300)
committerTeemu Murtola <teemu.murtola@gmail.com>
Mon, 24 Sep 2012 15:43:18 +0000 (18:43 +0300)
As a supporting change, remove trailing space from t_pdbinfo.atomnm, as
the trailing whitespace does not seem to be used anywhere.
This makes it possible to use it easily in the selection code.

Fixes #1007; fix backported from Iac36bda8.

Also includes changes from 8bddac3 to make the backport easier.

Change-Id: Iac36bda8a84d0a6c131445e7f47ad91d7209fb10

include/types/atoms.h
src/gmxlib/pdbio.c
src/gmxlib/selection/selhelp.c
src/gmxlib/selection/selmethod.c
src/gmxlib/selection/sm_simple.c

index ea31d9db53e6f579197922b1b06776bbafe5983d..ce5eb7d80ebd5f82ac65855cd8e3b16df1f2757a 100644 (file)
@@ -71,7 +71,7 @@ typedef struct {
   int  type;                    /* PDB record name                      */
   int  atomnr;                  /* PDB atom number                      */
   char altloc;                  /* Alternate location indicator         */
-  char atomnm[6];               /* True atom name including spaces      */
+  char atomnm[6];               /* True atom name including leading spaces */
   real occup;                   /* Occupancy                            */
   real bfac;                    /* B-factor                             */
   gmx_bool bAnisotropic;        /* (an)isotropic switch                 */
index a546efe2439c14c0657d965a2fb463006a748169..2edfa812ae6af50009ccb2b28a266e543dd37fa6 100644 (file)
@@ -505,6 +505,7 @@ static int read_atom(t_symtab *symtab,
   for(k=0; (k<4); k++,j++) anm[k]=line[j];
   anm[k]=nc;
   strcpy(anm_copy,anm);
+  rtrim(anm_copy);
   atomnumber = NOTSET;
   trim(anm);
   altloc=line[j];
index 0bbe59fabac7654136541e33396261d4779a8d32..e2972d9d091d95d02bb0067e962e071931022abf 100644 (file)
@@ -193,7 +193,14 @@ static const char *help_limits[] = {
     "[TT]charge -1 to -0.7[tt][BR]",
     "result in a syntax error. A workaround is to write[BR]",
     "[TT]charge {-1 to -0.7}[tt][BR]",
-    "instead.",
+    "instead.[PAR]",
+
+    "When [TT]name[tt] selection keyword is used together with PDB input",
+    "files, the behavior may be unintuitive. When Gromacs reads in a PDB",
+    "file, 4 character atom names that start with a digit are transformed",
+    "such that, e.g., 1HG2 becomes HG21, and the latter is what is matched",
+    "by the [TT]name[tt] keyword. Use [TT]pdbname[tt] to match the atom name",
+    "as it appears in the input PDB file.",
 };
 
 static const char *help_positions[] = {
index 5d832fd3cc7f88d93051a56fbafdf19b5588aa55..5730303986da2af576b19105c98460e51e0515b4 100644 (file)
@@ -76,6 +76,7 @@ extern gmx_ana_selmethod_t sm_resnr;
 extern gmx_ana_selmethod_t sm_resindex;
 extern gmx_ana_selmethod_t sm_molindex;
 extern gmx_ana_selmethod_t sm_atomname;
+extern gmx_ana_selmethod_t sm_pdbatomname;
 extern gmx_ana_selmethod_t sm_atomtype;
 extern gmx_ana_selmethod_t sm_resname;
 extern gmx_ana_selmethod_t sm_insertcode;
@@ -134,7 +135,11 @@ static const t_register_method smtable_def[] = {
     {"mol",        &sm_molindex},
     {"molecule",   &sm_molindex},
     {NULL,         &sm_atomname},
+    {"name",       &sm_atomname},
+    {NULL,         &sm_pdbatomname},
+    {"pdbname",    &sm_pdbatomname},
     {NULL,         &sm_atomtype},
+    {"type",       &sm_atomtype},
     {NULL,         &sm_resname},
     {NULL,         &sm_insertcode},
     {NULL,         &sm_chain},
index 1810b12454bba5764ecaaedbbbe67452946f8e44..669dda7e9dee6f8cb47de6dc2bb6d7db1456b7e1 100644 (file)
@@ -35,6 +35,9 @@
 #include <config.h>
 #endif
 
+#include <string2.h>
+#include <macros.h>
+
 #include <position.h>
 #include <selmethod.h>
 
@@ -65,14 +68,18 @@ check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data
 static int
 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
-/** Evaluates the \p name selection keyword. */
+/** Evaluates the \p atomname selection keyword. */
 static int
 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
+/** Evaluates the \p pdbatomname selection keyword. */
+static int
+evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+                     gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Checks whether atom types are present in the topology. */
 static int
 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
-/** Evaluates the \p type selection keyword. */
+/** Evaluates the \p atomtype selection keyword. */
 static int
 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
@@ -125,6 +132,26 @@ static int
 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 
+/** Help text for atom name selection keywords. */
+static const char *help_atomname[] = {
+    "ATOM NAME SELECTION KEYWORDS[PAR]",
+
+    "[TT]name[tt] [TT]pdbname[tt] [TT]atomname[tt] [TT]pdbatomname[tt][PAR]",
+
+    "These keywords select atoms by name. [TT]name[tt] selects atoms using",
+    "the Gromacs atom naming convention.",
+    "For input formats other than PDB, the atom names are matched exactly",
+    "as they appear in the input file. For PDB files, 4 character atom names",
+    "that start with a digit are matched after moving the digit to the end",
+    "(e.g., to match 3HG2 from a PDB file, use [TT]name HG23[tt]).",
+    "[TT]pdbname[tt] can only be used with a PDB input file, and selects",
+    "atoms based on the exact name given in the input file, without the",
+    "transformation described above.[PAR]",
+
+    "[TT]atomname[tt] and [TT]pdbatomname[tt] are synonyms for the above two",
+    "keywords."
+};
+
 /** \internal Selection method data for \p all selection keyword. */
 gmx_ana_selmethod_t sm_all = {
     "all", GROUP_VALUE, 0,
@@ -211,7 +238,7 @@ gmx_ana_selmethod_t sm_molindex = {
 
 /** \internal Selection method data for \p name selection keyword. */
 gmx_ana_selmethod_t sm_atomname = {
-    "name", STR_VALUE, SMETH_REQTOP,
+    "atomname", STR_VALUE, SMETH_REQTOP,
     0, NULL,
     NULL,
     NULL,
@@ -221,11 +248,27 @@ gmx_ana_selmethod_t sm_atomname = {
     NULL,
     &evaluate_atomname,
     NULL,
+    {NULL, asize(help_atomname), help_atomname}
+};
+
+/** \internal Selection method data for \p pdbatomname selection keyword. */
+gmx_ana_selmethod_t sm_pdbatomname = {
+    "pdbatomname", STR_VALUE, SMETH_REQTOP,
+    0, NULL,
+    NULL,
+    NULL,
+    &check_pdbinfo,
+    NULL,
+    NULL,
+    NULL,
+    &evaluate_pdbatomname,
+    NULL,
+    {NULL, asize(help_atomname), help_atomname}
 };
 
 /** \internal Selection method data for \p type selection keyword. */
 gmx_ana_selmethod_t sm_atomtype = {
-    "type", STR_VALUE, SMETH_REQTOP,
+    "atomtype", STR_VALUE, SMETH_REQTOP,
     0, NULL,
     NULL,
     NULL,
@@ -545,6 +588,31 @@ evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     return 0;
 }
 
+/*!
+ * See sel_updatefunc() for description of the parameters.
+ * \p data is not used.
+ *
+ * Returns the PDB atom name for each atom in \p out->u.s.
+ */
+static int
+evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+                     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)
+    {
+        char *s = top->atoms.pdbinfo[g->index[i]].atomnm;
+        while (isspace(*s))
+        {
+            ++s;
+        }
+        out->u.s[i] = s;
+    }
+    return 0;
+}
+
 /*!
  * \param[in] top  Topology structure.
  * \param     npar Not used.