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,15 +63,18 @@ struct ValidateItem
const ValidateType* mType;
cif::iset mEnums;
std::string mDefault;
ValidateItem* mParent = nullptr;
std::set<ValidateItem*>
mChildren;
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
{
return icompare(mTag, rhs.mTag) < 0;
......@@ -108,6 +111,12 @@ struct ValidateCategory
}
};
struct ValidateLink
{
ValidateItem* mParent;
ValidateItem* mChild;
};
// --------------------------------------------------------------------
class Validator
......@@ -130,6 +139,10 @@ class Validator
void addCategoryValidator(ValidateCategory&& v);
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);
std::string dictName() const { return mName; }
......@@ -149,6 +162,7 @@ class Validator
// std::set<uint32> mSubCategories;
std::set<ValidateType> mTypeValidators;
std::set<ValidateCategory> mCategoryValidators;
std::vector<ValidateLink> mLinkValidators;
};
}
......@@ -1446,28 +1446,46 @@ void Category::erase(Row r)
for (auto& col: mColumns)
{
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)
for (auto& l: mValidator->getLinksForParent(mName, col.mName))
{
if (child->mCategory == nullptr)
continue;
assert(l.mParent == col.mValidator);
auto childCat = mDb.get(child->mCategory->mName);
if (not keys.count(col.mName))
continue;
const char* value = r[col.mName].c_str();
auto childCat = mDb.get(l.mChild->mCategory->mName);
if (childCat == nullptr)
continue;
auto rows = childCat->find(Key(child->mTag) == value);
auto rows = childCat->find(Key(l.mChild->mTag) == value);
for (auto& cr: rows)
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)
......@@ -2033,28 +2051,29 @@ void Row::assign(size_t column, const string& value, bool emplacing)
if (reinsert)
cat->mIndex->insert(mData);
// see if we need to update any child categories that depend on this value
auto iv = col.mValidator;
if (not emplacing and iv != nullptr and not iv->mChildren.empty())
{
for (auto child: iv->mChildren)
{
if (child->mCategory == nullptr)
continue;
auto childCat = db.get(child->mCategory->mName);
if (childCat == nullptr)
continue;
#if DEBUG
cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
#endif
auto rows = childCat->find(Key(child->mTag) == oldStrValue);
for (auto& cr: rows)
cr.assign(child->mTag, value, false);
}
}
#pragma warning("doen!")
// // see if we need to update any child categories that depend on this value
// auto iv = col.mValidator;
// if (not emplacing and iv != nullptr and not iv->mChildren.empty())
// {
// for (auto child: iv->mChildren)
// {
// if (child->mCategory == nullptr)
// continue;
//
// auto childCat = db.get(child->mCategory->mName);
// if (childCat == nullptr)
// continue;
//
//#if DEBUG
//cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
//#endif
//
// auto rows = childCat->find(Key(child->mTag) == oldStrValue);
// for (auto& cr: rows)
// cr.assign(child->mTag, value, false);
// }
// }
}
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);
}
// see if we need to update any child categories that depend on these values
auto iv = col.mValidator;
if ((ai != nullptr or bi != nullptr) and
iv != nullptr and not iv->mChildren.empty())
{
for (auto child: iv->mChildren)
{
if (child->mCategory == nullptr)
continue;
auto childCat = db.get(child->mCategory->mName);
if (childCat == nullptr)
continue;
#if DEBUG
cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
#endif
if (ai != nullptr)
{
auto rows = childCat->find(Key(child->mTag) == string(ai->mText));
for (auto& cr: rows)
cr.assign(child->mTag, bi == nullptr ? "" : bi->mText, false);
}
if (bi != nullptr)
{
auto rows = childCat->find(Key(child->mTag) == string(bi->mText));
for (auto& cr: rows)
cr.assign(child->mTag, ai == nullptr ? "" : ai->mText, false);
}
}
}
#pragma warning("doen!")
// // see if we need to update any child categories that depend on these values
// auto iv = col.mValidator;
// if ((ai != nullptr or bi != nullptr) and
// iv != nullptr and not iv->mChildren.empty())
// {
// for (auto child: iv->mChildren)
// {
// if (child->mCategory == nullptr)
// continue;
//
// auto childCat = db.get(child->mCategory->mName);
// if (childCat == nullptr)
// continue;
//
//#if DEBUG
//cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
//#endif
// if (ai != nullptr)
// {
// auto rows = childCat->find(Key(child->mTag) == string(ai->mText));
// for (auto& cr: rows)
// cr.assign(child->mTag, bi == nullptr ? "" : bi->mText, false);
// }
//
// if (bi != nullptr)
// {
// auto rows = childCat->find(Key(child->mTag) == string(bi->mText));
// for (auto& cr: rows)
// cr.assign(child->mTag, ai == nullptr ? "" : ai->mText, false);
// }
// }
// }
}
void Row::assign(const Item& value, bool emplacing)
......
......@@ -666,6 +666,7 @@ struct DictParserDataImpl
// temporary values for constructing dictionaries
vector<ValidateCategory> mCategoryValidators;
map<string,vector<ValidateItem>> mItemValidators;
set<tuple<string,string>> mLinkedItems;
};
DictParser::DictParser(Validator& validator, std::istream& is)
......@@ -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()
if (piv == nullptr)
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
......
......@@ -138,21 +138,25 @@ int ValidateType::compare(const char* a, const char* b) const
// --------------------------------------------------------------------
void ValidateItem::setParent(ValidateItem* parent)
{
mParent = parent;
if (mType == nullptr and mParent != nullptr)
mType = mParent->mType;
if (mParent != nullptr)
{
mParent->mChildren.insert(this);
if (mCategory->mKeys == vector<string>{mTag})
mParent->mForeignKeys.insert(this);
}
}
//void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
//{
//// if (mParent != nullptr and VERBOSE)
//// cerr << "replacing parent in " << mCategory->mName << " from " << mParent->mCategory->mName << " to " << parent->mCategory->mName << endl;
//// mParent = parent;
//
// if (mType == nullptr and parent != nullptr)
// mType = parent->mType;
//
// if (parent != nullptr)
// {
// mLinked.push_back({parent, parentItem, childItem});
//
// parent->mChildren.insert(this);
////
//// if (mCategory->mKeys == vector<string>{mTag})
//// parent->mForeignKeys.insert(this);
// }
//}
void ValidateItem::operator()(string value) const
{
......@@ -258,6 +262,37 @@ ValidateItem* Validator::getValidatorForItem(string tag) const
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)
{
if (mStrict or fatal)
......
......@@ -114,7 +114,7 @@ const set<string> kSupportedRecords{
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()
int residueCount = (residuePerChainCounter[chainID] += 1);
// 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
(chain.mTerIndex > 0 and residueCount >= chain.mTerIndex))
{
......@@ -5099,24 +5099,43 @@ void PDBFileParser::ParseCoordinate(int modelNr)
string groupPDB = mRec->is("ATOM ") ? "ATOM" : "HETATM";
// int serial = vI(7, 11); // 7 - 11 Integer serial Atom serial number.
string name = vS(13, 16); // 13 - 16 Atom name Atom name.
char altLoc = vC(17); // 17 Character altLoc Alternate location indicator.
string resName = vS(18, 20); // 18 - 20 Residue name resName Residue name.
char chainID = vC(22); // 22 Character chainID Chain identifier.
int resSeq = vI(23, 26); // 23 - 26 Integer resSeq Residue sequence number.
char iCode = vC(27); // 27 AChar iCode Code for insertion of residues.
string x = vF(31, 38); // 31 - 38 Real(8.3) x Orthogonal coordinates for X in Angstroms.
string y = vF(39, 46); // 39 - 46 Real(8.3) y Orthogonal coordinates for Y in Angstroms.
string z = vF(47, 54); // 47 - 54 Real(8.3) z Orthogonal coordinates for Z in Angstroms.
string occupancy = vF(55, 60); // 55 - 60 Real(6.2) occupancy Occupancy.
string name = vS(13, 16); // 13 - 16 Atom name Atom name.
char altLoc = vC(17); // 17 Character altLoc Alternate location indicator.
string resName = vS(18, 20); // 18 - 20 Residue name resName Residue name.
char chainID = vC(22); // 22 Character chainID Chain identifier.
int resSeq = vI(23, 26); // 23 - 26 Integer resSeq Residue sequence number.
char iCode = vC(27); // 27 AChar iCode Code for insertion of residues.
string x = vF(31, 38); // 31 - 38 Real(8.3) x Orthogonal coordinates for X in Angstroms.
string y = vF(39, 46); // 39 - 46 Real(8.3) y Orthogonal coordinates for Y in Angstroms.
string z = vF(47, 54); // 47 - 54 Real(8.3) z Orthogonal coordinates for Z in Angstroms.
string occupancy = vF(55, 60); // 55 - 60 Real(6.2) occupancy Occupancy.
string tempFactor = vF(61, 66); // 61 - 66 Real(6.2) tempFactor Temperature factor.
string element = vS(77, 78); // 77 - 78 LString(2) element Element symbol, right-justified.
string element = vS(77, 78); // 77 - 78 LString(2) element Element symbol, right-justified.
string charge = vS(79, 80); // 79 - 80 LString(2) charge Charge on the atom.
string entityId = mAsymID2EntityID[asymId];
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({
{ "group_PDB" , groupPDB },
{ "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