Commit 6f93fa37 by Maarten L. Hekkelman

new conditional iterator type

parent 598f953c
...@@ -443,6 +443,7 @@ class Structure ...@@ -443,6 +443,7 @@ class Structure
std::list<Polymer>& polymers() { return mPolymers; } std::list<Polymer>& polymers() { return mPolymers; }
const std::vector<Residue>& nonPolymers() const { return mNonPolymers; } const std::vector<Residue>& nonPolymers() const { return mNonPolymers; }
const std::vector<Residue>& branchResidues() const { return mBranchResidues; }
Atom getAtomByID(std::string id) const; Atom getAtomByID(std::string id) const;
// Atom getAtomByLocation(Point pt, float maxDistance) const; // Atom getAtomByLocation(Point pt, float maxDistance) const;
...@@ -450,10 +451,6 @@ class Structure ...@@ -450,10 +451,6 @@ class Structure
Atom getAtomByLabel(const std::string& atomID, const std::string& asymID, Atom getAtomByLabel(const std::string& atomID, const std::string& asymID,
const std::string& compID, int seqID, const std::string& altID = ""); const std::string& compID, int seqID, const std::string& altID = "");
// Atom getAtomByAuth(const std::string& atomID, const std::string& asymID,
// const std::string& compID, int seqID, const std::string& altID = "",
// const std::string& pdbxAuthInsCode = "");
const Residue& getResidue(const std::string& asymID, const std::string& compID, int seqID) const; const Residue& getResidue(const std::string& asymID, const std::string& compID, int seqID) const;
// map between auth and label locations // map between auth and label locations
...@@ -487,65 +484,65 @@ class Structure ...@@ -487,65 +484,65 @@ class Structure
/// Will asssign new atom_id's to all atoms. Be carefull /// Will asssign new atom_id's to all atoms. Be carefull
void sortAtoms(); void sortAtoms();
// iterator for all residues // // iterator for all residues
class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue> // class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue>
{ // {
public: // public:
typedef std::iterator<std::forward_iterator_tag, const Residue> baseType; // typedef std::iterator<std::forward_iterator_tag, const Residue> baseType;
typedef typename baseType::pointer pointer; // typedef typename baseType::pointer pointer;
typedef typename baseType::reference reference; // typedef typename baseType::reference reference;
typedef std::list<Polymer>::const_iterator poly_iterator; // typedef std::list<Polymer>::const_iterator poly_iterator;
residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex); // residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex);
reference operator*(); // reference operator*();
pointer operator->(); // pointer operator->();
residue_iterator& operator++(); // residue_iterator& operator++();
residue_iterator operator++(int); // residue_iterator operator++(int);
bool operator==(const residue_iterator& rhs) const; // bool operator==(const residue_iterator& rhs) const;
bool operator!=(const residue_iterator& rhs) const; // bool operator!=(const residue_iterator& rhs) const;
private: // private:
const Structure& mStructure; // const Structure& mStructure;
poly_iterator mPolyIter; // poly_iterator mPolyIter;
size_t mPolyResIndex; // size_t mPolyResIndex;
size_t mNonPolyIndex; // size_t mNonPolyIndex;
}; // };
class residue_view // class residue_view
{ // {
public: // public:
residue_view(const Structure* s) : mStructure(s) {} // residue_view(const Structure* s) : mStructure(s) {}
residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {} // residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {}
residue_view& operator=(residue_view& rhs) // residue_view& operator=(residue_view& rhs)
{ // {
mStructure = rhs.mStructure; // mStructure = rhs.mStructure;
return *this; // return *this;
} // }
residue_iterator begin() const { return residue_iterator(mStructure, mStructure->mPolymers.begin(), 0, 0); } // residue_iterator begin() const { return residue_iterator(mStructure, mStructure->mPolymers.begin(), 0, 0); }
residue_iterator end() const { return residue_iterator(mStructure, mStructure->mPolymers.end(), 0, mStructure->mNonPolymers.size()); } // residue_iterator end() const { return residue_iterator(mStructure, mStructure->mPolymers.end(), 0, mStructure->mNonPolymers.size()); }
size_t size() const // size_t size() const
{ // {
size_t ps = std::accumulate(mStructure->mPolymers.begin(), mStructure->mPolymers.end(), 0UL, [](size_t s, auto& p) { return s + p.size(); }); // size_t ps = std::accumulate(mStructure->mPolymers.begin(), mStructure->mPolymers.end(), 0UL, [](size_t s, auto& p) { return s + p.size(); });
return ps + mStructure->mNonPolymers.size(); // return ps + mStructure->mNonPolymers.size();
} // }
private: // private:
const Structure* mStructure; // const Structure* mStructure;
}; // };
residue_view residues() const { return residue_view(this); } // residue_view residues() const { return residue_view(this); }
private: private:
friend Polymer; friend Polymer;
friend Residue; friend Residue;
friend residue_view; // friend residue_view;
friend residue_iterator; // friend residue_iterator;
cif::Category& category(const char* name) const; cif::Category& category(const char* name) const;
cif::Datablock& datablock() const; cif::Datablock& datablock() const;
...@@ -560,7 +557,7 @@ class Structure ...@@ -560,7 +557,7 @@ class Structure
AtomView mAtoms; AtomView mAtoms;
std::vector<size_t> mAtomIndex; std::vector<size_t> mAtomIndex;
std::list<Polymer> mPolymers; std::list<Polymer> mPolymers;
std::vector<Residue> mNonPolymers; std::vector<Residue> mNonPolymers, mBranchResidues;
}; };
} }
...@@ -1732,6 +1732,17 @@ void Structure::loadData() ...@@ -1732,6 +1732,17 @@ void Structure::loadData()
else if (mNonPolymers.empty() or mNonPolymers.back().asymID() != asymID) else if (mNonPolymers.empty() or mNonPolymers.back().asymID() != asymID)
mNonPolymers.emplace_back(*this, monID, asymID); mNonPolymers.emplace_back(*this, monID, asymID);
} }
auto& branchScheme = category("pdbx_branch_scheme");
for (auto& r: branchScheme)
{
std::string asymID, monID, num;
cif::tie(asymID, monID, num) =
r.get("asym_id", "mon_id", "num");
mBranchResidues.emplace_back(*this, monID, asymID, num);
}
} }
void Structure::updateAtomIndex() void Structure::updateAtomIndex()
...@@ -2038,64 +2049,64 @@ void Structure::insertCompound(const std::string& compoundID, bool isEntity) ...@@ -2038,64 +2049,64 @@ void Structure::insertCompound(const std::string& compoundID, bool isEntity)
} }
} }
// -------------------------------------------------------------------- // // --------------------------------------------------------------------
Structure::residue_iterator::residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex) // Structure::residue_iterator::residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex)
: mStructure(*s), mPolyIter(polyIter), mPolyResIndex(polyResIndex), mNonPolyIndex(nonPolyIndex) // : mStructure(*s), mPolyIter(polyIter), mPolyResIndex(polyResIndex), mNonPolyIndex(nonPolyIndex)
{ // {
while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size()) // while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size())
++mPolyIter; // ++mPolyIter;
} // }
auto Structure::residue_iterator::operator*() -> reference // auto Structure::residue_iterator::operator*() -> reference
{ // {
if (mPolyIter != mStructure.mPolymers.end()) // if (mPolyIter != mStructure.mPolymers.end())
return (*mPolyIter)[mPolyResIndex]; // return (*mPolyIter)[mPolyResIndex];
else // else
return mStructure.mNonPolymers[mNonPolyIndex]; // return mStructure.mNonPolymers[mNonPolyIndex];
} // }
auto Structure::residue_iterator::operator->() -> pointer // auto Structure::residue_iterator::operator->() -> pointer
{ // {
if (mPolyIter != mStructure.mPolymers.end()) // if (mPolyIter != mStructure.mPolymers.end())
return &(*mPolyIter)[mPolyResIndex]; // return &(*mPolyIter)[mPolyResIndex];
else // else
return &mStructure.mNonPolymers[mNonPolyIndex]; // return &mStructure.mNonPolymers[mNonPolyIndex];
} // }
Structure::residue_iterator& Structure::residue_iterator::operator++() // Structure::residue_iterator& Structure::residue_iterator::operator++()
{ // {
if (mPolyIter != mStructure.mPolymers.end()) // if (mPolyIter != mStructure.mPolymers.end())
{ // {
++mPolyResIndex; // ++mPolyResIndex;
if (mPolyResIndex >= mPolyIter->size()) // if (mPolyResIndex >= mPolyIter->size())
{ // {
++mPolyIter; // ++mPolyIter;
mPolyResIndex = 0; // mPolyResIndex = 0;
} // }
} // }
else // else
++mNonPolyIndex; // ++mNonPolyIndex;
return *this; // return *this;
} // }
Structure::residue_iterator Structure::residue_iterator::operator++(int) // Structure::residue_iterator Structure::residue_iterator::operator++(int)
{ // {
auto result = *this; // auto result = *this;
operator++(); // operator++();
return result; // return result;
} // }
bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const // bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const
{ // {
return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex; // return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex;
} // }
bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const // bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const
{ // {
return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex; // return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex;
} // }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -1073,4 +1073,98 @@ _cat_2.parent_id3 ...@@ -1073,4 +1073,98 @@ _cat_2.parent_id3
cat1.erase(cif::Key("id") == 30); cat1.erase(cif::Key("id") == 30);
BOOST_CHECK(cat1.size() == 0); BOOST_CHECK(cat1.size() == 0);
BOOST_CHECK(cat2.size() == 0); BOOST_CHECK(cat2.size() == 0);
} }
\ No newline at end of file
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(c1)
{
cif::VERBOSE = 1;
auto f = R"(data_TEST
#
loop_
_test.id
_test.name
1 aap
2 noot
3 mies
4 .
5 ?
)"_cf;
auto& db = f.firstDatablock();
for (auto r: db["test"].find(cif::Key("id") == 1))
{
const auto& [id, name] = r.get<int, std::string>({"id", "name"});
BOOST_CHECK(id == 1);
BOOST_CHECK(name == "aap");
}
for (auto r: db["test"].find(cif::Key("id") == 4))
{
const auto& [id, name] = r.get<int, std::string>({"id", "name"});
BOOST_CHECK(id == 4);
BOOST_CHECK(name.empty());
}
for (auto r: db["test"].find(cif::Key("id") == 5))
{
const auto& [id, name] = r.get<int, std::string>({"id", "name"});
BOOST_CHECK(id == 5);
BOOST_CHECK(name.empty());
}
// optional
for (auto r: db["test"])
{
const auto& [id, name] = r.get<int, std::optional<std::string>>({"id", "name"});
switch (id)
{
case 1: BOOST_CHECK(name == "aap"); break;
case 2: BOOST_CHECK(name == "noot"); break;
case 3: BOOST_CHECK(name == "mies"); break;
case 4:
case 5: BOOST_CHECK(not name); break;
default:
BOOST_CHECK(false);
}
}
}
BOOST_AUTO_TEST_CASE(c2)
{
cif::VERBOSE = 1;
auto f = R"(data_TEST
#
loop_
_test.id
_test.name
1 aap
2 noot
3 mies
4 .
5 ?
)"_cf;
auto& db = f.firstDatablock();
// query tests
for (const auto& [id, name]: db["test"].find<int, std::optional<std::string>>(cif::All(), { "id", "name" }))
{
switch (id)
{
case 1: BOOST_CHECK(name == "aap"); break;
case 2: BOOST_CHECK(name == "noot"); break;
case 3: BOOST_CHECK(name == "mies"); break;
case 4:
case 5: BOOST_CHECK(not name); break;
default:
BOOST_CHECK(false);
}
}
}
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