Commit b85f340c by maarten

chiron, updates

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@219 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent c73e18fc
...@@ -35,7 +35,7 @@ extern int VERBOSE; ...@@ -35,7 +35,7 @@ extern int VERBOSE;
cif::Category atomSite("atom_site"); cif::Category atomSite("atom_site");
size_t nr{}; size_t nr{};
for (myAtom: atoms) for (auto& myAtom: atoms)
{ {
atomSite.push_back({ atomSite.push_back({
{ "group_PDB", "ATOM" }, { "group_PDB", "ATOM" },
...@@ -245,6 +245,8 @@ namespace detail ...@@ -245,6 +245,8 @@ namespace detail
return *this; return *this;
} }
void swap(ItemReference& b);
// operator string() const { return c_str(); } // operator string() const { return c_str(); }
template<typename T> template<typename T>
...@@ -537,6 +539,8 @@ class Row ...@@ -537,6 +539,8 @@ class Row
void assign(const string& name, const string& value, bool emplacing); void assign(const string& name, const string& value, bool emplacing);
void assign(const Item& i, bool emplacing); void assign(const Item& i, bool emplacing);
static void swap(const string& name, ItemRow* a, ItemRow* b);
ItemRow* mData; ItemRow* mData;
}; };
...@@ -1163,5 +1167,11 @@ inline void swap(cif::Row& a, cif::Row& b) ...@@ -1163,5 +1167,11 @@ inline void swap(cif::Row& a, cif::Row& b)
a.swap(b); a.swap(b);
} }
template<>
inline void swap(cif::detail::ItemReference& a, cif::detail::ItemReference& b)
{
a.swap(b);
}
} }
...@@ -337,6 +337,7 @@ class Structure ...@@ -337,6 +337,7 @@ class Structure
// Actions // Actions
void removeAtom(Atom& a); void removeAtom(Atom& a);
void swapAtoms(Atom& a1, Atom& a2); // swap the labels for these atoms
private: private:
friend Polymer; friend Polymer;
......
...@@ -246,6 +246,11 @@ bool ItemReference::empty() const ...@@ -246,6 +246,11 @@ bool ItemReference::empty() const
return c_str() == kEmptyResult; return c_str() == kEmptyResult;
} }
void ItemReference::swap(ItemReference& b)
{
Row::swap(mName, mRow, b.mRow);
}
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -1786,7 +1791,7 @@ void Row::assign(const string& name, const string& value, bool emplacing) ...@@ -1786,7 +1791,7 @@ void Row::assign(const string& name, const string& value, bool emplacing)
auto cat = mData->mCategory; auto cat = mData->mCategory;
auto cix = cat->addColumn(name); auto cix = cat->addColumn(name);
auto& col = cat->mColumns[cix]; auto& col = cat->mColumns[cix];
// auto& db = cat->mDb; auto& db = cat->mDb;
const char* oldValue = nullptr; const char* oldValue = nullptr;
for (auto iv = mData->mValues; iv != nullptr; iv = iv->mNext) for (auto iv = mData->mValues; iv != nullptr; iv = iv->mNext)
...@@ -1812,37 +1817,12 @@ void Row::assign(const string& name, const string& value, bool emplacing) ...@@ -1812,37 +1817,12 @@ void Row::assign(const string& name, const string& value, bool emplacing)
bool reinsert = false; bool reinsert = false;
if (not emplacing) // an update of an Item's value if (not emplacing and // an update of an Item's value
cat->mIndex != nullptr and cat->keyFields().count(name))
{ {
////#if DEBUG reinsert = cat->mIndex->find(mData);
//// if (VERBOSE) if (reinsert)
//// cerr << "reassigning the value of Key field _" << cat->mName << '.' << name << endl; cat->mIndex->erase(mData);
////#endif
// // see if we need to update any child categories that depend on this value
// auto iv = col.mValidator;
// if (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;
//
// auto rows = childCat->find(Key(child->mTag) == oldValue);
// for (auto& cr: rows)
// cr.assign(child->mTag, value, false);
// }
// }
if (cat->mIndex != nullptr and cat->keyFields().count(name))
{
reinsert = cat->mIndex->find(mData);
if (reinsert)
cat->mIndex->erase(mData);
}
} }
// first remove old value with cix // first remove old value with cix
...@@ -1872,11 +1852,6 @@ void Row::assign(const string& name, const string& value, bool emplacing) ...@@ -1872,11 +1852,6 @@ void Row::assign(const string& name, const string& value, bool emplacing)
} }
} }
#if DEBUG
for (auto iv = mData->mValues; iv != nullptr; iv = iv->mNext)
assert(iv != iv->mNext and (iv->mNext == nullptr or iv != iv->mNext->mNext));
#endif
if (not value.empty()) if (not value.empty())
{ {
auto nv = new(value.length()) ItemValue(value.c_str(), cix); auto nv = new(value.length()) ItemValue(value.c_str(), cix);
...@@ -1892,15 +1867,168 @@ void Row::assign(const string& name, const string& value, bool emplacing) ...@@ -1892,15 +1867,168 @@ void Row::assign(const string& name, 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 #if DEBUG
for (auto iv = mData->mValues; iv != nullptr; iv = iv->mNext) cerr << "fixing linked item " << child->mCategory->mName << '.' << child->mTag << endl;
assert(iv != iv->mNext and (iv->mNext == nullptr or iv != iv->mNext->mNext));
#endif #endif
auto rows = childCat->find(Key(child->mTag) == oldValue);
for (auto& cr: rows)
cr.assign(child->mTag, value, false);
}
}
}
void Row::swap(const string& name, ItemRow* a, ItemRow* b)
{
if (a == nullptr or b == nullptr)
throw logic_error("invalid Rows in swap");
assert(a->mCategory == b->mCategory);
if (a->mCategory != b->mCategory)
throw logic_error("Categories not same in swap");
auto cat = a->mCategory;
auto cix = cat->addColumn(name);
auto& col = cat->mColumns[cix];
auto& db = cat->mDb;
// If the field is part of the Key for this Category, remove it from the index
// before updating
bool reinsert = false;
if (cat->mIndex != nullptr and cat->keyFields().count(name))
{
reinsert = true;
cat->mIndex->erase(a);
cat->mIndex->erase(b);
}
ItemValue* ap = nullptr;
ItemValue* ai = nullptr;
ItemValue* bp = nullptr;
ItemValue* bi = nullptr;
if (a->mValues == nullptr)
;
else if (a->mValues->mColumnIndex == cix)
ai = a->mValues;
else
{
ap = a->mValues;
while (ap->mNext != nullptr)
{
if (ap->mNext->mColumnIndex == cix)
{
ai = ap->mNext;
ap->mNext = ai->mNext;
ai->mNext = nullptr;
break;
}
ap = ap->mNext;
}
}
if (b->mValues == nullptr)
;
else if (b->mValues->mColumnIndex == cix)
bi = b->mValues;
else
{
bp = b->mValues;
while (bp->mNext != nullptr)
{
if (bp->mNext->mColumnIndex == cix)
{
bi = bp->mNext;
bp->mNext = bi->mNext;
bi->mNext = nullptr;
break;
}
bp = bp->mNext;
}
}
if (ai != nullptr)
{
if (bp == nullptr)
b->mValues = ai;
else
{
ai->mNext = bp->mNext;
bp->mNext = ai;
}
}
if (bi != nullptr)
{
if (ap == nullptr)
a->mValues = bi;
else
{
bi->mNext = ap->mNext;
ap->mNext = bi;
}
}
if (reinsert) if (reinsert)
cat->mIndex->insert(mData); {
cat->mIndex->insert(a);
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);
}
}
}
} }
void Row::assign(const Item& value, bool emplacing) void Row::assign(const Item& value, bool emplacing)
{ {
assign(value.name(), value.value(), emplacing); assign(value.name(), value.value(), emplacing);
......
...@@ -335,19 +335,19 @@ Atom& Atom::operator=(const Atom& rhs) ...@@ -335,19 +335,19 @@ Atom& Atom::operator=(const Atom& rhs)
} }
template<> template<>
string Atom::property<string>(const std::string& name) const string Atom::property<string>(const string& name) const
{ {
return mImpl->property(name); return mImpl->property(name);
} }
template<> template<>
int Atom::property<int>(const std::string& name) const int Atom::property<int>(const string& name) const
{ {
return stoi(mImpl->property(name)); return stoi(mImpl->property(name));
} }
template<> template<>
float Atom::property<float>(const std::string& name) const float Atom::property<float>(const string& name) const
{ {
return stof(mImpl->property(name)); return stof(mImpl->property(name));
} }
...@@ -811,7 +811,8 @@ struct StructureImpl ...@@ -811,7 +811,8 @@ struct StructureImpl
} }
void removeAtom(Atom& a); void removeAtom(Atom& a);
void swapAtoms(Atom& a1, Atom& a2);
File* mFile; File* mFile;
uint32 mModelNr; uint32 mModelNr;
AtomView mAtoms; AtomView mAtoms;
...@@ -838,6 +839,29 @@ void StructureImpl::removeAtom(Atom& a) ...@@ -838,6 +839,29 @@ void StructureImpl::removeAtom(Atom& a)
mAtoms.erase(remove(mAtoms.begin(), mAtoms.end(), a), mAtoms.end()); mAtoms.erase(remove(mAtoms.begin(), mAtoms.end(), a), mAtoms.end());
} }
void StructureImpl::swapAtoms(Atom& a1, Atom& a2)
{
cif::Datablock& db = *mFile->impl().mDb;
auto& atomSites = db["atom_site"];
auto r1 = atomSites.find(cif::Key("id") == a1.id());
auto r2 = atomSites.find(cif::Key("id") == a2.id());
if (r1.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a1.id() + " is " + to_string(r1.size()));
if (r2.size() != 1)
throw runtime_error("Cannot swap atoms since the number of atoms with id " + a2.id() + " is " + to_string(r2.size()));
auto l1 = r1.front()["label_atom_id"];
auto l2 = r2.front()["label_atom_id"];
swap(l1, l2);
auto l3 = r1.front()["auth_atom_id"];
auto l4 = r2.front()["auth_atom_id"];
swap(l3, l4);
}
Structure::Structure(File& f, uint32 modelNr) Structure::Structure(File& f, uint32 modelNr)
: mImpl(new StructureImpl(*this, f, modelNr)) : mImpl(new StructureImpl(*this, f, modelNr))
{ {
...@@ -1036,4 +1060,9 @@ void Structure::removeAtom(Atom& a) ...@@ -1036,4 +1060,9 @@ void Structure::removeAtom(Atom& a)
mImpl->removeAtom(a); mImpl->removeAtom(a);
} }
void Structure::swapAtoms(Atom& a1, Atom& a2)
{
mImpl->swapAtoms(a1, a2);
}
} }
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