Refactor ResidueTypes
authorPaul Bauer <paul.bauer.q@gmail.com>
Mon, 7 Jan 2019 14:46:06 +0000 (15:46 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Mon, 21 Jan 2019 10:13:15 +0000 (11:13 +0100)
Changed datastructures to C++.
Replaced raw pointers with std::vector and std::string.
Removed unused function in residuetypes.h.

Change-Id: Idb4a5a879545a5de26b13bb8b484cd3debd6fba2

src/gromacs/fileio/pdbio.cpp
src/gromacs/gmxana/gmx_chi.cpp
src/gromacs/gmxpreprocess/gen_vsite.cpp
src/gromacs/gmxpreprocess/pdb2gmx.cpp
src/gromacs/topology/atomprop.cpp
src/gromacs/topology/index.cpp
src/gromacs/topology/residuetypes.cpp
src/gromacs/topology/residuetypes.h

index 018d9a926a9cc46c2e148ee97abad72d718a3d81..b6882696e6c618c97c0b7a0336b86799fd8137e1 100644 (file)
@@ -308,17 +308,12 @@ void write_pdbfile_indexed(FILE *out, const char *title,
                            gmx_conect conect, gmx_bool bTerSepChains,
                            bool usePqrFormat)
 {
-    gmx_conect_t     *gc = static_cast<gmx_conect_t *>(conect);
-    int               i, ii;
-    int               resind, resnr;
-    enum PDB_record   type;
-    unsigned char     resic, ch;
-    char              altloc;
-    real              occup, bfac;
-    gmx_bool          bOccup;
-    int               chainnum, lastchainnum;
-    const char       *p_restype;
-    const char       *p_lastrestype;
+    gmx_conect_t   *gc = static_cast<gmx_conect_t *>(conect);
+    enum PDB_record type;
+    char            altloc;
+    real            occup, bfac;
+    gmx_bool        bOccup;
+
 
     fprintf(out, "TITLE     %s\n", (title && title[0]) ? title : gmx::bromacs().c_str());
     if (box && ( (norm2(box[XX]) != 0.0f) || (norm2(box[YY]) != 0.0f) || (norm2(box[ZZ]) != 0.0f) ) )
@@ -331,9 +326,9 @@ void write_pdbfile_indexed(FILE *out, const char *title,
          * otherwise set them all to one
          */
         bOccup = TRUE;
-        for (ii = 0; (ii < nindex) && bOccup; ii++)
+        for (int ii = 0; (ii < nindex) && bOccup; ii++)
         {
-            i      = index[ii];
+            int i      = index[ii];
             bOccup = bOccup && (atoms->pdbinfo[i].occup == 0.0);
         }
     }
@@ -344,23 +339,26 @@ void write_pdbfile_indexed(FILE *out, const char *title,
 
     fprintf(out, "MODEL %8d\n", model_nr > 0 ? model_nr : 1);
 
-    lastchainnum      = -1;
-    p_restype         = nullptr;
+    int         lastchainnum      = -1;
+    std::string prevRestype;
+    std::string lastRestype;
 
     ResidueType rt;
-    for (ii = 0; ii < nindex; ii++)
+    for (int ii = 0; ii < nindex; ii++)
     {
-        i             = index[ii];
-        resind        = atoms->atom[i].resind;
-        chainnum      = atoms->resinfo[resind].chainnum;
-        p_lastrestype = p_restype;
-        rt.nameIndexedInResidueTypes(*atoms->resinfo[resind].name, &p_restype);
+        int i             = index[ii];
+        int resind        = atoms->atom[i].resind;
+        int chainnum      = atoms->resinfo[resind].chainnum;
+        lastRestype = prevRestype;
+        prevRestype = rt.typeNameForIndexedResidue(*atoms->resinfo[resind].name);
 
         /* Add a TER record if we changed chain, and if either the previous or this chain is protein/DNA/RNA. */
         if (bTerSepChains && ii > 0 && chainnum != lastchainnum)
         {
             /* Only add TER if the previous chain contained protein/DNA/RNA. */
-            if (rt.namedResidueHasType(p_lastrestype, "Protein") || rt.namedResidueHasType(p_lastrestype, "DNA") || rt.namedResidueHasType(p_lastrestype, "RNA"))
+            if (rt.namedResidueHasType(lastRestype, "Protein") ||
+                rt.namedResidueHasType(lastRestype, "DNA") ||
+                rt.namedResidueHasType(lastRestype, "RNA"))
             {
                 fprintf(out, "TER\n");
             }
@@ -372,8 +370,9 @@ void write_pdbfile_indexed(FILE *out, const char *title,
 
         /* rename HG12 to 2HG1, etc. */
         nm    = xlate_atomname_gmx2pdb(nm);
-        resnr = atoms->resinfo[resind].nr;
-        resic = atoms->resinfo[resind].ic;
+        int           resnr = atoms->resinfo[resind].nr;
+        unsigned char resic = atoms->resinfo[resind].ic;
+        unsigned char ch;
         if (chainid != ' ')
         {
             ch = chainid;
@@ -455,7 +454,7 @@ void write_pdbfile_indexed(FILE *out, const char *title,
     if (nullptr != gc)
     {
         /* Write conect records */
-        for (i = 0; (i < gc->nconect); i++)
+        for (int i = 0; (i < gc->nconect); i++)
         {
             fprintf(out, "CONECT%5d%5d\n", gc->conect[i].ai+1, gc->conect[i].aj+1);
         }
index 7524dfc27011a3dceb24293eef381f8a5cd5d184..4931615de89e916d1218abdf4dcb7dbda95d8549 100644 (file)
@@ -742,7 +742,7 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt,
                     normalize_histo(nbin, his_aa[Dih][i], (360.0/nbin), normhisto);
                 }
 
-                residue_name = rt->nameFromResidueIndex(i);
+                residue_name = rt->nameFromResidueIndex(i).c_str();
                 switch (Dih)
                 {
                     case edPhi:
index 5b308bc55df01361eaeea74f06bc59dd9ba146fd..b55d8a37f478836cabcc01020c33f4504de1406b 100644 (file)
@@ -1669,7 +1669,7 @@ void do_vsites(int nrtp, t_restp rtp[], gpp_atomtype *atype,
          * N-terminus that must be treated first.
          */
         if (bVsiteAromatics &&
-            !strcmp(*(at->atomname[i]), "CA") &&
+            (strcmp(*(at->atomname[i]), "CA") == 0) &&
             !bResProcessed[resind] &&
             rt.namedResidueHasType(*(at->resinfo[resind].name), "Protein") )
         {
index 2932c831f62f0f01a98ecdec0ceaf0e0e75905f9..d5826a0570e47543d54d4ebd0d4862cf55dc392c 100644 (file)
@@ -586,7 +586,8 @@ static int read_pdball(const char *inf, bool bOutput, const char *outf, char **t
     rename_pdbres(atoms, "WAT", watres, false, symtab);
 
     rename_atoms("xlateat.dat", nullptr,
-                 atoms, symtab, nullptr, true, rt, true, bVerbose);
+                 atoms, symtab, nullptr, true,
+                 rt, true, bVerbose);
 
     if (natom == 0)
     {
@@ -887,14 +888,13 @@ checkResidueTypeSanity(t_atoms     *pdba,
     if (chainID0 != ' ')
     {
         bool        allResiduesHaveSameType = true;
-        const char *restype0;
-        const char *restype;
-        rt->nameIndexedInResidueTypes(*pdba->resinfo[r0].name, &restype0);
+        std::string restype;
+        std::string restype0 = rt->typeNameForIndexedResidue(*pdba->resinfo[r0].name);
 
         for (int i = r0 + 1; i < r1; i++)
         {
-            rt->nameIndexedInResidueTypes(*pdba->resinfo[i].name, &restype);
-            if (gmx_strcasecmp(restype, restype0))
+            restype = rt->typeNameForIndexedResidue(*pdba->resinfo[i].name);
+            if (gmx_strcasecmp(restype.c_str(), restype0.c_str()))
             {
                 allResiduesHaveSameType = false;
                 residueString           = gmx::formatString("%s%d", *pdba->resinfo[i].name, pdba->resinfo[i].nr);
@@ -913,7 +913,7 @@ checkResidueTypeSanity(t_atoms     *pdba,
                       "such as ligands, they should not have the same chain ID as the "
                       "adjacent protein chain since it's a separate molecule.",
                       startResidueString.c_str(), endResidueString.c_str(),
-                      restype0, residueString.c_str(), restype);
+                      restype0.c_str(), residueString.c_str(), restype.c_str());
         }
     }
 }
@@ -922,8 +922,7 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end,
                         ResidueType *rt)
 {
     int         i;
-    const char *p_startrestype;
-    const char *p_restype;
+    std::string p_startrestype;
 
     *r_start = -1;
     *r_end   = -1;
@@ -949,13 +948,13 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end,
     /* Find the starting terminus (typially N or 5') */
     for (i = r0; i < r1 && *r_start == -1; i++)
     {
-        rt->nameIndexedInResidueTypes(*pdba->resinfo[i].name, &p_startrestype);
-        if (!gmx_strcasecmp(p_startrestype, "Protein") || !gmx_strcasecmp(p_startrestype, "DNA") || !gmx_strcasecmp(p_startrestype, "RNA") )
+        p_startrestype = rt->typeNameForIndexedResidue(*pdba->resinfo[i].name);
+        if (!gmx_strcasecmp(p_startrestype.c_str(), "Protein") || !gmx_strcasecmp(p_startrestype.c_str(), "DNA") || !gmx_strcasecmp(p_startrestype.c_str(), "RNA") )
         {
             printf("Identified residue %s%d as a starting terminus.\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr);
             *r_start = i;
         }
-        else if (!gmx_strcasecmp(p_startrestype, "Ion"))
+        else if (!gmx_strcasecmp(p_startrestype.c_str(), "Ion"))
         {
             if (ionNotes < 5)
             {
@@ -1001,14 +1000,14 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end,
     if (*r_start >= 0)
     {
         /* Go through the rest of the residues, check that they are the same class, and identify the ending terminus. */
-        for (i = *r_start; i < r1; i++)
+        for (int i = *r_start; i < r1; i++)
         {
-            rt->nameIndexedInResidueTypes(*pdba->resinfo[i].name, &p_restype);
-            if (!gmx_strcasecmp(p_restype, p_startrestype) && endWarnings == 0)
+            std::string p_restype = rt->typeNameForIndexedResidue(*pdba->resinfo[i].name);
+            if (!gmx_strcasecmp(p_restype.c_str(), p_startrestype.c_str()) && endWarnings == 0)
             {
                 *r_end = i;
             }
-            else if (!gmx_strcasecmp(p_startrestype, "Ion"))
+            else if (!gmx_strcasecmp(p_startrestype.c_str(), "Ion"))
             {
                 if (ionNotes < 5)
                 {
@@ -1033,8 +1032,8 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end,
                            "introduce a break, but that will be catastrophic if they should in fact be\n"
                            "linked. Please check your structure, and add %s to residuetypes.dat\n"
                            "if this was not correct.\n\n",
-                           *pdba->resinfo[i].name, pdba->resinfo[i].nr, p_restype,
-                           *pdba->resinfo[*r_start].name, pdba->resinfo[*r_start].nr, p_startrestype, *pdba->resinfo[i].name);
+                           *pdba->resinfo[i].name, pdba->resinfo[i].nr, p_restype.c_str(),
+                           *pdba->resinfo[*r_start].name, pdba->resinfo[*r_start].nr, p_startrestype.c_str(), *pdba->resinfo[i].name);
                 }
                 if (endWarnings == 4)
                 {
@@ -1683,16 +1682,20 @@ int pdb2gmx::run()
 
     /* Add all alternative names from the residue renaming database to the list
        of recognized amino/nucleic acids. */
-    const char *p_restype;
     for (int i = 0; i < nrtprename; i++)
     {
         /* Only add names if the 'standard' gromacs/iupac base name was found */
-        if (rt.nameIndexedInResidueTypes(rtprename[i].gmx, &p_restype))
+
+        /* TODO this should be changed with gmx::optional so that we only need
+         * to search rt once.
+         */
+        if (rt.nameIndexedInResidueTypes(rtprename[i].gmx))
         {
-            rt.addResidue(rtprename[i].main, p_restype);
-            rt.addResidue(rtprename[i].nter, p_restype);
-            rt.addResidue(rtprename[i].cter, p_restype);
-            rt.addResidue(rtprename[i].bter, p_restype);
+            std::string restype = rt.typeNameForIndexedResidue(rtprename[i].gmx);
+            rt.addResidue(rtprename[i].main, restype);
+            rt.addResidue(rtprename[i].nter, restype);
+            rt.addResidue(rtprename[i].cter, restype);
+            rt.addResidue(rtprename[i].bter, restype);
         }
     }
 
@@ -2191,9 +2194,9 @@ int pdb2gmx::run()
 
         /* make up molecule name(s) */
 
-        int k = (cc->nterpairs > 0 && cc->r_start[0] >= 0) ? cc->r_start[0] : 0;
+        int         k = (cc->nterpairs > 0 && cc->r_start[0] >= 0) ? cc->r_start[0] : 0;
 
-        rt.nameIndexedInResidueTypes(*pdba->resinfo[k].name, &p_restype);
+        std::string restype = rt.typeNameForIndexedResidue(*pdba->resinfo[k].name);
 
         std::string molname;
         std::string suffix;
@@ -2228,12 +2231,12 @@ int pdb2gmx::run()
 
             if (suffix.length() > 0)
             {
-                molname.append(p_restype);
+                molname.append(restype);
                 molname.append(suffix);
             }
             else
             {
-                molname = p_restype;
+                molname = restype;
             }
         }
         std::string itp_fn   = topologyFile_;;
index 3551002478bc5718606ac581739573654a721f42..47dd6acea5719ad519cad56b199c4e00c3c1d7d3 100644 (file)
@@ -155,7 +155,7 @@ static int findPropertyIndex(AtomProperty *ap, ResidueType *restype,
 {
     int      j = NOTFOUND;
 
-    bool     bProtein  = restype->namedResidueHasType(residueName.c_str(), "Protein");
+    bool     bProtein  = restype->namedResidueHasType(residueName, "Protein");
     bool     bProtWild = residueName == "AAA";
     int      malen     = NOTFOUND;
     int      mrlen     = NOTFOUND;
index 6d12641b26fc47621307cfeae2edfd50c188f46e..f7359cf1f817c06b8786c5868fddbf8becef66c5 100644 (file)
@@ -587,16 +587,13 @@ void analyse(const t_atoms *atoms, t_blocka *gb, char ***gn, gmx_bool bASK, gmx_
         int i = 0;
 
         resnm = *atoms->resinfo[i].name;
-        const char *type = nullptr;
-        rt.nameIndexedInResidueTypes(resnm, &type);
-        restype.emplace_back(type);
+        restype.emplace_back(rt.typeNameForIndexedResidue(resnm));
         previousTypename.push_back(restype[i]);
 
         for (i = 1; i < atoms->nres; i++)
         {
             resnm = *atoms->resinfo[i].name;
-            rt.nameIndexedInResidueTypes(resnm, &type);
-            restype.emplace_back(type);
+            restype.emplace_back(rt.typeNameForIndexedResidue(resnm));
 
             /* Note that this does not lead to a N*N loop, but N*K, where
              * K is the number of residue _types_, which is small and independent of N.
index ddd8087b492dc16f7267137b7f9fa683b0447380..e8123c46e8732dd978e3f8beaf2dadc437960c83 100644 (file)
@@ -41,7 +41,9 @@
 
 #include <algorithm>
 #include <iterator>
+#include <string>
 
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/strdb.h"
 
 //! Definition for residue type that is not known.
-const char undefinedResidueType[] = "Other";
+const std::string c_undefinedResidueType = "Other";
 
 //! Single ResidueType entry object
 struct ResidueTypeEntry
 {
-    //! Name of residue.
-    char *residueName;
-    //! Type name for residue entry.
-    char *residueType;
+    //! Default constructor creates complete object.
+    ResidueTypeEntry(const std::string &rName, const std::string &rType)
+        : residueName(rName), residueType(rType)
+    {}
+    //! Name of the residue in the entry.
+    std::string residueName;
+    //! Type of the residue in the entry.
+    std::string residueType;
 };
 
 //! Implementation detail for ResidueTypes
 class ResidueType::Impl
 {
     public:
-        //! Number of entries
-        int               n     = 0;
         //! Storage object for entries.
-        ResidueTypeEntry *entry = nullptr;
+        std::vector<ResidueTypeEntry> entry;
 };
 
 ResidueType::ResidueType()
@@ -95,87 +99,89 @@ ResidueType::ResidueType()
 
 ResidueType::~ResidueType()
 {
-    for (int i = 0; i < impl_->n; i++)
-    {
-        sfree(impl_->entry[i].residueName);
-        sfree(impl_->entry[i].residueType);
-    }
-    sfree(impl_->entry);
 }
 
-bool ResidueType::nameIndexedInResidueTypes(const char *residueName, const char **residueTypePointer)
+/*! \brief
+ * Find a residue entry by the residue name.
+ *
+ * \param[in] entries Currently registered residue entries in the database.
+ * \param[in] residueName Name of a residue to compare to database.
+ * \returns A pointer to the entry that was found, or nullptr.
+ */
+static gmx::ArrayRef<const ResidueTypeEntry>::iterator
+residueEntryByResidueName(gmx::ArrayRef<const ResidueTypeEntry> entries, const std::string &residueName)
 {
-    int    i, rc;
-
-    rc = -1;
-    for (i = 0; i < impl_->n && rc; i++)
-    {
-        rc = gmx_strcasecmp(impl_->entry[i].residueName, residueName);
-    }
-
-    *residueTypePointer = (rc == 0) ? impl_->entry[i-1].residueType : undefinedResidueType;
-
-    return (rc == 0);
+    return std::find_if(entries.begin(), entries.end(),
+                        [&residueName](const ResidueTypeEntry &old)
+                        { return gmx_strcasecmp(old.residueName.c_str(), residueName.c_str()) == 0; });
 }
 
-void ResidueType::addResidue(const char *residueName, const char *residueType)
+bool ResidueType::nameIndexedInResidueTypes(const std::string &residueName)
 {
-    const char *  p_oldtype;
+    return residueEntryByResidueName(impl_->entry, residueName) != nullptr;
+}
 
-    bool          found = nameIndexedInResidueTypes(residueName, &p_oldtype);
+void ResidueType::addResidue(const std::string &residueName, const std::string &residueType)
+{
+    gmx::ArrayRef<const ResidueTypeEntry> temp(impl_->entry);
+    auto found = residueEntryByResidueName(temp, residueName);
 
-    if (found && gmx_strcasecmp(p_oldtype, residueType))
+    if (found != temp.end())
     {
-        fprintf(stderr, "Warning: Residue '%s' already present with type '%s' in database, ignoring new type '%s'.",
-                residueName, p_oldtype, residueType);
+        if (gmx_strcasecmp(found->residueType.c_str(), residueType.c_str()))
+        {
+            fprintf(stderr, "Warning: Residue '%s' already present with type '%s' in database, ignoring new type '%s'.\n",
+                    residueName.c_str(), found->residueType.c_str(), residueType.c_str());
+        }
     }
-
-    if (!found)
+    else
     {
-        srenew(impl_->entry, impl_->n+1);
-        impl_->entry[impl_->n].residueName = gmx_strdup(residueName);
-        impl_->entry[impl_->n].residueType = gmx_strdup(residueType);
-        impl_->n++;
+        impl_->entry.emplace_back(residueName, residueType);
     }
 }
 
-bool ResidueType::namedResidueHasType(const char *residueName, const char *residueType)
+bool ResidueType::namedResidueHasType(const std::string &residueName, const std::string &residueType)
 {
-    bool        rc;
-    const char *p_type;
-
-    rc = nameIndexedInResidueTypes(residueName, &p_type) &&
-        gmx_strcasecmp(p_type, residueType) == 0;
-
-    return rc;
+    gmx::ArrayRef<const ResidueTypeEntry> temp(impl_->entry);
+    auto found = residueEntryByResidueName(temp, residueName);
+    return  ((found != temp.end()) &&
+             (gmx_strcasecmp(residueType.c_str(), found->residueType.c_str()) == 0));
 }
 
 int ResidueType::numberOfEntries() const
 {
-    return impl_->n;
+    return impl_->entry.size();
 }
 
-int ResidueType::indexFromResidueName(const char *residueName) const
+int ResidueType::indexFromResidueName(const std::string &residueName) const
 {
-    int i, rc;
+    gmx::ArrayRef<const ResidueTypeEntry> temp(impl_->entry);
+    auto found = residueEntryByResidueName(temp, residueName);
+    return (found != temp.end()) ? std::distance(temp.begin(), found) : -1;
+}
 
-    rc = -1;
-    for (i = 0; i < impl_->n && rc; i++)
+const std::string ResidueType::nameFromResidueIndex(int index) const
+{
+    if (index >= 0 && index < static_cast<int>(impl_->entry.size()))
     {
-        rc = gmx_strcasecmp(impl_->entry[i].residueName, residueName);
+        return impl_->entry[index].residueName;
+    }
+    else
+    {
+        return "";
     }
-
-    return (0 == rc) ? i-1 : -1;
 }
 
-const char *ResidueType::nameFromResidueIndex(int index) const
+const std::string ResidueType::typeNameForIndexedResidue(const std::string &residueName)
 {
-    if (index >= 0 && index < impl_->n)
+    gmx::ArrayRef<const ResidueTypeEntry> temp(impl_->entry);
+    auto found = residueEntryByResidueName(temp, residueName);
+    if (found != temp.end())
     {
-        return impl_->entry[index].residueName;
+        return found->residueType;
     }
     else
     {
-        return nullptr;
+        return c_undefinedResidueType;
     }
 }
index 3cd9ed59c69e5316591c07ef9b3d76585a2ff890..8b439b5011a8da52464876d76f857fdd2a7f8719 100644 (file)
@@ -35,6 +35,8 @@
 #ifndef GMX_TOPOLOGY_RESIDUETYPES_H
 #define GMX_TOPOLOGY_RESIDUETYPES_H
 
+#include <string>
+
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/classhelpers.h"
 
@@ -55,20 +57,18 @@ class ResidueType
         int numberOfEntries() const;
         /*! \brief
          * Return true if residue \p residueName is found or false otherwise.
-         * \p residueTypePointer is set to the type name, or "Other" if not found.
          *
          * \param[in] residueName Residue name to search database for.
-         * \param[out] residueTypePointer Name of found type or "Other".
          * \returns true if successful.
          */
-        bool nameIndexedInResidueTypes(const char *residueName, const char **residueTypePointer);
+        bool nameIndexedInResidueTypes(const std::string &residueName);
         /*! \brief
          * Add entry to ResidueTypes if unique.
          *
          * \param[in] residueName Name of new residue.
          * \param[in] residueType Type of new residue.
          */
-        void addResidue(const char *residueName, const char *residueType);
+        void addResidue(const std::string &residueName, const std::string &residueType);
         /*! \brief
          * Checks if the indicated \p residueName if of \p residueType.
          *
@@ -76,21 +76,29 @@ class ResidueType
          * \param[in] residueType Which ResidueType the residue should have.
          * \returns If the check was successful.
          */
-        bool namedResidueHasType(const char *residueName, const char *residueType);
+        bool namedResidueHasType(const std::string &residueName, const std::string &residueType);
         /*! \brief
-         * Get entry index in ResidueTypes with name \p residueName.
+         * Get index to entry in ResidueTypes with name \p residueName.
          *
          * \param[in] residueName Name of the residue being searched.
-         * \returns Value of the entry or -1.
+         * \returns The index or -1 if not found.
          */
-        int indexFromResidueName(const char *residueName) const;
+        int indexFromResidueName(const std::string &residueName) const;
         /*! \brief
          * Get the name of the entry in ResidueTypes with \p index.
          *
          * \param[in] index Which entry should be returned.
          * \returns The name of the entry at \p index, or nullptr.
          */
-        const char *nameFromResidueIndex(int index) const;
+        const std::string nameFromResidueIndex(int index) const;
+        /*! \brief
+         * Get name of residue type for already defined residue.
+         *
+         *
+         * \param[in] residueName Name of the residue to search for.
+         * \returns Type name or UndefineResidueName if not found.
+         */
+        const std::string typeNameForIndexedResidue(const std::string &residueName);
 
     private:
         //! Implementation pointer.
@@ -99,5 +107,4 @@ class ResidueType
         gmx::PrivateImplPointer<Impl> impl_;
 };
 
-
 #endif