#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/atomprop.h"
#include "gromacs/topology/ifunc.h"
-#include "gromacs/topology/residuetypes.h"
#include "gromacs/topology/symtab.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/coolstuff.h"
fprintf(out, "MODEL %8d\n", model_nr > 0 ? model_nr : 1);
- ResidueTypeMap rt;
for (int ii = 0; ii < nindex; ii++)
{
int i = index[ii];
#include <vector>
#include "gromacs/gmxana/gstat.h"
-#include "gromacs/topology/residuetypes.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/fatalerror.h"
-std::vector<t_dlist> mk_dlist(FILE* log,
- const t_atoms* atoms,
- gmx_bool bPhi,
- gmx_bool bPsi,
- gmx_bool bChi,
- gmx_bool bHChi,
- int maxchi,
- int r0,
- ResidueTypeMap* rt)
+std::vector<t_dlist> mk_dlist(FILE* log,
+ const t_atoms* atoms,
+ gmx_bool bPhi,
+ gmx_bool bPsi,
+ gmx_bool bChi,
+ gmx_bool bHChi,
+ int maxchi,
+ int r0,
+ const ResidueTypeMap& residueTypeMap)
{
int i, j, ii;
t_dihatms atm, prev;
/* Prevent use of unknown residues. If one adds a custom residue to
* residuetypes.dat but somehow loses it, changes it, or does analysis on
* another machine, the residue type will be unknown. */
- if (!rt->nameIndexedInResidueTypeMap(thisres))
+ if (residueTypeMap.find(thisres) == residueTypeMap.end())
{
gmx_fatal(FARGS,
"Unknown residue %s when searching for residue type.\n"
// Build a list of unique residue names found in the dihedral
// list, so we can loop over those unique names conveniently. The
- // names are the same as the residue names found in rt in the
+ // names are the same as the residue names found in residueTypeMap in the
// caller, but ResidueTypeMap doesn't yet have a way to loop over its
// contents.
std::unordered_set<std::string> uniqueResidueNames;
}
fprintf(log, "Title: %s\n", name);
- ResidueTypeMap rt;
- std::vector<t_dlist> dlist = mk_dlist(log, &atoms, bPhi, bPsi, bChi, bHChi, maxchi, r0, &rt);
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
+ std::vector<t_dlist> dlist =
+ mk_dlist(log, &atoms, bPhi, bPsi, bChi, bHChi, maxchi, r0, residueTypeMap);
fprintf(stderr, "%zu residues with dihedrals found\n", dlist.size());
if (dlist.empty())
#include "gromacs/commandline/pargs.h"
#include "gromacs/topology/index.h"
+#include "gromacs/topology/residuetypes.h"
struct gmx_output_env_t;
-class ResidueTypeMap;
/* must correspond with 'leg' g_chi.c:727 */
enum
gmx_bool has_dihedral(int Dih, const t_dlist& dlist);
-std::vector<t_dlist> mk_dlist(FILE* log,
- const t_atoms* atoms,
- gmx_bool bPhi,
- gmx_bool bPsi,
- gmx_bool bChi,
- gmx_bool bHChi,
- int maxchi,
- int r0,
- ResidueTypeMap* rt);
+/*! \brief Describe the dihedrals in the residues of the \c atoms
+ * structure
+ *
+ * Return a vector with a t_dlist entry for each residue in \c
+ * atoms. The entry for a residue contains its name, its index within
+ * the residues, and a mapping from chemical peptide atom names to
+ * atom indices based on the atom names. Many fields of t_dlist are
+ * not yet filled. */
+std::vector<t_dlist> mk_dlist(FILE* log,
+ const t_atoms* atoms,
+ gmx_bool bPhi,
+ gmx_bool bPsi,
+ gmx_bool bChi,
+ gmx_bool bHChi,
+ int maxchi,
+ int r0,
+ const ResidueTypeMap& rt);
void pr_dlist(FILE* fp,
gmx::ArrayRef<const t_dlist> dlist,
fprintf(fp, "\n");
}
-static int get_atype(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueTypeMap* rt)
+static int get_atype(int atom,
+ t_atoms* at,
+ gmx::ArrayRef<const PreprocessResidue> rtpFFDB,
+ const ResidueTypeMap& residueTypeMap)
{
int type;
bool bNterm;
{
/* get type from rtpFFDB */
auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB);
- bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein")
+ bNterm = namedResidueHasType(
+ residueTypeMap, *(at->resinfo[at->atom[atom].resind].name), "Protein")
&& (at->atom[atom].resind == 0);
int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm);
type = localPpResidue->atom[j].type;
return *tp;
}
-static real get_amass(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueTypeMap* rt)
+static real get_amass(int atom,
+ t_atoms* at,
+ gmx::ArrayRef<const PreprocessResidue> rtpFFDB,
+ const ResidueTypeMap& residueTypeMap)
{
real mass;
bool bNterm;
{
/* get mass from rtpFFDB */
auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB);
- bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein")
+ bNterm = namedResidueHasType(
+ residueTypeMap, *(at->resinfo[at->atom[atom].resind].name), "Protein")
&& (at->atom[atom].resind == 0);
int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm);
mass = localPpResidue->atom[j].m;
/* make index to tell which residues were already processed */
std::vector<bool> bResProcessed(at->nres);
- ResidueTypeMap rt;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
/* generate vsite constructions */
/* loop over all atoms */
* N-terminus that must be treated first.
*/
if (bVsiteAromatics && (strcmp(*(at->atomname[i]), "CA") == 0) && !bResProcessed[resind]
- && rt.namedResidueHasType(*(at->resinfo[resind].name), "Protein"))
+ && namedResidueHasType(residueTypeMap, *(at->resinfo[resind].name), "Protein"))
{
/* mark this residue */
bResProcessed[resind] = TRUE;
and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */
count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies);
/* get Heavy atom type */
- tpHeavy = get_atype(Heavy, at, rtpFFDB, &rt);
+ tpHeavy = get_atype(Heavy, at, rtpFFDB, residueTypeMap);
strcpy(tpname, *atype->atomNameFromAtomType(tpHeavy));
bWARNING = FALSE;
/* get dummy mass type from first char of heavy atom type (N or C) */
strcpy(nexttpname,
- *atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, &rt)));
+ *atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, residueTypeMap)));
std::string ch = get_dummymass_name(vsiteconflist, tpname, nexttpname);
std::string name;
if (ch.empty())
/* get atom masses, and set Heavy and Hatoms mass to zero */
for (int j = 0; j < nrHatoms; j++)
{
- mHtot += get_amass(Hatoms[j], at, rtpFFDB, &rt);
+ mHtot += get_amass(Hatoms[j], at, rtpFFDB, residueTypeMap);
at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
}
- mtot = mHtot + get_amass(Heavy, at, rtpFFDB, &rt);
+ mtot = mHtot + get_amass(Heavy, at, rtpFFDB, residueTypeMap);
at->atom[Heavy].m = at->atom[Heavy].mB = 0;
if (mHmult != 1.0)
{
gmx_fio_fclose(fp);
}
-int read_pdball(const char* inf,
- bool bOutput,
- const char* outf,
- char** title,
- t_atoms* atoms,
- rvec** x,
- PbcType* pbcType,
- matrix box,
- bool bRemoveH,
- t_symtab* symtab,
- ResidueTypeMap* rt,
- const char* watres,
- AtomProperties* aps,
- bool bVerbose)
+int read_pdball(const char* inf,
+ bool bOutput,
+ const char* outf,
+ char** title,
+ t_atoms* atoms,
+ rvec** x,
+ PbcType* pbcType,
+ matrix box,
+ bool bRemoveH,
+ t_symtab* symtab,
+ const ResidueTypeMap& residueTypeMap,
+ const char* watres,
+ AtomProperties* aps,
+ bool bVerbose)
/* Read a pdb file. (containing proteins) */
{
int natom, new_natom, i;
rename_pdbres(atoms, "SOL", watres, false, symtab);
rename_pdbres(atoms, "WAT", watres, false, symtab);
- rename_atoms("xlateat.dat", nullptr, atoms, symtab, {}, true, rt, true, bVerbose);
+ rename_atoms("xlateat.dat", nullptr, atoms, symtab, {}, true, residueTypeMap, true, bVerbose);
if (natom == 0)
{
return pdba->nr;
}
-void checkResidueTypeSanity(t_atoms* pdba, int r0, int r1, ResidueTypeMap* rt)
+void checkResidueTypeSanity(t_atoms* pdba, int r0, int r1, const ResidueTypeMap& residueTypeMap)
{
std::string startResidueString =
gmx::formatString("%s%d", *pdba->resinfo[r0].name, pdba->resinfo[r0].nr);
{
bool allResiduesHaveSameType = true;
std::string restype;
- std::string restype0 = rt->typeOfNamedDatabaseResidue(*pdba->resinfo[r0].name);
+ std::string restype0 = typeOfNamedDatabaseResidue(residueTypeMap, *pdba->resinfo[r0].name);
for (int i = r0 + 1; i < r1; i++)
{
- restype = rt->typeOfNamedDatabaseResidue(*pdba->resinfo[i].name);
+ restype = typeOfNamedDatabaseResidue(residueTypeMap, *pdba->resinfo[i].name);
if (!gmx::equalCaseInsensitive(restype, restype0))
{
allResiduesHaveSameType = false;
}
}
-void find_nc_ter(t_atoms* pdba, int r0, int r1, int* r_start, int* r_end, ResidueTypeMap* rt, const gmx::MDLogger& logger)
+void find_nc_ter(t_atoms* pdba,
+ int r0,
+ int r1,
+ int* r_start,
+ int* r_end,
+ const ResidueTypeMap& residueTypeMap,
+ const gmx::MDLogger& logger)
{
- int i;
- std::optional<std::string> startrestype;
+ std::optional<std::string> residueTypeOfStartingTerminus;
*r_start = -1;
*r_end = -1;
// Check that all residues have the same chain identifier, and if it is
// non-blank we also require the residue types to match.
- checkResidueTypeSanity(pdba, r0, r1, rt);
+ checkResidueTypeSanity(pdba, r0, r1, residueTypeMap);
// If we return correctly from checkResidueTypeSanity(), the only
// remaining cases where we can have non-matching residue types is if
char chainID = pdba->resinfo[r0].chainid;
/* Find the starting terminus (typially N or 5') */
- for (i = r0; i < r1 && *r_start == -1; i++)
+ for (int i = r0; i < r1 && *r_start == -1; i++)
{
- startrestype = rt->optionalTypeOfNamedDatabaseResidue(*pdba->resinfo[i].name);
- if (!startrestype)
+ auto foundIt = residueTypeMap.find(*pdba->resinfo[i].name);
+ if (foundIt == residueTypeMap.end())
{
continue;
}
- if (gmx::equalCaseInsensitive(*startrestype, "Protein")
- || gmx::equalCaseInsensitive(*startrestype, "DNA")
- || gmx::equalCaseInsensitive(*startrestype, "RNA"))
+ residueTypeOfStartingTerminus = foundIt->second;
+ if (gmx::equalCaseInsensitive(residueTypeOfStartingTerminus.value(), "Protein")
+ || gmx::equalCaseInsensitive(residueTypeOfStartingTerminus.value(), "DNA")
+ || gmx::equalCaseInsensitive(residueTypeOfStartingTerminus.value(), "RNA"))
{
GMX_LOG(logger.info)
.asParagraph()
pdba->resinfo[i].nr);
*r_start = i;
}
- else if (gmx::equalCaseInsensitive(*startrestype, "Ion"))
+ else if (gmx::equalCaseInsensitive(residueTypeOfStartingTerminus.value(), "Ion"))
{
if (ionNotes < 5)
{
/* Go through the rest of the residues, check that they are the same class, and identify the ending terminus. */
for (int i = *r_start; i < r1; i++)
{
- std::optional<std::string> restype =
- rt->optionalTypeOfNamedDatabaseResidue(*pdba->resinfo[i].name);
- if (!restype)
+ auto foundIt = residueTypeMap.find(*pdba->resinfo[i].name);
+ if (foundIt == residueTypeMap.end())
{
continue;
}
- if (gmx::equalCaseInsensitive(*restype, *startrestype) && endWarnings == 0)
+ const std::string& residueTypeOfCurrentResidue = foundIt->second;
+ if (gmx::equalCaseInsensitive(residueTypeOfCurrentResidue, residueTypeOfStartingTerminus.value())
+ && endWarnings == 0)
{
*r_end = i;
}
- else if (gmx::equalCaseInsensitive(*startrestype, "Ion"))
+ else if (gmx::equalCaseInsensitive(residueTypeOfStartingTerminus.value(), "Ion"))
{
if (ionNotes < 5)
{
"if this was not correct.",
*pdba->resinfo[i].name,
pdba->resinfo[i].nr,
- restype->c_str(),
+ residueTypeOfCurrentResidue.c_str(),
*pdba->resinfo[*r_start].name,
pdba->resinfo[*r_start].nr,
- startrestype->c_str(),
+ residueTypeOfStartingTerminus.value().c_str(),
*pdba->resinfo[i].name);
}
if (endWarnings == 4)
open_symtab(&symtab);
/* Residue type database */
- ResidueTypeMap rt;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
/* Read residue renaming database(s), if present */
std::vector<std::string> rrn = fflib_search_file_end(ffdir_, ".r2b", FALSE);
for (const auto& rename : rtprename)
{
/* Only add names if the 'standard' gromacs/iupac base name was found */
- if (auto restype = rt.optionalTypeOfNamedDatabaseResidue(rename.gmx))
+ if (auto foundIt = residueTypeMap.find(rename.gmx); foundIt != residueTypeMap.end())
{
- rt.addResidue(rename.main, *restype);
- rt.addResidue(rename.nter, *restype);
- rt.addResidue(rename.cter, *restype);
- rt.addResidue(rename.bter, *restype);
+ // Add the renamed forms with the same residue type as the standard form
+ auto& residueType = foundIt->second;
+ addResidue(&residueTypeMap, rename.main, residueType);
+ addResidue(&residueTypeMap, rename.nter, residueType);
+ addResidue(&residueTypeMap, rename.cter, residueType);
+ addResidue(&residueTypeMap, rename.bter, residueType);
}
}
box,
bRemoveH_,
&symtab,
- &rt,
+ residueTypeMap,
watres,
&aps,
bVerbose_);
j = 0;
for (int i = 0; i < cc->nterpairs; i++)
{
- find_nc_ter(
- pdba, cc->chainstart[i], cc->chainstart[i + 1], &(cc->r_start[j]), &(cc->r_end[j]), &rt, logger);
+ find_nc_ter(pdba,
+ cc->chainstart[i],
+ cc->chainstart[i + 1],
+ &(cc->r_start[j]),
+ &(cc->r_end[j]),
+ residueTypeMap,
+ logger);
if (cc->r_start[j] >= 0 && cc->r_end[j] >= 0)
{
if (checkChainCyclicity(
requires some re-thinking of code in gen_vsite.c, which I won't
do now :( AF 26-7-99 */
- rename_atoms(nullptr, ffdir_, pdba, &symtab, restp_chain, false, &rt, false, bVerbose_);
+ rename_atoms(nullptr, ffdir_, pdba, &symtab, restp_chain, false, residueTypeMap, false, bVerbose_);
match_atomnames_with_rtp(restp_chain, hb_chain, pdba, &symtab, x, bVerbose_, logger);
int k = (cc->nterpairs > 0 && cc->r_start[0] >= 0) ? cc->r_start[0] : 0;
- std::string restype = rt.typeOfNamedDatabaseResidue(*pdba->resinfo[k].name);
+ std::string restype = typeOfNamedDatabaseResidue(residueTypeMap, *pdba->resinfo[k].name);
std::string molname;
std::string suffix;
static int name2type(t_atoms* at,
int** cgnr,
gmx::ArrayRef<const PreprocessResidue> usedPpResidues,
- ResidueTypeMap* rt,
+ const ResidueTypeMap& residueTypeMap,
const gmx::MDLogger& logger)
{
int i, j, prevresind, i0, prevcg, cg, curcg;
if (at->atom[i].resind != resind)
{
resind = at->atom[i].resind;
- bool bProt = rt->namedResidueHasType(*(at->resinfo[resind].name), "Protein");
+ bool bProt = namedResidueHasType(residueTypeMap, *(at->resinfo[resind].name), "Protein");
bNterm = bProt && (resind == 0);
if (resind > 0)
{
int i, nmissat;
gmx::EnumerationArray<BondedTypes, int> bts;
- ResidueTypeMap rt;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
/* Make bonds */
at2bonds(&(plist[F_BONDS]), globalPatches, atoms, *x, long_bond_dist, short_bond_dist, cyclicBondsIndex, logger);
/* specbonds: disulphide bonds & heme-his */
do_ssbonds(&(plist[F_BONDS]), atoms, ssbonds, bAllowMissing);
- nmissat = name2type(atoms, &cgnr, usedPpResidues, &rt, logger);
+ nmissat = name2type(atoms, &cgnr, usedPpResidues, residueTypeMap, logger);
if (nmissat)
{
if (bAllowMissing)
t_symtab* symtab,
gmx::ArrayRef<const PreprocessResidue> localPpResidue,
bool bResname,
- ResidueTypeMap* rt,
+ const ResidueTypeMap& rt,
bool bReorderNum,
bool bVerbose)
{
/* Match the residue name */
bMatch = (xlatom[i].res == nullptr
|| (gmx_strcasecmp("protein-nterm", xlatom[i].res) == 0
- && rt->namedResidueHasType(rnm, "Protein") && bStartTerm)
+ && namedResidueHasType(rt, rnm, "Protein") && bStartTerm)
|| (gmx_strcasecmp("protein-cterm", xlatom[i].res) == 0
- && rt->namedResidueHasType(rnm, "Protein") && bEndTerm)
+ && namedResidueHasType(rt, rnm, "Protein") && bEndTerm)
|| (gmx_strcasecmp("protein", xlatom[i].res) == 0
- && rt->namedResidueHasType(rnm, "Protein"))
+ && namedResidueHasType(rt, rnm, "Protein"))
|| (gmx_strcasecmp("DNA", xlatom[i].res) == 0
- && rt->namedResidueHasType(rnm, "DNA"))
+ && namedResidueHasType(rt, rnm, "DNA"))
|| (gmx_strcasecmp("RNA", xlatom[i].res) == 0
- && rt->namedResidueHasType(rnm, "RNA")));
+ && namedResidueHasType(rt, rnm, "RNA")));
if (!bMatch)
{
const char* ptr0 = rnm;
#ifndef GMX_GMXPREPROCESS_XLATE_H
#define GMX_GMXPREPROCESS_XLATE_H
-class ResidueTypeMap;
+#include "gromacs/topology/residuetypes.h"
+
struct t_atoms;
struct PreprocessResidue;
struct t_symtab;
t_symtab* symtab,
gmx::ArrayRef<const PreprocessResidue> restp,
bool bResname,
- ResidueTypeMap* rt,
+ const ResidueTypeMap& rt,
bool bReorderNum,
bool bVerbose);
//! The different atom properties.
AtomProperty prop[epropNR];
//! The residue types.
- ResidueTypeMap residueTypeMap;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
};
/*! \brief
* \param[in] bExact Do we have the correct match.
* \returns The index for the property.
*/
-static int findPropertyIndex(AtomProperty* ap,
- ResidueTypeMap* residueTypeMap,
- const std::string& residueName,
- const std::string& atomName,
- gmx_bool* bExact)
+static int findPropertyIndex(AtomProperty* ap,
+ const ResidueTypeMap& residueTypeMap,
+ const std::string& residueName,
+ const std::string& atomName,
+ gmx_bool* bExact)
{
int j = NOTFOUND;
- bool bProtein = residueTypeMap->namedResidueHasType(residueName, "Protein");
+ bool bProtein = namedResidueHasType(residueTypeMap, residueName, "Protein");
bool bProtWild = residueName == "AAA";
int malen = NOTFOUND;
int mrlen = NOTFOUND;
* \param[in] propValue Value of property.
* \param[in] line Where to add property.
*/
-static void addProperty(AtomProperty* ap,
- ResidueTypeMap* residueTypeMap,
- const std::string& residueName,
- const std::string& atomName,
- real propValue,
- int line)
+static void addProperty(AtomProperty* ap,
+ const ResidueTypeMap& residueTypeMap,
+ const std::string& residueName,
+ const std::string& atomName,
+ real propValue,
+ int line)
{
bool bExact = false;
int j = findPropertyIndex(ap, residueTypeMap, residueName, atomName, &bExact);
* \param[in] residueTypeMap Library of residue types.
* \param[in] factor Scaling factor for property.
*/
-static void readProperty(AtomProperty* ap, ResidueTypeMap* residueTypeMap, double factor)
+static void readProperty(AtomProperty* ap, const ResidueTypeMap& residueTypeMap, double factor)
{
char line[STRLEN], resnm[32], atomnm[32];
* \param[in] haveBeenWarned If we already set a warning before
* \returns True of warning should be printed.
*/
-static bool setProperties(AtomProperty* ap, ResidueTypeMap* residueTypeMap, int eprop, bool haveBeenWarned)
+static bool setProperties(AtomProperty* ap, const ResidueTypeMap& residueTypeMap, int eprop, bool haveBeenWarned)
{
const char* fns[epropNR] = {
"atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat", "elements.dat"
return &impl_->prop[eprop];
}
-ResidueTypeMap* AtomProperties::residueTypeMap()
-{
- return &impl_->residueTypeMap;
-}
-
//! Print warning that vdW radii and masses are guessed.
static void printWarning()
{
std::string tmpAtomName, tmpResidueName;
bool bExact = false;
- if (setProperties(prop(eprop), residueTypeMap(), eprop, impl_->bWarned))
+ if (setProperties(prop(eprop), impl_->residueTypeMap, eprop, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
tmpAtomName = atomName;
}
const int j = findPropertyIndex(
- &(impl_->prop[eprop]), &impl_->residueTypeMap, residueName, tmpAtomName, &bExact);
+ &(impl_->prop[eprop]), impl_->residueTypeMap, residueName, tmpAtomName, &bExact);
if (eprop == epropVDW && !impl_->bWarnVDW)
{
std::string AtomProperties::elementFromAtomNumber(int atomNumber)
{
- if (setProperties(prop(epropElement), residueTypeMap(), epropElement, impl_->bWarned))
+ if (setProperties(prop(epropElement), impl_->residueTypeMap, epropElement, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
int AtomProperties::atomNumberFromElement(const char* element)
{
- if (setProperties(prop(epropElement), residueTypeMap(), epropElement, impl_->bWarned))
+ if (setProperties(prop(epropElement), impl_->residueTypeMap, epropElement, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
};
struct AtomProperty;
-class ResidueTypeMap;
/*! \brief
* Holds all the atom property information loaded.
*/
AtomProperty* prop(int eprop);
private:
- //! Get handle to residuetype library.
- ResidueTypeMap* residueTypeMap();
-
//! Implementation pointer.
class Impl;
add_grp(gb, gn, aid, "System");
/* For every residue, get a pointer to the residue type name */
- ResidueTypeMap rt;
+ ResidueTypeMap residueTypeMap = residueTypeMapFromLibraryFile("residuetypes.dat");
std::vector<std::string> restype;
std::vector<std::string> previousTypename;
if (atoms->nres > 0)
{
const char* resnm = *atoms->resinfo[0].name;
- restype.emplace_back(rt.typeOfNamedDatabaseResidue(resnm));
+ restype.emplace_back(typeOfNamedDatabaseResidue(residueTypeMap, resnm));
previousTypename.push_back(restype.back());
for (int i = 1; i < atoms->nres; i++)
{
const char* resnm = *atoms->resinfo[i].name;
- restype.emplace_back(rt.typeOfNamedDatabaseResidue(resnm));
+ restype.emplace_back(typeOfNamedDatabaseResidue(residueTypeMap, 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 "residuetypes.h"
-#include <cassert>
-#include <cstdio>
-
-#include <algorithm>
-#include <optional>
#include <string>
-#include <unordered_map>
-#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/strdb.h"
//! Definition for residue type that is not known.
const ResidueType c_undefinedResidueType = "Other";
-//! Function object for comparisons used in std::unordered_map
-class EqualCaseInsensitive
+void addResidue(ResidueTypeMap* residueTypeMap, const ResidueName& residueName, const ResidueType& residueType)
{
-public:
- bool operator()(const ResidueName& lhs, const ResidueName& rhs) const
+ if (auto [foundIt, insertionTookPlace] = residueTypeMap->insert({ residueName, residueType });
+ !insertionTookPlace)
{
- return gmx::equalCaseInsensitive(lhs, rhs);
+ if (!gmx::equalCaseInsensitive(foundIt->second, residueType))
+ {
+ fprintf(stderr,
+ "Warning: Residue '%s' already present with type '%s' in database, ignoring "
+ "new type '%s'.\n",
+ residueName.c_str(),
+ foundIt->second.c_str(),
+ residueType.c_str());
+ }
}
-};
-
-//! Implementation detail for ResidueTypeMap
-class ResidueTypeMap::Impl
-{
-public:
- //! Storage object for entries.
- std::unordered_map<ResidueName, ResidueType, std::hash<ResidueName>, EqualCaseInsensitive> entries;
-};
+}
-ResidueTypeMap::ResidueTypeMap() : impl_(new Impl)
+ResidueTypeMap residueTypeMapFromLibraryFile(const std::string& residueTypesDatFilename)
{
char line[STRLEN];
char resname[STRLEN], restype[STRLEN], dum[STRLEN];
- gmx::FilePtr db = gmx::openLibraryFile("residuetypes.dat");
+ gmx::FilePtr db = gmx::openLibraryFile(residueTypesDatFilename);
+ ResidueTypeMap residueTypeMap;
while (get_a_line(db.get(), line, STRLEN))
{
strip_comment(line);
FARGS,
"Incorrect number of columns (2 expected) for line in residuetypes.dat ");
}
- addResidue(resname, restype);
- }
- }
-}
-
-ResidueTypeMap::~ResidueTypeMap() = default;
-
-bool ResidueTypeMap::nameIndexedInResidueTypeMap(const ResidueName& residueName)
-{
- return impl_->entries.find(residueName) != impl_->entries.end();
-}
-
-void ResidueTypeMap::addResidue(const ResidueName& residueName, const ResidueType& residueType)
-{
- if (auto [foundIt, insertionTookPlace] = impl_->entries.insert({ residueName, residueType });
- !insertionTookPlace)
- {
- if (!gmx::equalCaseInsensitive(foundIt->second, residueType))
- {
- fprintf(stderr,
- "Warning: Residue '%s' already present with type '%s' in database, ignoring "
- "new type '%s'.\n",
- residueName.c_str(),
- foundIt->second.c_str(),
- residueType.c_str());
+ addResidue(&residueTypeMap, resname, restype);
}
}
+ return residueTypeMap;
}
-bool ResidueTypeMap::namedResidueHasType(const ResidueName& residueName, const ResidueType& residueType)
+bool namedResidueHasType(const ResidueTypeMap& residueTypeMap,
+ const ResidueName& residueName,
+ const ResidueType& residueType)
{
- if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
+ if (auto foundIt = residueTypeMap.find(residueName); foundIt != residueTypeMap.end())
{
return gmx::equalCaseInsensitive(residueType, foundIt->second);
}
return false;
}
-ResidueType ResidueTypeMap::typeOfNamedDatabaseResidue(const ResidueName& residueName)
+ResidueType typeOfNamedDatabaseResidue(const ResidueTypeMap& residueTypeMap, const ResidueName& residueName)
{
- if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
+ if (auto foundIt = residueTypeMap.find(residueName); foundIt != residueTypeMap.end())
{
return foundIt->second;
}
return c_undefinedResidueType;
}
-
-std::optional<ResidueType> ResidueTypeMap::optionalTypeOfNamedDatabaseResidue(const ResidueName& residueName)
-{
- if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
- {
- return std::make_optional(foundIt->second);
- }
- return std::nullopt;
-}
#ifndef GMX_TOPOLOGY_RESIDUETYPES_H
#define GMX_TOPOLOGY_RESIDUETYPES_H
-#include <memory>
-#include <optional>
#include <string>
+#include <unordered_map>
#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/stringutil.h"
/*! \brief Convenience type aliases
*
using ResidueType = std::string;
//! \}
-class ResidueTypeMap
-{
-public:
- //! Default constructor.
- ResidueTypeMap();
- //! Default destructor.
- ~ResidueTypeMap();
+/*! \brief Maps residue names to residue types
+ *
+ * The contents are typically loaded from share/top/residuetypes.dat
+ * or similar file provided in the users's working directory.
+ */
+using ResidueTypeMap =
+ std::unordered_map<ResidueName, ResidueType, std::hash<ResidueName>, gmx::EqualCaseInsensitive>;
+
+/*! \brief
+ * Add entry to ResidueTypeMap if unique.
+ *
+ * \param[in] residueTypeMap Map to which to add new name+type entry
+ * \param[in] residueName Name of new residue.
+ * \param[in] residueType Type of new residue.
+ */
+void addResidue(ResidueTypeMap* residueTypeMap, const ResidueName& residueName, const ResidueType& residueType);
- /*! \brief
- * Return true if residue \p residueName is found or false otherwise.
- *
- * \param[in] residueName Residue name to search database for.
- * \returns true if successful.
- */
- bool nameIndexedInResidueTypeMap(const ResidueName& residueName);
- /*! \brief
- * Add entry to ResidueTypeMap if unique.
- *
- * \param[in] residueName Name of new residue.
- * \param[in] residueType Type of new residue.
- */
- void addResidue(const ResidueName& residueName, const ResidueType& residueType);
- /*! \brief
- * Checks if the indicated \p residueName if of \p residueType.
- *
- * \param[in] residueName Residue that should be checked.
- * \param[in] residueType Which ResidueType the residue should have.
- * \returns If the check was successful.
- */
- bool namedResidueHasType(const ResidueName& residueName, const ResidueType& residueType);
- /*! \brief
- * Return the residue type if a residue with that name exists, or "Other"
- *
- * \param[in] residueName Name of the residue to search for.
- * \returns The residue type of any matching residue, or "Other"
- */
- ResidueType typeOfNamedDatabaseResidue(const ResidueName& residueName);
- /*! \brief
- * Return an optional residue type if a residue with that name exists
- *
- * \param[in] residueName Name of the residue to search for.
- * \returns An optional containing the residue type of any matching residue
- */
- std::optional<ResidueType> optionalTypeOfNamedDatabaseResidue(const ResidueName& residueName);
+/*! \brief Returns a ResidueTypeMap filled from a file
+ *
+ * The value of the parameter is typically "residuetypes.dat" which
+ * treats that as a GROMACS library file, ie. loads it from the working
+ * directory or from "share/top" corresponding to the sourced GMXRC.
+ *
+ * \param[in] residueTypesDatFilename Library file to read and from which to fill the returned map
+ */
+ResidueTypeMap residueTypeMapFromLibraryFile(const std::string& residueTypesDatFilename);
-private:
- //! Implementation pointer.
- class Impl;
+/*! \brief
+ * Checks if the indicated \p residueName is of \p residueType.
+ *
+ * \param[in] residueTypeMap Map to search
+ * \param[in] residueName Residue that should be checked.
+ * \param[in] residueType Which ResidueType the residue should have.
+ * \returns If the check was successful.
+ */
+bool namedResidueHasType(const ResidueTypeMap& residueTypeMap,
+ const ResidueName& residueName,
+ const ResidueType& residueType);
- std::unique_ptr<Impl> impl_;
-};
+/*! \brief
+ * Return the residue type if a residue with that name exists, or "Other"
+ *
+ * \param[in] residueTypeMap Map to search
+ * \param[in] residueName Name of the residue to search for.
+ * \returns The residue type of any matching residue, or "Other"
+ */
+ResidueType typeOfNamedDatabaseResidue(const ResidueTypeMap& residueTypeMap, const ResidueName& residueName);
#endif
*/
bool equalCaseInsensitive(const std::string& source, const std::string& target);
+//! Function object for comparisons with \c equalCaseInsensitive
+class EqualCaseInsensitive
+{
+public:
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return gmx::equalCaseInsensitive(lhs, rhs);
+ }
+};
+
/*! \brief
* Checks if at most \p maxLengthOfComparison characters of two strings match case insensitive.
*