Changed datastructures to C++.
Replaced raw pointers with std::vector and std::string.
Removed unused function in residuetypes.h.
Change-Id: Idb4a5a879545a5de26b13bb8b484cd3debd6fba2
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) ) )
* 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);
}
}
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");
}
/* 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;
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);
}
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:
* 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") )
{
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)
{
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);
"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());
}
}
}
ResidueType *rt)
{
int i;
- const char *p_startrestype;
- const char *p_restype;
+ std::string p_startrestype;
*r_start = -1;
*r_end = -1;
/* 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)
{
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)
{
"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)
{
/* 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);
}
}
/* 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;
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_;;
{
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;
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.
#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()
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;
}
}
#ifndef GMX_TOPOLOGY_RESIDUETYPES_H
#define GMX_TOPOLOGY_RESIDUETYPES_H
+#include <string>
+
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/classhelpers.h"
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.
*
* \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.
gmx::PrivateImplPointer<Impl> impl_;
};
-
#endif