Make moleculetype case sensitive
authorAlexey Shvetsov <alexxy@omrb.pnpi.spb.ru>
Wed, 25 Nov 2015 11:25:49 +0000 (14:25 +0300)
committerAlexey Shvetsov <alexxy@omrb.pnpi.spb.ru>
Sat, 26 Dec 2015 19:20:18 +0000 (20:20 +0100)
This is useful in case you have more than 36 chains
in your system with chain IDs set. PDB allows to use both
uppercase letters, lowercase letters and numbers for chain
identifiers. Now we can use the maximum of 62 chains.

We search for a case sensitive match first and if not found, for a
unique case insensitive match. The latter is done to not break old
topology files. The couple-moltype option is now case sensitive.

Change-Id: Ibbc7116740d573780020227a5a526e149bb9c5fe

src/gromacs/gmxpreprocess/topio.cpp
src/gromacs/gmxpreprocess/toppush.cpp

index ba8b4807c9fdedc816441c937e2bccff9a89cb78..6b7ef86e2fccd5d707a70fbcff7218241fff0ef3 100644 (file)
@@ -988,7 +988,7 @@ static char **read_topol(const char *infile, const char *outfile,
 
                             bCouple = (opts->couple_moltype != NULL &&
                                        (gmx_strcasecmp("system", opts->couple_moltype) == 0 ||
-                                        gmx_strcasecmp(*(mi0->name), opts->couple_moltype) == 0));
+                                        strcmp(*(mi0->name), opts->couple_moltype) == 0));
                             if (bCouple)
                             {
                                 nmol_couple += nrcopies;
index 6da0ff1d423d0c51e2cf26ec0c257c2c95df3b24..35d80c6cb9aeb5c1b9e1e3fb737b5f3ce687a417 100644 (file)
@@ -1419,11 +1419,11 @@ void push_molt(t_symtab *symtab, int *nmol, t_molinfo **mol, char *line,
         warning_error(wi, "Expected a molecule type name and nrexcl");
     }
 
-    /* Test if this atomtype overwrites another */
-    i = 0;
+    /* Test if this moleculetype overwrites another */
+    i    = 0;
     while (i < *nmol)
     {
-        if (gmx_strcasecmp(*((*mol)[i].name), type) == 0)
+        if (strcmp(*((*mol)[i].name), type) == 0)
         {
             gmx_fatal(FARGS, "moleculetype %s is redefined", type);
         }
@@ -2306,30 +2306,59 @@ void push_mol(int nrmols, t_molinfo mols[], char *pline, int *whichmol,
               int *nrcopies,
               warninp_t wi)
 {
-    int  i, copies;
     char type[STRLEN];
 
-    *nrcopies = 0;
-    if (sscanf(pline, "%s%d", type, &copies) != 2)
+    if (sscanf(pline, "%s%d", type, nrcopies) != 2)
     {
         too_few(wi);
         return;
     }
 
-    /* search moleculename */
-    for (i = 0; ((i < nrmols) && gmx_strcasecmp(type, *(mols[i].name))); i++)
+    /* Search moleculename.
+     * Here we originally only did case insensitive matching. But because
+     * some PDB files can have many chains and use case to generate more
+     * chain-identifiers, which in turn end up in our moleculetype name,
+     * we added support for case-sensitivity.
+     */
+    int nrcs    = 0;
+    int nrci    = 0;
+    int matchci = -1;
+    int matchcs = -1;
+    for (int i = 0; i < nrmols; i++)
     {
-        ;
+        if (strcmp(type, *(mols[i].name)) == 0)
+        {
+            nrcs++;
+            matchcs = i;
+        }
+        if (gmx_strcasecmp(type, *(mols[i].name)) == 0)
+        {
+            nrci++;
+            matchci = i;
+        }
     }
 
-    if (i < nrmols)
+    if (nrcs == 1)
     {
-        *nrcopies        = copies;
-        *whichmol        = i;
+        // select the case sensitive match
+        *whichmol = matchcs;
     }
     else
     {
-        gmx_fatal(FARGS, "No such moleculetype %s", type);
+        // avoid matching case-insensitive when we have multiple matches
+        if (nrci > 1)
+        {
+            gmx_fatal(FARGS, "For moleculetype '%s' in [ system ] %d case insensitive matches, but %d case sensitive matches were found. Check the case of the characters in the moleculetypes.", type, nrci, nrcs);
+        }
+        if (nrci == 1)
+        {
+            // select the unique case insensitive match
+            *whichmol = matchci;
+        }
+        else
+        {
+            gmx_fatal(FARGS, "No such moleculetype %s", type);
+        }
     }
 }