Commit 4c99710f by Maarten L. Hekkelman

Refactored iterators (Category, Row)

const versions of find
parent 59865cdb
...@@ -61,11 +61,12 @@ class File; ...@@ -61,11 +61,12 @@ class File;
class Atom class Atom
{ {
public: public:
// Atom(const structure& s, const std::string& id);
Atom(); Atom();
Atom(struct AtomImpl *impl); Atom(struct AtomImpl *impl);
Atom(const Atom &rhs); Atom(const Atom &rhs);
Atom(cif::Datablock &db, cif::Row &row);
// a special constructor to create symmetry copies // a special constructor to create symmetry copies
Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation); Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation);
...@@ -495,13 +496,13 @@ class Structure ...@@ -495,13 +496,13 @@ class Structure
/// \return The ID of the created entity /// \return The ID of the created entity
std::string createNonPolyEntity(const std::string &mon_id); std::string createNonPolyEntity(const std::string &mon_id);
/// \brief Create a new NonPolymer struct_asym with atoms constructed from \a atom_data, returns asym_id. /// \brief Create a new NonPolymer struct_asym with atoms constructed from \a atoms, returns asym_id.
/// This method assumes you are copying data from one cif file to another. /// This method assumes you are copying data from one cif file to another.
/// ///
/// \param entity_id The entity ID of the new nonpoly /// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of atom_site rows containing the data. /// \param atoms The array of atom_site rows containing the data.
/// \return The newly create asym ID /// \return The newly create asym ID
std::string createNonpoly(const std::string &entity_id, const std::vector<cif::Row> &atoms); std::string createNonpoly(const std::string &entity_id, const std::vector<mmcif::Atom> &atoms);
/// \brief To sort the atoms in order of model > asym-id > res-id > atom-id /// \brief To sort the atoms in order of model > asym-id > res-id > atom-id
/// Will asssign new atom_id's to all atoms. Be carefull /// Will asssign new atom_id's to all atoms. Be carefull
......
...@@ -2821,7 +2821,7 @@ Row::~Row() ...@@ -2821,7 +2821,7 @@ Row::~Row()
{ {
} }
void Row::next() void Row::next() const
{ {
if (mData != nullptr) if (mData != nullptr)
mData = mData->mNext; mData = mData->mNext;
...@@ -3263,7 +3263,7 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b) ...@@ -3263,7 +3263,7 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b)
} }
} }
std::vector<conditional_iterator_proxy<Row>> rs; std::vector<conditional_iterator_proxy<Category>> rs;
// first find the respective rows, then flip values, otherwise you won't find them anymore! // first find the respective rows, then flip values, otherwise you won't find them anymore!
for (size_t ab = 0; ab < 2; ++ab) for (size_t ab = 0; ab < 2; ++ab)
......
...@@ -368,7 +368,7 @@ CompoundFactoryImpl::CompoundFactoryImpl(const std::string &file, std::shared_pt ...@@ -368,7 +368,7 @@ CompoundFactoryImpl::CompoundFactoryImpl(const std::string &file, std::shared_pt
{ {
auto &chemComp = (*compList)["chem_comp"]; auto &chemComp = (*compList)["chem_comp"];
for (const auto &[id, name, group] : chemComp.rows<std::string, std::string, std::string>({"id", "name", "group"})) for (const auto &[id, name, group] : chemComp.rows<std::string, std::string, std::string>("id", "name", "group"))
{ {
std::string type; std::string type;
......
...@@ -230,7 +230,7 @@ void FileImpl::save(const std::string &p) ...@@ -230,7 +230,7 @@ void FileImpl::save(const std::string &p)
struct AtomImpl struct AtomImpl
{ {
AtomImpl(const AtomImpl &i) AtomImpl(const AtomImpl &i)
: mFile(i.mFile) : mDb(i.mDb)
, mID(i.mID) , mID(i.mID)
, mType(i.mType) , mType(i.mType)
, mAtomID(i.mAtomID) , mAtomID(i.mAtomID)
...@@ -250,13 +250,12 @@ struct AtomImpl ...@@ -250,13 +250,12 @@ struct AtomImpl
{ {
} }
AtomImpl(const File &f, const std::string &id) AtomImpl(cif::Datablock &db, const std::string &id)
: mFile(f) : mDb(db)
, mID(id) , mID(id)
, mRefcount(1) , mRefcount(1)
, mCompound(nullptr) , mCompound(nullptr)
{ {
auto &db = *mFile.impl().mDb;
auto &cat = db["atom_site"]; auto &cat = db["atom_site"];
mRow = cat[cif::Key("id") == mID]; mRow = cat[cif::Key("id") == mID];
...@@ -264,8 +263,18 @@ struct AtomImpl ...@@ -264,8 +263,18 @@ struct AtomImpl
prefetch(); prefetch();
} }
AtomImpl(const File &f, const std::string &id, cif::Row row) AtomImpl(cif::Datablock &db, cif::Row &row)
: mFile(f) : mDb(db)
, mID(row["id"].as<std::string>())
, mRow(row)
, mRefcount(1)
, mCompound(nullptr)
{
prefetch();
}
AtomImpl(cif::Datablock &db, const std::string &id, cif::Row row)
: mDb(db)
, mID(id) , mID(id)
, mRefcount(1) , mRefcount(1)
, mRow(row) , mRow(row)
...@@ -274,21 +283,8 @@ struct AtomImpl ...@@ -274,21 +283,8 @@ struct AtomImpl
prefetch(); prefetch();
} }
// AtomImpl(const AtomImpl& impl, const Point& d, const clipper::RTop_orth& rt)
// : mFile(impl.mFile), mID(impl.mID), mType(impl.mType), mAtomID(impl.mAtomID)
// , mCompID(impl.mCompID), mAsymID(impl.mAsymID), mSeqID(impl.mSeqID)
// , mAltID(impl.mAltID), mLocation(impl.mLocation), mRefcount(1)
// , mRow(impl.mRow), mCompound(impl.mCompound), mRadius(impl.mRadius)
// , mCachedProperties(impl.mCachedProperties)
// , mSymmetryCopy(true), mRTop(rt), mD(d)
// {
// mLocation += d;
// mLocation = ((clipper::Coord_orth)mLocation).transform(rt);
// mLocation -= d;
// }
AtomImpl(const AtomImpl &impl, const Point &loc, const std::string &sym_op) AtomImpl(const AtomImpl &impl, const Point &loc, const std::string &sym_op)
: mFile(impl.mFile) : mDb(impl.mDb)
, mID(impl.mID) , mID(impl.mID)
, mType(impl.mType) , mType(impl.mType)
, mAtomID(impl.mAtomID) , mAtomID(impl.mAtomID)
...@@ -341,16 +337,19 @@ struct AtomImpl ...@@ -341,16 +337,19 @@ struct AtomImpl
bool getAnisoU(float anisou[6]) const bool getAnisoU(float anisou[6]) const
{ {
auto &db = *mFile.impl().mDb;
auto &cat = db["atom_site_anisotrop"];
auto r = cat[cif::Key("id") == mID];
bool result = false; bool result = false;
if (not r.empty()) auto cat = mDb.get("atom_site_anisotrop");
if (cat)
{ {
result = true; auto r = cat->find1(cif::Key("id") == mID);
cif::tie(anisou[0], anisou[1], anisou[2], anisou[3], anisou[4], anisou[5]) =
r.get("U[1][1]", "U[1][2]", "U[1][3]", "U[2][2]", "U[2][3]", "U[3][3]"); if (not r.empty())
{
result = true;
cif::tie(anisou[0], anisou[1], anisou[2], anisou[3], anisou[4], anisou[5]) =
r.get("U[1][1]", "U[1][2]", "U[1][3]", "U[2][2]", "U[2][3]", "U[3][3]");
}
} }
return result; return result;
...@@ -445,7 +444,7 @@ struct AtomImpl ...@@ -445,7 +444,7 @@ struct AtomImpl
std::swap(mAtomID, b.mAtomID); std::swap(mAtomID, b.mAtomID);
} }
const File &mFile; const cif::Datablock &mDb;
std::string mID; std::string mID;
AtomType mType; AtomType mType;
...@@ -487,6 +486,11 @@ Atom::Atom(AtomImpl *impl) ...@@ -487,6 +486,11 @@ Atom::Atom(AtomImpl *impl)
{ {
} }
Atom::Atom(cif::Datablock &db, cif::Row &row)
: mImpl_(new AtomImpl(db, row))
{
}
AtomImpl *Atom::impl() AtomImpl *Atom::impl()
{ {
if (mImpl_ == nullptr) if (mImpl_ == nullptr)
...@@ -545,9 +549,12 @@ const cif::Row Atom::getRow() const ...@@ -545,9 +549,12 @@ const cif::Row Atom::getRow() const
const cif::Row Atom::getRowAniso() const const cif::Row Atom::getRowAniso() const
{ {
auto &db = *mImpl_->mFile.impl().mDb; auto &db = mImpl_->mDb;
auto &cat = db["atom_site_anisotrop"]; auto cat = db.get("atom_site_anisotrop");
return cat[cif::Key("id") == mImpl_->mID]; if (not cat)
return {};
else
return cat->find1(cif::Key("id") == mImpl_->mID);
} }
template <> template <>
...@@ -758,7 +765,7 @@ bool Atom::isWater() const ...@@ -758,7 +765,7 @@ bool Atom::isWater() const
bool Atom::operator==(const Atom &rhs) const bool Atom::operator==(const Atom &rhs) const
{ {
return impl() == rhs.impl() or return impl() == rhs.impl() or
(&impl()->mFile == &rhs.impl()->mFile and impl()->mID == rhs.impl()->mID); (&impl()->mDb == &rhs.impl()->mDb and impl()->mID == rhs.impl()->mID);
} }
// clipper::Atom Atom::toClipper() const // clipper::Atom Atom::toClipper() const
...@@ -1821,7 +1828,7 @@ Structure::Structure(File &f, size_t modelNr, StructureOpenOptions options) ...@@ -1821,7 +1828,7 @@ Structure::Structure(File &f, size_t modelNr, StructureOpenOptions options)
if ((options bitand StructureOpenOptions::SkipHydrogen) and type_symbol == "H") if ((options bitand StructureOpenOptions::SkipHydrogen) and type_symbol == "H")
continue; continue;
mAtoms.emplace_back(new AtomImpl(f, id, a)); mAtoms.emplace_back(new AtomImpl(*db, id, a));
} }
loadData(); loadData();
...@@ -2445,7 +2452,7 @@ std::string Structure::createNonPolyEntity(const std::string &comp_id) ...@@ -2445,7 +2452,7 @@ std::string Structure::createNonPolyEntity(const std::string &comp_id)
return insertCompound(comp_id, true); return insertCompound(comp_id, true);
} }
std::string Structure::createNonpoly(const std::string &entity_id, const std::vector<cif::Row> &atoms) std::string Structure::createNonpoly(const std::string &entity_id, const std::vector<mmcif::Atom> &atoms)
{ {
using namespace cif::literals; using namespace cif::literals;
...@@ -2468,26 +2475,26 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve ...@@ -2468,26 +2475,26 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
for (auto& atom: atoms) for (auto& atom: atoms)
{ {
atom_site.emplace({ atom_site.emplace({
{ "group_PDB", atom["group_PDB"].as<std::string>() }, { "group_PDB", atom.property<std::string>("group_PDB") },
{ "id", atom_site.getUniqueID("") }, { "id", atom_site.getUniqueID("") },
{ "type_symbol", atom["type_symbol"].as<std::string>() }, { "type_symbol", atom.property<std::string>("type_symbol") },
{ "label_atom_id", atom["label_atom_id"].as<std::string>() }, { "label_atom_id", atom.property<std::string>("label_atom_id") },
{ "label_alt_id", atom["label_alt_id"].as<std::string>() }, { "label_alt_id", atom.property<std::string>("label_alt_id") },
{ "label_comp_id", comp_id }, { "label_comp_id", comp_id },
{ "label_asym_id", asym_id }, { "label_asym_id", asym_id },
{ "label_entity_id", entity_id }, { "label_entity_id", entity_id },
{ "label_seq_id", "." }, { "label_seq_id", "." },
{ "pdbx_PDB_ins_code", "" }, { "pdbx_PDB_ins_code", "" },
{ "Cartn_x", atom["Cartn_x"].as<std::string>() }, { "Cartn_x", atom.property<std::string>("Cartn_x") },
{ "Cartn_y", atom["Cartn_y"].as<std::string>() }, { "Cartn_y", atom.property<std::string>("Cartn_y") },
{ "Cartn_z", atom["Cartn_z"].as<std::string>() }, { "Cartn_z", atom.property<std::string>("Cartn_z") },
{ "occupancy", atom["occupancy"].as<std::string>() }, { "occupancy", atom.property<std::string>("occupancy") },
{ "B_iso_or_equiv", atom["B_iso_or_equiv"].as<std::string>() }, { "B_iso_or_equiv", atom.property<std::string>("B_iso_or_equiv") },
{ "pdbx_formal_charge", atom["pdbx_formal_charge"].as<std::string>() }, { "pdbx_formal_charge", atom.property<std::string>("pdbx_formal_charge") },
{ "auth_seq_id", "" }, { "auth_seq_id", "" },
{ "auth_comp_id", comp_id }, { "auth_comp_id", comp_id },
{ "auth_asym_id", asym_id }, { "auth_asym_id", asym_id },
{ "auth_atom_id", atom["label_atom_id"].as<std::string>() }, { "auth_atom_id", atom.property<std::string>("label_atom_id") },
{ "pdbx_PDB_model_num", 1 } { "pdbx_PDB_model_num", 1 }
}); });
} }
...@@ -2568,7 +2575,7 @@ void Structure::cleanupEmptyCategories() ...@@ -2568,7 +2575,7 @@ void Structure::cleanupEmptyCategories()
{ {
// is this correct? // is this correct?
std::set<std::string> asym_ids; std::set<std::string> asym_ids;
for (const auto &[asym_id] : db["pdbx_branch_scheme"].find<std::string>("entity_id"_key == id, {"asym_id"})) for (const auto &[ asym_id ] : db["pdbx_branch_scheme"].find<std::string>("entity_id"_key == id, "asym_id"))
asym_ids.insert(asym_id); asym_ids.insert(asym_id);
count = asym_ids.size(); count = asym_ids.size();
} }
......
...@@ -86,10 +86,13 @@ HETATM C CHD . ? -4.342 36.262 -3.536 1.00 8.00 ? ...@@ -86,10 +86,13 @@ HETATM C CHD . ? -4.342 36.262 -3.536 1.00 8.00 ?
# that's enough to test with # that's enough to test with
)"_cf; )"_cf;
auto &atom_site = atoms["HEM"]["atom_site"]; auto &hem_data = atoms["HEM"];
auto &atom_site = hem_data["atom_site"];
auto hem_atoms = atom_site.rows(); auto hem_atoms = atom_site.rows();
std::vector<cif::Row> atom_data(hem_atoms.begin(), hem_atoms.end()); std::vector<mmcif::Atom> atom_data;
for (auto &hem_atom: hem_atoms)
atom_data.emplace_back(hem_data, hem_atom);
structure.createNonpoly(entity_id, atom_data); structure.createNonpoly(entity_id, atom_data);
......
...@@ -1158,7 +1158,7 @@ _test.name ...@@ -1158,7 +1158,7 @@ _test.name
// query tests // query tests
for (const auto& [id, name]: db["test"].rows<int, std::optional<std::string>>({ "id", "name" })) for (const auto& [id, name]: db["test"].rows<int, std::optional<std::string>>("id", "name"))
{ {
switch (id) switch (id)
{ {
...@@ -1193,7 +1193,7 @@ _test.name ...@@ -1193,7 +1193,7 @@ _test.name
auto& db = f.firstDatablock(); auto& db = f.firstDatablock();
// query tests // query tests
for (const auto& [id, name]: db["test"].find<int, std::optional<std::string>>(cif::All(), { "id", "name" })) for (const auto& [id, name]: db["test"].find<int, std::optional<std::string>>(cif::All(), "id", "name"))
{ {
switch (id) switch (id)
{ {
...@@ -1441,7 +1441,7 @@ _cat_3.num ...@@ -1441,7 +1441,7 @@ _cat_3.num
} }
int i = 0; int i = 0;
for (const auto &[id, name, num, desc]: cat2.rows<int,std::string,int,std::string>({"id", "name", "num", "desc"})) for (const auto &[id, name, num, desc]: cat2.rows<int,std::string,int,std::string>("id", "name", "num", "desc"))
{ {
switch (++i) switch (++i)
{ {
...@@ -1473,7 +1473,7 @@ _cat_3.num ...@@ -1473,7 +1473,7 @@ _cat_3.num
BOOST_CHECK(cat1.size() == 4); BOOST_CHECK(cat1.size() == 4);
i = 0; i = 0;
for (const auto &[id, name, desc]: cat1.rows<int,std::string,std::string>({"id", "name", "desc"})) for (const auto &[id, name, desc]: cat1.rows<int,std::string,std::string>("id", "name", "desc"))
{ {
switch (++i) switch (++i)
{ {
...@@ -1627,7 +1627,7 @@ PRO OXT HXT SING N N 17 ...@@ -1627,7 +1627,7 @@ PRO OXT HXT SING N N 17
std::set<std::tuple<std::string,std::string>> bonded; std::set<std::tuple<std::string,std::string>> bonded;
for (const auto& [atom_id_1, atom_id_2]: cc->rows<std::string,std::string>({ "atom_id_1", "atom_id_2" })) for (const auto& [atom_id_1, atom_id_2]: cc->rows<std::string,std::string>("atom_id_1", "atom_id_2"))
{ {
if (atom_id_1 > atom_id_2) if (atom_id_1 > atom_id_2)
bonded.insert({ atom_id_2, atom_id_1 }); bonded.insert({ atom_id_2, atom_id_1 });
......
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