Commit 4c99710f by Maarten L. Hekkelman

Refactored iterators (Category, Row)

const versions of find
parent 59865cdb
......@@ -680,7 +680,7 @@ class Row
mCascade = cascade;
}
void next(); ///< make this row point to the next ItemRow
void next() const;
struct const_iterator
{
......@@ -805,7 +805,7 @@ class Row
size_t ColumnForItemTag(const char *itemTag) const;
ItemRow *mData;
mutable ItemRow *mData;
uint32_t mLineNr = 0;
bool mCascade = true;
};
......@@ -1338,7 +1338,7 @@ namespace literals
// -----------------------------------------------------------------------
// iterators
template <typename RowType, typename... Ts>
template <typename CategoryType, typename... Ts>
class iterator_impl
{
public:
......@@ -1347,8 +1347,10 @@ class iterator_impl
static constexpr size_t N = sizeof...(Ts);
using row_type = std::conditional_t<std::is_const_v<CategoryType>, const Row, Row>;
using iterator_category = std::forward_iterator_tag;
using value_type = std::conditional_t<N == 0, RowType, std::tuple<Ts...>>;
using value_type = std::conditional_t<N == 0, row_type, std::tuple<Ts...>>;
using difference_type = std::ptrdiff_t;
using pointer = value_type *;
using reference = value_type &;
......@@ -1424,7 +1426,7 @@ class iterator_impl
return &mValue;
}
RowType row() const
row_type row() const
{
return mCurrent;
}
......@@ -1463,14 +1465,14 @@ class iterator_impl
private:
template <std::size_t... Is>
std::tuple<Ts...> get(Row row, std::index_sequence<Is...>) const
std::tuple<Ts...> get(row_type row, std::index_sequence<Is...>) const
{
if (row)
return std::tuple<Ts...>{row[mCix[Is]].template as<Ts>()...};
return {};
}
Row mCurrent;
row_type mCurrent;
value_type mValue;
std::array<size_t, N> mCix;
};
......@@ -1478,17 +1480,19 @@ class iterator_impl
// --------------------------------------------------------------------
// iterator proxy
template <typename RowType, typename... Ts>
template <typename CategoryType, typename... Ts>
class iterator_proxy
{
public:
static constexpr const size_t N = sizeof...(Ts);
using iterator = iterator_impl<RowType, Ts...>;
using row_iterator = iterator_impl<RowType>;
using row_type = std::conditional_t<std::is_const_v<CategoryType>, const Row, Row>;
using iterator = iterator_impl<row_type, Ts...>;
using row_iterator = iterator_impl<row_type>;
iterator_proxy(Category &cat, row_iterator pos, char const *const columns[N]);
iterator_proxy(Category &cat, row_iterator pos, std::initializer_list<char const *> columns);
iterator_proxy(CategoryType &cat, row_iterator pos, char const *const columns[N]);
iterator_proxy(CategoryType &cat, row_iterator pos, std::initializer_list<char const *> columns);
iterator_proxy(iterator_proxy &&p);
iterator_proxy &operator=(iterator_proxy &&p);
......@@ -1505,10 +1509,10 @@ class iterator_proxy
size_t size() const { return std::distance(begin(), end()); }
RowType front() { return *begin(); }
RowType back() { return *(std::prev(end())); }
row_type front() { return *begin(); }
row_type back() { return *(std::prev(end())); }
Category &category() const { return *mCat; }
CategoryType &category() const { return *mCat; }
void swap(iterator_proxy &rhs)
{
......@@ -1519,7 +1523,7 @@ class iterator_proxy
}
private:
Category *mCat;
CategoryType *mCat;
row_iterator mCBegin, mCEnd;
std::array<size_t, N> mCix;
};
......@@ -1527,16 +1531,15 @@ class iterator_proxy
// --------------------------------------------------------------------
// conditional iterator proxy
template <typename RowType, typename... Ts>
template <typename CategoryType, typename... Ts>
class conditional_iterator_proxy
{
public:
static constexpr const size_t N = sizeof...(Ts);
using base_iterator = iterator_impl<RowType, Ts...>;
using base_iterator = iterator_impl<CategoryType, Ts...>;
using value_type = typename base_iterator::value_type;
using row_type = std::remove_cv_t<RowType>;
using row_type = typename base_iterator::row_type;
using row_iterator = iterator_impl<row_type>;
class conditional_iterator_impl
......@@ -1548,7 +1551,7 @@ class conditional_iterator_proxy
using pointer = value_type *;
using reference = value_type &;
conditional_iterator_impl(Category &cat, row_iterator pos, const Condition &cond, const std::array<size_t, N> &cix);
conditional_iterator_impl(CategoryType &cat, row_iterator pos, const Condition &cond, const std::array<size_t, N> &cix);
conditional_iterator_impl(const conditional_iterator_impl &i) = default;
conditional_iterator_impl &operator=(const conditional_iterator_impl &i) = default;
......@@ -1595,7 +1598,7 @@ class conditional_iterator_proxy
bool operator!=(const iterator_impl<IRowType, ITs...> &rhs) const { return mBegin != rhs; }
private:
Category *mCat;
CategoryType *mCat;
base_iterator mBegin, mEnd;
const Condition *mCondition;
};
......@@ -1603,10 +1606,8 @@ class conditional_iterator_proxy
using iterator = conditional_iterator_impl;
using reference = typename iterator::reference;
conditional_iterator_proxy(Category &cat, row_iterator pos, Condition &&cond);
template <std::size_t TN = N, std::enable_if_t<TN != 0, bool> = true>
conditional_iterator_proxy(Category &cat, row_iterator pos, Condition &&cond, char const *const columns[N]);
template<typename... Ns>
conditional_iterator_proxy(CategoryType &cat, row_iterator pos, Condition &&cond, Ns... names);
conditional_iterator_proxy(conditional_iterator_proxy &&p);
conditional_iterator_proxy &operator=(conditional_iterator_proxy &&p);
......@@ -1623,14 +1624,14 @@ class conditional_iterator_proxy
size_t size() const { return std::distance(begin(), end()); }
RowType front() { return *begin(); }
row_type front() { return *begin(); }
Category &category() const { return *mCat; }
CategoryType &category() const { return *mCat; }
void swap(conditional_iterator_proxy &rhs);
private:
Category *mCat;
CategoryType *mCat;
Condition mCondition;
row_iterator mCBegin, mCEnd;
std::array<size_t, N> mCix;
......@@ -1843,43 +1844,68 @@ class Category
Row back() { return Row(mTail); }
Row operator[](Condition &&cond);
const Row operator[](Condition &&cond) const;
template <typename... Ts, size_t N>
iterator_proxy<Row, Ts...> rows(char const *const (&columns)[N])
template <typename... Ts, typename... Ns>
iterator_proxy<const Row, Ts...> rows(Ns... names) const
{
static_assert(sizeof...(Ts) == N, "The number of column titles should be equal to the number of types to return");
return iterator_proxy<Row, Ts...>(*this, begin(), columns);
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return iterator_proxy<const Row, Ts...>(*this, begin(), {names...});
}
template <typename... Ts, typename... Ns>
iterator_proxy<Row, Ts...> rows(Ns... names)
iterator_proxy<Category, Ts...> rows(Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return iterator_proxy<Row, Ts...>(*this, begin(), {names...});
return iterator_proxy<Category, Ts...>(*this, begin(), {names...});
}
conditional_iterator_proxy<Row> find(Condition &&cond)
conditional_iterator_proxy<Category> find(Condition &&cond)
{
return find(cbegin(), std::forward<Condition>(cond));
}
conditional_iterator_proxy<Row> find(const_iterator pos, Condition &&cond)
conditional_iterator_proxy<Category> find(const_iterator pos, Condition &&cond)
{
return {*this, pos, std::forward<Condition>(cond)};
}
template <typename... Ts, size_t N>
conditional_iterator_proxy<Row, Ts...> find(Condition &&cond, char const *const (&columns)[N])
conditional_iterator_proxy<const Category> find(Condition &&cond) const
{
static_assert(sizeof...(Ts) == N, "The number of column titles should be equal to the number of types to return");
return find<Ts...>(cbegin(), std::forward<Condition>(cond), std::forward<char const *const[N]>(columns));
return find(cbegin(), std::forward<Condition>(cond));
}
template <typename... Ts, size_t N>
conditional_iterator_proxy<Row, Ts...> find(const_iterator pos, Condition &&cond, char const *const (&columns)[N])
conditional_iterator_proxy<const Category> find(const_iterator pos, Condition &&cond) const
{
return conditional_iterator_proxy<const Category>{const_cast<Category&>(*this), pos, std::forward<Condition>(cond)};
}
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<Category, Ts...> find(Condition &&cond, Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return find<Ts...>(cbegin(), std::forward<Condition>(cond), std::forward<Ns>(names)...);
}
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<const Category, Ts...> find(Condition &&cond, Ns... names) const
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return find<Ts...>(cbegin(), std::forward<Condition>(cond), std::forward<Ns>(names)...);
}
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<Category, Ts...> find(const_iterator pos, Condition &&cond, Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return {*this, pos, std::forward<Condition>(cond), std::forward<Ns>(names)... };
}
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<const Category, Ts...> find(const_iterator pos, Condition &&cond, Ns... names) const
{
static_assert(sizeof...(Ts) == N, "The number of column titles should be equal to the number of types to return");
return {*this, pos, std::forward<Condition>(cond), columns};
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
return {*this, pos, std::forward<Condition>(cond), std::forward<Ns>(names)... };
}
// --------------------------------------------------------------------
......@@ -1903,16 +1929,34 @@ class Category
return *h.begin();
}
const Row find1(Condition &&cond) const
{
return find1(cbegin(), std::forward<Condition>(cond));
}
const Row find1(const_iterator pos, Condition &&cond) const
{
auto h = find(pos, std::forward<Condition>(cond));
if (h.empty())
throw std::runtime_error("No hits found");
if (h.size() != 1)
throw std::runtime_error("Hit not unique");
return *h.begin();
}
template <typename T>
T find1(Condition &&cond, const char* column)
T find1(Condition &&cond, const char* column) const
{
return find1<T>(cbegin(), std::forward<Condition>(cond), column);
}
template <typename T>
T find1(const_iterator pos, Condition &&cond, const char* column)
T find1(const_iterator pos, Condition &&cond, const char* column) const
{
auto h = find<T>(pos, std::forward<Condition>(cond), { column });
auto h = find<T>(pos, std::forward<Condition>(cond), column);
if (h.empty())
throw std::runtime_error("No hits found");
......@@ -1924,7 +1968,7 @@ class Category
}
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find1(Condition &&cond, Cs... columns)
std::tuple<Ts...> find1(Condition &&cond, Cs... columns) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
// static_assert(std::is_same_v<Cs, const char*>..., "The column names should be const char");
......@@ -1932,10 +1976,10 @@ class Category
}
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find1(const_iterator pos, Condition &&cond, Cs... columns)
std::tuple<Ts...> find1(const_iterator pos, Condition &&cond, Cs... columns) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
auto h = find<Ts...>(pos, std::forward<Condition>(cond), { columns... });
auto h = find<Ts...>(pos, std::forward<Condition>(cond), std::forward<Cs>(columns)...);
if (h.empty())
throw std::runtime_error("No hits found");
......@@ -2253,8 +2297,8 @@ inline void swap(cif::detail::ItemReference &a, cif::detail::ItemReference &b)
// --------------------------------------------------------------------
template <typename RowType, typename... Ts>
iterator_proxy<RowType, Ts...>::iterator_proxy(Category &cat, row_iterator pos, char const *const columns[N])
template <typename CategoryType, typename... Ts>
iterator_proxy<CategoryType, Ts...>::iterator_proxy(CategoryType &cat, row_iterator pos, char const *const columns[N])
: mCat(&cat)
, mCBegin(pos)
, mCEnd(cat.end())
......@@ -2263,8 +2307,8 @@ iterator_proxy<RowType, Ts...>::iterator_proxy(Category &cat, row_iterator pos,
mCix[i] = mCat->getColumnIndex(columns[i]);
}
template <typename RowType, typename... Ts>
iterator_proxy<RowType, Ts...>::iterator_proxy(Category &cat, row_iterator pos, std::initializer_list<char const *> columns)
template <typename CategoryType, typename... Ts>
iterator_proxy<CategoryType, Ts...>::iterator_proxy(CategoryType &cat, row_iterator pos, std::initializer_list<char const *> columns)
: mCat(&cat)
, mCBegin(pos)
, mCEnd(cat.end())
......@@ -2278,9 +2322,9 @@ iterator_proxy<RowType, Ts...>::iterator_proxy(Category &cat, row_iterator pos,
// --------------------------------------------------------------------
template <typename RowType, typename... Ts>
conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_impl::conditional_iterator_impl(
Category &cat, row_iterator pos, const Condition &cond, const std::array<size_t, N> &cix)
template <typename CategoryType, typename... Ts>
conditional_iterator_proxy<CategoryType, Ts...>::conditional_iterator_impl::conditional_iterator_impl(
CategoryType &cat, row_iterator pos, const Condition &cond, const std::array<size_t, N> &cix)
: mCat(&cat)
, mBegin(pos, cix)
, mEnd(cat.end(), cix)
......@@ -2288,8 +2332,8 @@ conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_impl::condition
{
}
template <typename RowType, typename... Ts>
conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_proxy(conditional_iterator_proxy &&p)
template <typename CategoryType, typename... Ts>
conditional_iterator_proxy<CategoryType, Ts...>::conditional_iterator_proxy(conditional_iterator_proxy &&p)
: mCat(nullptr)
, mCBegin(p.mCBegin)
, mCEnd(p.mCEnd)
......@@ -2300,63 +2344,54 @@ conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_proxy(condition
mCondition.swap(p.mCondition);
}
template <typename RowType, typename... Ts>
conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_proxy(Category &cat, row_iterator pos, Condition &&cond)
template <typename CategoryType, typename... Ts>
template <typename... Ns>
conditional_iterator_proxy<CategoryType, Ts...>::conditional_iterator_proxy(CategoryType &cat, row_iterator pos, Condition &&cond, Ns... names)
: mCat(&cat)
, mCondition(std::move(cond))
, mCBegin(pos)
, mCEnd(cat.end())
{
mCondition.prepare(cat);
static_assert(sizeof...(Ts) == sizeof...(Ns), "Number of column names should be equal to number of requested value types");
while (mCBegin != mCEnd and not mCondition(*mCat, mCBegin.row()))
++mCBegin;
}
size_t N = sizeof...(Ns);
template <typename RowType, typename... Ts>
template <std::size_t TN, std::enable_if_t<TN != 0, bool>>
conditional_iterator_proxy<RowType, Ts...>::conditional_iterator_proxy(Category &cat, row_iterator pos, Condition &&cond, const char *const columns[N])
: mCat(&cat)
, mCondition(std::move(cond))
, mCBegin(pos)
, mCEnd(cat.end())
{
mCondition.prepare(cat);
while (mCBegin != mCEnd and not mCondition(*mCat, mCBegin.row()))
++mCBegin;
for (size_t i = 0; i < N; ++i)
mCix[i] = mCat->getColumnIndex(columns[i]);
size_t i = 0;
((mCix[i++] = mCat->getColumnIndex(names)), ...);
}
template <typename RowType, typename... Ts>
conditional_iterator_proxy<RowType, Ts...> &conditional_iterator_proxy<RowType, Ts...>::operator=(conditional_iterator_proxy &&p)
template <typename CategoryType, typename... Ts>
conditional_iterator_proxy<CategoryType, Ts...> &conditional_iterator_proxy<CategoryType, Ts...>::operator=(conditional_iterator_proxy &&p)
{
swap(p);
return *this;
}
template <typename RowType, typename... Ts>
typename conditional_iterator_proxy<RowType, Ts...>::iterator conditional_iterator_proxy<RowType, Ts...>::begin() const
template <typename CategoryType, typename... Ts>
typename conditional_iterator_proxy<CategoryType, Ts...>::iterator conditional_iterator_proxy<CategoryType, Ts...>::begin() const
{
return iterator(*mCat, mCBegin, mCondition, mCix);
}
template <typename RowType, typename... Ts>
typename conditional_iterator_proxy<RowType, Ts...>::iterator conditional_iterator_proxy<RowType, Ts...>::end() const
template <typename CategoryType, typename... Ts>
typename conditional_iterator_proxy<CategoryType, Ts...>::iterator conditional_iterator_proxy<CategoryType, Ts...>::end() const
{
return iterator(*mCat, mCEnd, mCondition, mCix);
}
template <typename RowType, typename... Ts>
bool conditional_iterator_proxy<RowType, Ts...>::empty() const
template <typename CategoryType, typename... Ts>
bool conditional_iterator_proxy<CategoryType, Ts...>::empty() const
{
return mCBegin == mCEnd;
}
template <typename RowType, typename... Ts>
void conditional_iterator_proxy<RowType, Ts...>::swap(conditional_iterator_proxy &rhs)
template <typename CategoryType, typename... Ts>
void conditional_iterator_proxy<CategoryType, Ts...>::swap(conditional_iterator_proxy &rhs)
{
std::swap(mCat, rhs.mCat);
mCondition.swap(rhs.mCondition);
......
......@@ -61,11 +61,12 @@ class File;
class Atom
{
public:
// Atom(const structure& s, const std::string& id);
Atom();
Atom(struct AtomImpl *impl);
Atom(const Atom &rhs);
Atom(cif::Datablock &db, cif::Row &row);
// a special constructor to create symmetry copies
Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation);
......@@ -495,13 +496,13 @@ class Structure
/// \return The ID of the created entity
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.
///
/// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of atom_site rows containing the data.
/// \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
/// Will asssign new atom_id's to all atoms. Be carefull
......
......@@ -2821,7 +2821,7 @@ Row::~Row()
{
}
void Row::next()
void Row::next() const
{
if (mData != nullptr)
mData = mData->mNext;
......@@ -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!
for (size_t ab = 0; ab < 2; ++ab)
......
......@@ -368,7 +368,7 @@ CompoundFactoryImpl::CompoundFactoryImpl(const std::string &file, std::shared_pt
{
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;
......
......@@ -230,7 +230,7 @@ void FileImpl::save(const std::string &p)
struct AtomImpl
{
AtomImpl(const AtomImpl &i)
: mFile(i.mFile)
: mDb(i.mDb)
, mID(i.mID)
, mType(i.mType)
, mAtomID(i.mAtomID)
......@@ -250,13 +250,12 @@ struct AtomImpl
{
}
AtomImpl(const File &f, const std::string &id)
: mFile(f)
AtomImpl(cif::Datablock &db, const std::string &id)
: mDb(db)
, mID(id)
, mRefcount(1)
, mCompound(nullptr)
{
auto &db = *mFile.impl().mDb;
auto &cat = db["atom_site"];
mRow = cat[cif::Key("id") == mID];
......@@ -264,8 +263,18 @@ struct AtomImpl
prefetch();
}
AtomImpl(const File &f, const std::string &id, cif::Row row)
: mFile(f)
AtomImpl(cif::Datablock &db, cif::Row &row)
: 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)
, mRefcount(1)
, mRow(row)
......@@ -274,21 +283,8 @@ struct AtomImpl
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)
: mFile(impl.mFile)
: mDb(impl.mDb)
, mID(impl.mID)
, mType(impl.mType)
, mAtomID(impl.mAtomID)
......@@ -341,16 +337,19 @@ struct AtomImpl
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;
if (not r.empty())
auto cat = mDb.get("atom_site_anisotrop");
if (cat)
{
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]");
auto r = cat->find1(cif::Key("id") == mID);
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;
......@@ -445,7 +444,7 @@ struct AtomImpl
std::swap(mAtomID, b.mAtomID);
}
const File &mFile;
const cif::Datablock &mDb;
std::string mID;
AtomType mType;
......@@ -487,6 +486,11 @@ Atom::Atom(AtomImpl *impl)
{
}
Atom::Atom(cif::Datablock &db, cif::Row &row)
: mImpl_(new AtomImpl(db, row))
{
}
AtomImpl *Atom::impl()
{
if (mImpl_ == nullptr)
......@@ -545,9 +549,12 @@ const cif::Row Atom::getRow() const
const cif::Row Atom::getRowAniso() const
{
auto &db = *mImpl_->mFile.impl().mDb;
auto &cat = db["atom_site_anisotrop"];
return cat[cif::Key("id") == mImpl_->mID];
auto &db = mImpl_->mDb;
auto cat = db.get("atom_site_anisotrop");
if (not cat)
return {};
else
return cat->find1(cif::Key("id") == mImpl_->mID);
}
template <>
......@@ -758,7 +765,7 @@ bool Atom::isWater() const
bool Atom::operator==(const Atom &rhs) const
{
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
......@@ -1821,7 +1828,7 @@ Structure::Structure(File &f, size_t modelNr, StructureOpenOptions options)
if ((options bitand StructureOpenOptions::SkipHydrogen) and type_symbol == "H")
continue;
mAtoms.emplace_back(new AtomImpl(f, id, a));
mAtoms.emplace_back(new AtomImpl(*db, id, a));
}
loadData();
......@@ -2445,7 +2452,7 @@ std::string Structure::createNonPolyEntity(const std::string &comp_id)
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;
......@@ -2468,26 +2475,26 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
for (auto& atom: atoms)
{
atom_site.emplace({
{ "group_PDB", atom["group_PDB"].as<std::string>() },
{ "group_PDB", atom.property<std::string>("group_PDB") },
{ "id", atom_site.getUniqueID("") },
{ "type_symbol", atom["type_symbol"].as<std::string>() },
{ "label_atom_id", atom["label_atom_id"].as<std::string>() },
{ "label_alt_id", atom["label_alt_id"].as<std::string>() },
{ "type_symbol", atom.property<std::string>("type_symbol") },
{ "label_atom_id", atom.property<std::string>("label_atom_id") },
{ "label_alt_id", atom.property<std::string>("label_alt_id") },
{ "label_comp_id", comp_id },
{ "label_asym_id", asym_id },
{ "label_entity_id", entity_id },
{ "label_seq_id", "." },
{ "pdbx_PDB_ins_code", "" },
{ "Cartn_x", atom["Cartn_x"].as<std::string>() },
{ "Cartn_y", atom["Cartn_y"].as<std::string>() },
{ "Cartn_z", atom["Cartn_z"].as<std::string>() },
{ "occupancy", atom["occupancy"].as<std::string>() },
{ "B_iso_or_equiv", atom["B_iso_or_equiv"].as<std::string>() },
{ "pdbx_formal_charge", atom["pdbx_formal_charge"].as<std::string>() },
{ "Cartn_x", atom.property<std::string>("Cartn_x") },
{ "Cartn_y", atom.property<std::string>("Cartn_y") },
{ "Cartn_z", atom.property<std::string>("Cartn_z") },
{ "occupancy", atom.property<std::string>("occupancy") },
{ "B_iso_or_equiv", atom.property<std::string>("B_iso_or_equiv") },
{ "pdbx_formal_charge", atom.property<std::string>("pdbx_formal_charge") },
{ "auth_seq_id", "" },
{ "auth_comp_id", comp_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 }
});
}
......@@ -2568,7 +2575,7 @@ void Structure::cleanupEmptyCategories()
{
// is this correct?
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);
count = asym_ids.size();
}
......
......@@ -86,10 +86,13 @@ HETATM C CHD . ? -4.342 36.262 -3.536 1.00 8.00 ?
# that's enough to test with
)"_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();
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);
......
......@@ -1158,7 +1158,7 @@ _test.name
// 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)
{
......@@ -1193,7 +1193,7 @@ _test.name
auto& db = f.firstDatablock();
// 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)
{
......@@ -1441,7 +1441,7 @@ _cat_3.num
}
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)
{
......@@ -1473,7 +1473,7 @@ _cat_3.num
BOOST_CHECK(cat1.size() == 4);
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)
{
......@@ -1627,7 +1627,7 @@ PRO OXT HXT SING N N 17
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)
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