Commit 6f93fa37 by Maarten L. Hekkelman

new conditional iterator type

parent 598f953c
......@@ -443,6 +443,7 @@ class Structure
std::list<Polymer>& polymers() { return mPolymers; }
const std::vector<Residue>& nonPolymers() const { return mNonPolymers; }
const std::vector<Residue>& branchResidues() const { return mBranchResidues; }
Atom getAtomByID(std::string id) const;
// Atom getAtomByLocation(Point pt, float maxDistance) const;
......@@ -450,10 +451,6 @@ class Structure
Atom getAtomByLabel(const std::string& atomID, const std::string& asymID,
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;
// map between auth and label locations
......@@ -487,65 +484,65 @@ class Structure
/// Will asssign new atom_id's to all atoms. Be carefull
void sortAtoms();
// iterator for all residues
// // iterator for all residues
class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue>
{
public:
typedef std::iterator<std::forward_iterator_tag, const Residue> baseType;
typedef typename baseType::pointer pointer;
typedef typename baseType::reference reference;
// class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue>
// {
// public:
// typedef std::iterator<std::forward_iterator_tag, const Residue> baseType;
// typedef typename baseType::pointer pointer;
// 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*();
pointer operator->();
// reference operator*();
// pointer operator->();
residue_iterator& operator++();
residue_iterator operator++(int);
// residue_iterator& operator++();
// 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:
const Structure& mStructure;
poly_iterator mPolyIter;
size_t mPolyResIndex;
size_t mNonPolyIndex;
};
class residue_view
{
public:
residue_view(const Structure* s) : mStructure(s) {}
residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {}
residue_view& operator=(residue_view& rhs)
{
mStructure = rhs.mStructure;
return *this;
}
// private:
// const Structure& mStructure;
// poly_iterator mPolyIter;
// size_t mPolyResIndex;
// size_t mNonPolyIndex;
// };
// class residue_view
// {
// public:
// residue_view(const Structure* s) : mStructure(s) {}
// residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {}
// residue_view& operator=(residue_view& rhs)
// {
// mStructure = rhs.mStructure;
// return *this;
// }
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()); }
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(); });
return ps + mStructure->mNonPolymers.size();
}
// 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()); }
// 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(); });
// return ps + mStructure->mNonPolymers.size();
// }
private:
const Structure* mStructure;
};
// private:
// const Structure* mStructure;
// };
residue_view residues() const { return residue_view(this); }
// residue_view residues() const { return residue_view(this); }
private:
friend Polymer;
friend Residue;
friend residue_view;
friend residue_iterator;
// friend residue_view;
// friend residue_iterator;
cif::Category& category(const char* name) const;
cif::Datablock& datablock() const;
......@@ -560,7 +557,7 @@ class Structure
AtomView mAtoms;
std::vector<size_t> mAtomIndex;
std::list<Polymer> mPolymers;
std::vector<Residue> mNonPolymers;
std::vector<Residue> mNonPolymers, mBranchResidues;
};
}
......@@ -1732,6 +1732,17 @@ void Structure::loadData()
else if (mNonPolymers.empty() or mNonPolymers.back().asymID() != 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()
......@@ -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)
: mStructure(*s), mPolyIter(polyIter), mPolyResIndex(polyResIndex), mNonPolyIndex(nonPolyIndex)
{
while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size())
++mPolyIter;
}
// 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)
// {
// while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size())
// ++mPolyIter;
// }
auto Structure::residue_iterator::operator*() -> reference
{
if (mPolyIter != mStructure.mPolymers.end())
return (*mPolyIter)[mPolyResIndex];
else
return mStructure.mNonPolymers[mNonPolyIndex];
}
// auto Structure::residue_iterator::operator*() -> reference
// {
// if (mPolyIter != mStructure.mPolymers.end())
// return (*mPolyIter)[mPolyResIndex];
// else
// return mStructure.mNonPolymers[mNonPolyIndex];
// }
auto Structure::residue_iterator::operator->() -> pointer
{
if (mPolyIter != mStructure.mPolymers.end())
return &(*mPolyIter)[mPolyResIndex];
else
return &mStructure.mNonPolymers[mNonPolyIndex];
}
// auto Structure::residue_iterator::operator->() -> pointer
// {
// if (mPolyIter != mStructure.mPolymers.end())
// return &(*mPolyIter)[mPolyResIndex];
// else
// return &mStructure.mNonPolymers[mNonPolyIndex];
// }
Structure::residue_iterator& Structure::residue_iterator::operator++()
{
if (mPolyIter != mStructure.mPolymers.end())
{
++mPolyResIndex;
if (mPolyResIndex >= mPolyIter->size())
{
++mPolyIter;
mPolyResIndex = 0;
}
}
else
++mNonPolyIndex;
return *this;
}
// Structure::residue_iterator& Structure::residue_iterator::operator++()
// {
// if (mPolyIter != mStructure.mPolymers.end())
// {
// ++mPolyResIndex;
// if (mPolyResIndex >= mPolyIter->size())
// {
// ++mPolyIter;
// mPolyResIndex = 0;
// }
// }
// else
// ++mNonPolyIndex;
// return *this;
// }
Structure::residue_iterator Structure::residue_iterator::operator++(int)
{
auto result = *this;
operator++();
return result;
}
// Structure::residue_iterator Structure::residue_iterator::operator++(int)
// {
// auto result = *this;
// operator++();
// return result;
// }
bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const
{
return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex;
}
// bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const
// {
// return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex;
// }
bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const
{
return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex;
}
// bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const
// {
// return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex;
// }
// --------------------------------------------------------------------
......
......@@ -1073,4 +1073,98 @@ _cat_2.parent_id3
cat1.erase(cif::Key("id") == 30);
BOOST_CHECK(cat1.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