Commit 95d0d557 by maarten

diverse bugs, refactored links

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@388 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent ec09e7ba
...@@ -63,14 +63,17 @@ struct ValidateItem ...@@ -63,14 +63,17 @@ struct ValidateItem
const ValidateType* mType; const ValidateType* mType;
cif::iset mEnums; cif::iset mEnums;
std::string mDefault; std::string mDefault;
ValidateItem* mParent = nullptr;
std::set<ValidateItem*>
mChildren;
ValidateCategory* mCategory = nullptr; ValidateCategory* mCategory = nullptr;
std::set<ValidateItem*>
mForeignKeys;
void setParent(ValidateItem* parent); // ItemLinked is used for non-key links
struct ItemLinked
{
ValidateItem* mParent;
std::string mParentItem;
std::string mChildItem;
};
std::vector<ItemLinked> mLinked;
bool operator<(const ValidateItem& rhs) const bool operator<(const ValidateItem& rhs) const
{ {
...@@ -108,6 +111,12 @@ struct ValidateCategory ...@@ -108,6 +111,12 @@ struct ValidateCategory
} }
}; };
struct ValidateLink
{
ValidateItem* mParent;
ValidateItem* mChild;
};
// -------------------------------------------------------------------- // --------------------------------------------------------------------
class Validator class Validator
...@@ -130,6 +139,10 @@ class Validator ...@@ -130,6 +139,10 @@ class Validator
void addCategoryValidator(ValidateCategory&& v); void addCategoryValidator(ValidateCategory&& v);
const ValidateCategory* getValidatorForCategory(std::string category) const; const ValidateCategory* getValidatorForCategory(std::string category) const;
void addLinkValidator(ValidateLink&& v);
std::vector<ValidateLink> getLinksForParent(std::string category, std::string item) const;
std::vector<ValidateLink> getLinksForChild(std::string category, std::string item) const;
void reportError(const std::string& msg, bool fatal); void reportError(const std::string& msg, bool fatal);
std::string dictName() const { return mName; } std::string dictName() const { return mName; }
...@@ -149,6 +162,7 @@ class Validator ...@@ -149,6 +162,7 @@ class Validator
// std::set<uint32> mSubCategories; // std::set<uint32> mSubCategories;
std::set<ValidateType> mTypeValidators; std::set<ValidateType> mTypeValidators;
std::set<ValidateCategory> mCategoryValidators; std::set<ValidateCategory> mCategoryValidators;
std::vector<ValidateLink> mLinkValidators;
}; };
} }
...@@ -1446,28 +1446,46 @@ void Category::erase(Row r) ...@@ -1446,28 +1446,46 @@ void Category::erase(Row r)
for (auto& col: mColumns) for (auto& col: mColumns)
{ {
auto iv = col.mValidator; for (auto& l: mValidator->getLinksForParent(mName, col.mName))
if (iv == nullptr or iv->mChildren.empty()) {
continue; assert(l.mParent == col.mValidator);
if (not keys.count(col.mName)) if (not keys.count(col.mName))
continue; continue;
const char* value = r[col.mName].c_str(); const char* value = r[col.mName].c_str();
for (auto child: iv->mChildren) auto childCat = mDb.get(l.mChild->mCategory->mName);
{
if (child->mCategory == nullptr)
continue;
auto childCat = mDb.get(child->mCategory->mName);
if (childCat == nullptr) if (childCat == nullptr)
continue; continue;
auto rows = childCat->find(Key(child->mTag) == value); auto rows = childCat->find(Key(l.mChild->mTag) == value);
for (auto& cr: rows) for (auto& cr: rows)
childCat->erase(cr); childCat->erase(cr);
} }
// auto iv = col.mValidator;
// if (iv == nullptr or iv->mChildren.empty())
// continue;
//
// if (not keys.count(col.mName))
// continue;
//
// const char* value = r[col.mName].c_str();
//
// for (auto child: iv->mChildren)
// {
// if (child->mCategory == nullptr)
// continue;
//
// auto childCat = mDb.get(child->mCategory->mName);
// if (childCat == nullptr)
// continue;
//
// auto rows = childCat->find(Key(child->mTag) == value);
// for (auto& cr: rows)
// childCat->erase(cr);
// }
} }
if (mHead == nullptr) if (mHead == nullptr)
...@@ -2033,28 +2051,29 @@ void Row::assign(size_t column, const string& value, bool emplacing) ...@@ -2033,28 +2051,29 @@ void Row::assign(size_t column, const string& value, bool emplacing)
if (reinsert) if (reinsert)
cat->mIndex->insert(mData); cat->mIndex->insert(mData);
// see if we need to update any child categories that depend on this value #pragma warning("doen!")
auto iv = col.mValidator; // // see if we need to update any child categories that depend on this value
if (not emplacing and iv != nullptr and not iv->mChildren.empty()) // auto iv = col.mValidator;
{ // if (not emplacing and iv != nullptr and not iv->mChildren.empty())
for (auto child: iv->mChildren) // {
{ // for (auto child: iv->mChildren)
if (child->mCategory == nullptr) // {
continue; // if (child->mCategory == nullptr)
// continue;
auto childCat = db.get(child->mCategory->mName); //
if (childCat == nullptr) // auto childCat = db.get(child->mCategory->mName);
continue; // if (childCat == nullptr)
// continue;
#if DEBUG //
cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl; //#if DEBUG
#endif //cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
//#endif
auto rows = childCat->find(Key(child->mTag) == oldStrValue); //
for (auto& cr: rows) // auto rows = childCat->find(Key(child->mTag) == oldStrValue);
cr.assign(child->mTag, value, false); // for (auto& cr: rows)
} // cr.assign(child->mTag, value, false);
} // }
// }
} }
void Row::swap(size_t cix, ItemRow* a, ItemRow* b) void Row::swap(size_t cix, ItemRow* a, ItemRow* b)
...@@ -2156,38 +2175,39 @@ void Row::swap(size_t cix, ItemRow* a, ItemRow* b) ...@@ -2156,38 +2175,39 @@ void Row::swap(size_t cix, ItemRow* a, ItemRow* b)
cat->mIndex->insert(b); cat->mIndex->insert(b);
} }
// see if we need to update any child categories that depend on these values #pragma warning("doen!")
auto iv = col.mValidator; // // see if we need to update any child categories that depend on these values
if ((ai != nullptr or bi != nullptr) and // auto iv = col.mValidator;
iv != nullptr and not iv->mChildren.empty()) // if ((ai != nullptr or bi != nullptr) and
{ // iv != nullptr and not iv->mChildren.empty())
for (auto child: iv->mChildren) // {
{ // for (auto child: iv->mChildren)
if (child->mCategory == nullptr) // {
continue; // if (child->mCategory == nullptr)
// continue;
auto childCat = db.get(child->mCategory->mName); //
if (childCat == nullptr) // auto childCat = db.get(child->mCategory->mName);
continue; // if (childCat == nullptr)
// continue;
#if DEBUG //
cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl; //#if DEBUG
#endif //cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
if (ai != nullptr) //#endif
{ // if (ai != nullptr)
auto rows = childCat->find(Key(child->mTag) == string(ai->mText)); // {
for (auto& cr: rows) // auto rows = childCat->find(Key(child->mTag) == string(ai->mText));
cr.assign(child->mTag, bi == nullptr ? "" : bi->mText, false); // for (auto& cr: rows)
} // cr.assign(child->mTag, bi == nullptr ? "" : bi->mText, false);
// }
if (bi != nullptr) //
{ // if (bi != nullptr)
auto rows = childCat->find(Key(child->mTag) == string(bi->mText)); // {
for (auto& cr: rows) // auto rows = childCat->find(Key(child->mTag) == string(bi->mText));
cr.assign(child->mTag, ai == nullptr ? "" : ai->mText, false); // for (auto& cr: rows)
} // cr.assign(child->mTag, ai == nullptr ? "" : ai->mText, false);
} // }
} // }
// }
} }
void Row::assign(const Item& value, bool emplacing) void Row::assign(const Item& value, bool emplacing)
......
...@@ -666,6 +666,7 @@ struct DictParserDataImpl ...@@ -666,6 +666,7 @@ struct DictParserDataImpl
// temporary values for constructing dictionaries // temporary values for constructing dictionaries
vector<ValidateCategory> mCategoryValidators; vector<ValidateCategory> mCategoryValidators;
map<string,vector<ValidateItem>> mItemValidators; map<string,vector<ValidateItem>> mItemValidators;
set<tuple<string,string>> mLinkedItems;
}; };
DictParser::DictParser(Validator& validator, std::istream& is) DictParser::DictParser(Validator& validator, std::istream& is)
...@@ -838,6 +839,16 @@ void DictParser::parseSaveFrame() ...@@ -838,6 +839,16 @@ void DictParser::parseSaveFrame()
// ... // ...
} }
} }
// collect the dict from our dataBlock and construct validators
for (auto i: dict["item_linked"])
{
string childTagName, parentTagName;
cif::tie(childTagName, parentTagName) = i.get("child_name", "parent_name");
mImpl->mLinkedItems.emplace(childTagName, parentTagName);
}
} }
} }
...@@ -861,7 +872,26 @@ void DictParser::linkItems() ...@@ -861,7 +872,26 @@ void DictParser::linkItems()
if (piv == nullptr) if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified"); error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
civ->setParent(piv); // civ->setParent(piv);
// civ->addLinked(piv, piv->mTag, civ->mTag);
mValidator.addLinkValidator({piv, civ});
}
for (auto li: mImpl->mLinkedItems)
{
string child, parent;
std::tie(child, parent) = li;
auto civ = mValidator.getValidatorForItem(child);
if (civ == nullptr)
error("in pdbx_item_linked_group_list, item '" + child + "' is not specified");
auto piv = mValidator.getValidatorForItem(parent);
if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
// civ->addLinked(piv, piv->mTag, civ->mTag);
mValidator.addLinkValidator({piv, civ});
} }
// now make sure the itemType is specified for all itemValidators // now make sure the itemType is specified for all itemValidators
......
...@@ -138,21 +138,25 @@ int ValidateType::compare(const char* a, const char* b) const ...@@ -138,21 +138,25 @@ int ValidateType::compare(const char* a, const char* b) const
// -------------------------------------------------------------------- // --------------------------------------------------------------------
void ValidateItem::setParent(ValidateItem* parent) //void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
{ //{
mParent = parent; //// if (mParent != nullptr and VERBOSE)
//// cerr << "replacing parent in " << mCategory->mName << " from " << mParent->mCategory->mName << " to " << parent->mCategory->mName << endl;
if (mType == nullptr and mParent != nullptr) //// mParent = parent;
mType = mParent->mType; //
// if (mType == nullptr and parent != nullptr)
if (mParent != nullptr) // mType = parent->mType;
{ //
mParent->mChildren.insert(this); // if (parent != nullptr)
// {
if (mCategory->mKeys == vector<string>{mTag}) // mLinked.push_back({parent, parentItem, childItem});
mParent->mForeignKeys.insert(this); //
} // parent->mChildren.insert(this);
} ////
//// if (mCategory->mKeys == vector<string>{mTag})
//// parent->mForeignKeys.insert(this);
// }
//}
void ValidateItem::operator()(string value) const void ValidateItem::operator()(string value) const
{ {
...@@ -258,6 +262,37 @@ ValidateItem* Validator::getValidatorForItem(string tag) const ...@@ -258,6 +262,37 @@ ValidateItem* Validator::getValidatorForItem(string tag) const
return result; return result;
} }
void Validator::addLinkValidator(ValidateLink&& v)
{
if (v.mChild->mType == nullptr and v.mParent->mType != nullptr)
v.mChild->mType = v.mParent->mType;
mLinkValidators.emplace_back(move(v));
}
vector<ValidateLink> Validator::getLinksForParent(string category, string item) const
{
vector<ValidateLink> result;
for (auto& l: mLinkValidators)
{
if (l.mParent->mCategory->mName == category and l.mParent->mTag == item)
result.push_back(l);
}
return result;
}
vector<ValidateLink> Validator::getLinksForChild(string category, string item) const
{
vector<ValidateLink> result;
for (auto& l: mLinkValidators)
{
if (l.mChild->mCategory->mName == category and l.mChild->mTag == item)
result.push_back(l);
}
return result;
}
void Validator::reportError(const string& msg, bool fatal) void Validator::reportError(const string& msg, bool fatal)
{ {
if (mStrict or fatal) if (mStrict or fatal)
......
...@@ -114,7 +114,7 @@ const set<string> kSupportedRecords{ ...@@ -114,7 +114,7 @@ const set<string> kSupportedRecords{
bool isWater(const string& resname) bool isWater(const string& resname)
{ {
return resname == "HOH" or resname == "H2O" or resname == "OH2" or resname == "WAT" or resname == "DOD"; return resname == "HOH" or resname == "H2O" or resname == "OH2" or resname == "WAT" or resname == "DOD" or resname == "WAT";
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -3489,7 +3489,7 @@ void PDBFileParser::ConstructEntities() ...@@ -3489,7 +3489,7 @@ void PDBFileParser::ConstructEntities()
int residueCount = (residuePerChainCounter[chainID] += 1); int residueCount = (residuePerChainCounter[chainID] += 1);
// There appears to be a program that writes out HETATM records as ATOM records.... // There appears to be a program that writes out HETATM records as ATOM records....
if (r->is("HETATM") or if (not (CompoundFactory::instance().isKnownPeptide(resName) or CompoundFactory::instance().isKnownBase(resName)) or
terminatedChains.count(chainID) or terminatedChains.count(chainID) or
(chain.mTerIndex > 0 and residueCount >= chain.mTerIndex)) (chain.mTerIndex > 0 and residueCount >= chain.mTerIndex))
{ {
...@@ -5117,6 +5117,25 @@ void PDBFileParser::ParseCoordinate(int modelNr) ...@@ -5117,6 +5117,25 @@ void PDBFileParser::ParseCoordinate(int modelNr)
charge = pdb2cifCharge(charge); charge = pdb2cifCharge(charge);
if (CompoundFactory::instance().isKnownPeptide(resName) or CompoundFactory::instance().isKnownBase(resName))
{
if (groupPDB == "HETATM")
{
if (VERBOSE)
cerr << "Changing atom from HETATM to ATOM at line " << mRec->mLineNr << endl;
groupPDB = "ATOM";
}
}
else
{
if (groupPDB == "ATOM")
{
if (VERBOSE)
cerr << "Changing atom from ATOM to HETATM at line " << mRec->mLineNr << endl;
groupPDB = "HETATM";
}
}
getCategory("atom_site")->emplace({ getCategory("atom_site")->emplace({
{ "group_PDB" , groupPDB }, { "group_PDB" , groupPDB },
{ "id", mAtomId }, { "id", mAtomId },
......
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