fprintf(out, "MODEL %8d\n", model_nr > 0 ? model_nr : 1);
- ResidueType rt;
+ ResidueTypeMap rt;
for (int ii = 0; ii < nindex; ii++)
{
int i = index[ii];
#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,
- ResidueType* 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,
+ ResidueTypeMap* rt)
{
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->nameIndexedInResidueTypes(thisres))
+ if (!rt->nameIndexedInResidueTypeMap(thisres))
{
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
- // caller, but ResidueType doesn't yet have a way to loop over its
+ // caller, but ResidueTypeMap doesn't yet have a way to loop over its
// contents.
std::unordered_set<std::string> uniqueResidueNames;
for (const auto& dihedral : dlist)
}
fprintf(log, "Title: %s\n", name);
- ResidueType rt;
+ ResidueTypeMap rt;
std::vector<t_dlist> dlist = mk_dlist(log, &atoms, bPhi, bPsi, bChi, bHChi, maxchi, r0, &rt);
fprintf(stderr, "%zu residues with dihedrals found\n", dlist.size());
#include "gromacs/topology/index.h"
struct gmx_output_env_t;
-class ResidueType;
+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,
- ResidueType* 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,
+ 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, ResidueType* rt)
+static int get_atype(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueTypeMap* rt)
{
int type;
bool bNterm;
return *tp;
}
-static real get_amass(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueType* rt)
+static real get_amass(int atom, t_atoms* at, gmx::ArrayRef<const PreprocessResidue> rtpFFDB, ResidueTypeMap* rt)
{
real mass;
bool bNterm;
/* make index to tell which residues were already processed */
std::vector<bool> bResProcessed(at->nres);
- ResidueType rt;
+ ResidueTypeMap rt;
/* generate vsite constructions */
/* loop over all atoms */
matrix box,
bool bRemoveH,
t_symtab* symtab,
- ResidueType* rt,
+ ResidueTypeMap* rt,
const char* watres,
AtomProperties* aps,
bool bVerbose)
return pdba->nr;
}
-void checkResidueTypeSanity(t_atoms* pdba, int r0, int r1, ResidueType* rt)
+void checkResidueTypeSanity(t_atoms* pdba, int r0, int r1, ResidueTypeMap* rt)
{
std::string startResidueString =
gmx::formatString("%s%d", *pdba->resinfo[r0].name, pdba->resinfo[r0].nr);
}
}
-void find_nc_ter(t_atoms* pdba, int r0, int r1, int* r_start, int* r_end, ResidueType* rt, const gmx::MDLogger& logger)
+void find_nc_ter(t_atoms* pdba, int r0, int r1, int* r_start, int* r_end, ResidueTypeMap* rt, const gmx::MDLogger& logger)
{
int i;
std::optional<std::string> startrestype;
open_symtab(&symtab);
/* Residue type database */
- ResidueType rt;
+ ResidueTypeMap rt;
/* Read residue renaming database(s), if present */
std::vector<std::string> rrn = fflib_search_file_end(ffdir_, ".r2b", FALSE);
static int name2type(t_atoms* at,
int** cgnr,
gmx::ArrayRef<const PreprocessResidue> usedPpResidues,
- ResidueType* rt,
+ ResidueTypeMap* rt,
const gmx::MDLogger& logger)
{
int i, j, prevresind, i0, prevcg, cg, curcg;
int i, nmissat;
gmx::EnumerationArray<BondedTypes, int> bts;
- ResidueType rt;
+ ResidueTypeMap rt;
/* Make bonds */
at2bonds(&(plist[F_BONDS]), globalPatches, atoms, *x, long_bond_dist, short_bond_dist, cyclicBondsIndex, logger);
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2017,2018 by the GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
t_symtab* symtab,
gmx::ArrayRef<const PreprocessResidue> localPpResidue,
bool bResname,
- ResidueType* rt,
+ ResidueTypeMap* rt,
bool bReorderNum,
bool bVerbose)
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#ifndef GMX_GMXPREPROCESS_XLATE_H
#define GMX_GMXPREPROCESS_XLATE_H
-class ResidueType;
+class ResidueTypeMap;
struct t_atoms;
struct PreprocessResidue;
struct t_symtab;
t_symtab* symtab,
gmx::ArrayRef<const PreprocessResidue> restp,
bool bResname,
- ResidueType* rt,
+ ResidueTypeMap* rt,
bool bReorderNum,
bool bVerbose);
//! The different atom properties.
AtomProperty prop[epropNR];
//! The residue types.
- ResidueType restype;
+ ResidueTypeMap residueTypeMap;
};
/*! \brief
* Finds the index for the property being searched.
*
* \param[in] ap Property to search for.
- * \param[in] restype Residuetypes in database.
+ * \param[in] residueTypeMap Residuetypes in database.
* \param[in] residueName The name of the residue to look for.
* \param[in] atomName The name of the atom to look for.
* \param[in] bExact Do we have the correct match.
* \returns The index for the property.
*/
static int findPropertyIndex(AtomProperty* ap,
- ResidueType* restype,
+ ResidueTypeMap* residueTypeMap,
const std::string& residueName,
const std::string& atomName,
gmx_bool* bExact)
{
int j = NOTFOUND;
- bool bProtein = restype->namedResidueHasType(residueName, "Protein");
+ bool bProtein = residueTypeMap->namedResidueHasType(residueName, "Protein");
bool bProtWild = residueName == "AAA";
int malen = NOTFOUND;
int mrlen = NOTFOUND;
* Add new property to list.
*
* \param[in] ap Atomproperty to add.
- * \param[in] restype Residue type database to use.
+ * \param[in] residueTypeMap Residue type database to use.
* \param[in] residueName Name of the residue.
* \param[in] atomName Name of the atom.
* \param[in] propValue Value of property.
* \param[in] line Where to add property.
*/
static void addProperty(AtomProperty* ap,
- ResidueType* restype,
+ ResidueTypeMap* residueTypeMap,
const std::string& residueName,
const std::string& atomName,
real propValue,
int line)
{
bool bExact = false;
- int j = findPropertyIndex(ap, restype, residueName, atomName, &bExact);
+ int j = findPropertyIndex(ap, residueTypeMap, residueName, atomName, &bExact);
if (!bExact)
{
* Read property value into structure.
*
* \param[in] ap Atomproperty to be read in.
- * \param[in] restype Library of residue types.
+ * \param[in] residueTypeMap Library of residue types.
* \param[in] factor Scaling factor for property.
*/
-static void readProperty(AtomProperty* ap, ResidueType* restype, double factor)
+static void readProperty(AtomProperty* ap, ResidueTypeMap* residueTypeMap, double factor)
{
char line[STRLEN], resnm[32], atomnm[32];
if (sscanf(line, "%31s %31s %20lf", resnm, atomnm, &pp) == 3)
{
pp *= factor;
- addProperty(ap, restype, resnm, atomnm, pp, line_no);
+ addProperty(ap, residueTypeMap, resnm, atomnm, pp, line_no);
}
else
{
* Set value for properties.
*
* \param[in] ap Atomproperty to set.
- * \param[in] restype Library of residue types.
+ * \param[in] residueTypeMap Library of residue types.
* \param[in] eprop Which property to set.
* \param[in] haveBeenWarned If we already set a warning before
* \returns True of warning should be printed.
*/
-static bool setProperties(AtomProperty* ap, ResidueType* restype, int eprop, bool haveBeenWarned)
+static bool setProperties(AtomProperty* ap, ResidueTypeMap* residueTypeMap, int eprop, bool haveBeenWarned)
{
const char* fns[epropNR] = {
"atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat", "elements.dat"
{
ap->db = fns[eprop];
ap->def = def[eprop];
- readProperty(ap, restype, fac[eprop]);
+ readProperty(ap, residueTypeMap, fac[eprop]);
if (debug)
{
return &impl_->prop[eprop];
}
-ResidueType* AtomProperties::restype()
+ResidueTypeMap* AtomProperties::residueTypeMap()
{
- return &impl_->restype;
+ return &impl_->residueTypeMap;
}
//! Print warning that vdW radii and masses are guessed.
std::string tmpAtomName, tmpResidueName;
bool bExact = false;
- if (setProperties(prop(eprop), restype(), eprop, impl_->bWarned))
+ if (setProperties(prop(eprop), residueTypeMap(), eprop, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
tmpAtomName = atomName;
}
const int j = findPropertyIndex(
- &(impl_->prop[eprop]), &impl_->restype, 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), restype(), epropElement, impl_->bWarned))
+ if (setProperties(prop(epropElement), residueTypeMap(), epropElement, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
int AtomProperties::atomNumberFromElement(const char* element)
{
- if (setProperties(prop(epropElement), restype(), epropElement, impl_->bWarned))
+ if (setProperties(prop(epropElement), residueTypeMap(), epropElement, impl_->bWarned))
{
printWarning();
impl_->bWarned = true;
};
struct AtomProperty;
-class ResidueType;
+class ResidueTypeMap;
/*! \brief
* Holds all the atom property information loaded.
*/
* \returns Pointer to property entry.
*/
AtomProperty* prop(int eprop);
- //! Get handle to residuetype library.
- ResidueType* restype();
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 */
- ResidueType rt;
+ ResidueTypeMap rt;
std::vector<std::string> restype;
std::vector<std::string> previousTypename;
#include <algorithm>
#include <optional>
#include <string>
+#include <unordered_map>
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/strdb.h"
//! Definition for residue type that is not known.
-const std::string c_undefinedResidueType = "Other";
+const ResidueType c_undefinedResidueType = "Other";
-//! Single ResidueType entry object
-struct ResidueTypeEntry
+//! Function object for comparisons used in std::unordered_map
+class EqualCaseInsensitive
{
- //! Default constructor creates complete object.
- ResidueTypeEntry(const std::string& rName, const std::string& rType) :
- residueName(rName), residueType(rType)
+public:
+ bool operator()(const ResidueName& lhs, const ResidueName& rhs) const
{
+ return gmx::equalCaseInsensitive(lhs, rhs);
}
- //! 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
+//! Implementation detail for ResidueTypeMap
+class ResidueTypeMap::Impl
{
public:
//! Storage object for entries.
- std::vector<ResidueTypeEntry> entry;
+ std::unordered_map<ResidueName, ResidueType, std::hash<ResidueName>, EqualCaseInsensitive> entries;
};
-ResidueType::ResidueType() : impl_(new Impl)
+ResidueTypeMap::ResidueTypeMap() : impl_(new Impl)
{
char line[STRLEN];
char resname[STRLEN], restype[STRLEN], dum[STRLEN];
}
}
-ResidueType::~ResidueType() {}
+ResidueTypeMap::~ResidueTypeMap() = default;
-/*! \brief
- * Return an optional const iterator to a residue entry that matches the given name.
- *
- * \param[in] entries Currently registered residue entries in the database.
- * \param[in] residueName Name of a residue to compare to database.
- * \returns An optional iterator to the residue entry that was found.
- */
-static std::optional<gmx::ArrayRef<const ResidueTypeEntry>::const_iterator>
-findResidueEntryWithName(gmx::ArrayRef<const ResidueTypeEntry> entries, const std::string& residueName)
+bool ResidueTypeMap::nameIndexedInResidueTypeMap(const ResidueName& residueName)
{
- auto foundIt =
- std::find_if(entries.begin(), entries.end(), [&residueName](const ResidueTypeEntry& old) {
- return gmx::equalCaseInsensitive(residueName, old.residueName);
- });
- return (foundIt != entries.end()) ? std::make_optional(foundIt) : std::nullopt;
+ return impl_->entries.find(residueName) != impl_->entries.end();
}
-bool ResidueType::nameIndexedInResidueTypes(const std::string& residueName)
+void ResidueTypeMap::addResidue(const ResidueName& residueName, const ResidueType& residueType)
{
- return findResidueEntryWithName(impl_->entry, residueName).has_value();
-}
-
-void ResidueType::addResidue(const std::string& residueName, const std::string& residueType)
-{
- if (auto foundIt = findResidueEntryWithName(impl_->entry, residueName))
+ if (auto [foundIt, insertionTookPlace] = impl_->entries.insert({ residueName, residueType });
+ !insertionTookPlace)
{
- if (!gmx::equalCaseInsensitive((*foundIt)->residueType, residueType))
+ 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)->residueType.c_str(),
+ foundIt->second.c_str(),
residueType.c_str());
}
}
- else
- {
- impl_->entry.emplace_back(residueName, residueType);
- }
}
-bool ResidueType::namedResidueHasType(const std::string& residueName, const std::string& residueType)
+bool ResidueTypeMap::namedResidueHasType(const ResidueName& residueName, const ResidueType& residueType)
{
- auto foundIt = findResidueEntryWithName(impl_->entry, residueName);
- return foundIt ? gmx::equalCaseInsensitive(residueType, (*foundIt)->residueType) : false;
+ if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
+ {
+ return gmx::equalCaseInsensitive(residueType, foundIt->second);
+ }
+ return false;
}
-std::string ResidueType::typeOfNamedDatabaseResidue(const std::string& residueName)
+ResidueType ResidueTypeMap::typeOfNamedDatabaseResidue(const ResidueName& residueName)
{
- auto foundIt = findResidueEntryWithName(impl_->entry, residueName);
- return foundIt ? (*foundIt)->residueType : c_undefinedResidueType;
+ if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
+ {
+ return foundIt->second;
+ }
+ return c_undefinedResidueType;
}
-std::optional<std::string> ResidueType::optionalTypeOfNamedDatabaseResidue(const std::string& residueName)
+std::optional<ResidueType> ResidueTypeMap::optionalTypeOfNamedDatabaseResidue(const ResidueName& residueName)
{
- auto foundIt = findResidueEntryWithName(impl_->entry, residueName);
- return foundIt ? std::make_optional((*foundIt)->residueType) : std::nullopt;
+ if (auto foundIt = impl_->entries.find(residueName); foundIt != impl_->entries.end())
+ {
+ return std::make_optional(foundIt->second);
+ }
+ return std::nullopt;
}
#include "gromacs/utility/basedefinitions.h"
-struct ResidueTypeEntry;
+/*! \brief Convenience type aliases
+ *
+ * These are not as useful as strong types, but they will
+ * help clarify usage to humans in some cases. */
+//! \{
+using ResidueName = std::string;
+using ResidueType = std::string;
+//! \}
-class ResidueType
+class ResidueTypeMap
{
public:
//! Default constructor.
- ResidueType();
+ ResidueTypeMap();
//! Default destructor.
- ~ResidueType();
-
- //! Get handle to underlying residue type data.
- ResidueTypeEntry* ResidueTypes();
+ ~ResidueTypeMap();
/*! \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 nameIndexedInResidueTypes(const std::string& residueName);
+ bool nameIndexedInResidueTypeMap(const ResidueName& residueName);
/*! \brief
- * Add entry to ResidueTypes if unique.
+ * Add entry to ResidueTypeMap if unique.
*
* \param[in] residueName Name of new residue.
* \param[in] residueType Type of new residue.
*/
- void addResidue(const std::string& residueName, const std::string& residueType);
+ void addResidue(const ResidueName& residueName, const ResidueType& 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 std::string& residueName, const std::string& residueType);
+ 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"
*/
- std::string typeOfNamedDatabaseResidue(const std::string& residueName);
+ 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<std::string> optionalTypeOfNamedDatabaseResidue(const std::string& residueName);
+ std::optional<ResidueType> optionalTypeOfNamedDatabaseResidue(const ResidueName& residueName);
private:
//! Implementation pointer.