Commit 7f23c842 by Maarten L. Hekkelman

clean-up

parent 74bd2585
...@@ -1876,6 +1876,7 @@ class Category ...@@ -1876,6 +1876,7 @@ class Category
bool hasParent(Row r, const Category& parentCat, const ValidateLink& link) const; bool hasParent(Row r, const Category& parentCat, const ValidateLink& link) const;
bool hasChildren(Row r) const; bool hasChildren(Row r) const;
bool hasParents(Row r) const;
RowSet getChildren(Row r, Category& childCat); RowSet getChildren(Row r, Category& childCat);
RowSet getChildren(Row r, const char* childCat); RowSet getChildren(Row r, const char* childCat);
......
...@@ -484,6 +484,8 @@ class Structure ...@@ -484,6 +484,8 @@ class Structure
const std::vector<Residue>& getNonPolymers() const { return mNonPolymers; } const std::vector<Residue>& getNonPolymers() const { return mNonPolymers; }
const std::vector<Residue>& getBranchResidues() const { return mBranchResidues; } const std::vector<Residue>& getBranchResidues() const { return mBranchResidues; }
void cleanupEmptyCategories();
private: private:
friend Polymer; friend Polymer;
friend Residue; friend Residue;
......
...@@ -1915,6 +1915,37 @@ bool Category::hasChildren(Row r) const ...@@ -1915,6 +1915,37 @@ bool Category::hasChildren(Row r) const
return result; return result;
} }
bool Category::hasParents(Row r) const
{
assert(mValidator != nullptr);
assert(mCatValidator != nullptr);
bool result = false;
for (auto& link: mValidator->getLinksForChild(mName))
{
auto parentCat = mDb.get(link->mParentCategory);
if (parentCat == nullptr)
continue;
Condition cond;
for (size_t ix = 0; ix < link->mChildKeys.size(); ++ix)
{
const char* value = r[link->mChildKeys[ix]].c_str();
cond = std::move(cond) && (Key(link->mParentKeys[ix]) == value);
}
result = not parentCat->find(std::move(cond)).empty();
if (result)
break;
}
return result;
}
RowSet Category::getChildren(Row r, const char* childCat) RowSet Category::getChildren(Row r, const char* childCat)
{ {
return getChildren(r, mDb[childCat]); return getChildren(r, mDb[childCat]);
......
...@@ -65,6 +65,7 @@ std::string to_string(BondType bondType) ...@@ -65,6 +65,7 @@ std::string to_string(BondType bondType)
case BondType::delo: return "delo"; case BondType::delo: return "delo";
case BondType::pi: return "pi"; case BondType::pi: return "pi";
} }
throw std::invalid_argument("Invalid bondType");
} }
BondType from_string(const std::string& bondType) BondType from_string(const std::string& bondType)
......
...@@ -2291,6 +2291,7 @@ void Structure::changeResidue(const Residue& res, const std::string& newCompound ...@@ -2291,6 +2291,7 @@ void Structure::changeResidue(const Residue& res, const std::string& newCompound
for (auto &nps : pdbxNonPolyScheme.find("asym_id"_key == asymID)) for (auto &nps : pdbxNonPolyScheme.find("asym_id"_key == asymID))
{ {
nps.assign("mon_id", newCompound, true); nps.assign("mon_id", newCompound, true);
nps.assign("auth_mon_id", newCompound, true);
nps.assign("entity_id", entityID, true); nps.assign("entity_id", entityID, true);
} }
...@@ -2338,7 +2339,69 @@ void Structure::changeResidue(const Residue& res, const std::string& newCompound ...@@ -2338,7 +2339,69 @@ void Structure::changeResidue(const Residue& res, const std::string& newCompound
} }
for (auto a: atoms) for (auto a: atoms)
{
atomSites.update_value(cif::Key("id") == a.id(), "label_comp_id", newCompound); atomSites.update_value(cif::Key("id") == a.id(), "label_comp_id", newCompound);
atomSites.update_value(cif::Key("id") == a.id(), "auth_comp_id", newCompound);
}
}
void Structure::cleanupEmptyCategories()
{
using namespace cif::literals;
cif::Datablock& db = *mFile.impl().mDb;
auto &atomSite = db["atom_site"];
// Remove chem_comp's for which there are no atoms at all
auto &chem_comp = db["chem_comp"];
cif::RowSet obsoleteChemComps(chem_comp);
for (auto chemComp : chem_comp)
{
std::string compID = chemComp["id"].as<std::string>();
if (atomSite.exists("label_comp_id"_key == compID or "auth_comp_id"_key == compID))
continue;
obsoleteChemComps.push_back(chemComp);
}
for (auto chemComp : obsoleteChemComps)
chem_comp.erase(chemComp);
// similarly, remove entities not referenced by any atom
auto &entities = db["entity"];
cif::RowSet obsoleteEntities(entities);
for (auto entity : entities)
{
std::string entityID = entity["id"].as<std::string>();
if (atomSite.exists("label_entity_id"_key == entityID))
continue;
obsoleteEntities.push_back(entity);
}
for (auto entity : obsoleteEntities)
entities.erase(entity);
// the rest?
for (const char *cat : { "pdbx_entity_nonpoly" })
{
auto &category = db[cat];
cif::RowSet empty(category);
for (auto row : category)
{
if (not category.hasChildren(row) and not category.hasParents(row))
empty.push_back(row);
}
for (auto row : empty)
category.erase(row);
}
} }
} }
...@@ -24,6 +24,8 @@ int main(int argc, char* argv[]) ...@@ -24,6 +24,8 @@ int main(int argc, char* argv[])
auto &res = structure.getResidue("B", "REA"); auto &res = structure.getResidue("B", "REA");
structure.changeResidue(res, "RXA", {}); structure.changeResidue(res, "RXA", {});
structure.cleanupEmptyCategories();
f.file().save(std::cout); f.file().save(std::cout);
return 0; return 0;
......
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