Commit cb3443ff by Maarten L. Hekkelman

Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop

parents 6b2c9dc3 8bbcba76
......@@ -25,7 +25,7 @@
cmake_minimum_required(VERSION 3.16)
# set the project name
project(cifpp VERSION 2.0.2 LANGUAGES CXX)
project(cifpp VERSION 3.0.0 LANGUAGES CXX)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
......
Version 3.0.0
- Replaced many strings in the API with string_view for
performance reasons.
- Upgraded mmcif::Structure
Version 2.0.2
- Added configuration flag to disable downloading CCD data during build
Note that there are now two flags for CCD data:
......
......@@ -238,9 +238,9 @@ class Datablock
const_iterator begin() const { return mCategories.begin(); }
const_iterator end() const { return mCategories.end(); }
Category &operator[](const std::string &name);
Category &operator[](std::string_view name);
std::tuple<iterator, bool> emplace(const std::string &name);
std::tuple<iterator, bool> emplace(std::string_view name);
bool isValid();
void validateLinks() const;
......@@ -248,8 +248,8 @@ class Datablock
void setValidator(Validator *v);
// this one only looks up a Category, returns nullptr if it does not exist
const Category *get(const std::string &name) const;
Category *get(const std::string &name);
const Category *get(std::string_view name) const;
Category *get(std::string_view name);
void getTagOrder(std::vector<std::string> &tags) const;
void write(std::ostream &os, const std::vector<std::string> &order);
......@@ -350,14 +350,14 @@ namespace detail
private:
friend class ::cif::Row;
ItemReference(const char *name, size_t column, Row &row)
ItemReference(std::string_view name, size_t column, Row &row)
: mName(name)
, mColumn(column)
, mRow(row)
{
}
ItemReference(const char *name, size_t column, const Row &row)
ItemReference(std::string_view name, size_t column, const Row &row)
: mName(name)
, mColumn(column)
, mRow(const_cast<Row &>(row))
......@@ -365,7 +365,7 @@ namespace detail
{
}
const char *mName;
std::string_view mName;
size_t mColumn;
Row &mRow;
bool mConst = false;
......@@ -746,16 +746,16 @@ class Row
return detail::ItemReference(itemTag, column, *this);
}
const detail::ItemReference operator[](const std::string &itemTag) const
const detail::ItemReference operator[](std::string_view itemTag) const
{
size_t column = ColumnForItemTag(itemTag.c_str());
return detail::ItemReference(itemTag.c_str(), column, *this);
size_t column = ColumnForItemTag(itemTag);
return detail::ItemReference(itemTag, column, *this);
}
detail::ItemReference operator[](const std::string &itemTag)
detail::ItemReference operator[](std::string_view itemTag)
{
size_t column = ColumnForItemTag(itemTag.c_str());
return detail::ItemReference(itemTag.c_str(), column, *this);
size_t column = ColumnForItemTag(itemTag);
return detail::ItemReference(itemTag, column, *this);
}
template <typename... Ts, size_t N>
......@@ -776,7 +776,7 @@ class Row
}
void assign(const std::vector<Item> &values);
void assign(const std::string &name, const std::string &value, bool updateLinked);
void assign(std::string_view name, const std::string &value, bool updateLinked);
bool operator==(const Row &rhs) const
{
......@@ -803,7 +803,7 @@ class Row
static void swap(size_t column, ItemRow *a, ItemRow *b);
size_t ColumnForItemTag(const char *itemTag) const;
size_t ColumnForItemTag(std::string_view itemTag) const;
mutable ItemRow *mData;
uint32_t mLineNr = 0;
......@@ -2077,8 +2077,8 @@ class Category
void getTagOrder(std::vector<std::string> &tags) const;
// return index for known column, or the next available column index
size_t getColumnIndex(const std::string &name) const;
bool hasColumn(const std::string &name) const;
size_t getColumnIndex(std::string_view name) const;
bool hasColumn(std::string_view name) const;
const std::string &getColumnName(size_t columnIndex) const;
std::vector<std::string> getColumnNames() const;
......@@ -2119,7 +2119,7 @@ class Category
void write(std::ostream &os, const std::vector<std::string> &order);
void write(std::ostream &os, const std::vector<size_t> &order, bool includeEmptyColumns);
size_t addColumn(const std::string &name);
size_t addColumn(std::string_view name);
Datablock &mDb;
std::string mName;
......@@ -2183,8 +2183,8 @@ class File
void append(Datablock *e);
Datablock *get(const std::string &name) const;
Datablock &operator[](const std::string &name);
Datablock *get(std::string_view name) const;
Datablock &operator[](std::string_view name);
struct iterator
{
......
......@@ -94,10 +94,6 @@ inline bool isUnquotedString(const char* s)
// --------------------------------------------------------------------
std::tuple<std::string,std::string> splitTagName(const std::string& tag);
// --------------------------------------------------------------------
using DatablockIndex = std::map<std::string,std::size_t>;
// --------------------------------------------------------------------
......
......@@ -67,8 +67,10 @@ std::string get_version_nr();
// some basic utilities: Since we're using ASCII input only, we define for optimisation
// our own case conversion routines.
bool iequals(const std::string &a, const std::string &b);
int icompare(const std::string &a, const std::string &b);
// bool iequals(const std::string &a, const std::string &b);
bool iequals(std::string_view a, std::string_view b);
// int icompare(const std::string &a, const std::string &b);
int icompare(std::string_view a, std::string_view b);
bool iequals(const char *a, const char *b);
int icompare(const char *a, const char *b);
......@@ -100,7 +102,7 @@ inline char tolower(int ch)
// --------------------------------------------------------------------
std::tuple<std::string, std::string> splitTagName(const std::string &tag);
std::tuple<std::string, std::string> splitTagName(std::string_view tag);
// --------------------------------------------------------------------
// generate a cif name, mainly used to generate asym_id's
......
......@@ -44,10 +44,10 @@ struct ValidateCategory;
class ValidationError : public std::exception
{
public:
ValidationError(const std::string& msg);
ValidationError(const std::string& cat, const std::string& item,
const std::string& msg);
const char* what() const noexcept { return mMsg.c_str(); }
ValidationError(const std::string &msg);
ValidationError(const std::string &cat, const std::string &item,
const std::string &msg);
const char *what() const noexcept { return mMsg.c_str(); }
std::string mMsg;
};
......@@ -55,10 +55,12 @@ class ValidationError : public std::exception
enum class DDL_PrimitiveType
{
Char, UChar, Numb
Char,
UChar,
Numb
};
DDL_PrimitiveType mapToPrimitiveType(const std::string& s);
DDL_PrimitiveType mapToPrimitiveType(std::string_view s);
struct ValidateType
{
......@@ -67,46 +69,46 @@ struct ValidateType
// std::regex mRx;
boost::regex mRx;
bool operator<(const ValidateType& rhs) const
bool operator<(const ValidateType &rhs) const
{
return icompare(mName, rhs.mName) < 0;
}
// compare values based on type
// int compare(const std::string& a, const std::string& b) const
// {
// return compare(a.c_str(), b.c_str());
// }
// int compare(const std::string& a, const std::string& b) const
// {
// return compare(a.c_str(), b.c_str());
// }
int compare(const char* a, const char* b) const;
int compare(const char *a, const char *b) const;
};
struct ValidateItem
{
std::string mTag;
bool mMandatory;
const ValidateType* mType;
const ValidateType *mType;
cif::iset mEnums;
std::string mDefault;
bool mDefaultIsNull;
ValidateCategory* mCategory = nullptr;
ValidateCategory *mCategory = nullptr;
// ItemLinked is used for non-key links
struct ItemLinked
{
ValidateItem* mParent;
ValidateItem *mParent;
std::string mParentItem;
std::string mChildItem;
};
std::vector<ItemLinked> mLinked;
bool operator<(const ValidateItem& rhs) const
bool operator<(const ValidateItem &rhs) const
{
return icompare(mTag, rhs.mTag) < 0;
}
bool operator==(const ValidateItem& rhs) const
bool operator==(const ValidateItem &rhs) const
{
return iequals(mTag, rhs.mTag);
}
......@@ -122,16 +124,16 @@ struct ValidateCategory
cif::iset mMandatoryFields;
std::set<ValidateItem> mItemValidators;
bool operator<(const ValidateCategory& rhs) const
bool operator<(const ValidateCategory &rhs) const
{
return icompare(mName, rhs.mName) < 0;
}
void addItemValidator(ValidateItem&& v);
void addItemValidator(ValidateItem &&v);
const ValidateItem* getValidatorForItem(std::string tag) const;
const ValidateItem *getValidatorForItem(std::string_view tag) const;
const std::set<ValidateItem>& itemValidators() const
const std::set<ValidateItem> &itemValidators() const
{
return mItemValidators;
}
......@@ -157,42 +159,41 @@ class Validator
Validator();
~Validator();
Validator(const Validator& rhs) = delete;
Validator& operator=(const Validator& rhs) = delete;
Validator(const Validator &rhs) = delete;
Validator &operator=(const Validator &rhs) = delete;
Validator(Validator&& rhs);
Validator& operator=(Validator&& rhs);
Validator(Validator &&rhs);
Validator &operator=(Validator &&rhs);
void addTypeValidator(ValidateType&& v);
const ValidateType* getValidatorForType(std::string typeCode) const;
void addTypeValidator(ValidateType &&v);
const ValidateType *getValidatorForType(std::string_view typeCode) const;
void addCategoryValidator(ValidateCategory&& v);
const ValidateCategory* getValidatorForCategory(std::string category) const;
void addCategoryValidator(ValidateCategory &&v);
const ValidateCategory *getValidatorForCategory(std::string_view category) const;
void addLinkValidator(ValidateLink&& v);
std::vector<const ValidateLink*> getLinksForParent(const std::string& category) const;
std::vector<const ValidateLink*> getLinksForChild(const std::string& category) const;
void addLinkValidator(ValidateLink &&v);
std::vector<const ValidateLink *> getLinksForParent(std::string_view category) const;
std::vector<const ValidateLink *> getLinksForChild(std::string_view category) const;
void reportError(const std::string& msg, bool fatal);
void reportError(const std::string &msg, bool fatal);
std::string dictName() const { return mName; }
void dictName(const std::string& name) { mName = name; }
void dictName(const std::string &name) { mName = name; }
std::string dictVersion() const { return mVersion; }
void dictVersion(const std::string& version) { mVersion = version; }
void dictVersion(const std::string &version) { mVersion = version; }
private:
// name is fully qualified here:
ValidateItem* getValidatorForItem(std::string name) const;
ValidateItem *getValidatorForItem(std::string_view name) const;
std::string mName;
std::string mVersion;
bool mStrict = false;
// std::set<uint32_t> mSubCategories;
// std::set<uint32_t> mSubCategories;
std::set<ValidateType> mTypeValidators;
std::set<ValidateCategory> mCategoryValidators;
std::vector<ValidateLink> mLinkValidators;
};
}
} // namespace cif
......@@ -461,9 +461,18 @@ class Structure
Atom getAtomByLabel(const std::string &atomID, const std::string &asymID,
const std::string &compID, int seqID, const std::string &altID = "");
/// \brief Return the atom closest to point \a p
Atom getAtomByPosition(Point p) const;
/// \brief Return the atom closest to point \a p with atom type \a type in a residue of type \a res_type
Atom getAtomByPositionAndType(Point p, std::string_view type, std::string_view res_type) const;
/// \brief Get a residue, if \a seqID is zero, the non-polymers are searched
const Residue &getResidue(const std::string &asymID, const std::string &compID, int seqID = 0) const;
/// \brief Get a the single residue for an asym with id \a asymID
const Residue &getResidue(const std::string &asymID) const;
// map between auth and label locations
std::tuple<std::string, int, std::string> MapAuthToLabel(const std::string &asymID,
......@@ -519,15 +528,16 @@ class Structure
void cleanupEmptyCategories();
/// \brief Direct access to underlying data
cif::Category &category(std::string_view name) const;
cif::Datablock &datablock() const;
private:
friend Polymer;
friend Residue;
// friend residue_view;
// friend residue_iterator;
cif::Category &category(const char *name) const;
cif::Datablock &datablock() const;
std::string insertCompound(const std::string &compoundID, bool isEntity);
void loadData();
......
......@@ -387,7 +387,7 @@ std::string Datablock::firstItem(const std::string &tag) const
return result;
}
auto Datablock::emplace(const std::string &name) -> std::tuple<iterator, bool>
auto Datablock::emplace(std::string_view name) -> std::tuple<iterator, bool>
{
bool isNew = false;
iterator i = find_if(begin(), end(), [name](const Category &cat) -> bool
......@@ -396,20 +396,20 @@ auto Datablock::emplace(const std::string &name) -> std::tuple<iterator, bool>
if (i == end())
{
isNew = true;
i = mCategories.emplace(end(), *this, name, mValidator);
i = mCategories.emplace(end(), *this, std::string(name), mValidator);
}
return std::make_tuple(i, isNew);
}
Category &Datablock::operator[](const std::string &name)
Category &Datablock::operator[](std::string_view name)
{
iterator i;
std::tie(i, std::ignore) = emplace(name);
return *i;
}
Category *Datablock::get(const std::string &name)
Category *Datablock::get(std::string_view name)
{
auto i = find_if(begin(), end(), [name](const Category &cat) -> bool
{ return iequals(cat.name(), name); });
......@@ -417,7 +417,7 @@ Category *Datablock::get(const std::string &name)
return i == end() ? nullptr : &*i;
}
const Category *Datablock::get(const std::string &name) const
const Category *Datablock::get(std::string_view name) const
{
auto i = find_if(begin(), end(), [name](const Category &cat) -> bool
{ return iequals(cat.name(), name); });
......@@ -1373,12 +1373,12 @@ void Category::setValidator(Validator *v)
mCatValidator = nullptr;
}
bool Category::hasColumn(const std::string &name) const
bool Category::hasColumn(std::string_view name) const
{
return getColumnIndex(name) < mColumns.size();
}
size_t Category::getColumnIndex(const std::string &name) const
size_t Category::getColumnIndex(std::string_view name) const
{
size_t result;
......@@ -1392,7 +1392,7 @@ size_t Category::getColumnIndex(const std::string &name) const
{
auto iv = mCatValidator->getValidatorForItem(name);
if (iv == nullptr)
std::cerr << "Invalid name used '" + name + "' is not a known column in " + mName << std::endl;
std::cerr << "Invalid name used '" << name << "' is not a known column in " + mName << std::endl;
}
return result;
......@@ -1411,8 +1411,10 @@ std::vector<std::string> Category::getColumnNames() const
return result;
}
size_t Category::addColumn(const std::string &name)
size_t Category::addColumn(std::string_view name)
{
using namespace std::literals;
size_t result = getColumnIndex(name);
if (result == mColumns.size())
......@@ -1423,10 +1425,10 @@ size_t Category::addColumn(const std::string &name)
{
itemValidator = mCatValidator->getValidatorForItem(name);
if (itemValidator == nullptr)
mValidator->reportError("tag " + name + " not allowed in Category " + mName, false);
mValidator->reportError("tag " + std::string(name) + " not allowed in Category " + mName, false);
}
mColumns.push_back({name, itemValidator});
mColumns.push_back(ItemColumn{std::string(name), itemValidator});
}
return result;
......@@ -2909,7 +2911,7 @@ void Row::assign(const Item &value, bool skipUpdateLinked)
assign(value.name(), value.value(), skipUpdateLinked);
}
void Row::assign(const std::string &name, const std::string &value, bool skipUpdateLinked)
void Row::assign(std::string_view name, const std::string &value, bool skipUpdateLinked)
{
try
{
......@@ -3309,7 +3311,7 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b)
}
}
size_t Row::ColumnForItemTag(const char *itemTag) const
size_t Row::ColumnForItemTag(std::string_view itemTag) const
{
size_t result = 0;
if (mData != nullptr)
......@@ -3549,7 +3551,7 @@ void File::write(std::ostream &os, const std::vector<std::string> &order)
}
}
Datablock *File::get(const std::string &name) const
Datablock *File::get(std::string_view name) const
{
const Datablock *result = mHead;
while (result != nullptr and not iequals(result->mName, name))
......@@ -3557,13 +3559,15 @@ Datablock *File::get(const std::string &name) const
return const_cast<Datablock *>(result);
}
Datablock &File::operator[](const std::string &name)
Datablock &File::operator[](std::string_view name)
{
using namespace std::literals;
Datablock *result = mHead;
while (result != nullptr and not iequals(result->mName, name))
result = result->mNext;
if (result == nullptr)
throw std::runtime_error("Datablock " + name + " does not exist");
throw std::runtime_error("Datablock " + std::string(name) + " does not exist");
return *result;
}
......
......@@ -811,7 +811,7 @@ typedef RM<3> RM3;
template<int N>
std::ostream& operator<<(std::ostream& os, RM<N>&& rm)
{
os << "REMARK " << std::setw(3) << std::right << N << " " << rm.mDesc << (rm.mWidth > 0 ? std::left : std::right) << std::fixed << std::setw(abs(rm.mWidth)) << std::setprecision(rm.mPrecision);
os << "REMARK " << std::setw(3) << std::right << N << " " << rm.mDesc << (rm.mWidth > 0 ? std::left : std::right) << std::fixed << std::setw(std::abs(rm.mWidth)) << std::setprecision(rm.mPrecision);
return os;
}
......@@ -824,7 +824,7 @@ struct SEP
std::ostream& operator<<(std::ostream& os, SEP&& sep)
{
os << sep.mText << (sep.mWidth > 0 ? std::left : std::right) << std::fixed << std::setw(abs(sep.mWidth)) << std::setprecision(sep.mPrecision);
os << sep.mText << (sep.mWidth > 0 ? std::left : std::right) << std::fixed << std::setw(std::abs(sep.mWidth)) << std::setprecision(sep.mPrecision);
return os;
}
......
......@@ -131,6 +131,14 @@ bool iequals(const std::string &a, const std::string &b)
return result;
}
bool iequals(std::string_view a, std::string_view b)
{
bool result = a.length() == b.length();
for (auto ai = a.begin(), bi = b.begin(); result and ai != a.end() and bi != b.end(); ++ai, ++bi)
result = tolower(*ai) == tolower(*bi);
return result;
}
bool iequals(const char *a, const char *b)
{
bool result = true;
......@@ -159,6 +167,25 @@ int icompare(const std::string &a, const std::string &b)
return d;
}
int icompare(std::string_view a, std::string_view b)
{
int d = 0;
auto ai = a.begin(), bi = b.begin();
for (; d == 0 and ai != a.end() and bi != b.end(); ++ai, ++bi)
d = tolower(*ai) - tolower(*bi);
if (d == 0)
{
if (ai != a.end())
d = 1;
else if (bi != b.end())
d = -1;
}
return d;
}
int icompare(const char *a, const char *b)
{
int d = 0;
......@@ -193,7 +220,7 @@ std::string toLowerCopy(const std::string &s)
// --------------------------------------------------------------------
std::tuple<std::string, std::string> splitTagName(const std::string &tag)
std::tuple<std::string, std::string> splitTagName(std::string_view tag)
{
if (tag.empty())
throw std::runtime_error("empty tag");
......
......@@ -37,19 +37,19 @@ extern int VERBOSE;
namespace cif
{
ValidationError::ValidationError(const std::string& msg)
ValidationError::ValidationError(const std::string &msg)
: mMsg(msg)
{
}
ValidationError::ValidationError(const std::string& cat, const std::string& item, const std::string& msg)
ValidationError::ValidationError(const std::string &cat, const std::string &item, const std::string &msg)
: mMsg("When validating _" + cat + '.' + item + ": " + msg)
{
}
// --------------------------------------------------------------------
DDL_PrimitiveType mapToPrimitiveType(const std::string& s)
DDL_PrimitiveType mapToPrimitiveType(std::string_view s)
{
DDL_PrimitiveType result;
if (iequals(s, "char"))
......@@ -65,7 +65,7 @@ DDL_PrimitiveType mapToPrimitiveType(const std::string& s)
// --------------------------------------------------------------------
int ValidateType::compare(const char* a, const char* b) const
int ValidateType::compare(const char *a, const char *b) const
{
int result = 0;
......@@ -146,7 +146,7 @@ int ValidateType::compare(const char* a, const char* b) const
}
}
}
catch (const std::invalid_argument& ex)
catch (const std::invalid_argument &ex)
{
result = 1;
}
......@@ -194,7 +194,7 @@ void ValidateItem::operator()(std::string value) const
// --------------------------------------------------------------------
void ValidateCategory::addItemValidator(ValidateItem&& v)
void ValidateCategory::addItemValidator(ValidateItem &&v)
{
if (v.mMandatory)
mMandatoryFields.insert(v.mTag);
......@@ -206,10 +206,10 @@ void ValidateCategory::addItemValidator(ValidateItem&& v)
std::cout << "Could not add validator for item " << v.mTag << " to category " << mName << std::endl;
}
const ValidateItem* ValidateCategory::getValidatorForItem(std::string tag) const
const ValidateItem *ValidateCategory::getValidatorForItem(std::string_view tag) const
{
const ValidateItem* result = nullptr;
auto i = mItemValidators.find(ValidateItem{tag});
const ValidateItem *result = nullptr;
auto i = mItemValidators.find(ValidateItem{std::string(tag)});
if (i != mItemValidators.end())
result = &*i;
else if (VERBOSE > 4)
......@@ -227,18 +227,18 @@ Validator::~Validator()
{
}
void Validator::addTypeValidator(ValidateType&& v)
void Validator::addTypeValidator(ValidateType &&v)
{
auto r = mTypeValidators.insert(std::move(v));
if (not r.second and VERBOSE > 4)
std::cout << "Could not add validator for type " << v.mName << std::endl;
}
const ValidateType* Validator::getValidatorForType(std::string typeCode) const
const ValidateType *Validator::getValidatorForType(std::string_view typeCode) const
{
const ValidateType* result = nullptr;
const ValidateType *result = nullptr;
auto i = mTypeValidators.find(ValidateType{ typeCode, DDL_PrimitiveType::Char, boost::regex() });
auto i = mTypeValidators.find(ValidateType{std::string(typeCode), DDL_PrimitiveType::Char, boost::regex()});
if (i != mTypeValidators.end())
result = &*i;
else if (VERBOSE > 4)
......@@ -246,17 +246,17 @@ const ValidateType* Validator::getValidatorForType(std::string typeCode) const
return result;
}
void Validator::addCategoryValidator(ValidateCategory&& v)
void Validator::addCategoryValidator(ValidateCategory &&v)
{
auto r = mCategoryValidators.insert(std::move(v));
if (not r.second and VERBOSE > 4)
std::cout << "Could not add validator for category " << v.mName << std::endl;
}
const ValidateCategory* Validator::getValidatorForCategory(std::string category) const
const ValidateCategory *Validator::getValidatorForCategory(std::string_view category) const
{
const ValidateCategory* result = nullptr;
auto i = mCategoryValidators.find(ValidateCategory{category});
const ValidateCategory *result = nullptr;
auto i = mCategoryValidators.find(ValidateCategory{std::string(category)});
if (i != mCategoryValidators.end())
result = &*i;
else if (VERBOSE > 4)
......@@ -264,16 +264,16 @@ const ValidateCategory* Validator::getValidatorForCategory(std::string category)
return result;
}
ValidateItem* Validator::getValidatorForItem(std::string tag) const
ValidateItem *Validator::getValidatorForItem(std::string_view tag) const
{
ValidateItem* result = nullptr;
ValidateItem *result = nullptr;
std::string cat, item;
std::tie(cat, item) = splitTagName(tag);
auto* cv = getValidatorForCategory(cat);
auto *cv = getValidatorForCategory(cat);
if (cv != nullptr)
result = const_cast<ValidateItem*>(cv->getValidatorForItem(item));
result = const_cast<ValidateItem *>(cv->getValidatorForItem(item));
if (result == nullptr and VERBOSE > 4)
std::cout << "No validator for item " << tag << std::endl;
......@@ -281,7 +281,7 @@ ValidateItem* Validator::getValidatorForItem(std::string tag) const
return result;
}
void Validator::addLinkValidator(ValidateLink&& v)
void Validator::addLinkValidator(ValidateLink &&v)
{
assert(v.mParentKeys.size() == v.mChildKeys.size());
if (v.mParentKeys.size() != v.mChildKeys.size())
......@@ -308,17 +308,17 @@ void Validator::addLinkValidator(ValidateLink&& v)
throw std::runtime_error("unknown child tag _" + v.mChildCategory + '.' + v.mChildKeys[i]);
if (civ->mType == nullptr and piv->mType != nullptr)
const_cast<ValidateItem*>(civ)->mType = piv->mType;
const_cast<ValidateItem *>(civ)->mType = piv->mType;
}
mLinkValidators.emplace_back(std::move(v));
}
std::vector<const ValidateLink*> Validator::getLinksForParent(const std::string& category) const
std::vector<const ValidateLink *> Validator::getLinksForParent(std::string_view category) const
{
std::vector<const ValidateLink*> result;
std::vector<const ValidateLink *> result;
for (auto& l: mLinkValidators)
for (auto &l : mLinkValidators)
{
if (l.mParentCategory == category)
result.push_back(&l);
......@@ -327,11 +327,11 @@ std::vector<const ValidateLink*> Validator::getLinksForParent(const std::string&
return result;
}
std::vector<const ValidateLink*> Validator::getLinksForChild(const std::string& category) const
std::vector<const ValidateLink *> Validator::getLinksForChild(std::string_view category) const
{
std::vector<const ValidateLink*> result;
std::vector<const ValidateLink *> result;
for (auto& l: mLinkValidators)
for (auto &l : mLinkValidators)
{
if (l.mChildCategory == category)
result.push_back(&l);
......@@ -340,7 +340,7 @@ std::vector<const ValidateLink*> Validator::getLinksForChild(const std::string&
return result;
}
void Validator::reportError(const std::string& msg, bool fatal)
void Validator::reportError(const std::string &msg, bool fatal)
{
if (mStrict or fatal)
throw ValidationError(msg);
......@@ -348,4 +348,4 @@ void Validator::reportError(const std::string& msg, bool fatal)
std::cerr << msg << std::endl;
}
}
} // namespace cif
......@@ -1952,6 +1952,58 @@ Atom Structure::getAtomByLabel(const std::string &atomID, const std::string &asy
throw std::out_of_range("Could not find atom with specified label");
}
Atom Structure::getAtomByPosition(Point p) const
{
double distance = std::numeric_limits<double>::max();
size_t index = std::numeric_limits<size_t>::max();
for (size_t i = 0; i < mAtoms.size(); ++i)
{
auto &a = mAtoms.at(i);
auto d = Distance(a.location(), p);
if (d < distance)
{
distance = d;
index = i;
}
}
if (index < mAtoms.size())
return mAtoms.at(index);
return {};
}
Atom Structure::getAtomByPositionAndType(Point p, std::string_view type, std::string_view res_type) const
{
double distance = std::numeric_limits<double>::max();
size_t index = std::numeric_limits<size_t>::max();
for (size_t i = 0; i < mAtoms.size(); ++i)
{
auto &a = mAtoms.at(i);
if (a.labelCompID() != res_type)
continue;
if (a.labelAtomID() != type)
continue;
auto d = Distance(a.location(), p);
if (d < distance)
{
distance = d;
index = i;
}
}
if (index < mAtoms.size())
return mAtoms.at(index);
return {};
}
const Residue &Structure::getResidue(const std::string &asymID, const std::string &compID, int seqID) const
{
for (auto &poly : mPolymers)
......@@ -1988,12 +2040,25 @@ const Residue &Structure::getResidue(const std::string &asymID, const std::strin
throw std::out_of_range("Could not find residue " + asymID + '/' + std::to_string(seqID));
}
const Residue &Structure::getResidue(const std::string &asymID) const
{
for (auto &res : mNonPolymers)
{
if (res.asymID() != asymID)
continue;
return res;
}
throw std::out_of_range("Could not find residue " + asymID);
}
File &Structure::getFile() const
{
return mFile;
}
cif::Category &Structure::category(const char *name) const
cif::Category &Structure::category(std::string_view name) const
{
auto &db = datablock();
return db[name];
......@@ -2411,8 +2476,15 @@ void Structure::changeResidue(const Residue &res, const std::string &newCompound
if (r.size() != 1)
continue;
if (a1 != a2)
r.front()["label_atom_id"] = a2;
if (a2.empty() or a2 == ".")
atomSites.erase(cif::Key("id") == i->id());
else if (a1 != a2)
{
auto ra = r.front();
ra["label_atom_id"] = a2;
ra["auth_atom_id"] = a2;
ra["type_symbol"] = AtomTypeTraits(compound->getAtomByID(a2).typeSymbol).symbol();
}
}
for (auto a : atoms)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment