Commit 6a0b6b99 by Maarten L. Hekkelman

using index in category

parent 08dd9dd5
......@@ -370,8 +370,7 @@ if(ENABLE_TESTING)
find_package(Boost REQUIRED headers)
list(APPEND CIFPP_tests unit-v2 unit-3d format model
# rename-compound sugar
list(APPEND CIFPP_tests unit-v2 unit-3d format model rename-compound sugar
)
foreach(CIFPP_TEST IN LISTS CIFPP_tests)
......
......@@ -159,6 +159,22 @@ class category
}
// --------------------------------------------------------------------
// A category can have a key, as defined by the validator/dictionary
/// @brief The key type
using key_type = row_initializer;
/// @brief Return a row_handle for the row specified by \a key
/// @param key The value for the key, fields specified in the dictionary should have a value
/// @return The row found in the index, or an undefined row_handle
row_handle operator[](const key_type &key);
const row_handle operator[](const key_type &key) const
{
return const_cast<category *>(this)->operator[](key);
}
// --------------------------------------------------------------------
template <typename... Ts, typename... Ns>
iterator_proxy<const category, Ts...> rows(Ns... names) const
......@@ -335,7 +351,7 @@ class category
iterator emplace(row_initializer &&ri)
{
return this->emplace(ri.m_items.begin(), ri.m_items.end());
return this->emplace(ri.begin(), ri.end());
}
template <typename ItemIter>
......
......@@ -86,6 +86,18 @@ class file : public std::list<datablock>
bool contains(std::string_view name) const;
datablock &front()
{
assert(not empty());
return std::list<datablock>::front();
}
const datablock &front() const
{
assert(not empty());
return std::list<datablock>::front();
}
datablock &operator[](std::string_view name);
const datablock &operator[](std::string_view name) const;
......
......@@ -34,19 +34,6 @@
#include <format>
#endif
/*
To modify a structure, you will have to use actions.
The currently supported actions are:
// - Move atom to new location
- Remove atom
// - Add new atom that was formerly missing
// - Add alternate residue
-
*/
namespace cif::mm
{
......@@ -63,10 +50,9 @@ class atom
private:
struct atom_impl : public std::enable_shared_from_this<atom_impl>
{
atom_impl(datablock &db, std::string_view id, row_handle row)
atom_impl(datablock &db, std::string_view id)
: m_db(db)
, m_id(id)
, m_row(row)
{
prefetch();
}
......@@ -84,95 +70,18 @@ class atom
int get_charge() const;
void moveTo(const point &p)
{
if (m_symop != "1_555")
throw std::runtime_error("Moving symmetry copy");
#if __cpp_lib_format
m_row.assign("Cartn_x", std::format("{:.3f}", p.getX()), false, false);
m_row.assign("Cartn_y", std::format("{:.3f}", p.getY()), false, false);
m_row.assign("Cartn_z", std::format("{:.3f}", p.getZ()), false, false);
#else
m_row.assign("Cartn_x", format("%.3f", p.m_x).str(), false, false);
m_row.assign("Cartn_y", format("%.3f", p.m_y).str(), false, false);
m_row.assign("Cartn_z", format("%.3f", p.m_z).str(), false, false);
#endif
m_location = p;
}
void moveTo(const point &p);
// const compound *compound() const;
std::string get_property(std::string_view name) const
{
return m_row[name].as<std::string>();
// for (auto &&[tag, ref] : mCachedRefs)
// {
// if (tag == name)
// return ref.as<std::string>();
// }
// mCachedRefs.emplace_back(name, const_cast<Row &>(mRow)[name]);
// return std::get<1>(mCachedRefs.back()).as<std::string>();
}
std::string get_property(std::string_view name) const;
int get_property_int(std::string_view name) const;
float get_property_float(std::string_view name) const;
int get_property_int(std::string_view name) const
{
int result = 0;
if (not m_row[name].empty())
{
auto s = get_property(name);
std::from_chars_result r = std::from_chars(s.data(), s.data() + s.length(), result);
if (r.ec != std::errc() and VERBOSE > 0)
std::cerr << "Error converting " << s << " to number for property " << name << std::endl;
}
return result;
}
float get_property_float(std::string_view name) const
{
float result = 0;
if (not m_row[name].empty())
{
auto s = get_property(name);
std::from_chars_result r = std::from_chars(s.data(), s.data() + s.length(), result);
if (r.ec != std::errc() and VERBOSE > 0)
std::cerr << "Error converting " << s << " to number for property " << name << std::endl;
}
return result;
}
void set_property(const std::string_view name, const std::string &value)
{
m_row.assign(name, value, true, true);
}
// const datablock &m_db;
// std::string mID;
// atom_type mType;
// std::string mAtomID;
// std::string mCompID;
// std::string m_asym_id;
// int m_seq_id;
// std::string mAltID;
// std::string m_auth_seq_id;
// point mLocation;
// row_handle mRow;
// // mutable std::vector<std::tuple<std::string, detail::ItemReference>> mCachedRefs;
// mutable const compound *mcompound = nullptr;
// bool mSymmetryCopy = false;
// bool mClone = false;
void set_property(const std::string_view name, const std::string &value);
const datablock &m_db;
std::string m_id;
row_handle m_row;
point m_location;
std::string m_symop = "1_555";
};
......@@ -190,10 +99,10 @@ class atom
{
}
atom(datablock &db, row_handle &row)
: atom(std::make_shared<atom_impl>(db, row["id"].as<std::string>(), row))
{
}
// atom(datablock &db, row_handle &row)
// : atom(std::make_shared<atom_impl>(db, row["id"].as<std::string>(), row))
// {
// }
// a special constructor to create symmetry copies
atom(const atom &rhs, const point &symmmetry_location, const std::string &symmetry_operation)
......@@ -897,10 +806,10 @@ class structure
/// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of sets of item data containing the data for the atoms.
/// \return The newly create asym ID
std::string create_non_poly(const std::string &entity_id, std::vector<std::vector<item>> &atom_info);
std::string create_non_poly(const std::string &entity_id, std::vector<row_initializer> atoms);
/// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a nag_atom_info
branch &create_branch(std::vector<std::vector<item>> &nag_atom_info);
/// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a atoms
branch &create_branch(std::vector<row_initializer> atoms);
/// \brief Extend an existing (sugar) branch identified by \a asymID with one sugar containing atoms constructed from \a atom_info
///
......@@ -908,7 +817,7 @@ class structure
/// \param atom_info Array containing the info for the atoms to construct for the new sugar
/// \param link_sugar The sugar to link to, note: this is the sugar number (1 based)
/// \param link_atom The atom id of the atom linked in the sugar
branch &extend_branch(const std::string &asym_id, std::vector<std::vector<item>> &atom_info,
branch &extend_branch(const std::string &asym_id, std::vector<row_initializer> atom_info,
int link_sugar, const std::string &link_atom);
/// \brief Remove \a branch
......
......@@ -277,7 +277,7 @@ class row_handle
// --------------------------------------------------------------------
class row_initializer
class row_initializer : public std::vector<item>
{
public:
friend class category;
......@@ -289,20 +289,17 @@ class row_initializer
row_initializer &operator=(row_initializer &&) = default;
row_initializer(std::initializer_list<item> items)
: m_items(items)
: std::vector<item>(items)
{
}
template <typename ItemIter, std::enable_if_t<std::is_same_v<typename ItemIter::value_type, item>, int> = 0>
row_initializer(ItemIter b, ItemIter e)
: m_items(b, e)
: std::vector<item>(b, e)
{
}
row_initializer(row_handle rh);
private:
std::vector<item> m_items;
};
} // namespace cif
\ No newline at end of file
......@@ -96,6 +96,32 @@ class row_comparator
return d;
}
int operator()(const row_initializer &a, const row *b) const
{
assert(b);
row_handle rhb(m_category, *b);
int d = 0, i = 0;
for (auto &c : m_comparator)
{
size_t k;
compareFunc f;
std::tie(k, f) = c;
std::string_view ka = a[i++].value();
std::string_view kb = rhb[k].text();
d = f(ka, kb);
if (d != 0)
break;
}
return d;
}
private:
typedef std::function<int(std::string_view, std::string_view)> compareFunc;
typedef std::tuple<size_t, compareFunc> key_comparator;
......@@ -126,6 +152,7 @@ class category_index
}
row *find(row *k) const;
row *find_by_value(row_initializer k) const;
void insert(row *r);
void erase(row *r);
......@@ -331,6 +358,37 @@ row *category_index::find(row *k) const
return r ? r->m_row : nullptr;
}
row *category_index::find_by_value(row_initializer k) const
{
// sort the values in k first
row_initializer k2;
for (auto &f : m_category.key_field_indices())
{
std::string fld = fld=m_category.get_column_name(f);
auto ki = find_if(k.begin(), k.end(), [&fld](item &i) { return i.name() == fld; });
if (ki == k.end())
k2.emplace_back(fld, "");
else
k2.emplace_back(*ki);
}
const entry *r = m_root;
while (r != nullptr)
{
int d = m_row_comparator(k2, r->m_row);
if (d < 0)
r = r->m_left;
else if (d > 0)
r = r->m_right;
else
break;
}
return r ? r->m_row : nullptr;
}
void category_index::insert(row *k)
{
m_root = insert(m_root, k);
......@@ -861,6 +919,17 @@ void category::validate_links() const
// --------------------------------------------------------------------
row_handle category::operator[](const key_type &key)
{
if (m_index == nullptr)
throw std::logic_error("Category " + m_name + " does not have an index");
auto row = m_index->find_by_value(key);
return row != nullptr ? row_handle{ *this, *row } : row_handle{};
}
// --------------------------------------------------------------------
condition category::get_parents_condition(row_handle rh, const category &parentCat) const
{
if (m_validator == nullptr or m_cat_validator == nullptr)
......@@ -1714,7 +1783,7 @@ void category::swap_item(size_t column_ix, row_handle &a, row_handle &b)
v->m_next = vb->m_next;
vb->m_next = nullptr;
if (rb->m_tail = vb)
if (rb->m_tail == vb)
rb->m_tail = v;
break;
......
......@@ -47,7 +47,7 @@ namespace cif::mm
atom::atom_impl::atom_impl(const atom_impl &impl, const point &loc, const std::string &sym_op)
: m_db(impl.m_db)
, m_id(impl.m_id)
, m_row(impl.m_row)
// , m_row(impl.m_row)
, m_location(loc)
, m_symop(sym_op)
{
......@@ -55,7 +55,65 @@ atom::atom_impl::atom_impl(const atom_impl &impl, const point &loc, const std::s
void atom::atom_impl::prefetch()
{
tie(m_location.m_x, m_location.m_y, m_location.m_z) = m_row.get("Cartn_x", "Cartn_y", "Cartn_z");
// tie(m_location.m_x, m_location.m_y, m_location.m_z) = m_row.get("Cartn_x", "Cartn_y", "Cartn_z");
}
void atom::atom_impl::moveTo(const point &p)
{
// if (m_symop != "1_555")
// throw std::runtime_error("Moving symmetry copy");
// #if __cpp_lib_format
// m_row.assign("Cartn_x", std::format("{:.3f}", p.getX()), false, false);
// m_row.assign("Cartn_y", std::format("{:.3f}", p.getY()), false, false);
// m_row.assign("Cartn_z", std::format("{:.3f}", p.getZ()), false, false);
// #else
// m_row.assign("Cartn_x", format("%.3f", p.m_x).str(), false, false);
// m_row.assign("Cartn_y", format("%.3f", p.m_y).str(), false, false);
// m_row.assign("Cartn_z", format("%.3f", p.m_z).str(), false, false);
// #endif
// m_location = p;
}
// const compound *compound() const;
std::string atom::atom_impl::get_property(std::string_view name) const
{
// return m_row[name].as<std::string>();
}
int atom::atom_impl::get_property_int(std::string_view name) const
{
int result = 0;
// if (not m_row[name].empty())
// {
// auto s = get_property(name);
// std::from_chars_result r = std::from_chars(s.data(), s.data() + s.length(), result);
// if (r.ec != std::errc() and VERBOSE > 0)
// std::cerr << "Error converting " << s << " to number for property " << name << std::endl;
// }
return result;
}
float atom::atom_impl::get_property_float(std::string_view name) const
{
float result = 0;
// if (not m_row[name].empty())
// {
// auto s = get_property(name);
// std::from_chars_result r = std::from_chars(s.data(), s.data() + s.length(), result);
// if (r.ec != std::errc() and VERBOSE > 0)
// std::cerr << "Error converting " << s << " to number for property " << name << std::endl;
// }
return result;
}
void atom::atom_impl::set_property(const std::string_view name, const std::string &value)
{
// m_row.assign(name, value, true, true);
}
// int atom::atom_impl::compare(const atom_impl &b) const
......@@ -92,17 +150,17 @@ void atom::atom_impl::prefetch()
int atom::atom_impl::get_charge() const
{
auto formalCharge = m_row["pdbx_formal_charge"].as<std::optional<int>>();
// auto formalCharge = m_row["pdbx_formal_charge"].as<std::optional<int>>();
if (not formalCharge.has_value())
{
auto c = cif::compound_factory::instance().create(get_property("label_comp_id"));
// if (not formalCharge.has_value())
// {
// auto c = cif::compound_factory::instance().create(get_property("label_comp_id"));
if (c != nullptr and c->atoms().size() == 1)
formalCharge = c->atoms().front().charge;
}
// if (c != nullptr and c->atoms().size() == 1)
// formalCharge = c->atoms().front().charge;
// }
return formalCharge.value_or(0);
// return formalCharge.value_or(0);
}
// const Compound *atom::atom_impl::compound() const
......@@ -919,12 +977,14 @@ polymer::polymer(const structure &s, const std::string &entityID, const std::str
, m_asym_id(asym_id)
// , mPolySeq(s.m_db["pdbx_poly_seq_scheme"), key("asym_id") == m_asym_id and key("entity_id") == m_entity_i])
{
using namespace cif::literals;
std::map<size_t, size_t> ix;
auto &poly_seq_scheme = s.get_datablock()["pdbx_poly_seq_scheme"];
reserve(poly_seq_scheme.size());
for (auto r : poly_seq_scheme)
for (auto r : poly_seq_scheme.find("asym_id"_key == asym_id))
{
int seqID;
std::string compoundID, authSeqID;
......@@ -1251,7 +1311,7 @@ void structure::load_atoms_for_model(StructureOpenOptions options)
if ((options bitand StructureOpenOptions::SkipHydrogen) and type_symbol == "H")
continue;
emplace_atom(std::make_shared<atom::atom_impl>(m_db, id, a));
emplace_atom(std::make_shared<atom::atom_impl>(m_db, id));
}
}
......@@ -1689,6 +1749,14 @@ atom &structure::emplace_atom(atom &&atom)
m_atom_index.insert(m_atom_index.begin() + R + 1, m_atoms.size());
// make sure the atom_type is known
auto &atom_type = m_db["atom_type"];
std::string symbol = atom.get_property("type_symbol");
using namespace cif::literals;
if (not atom_type.exists("symbol"_key == symbol))
atom_type.emplace({ { "symbol", symbol } });
return m_atoms.emplace_back(std::move(atom));
}
......@@ -2088,7 +2156,7 @@ std::string structure::create_non_poly(const std::string &entity_id, const std::
{"pdbx_PDB_model_num", 1}
});
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id, row));
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id));
res.add_atom(newAtom);
}
......@@ -2110,7 +2178,7 @@ std::string structure::create_non_poly(const std::string &entity_id, const std::
return asym_id;
}
std::string structure::create_non_poly(const std::string &entity_id, std::vector<std::vector<item>> &atom_info)
std::string structure::create_non_poly(const std::string &entity_id, std::vector<row_initializer> atoms)
{
using namespace literals;
......@@ -2131,14 +2199,14 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
auto &res = m_non_polymers.emplace_back(*this, comp_id, asym_id, 0, "1");
auto appendUnlessSet = [](std::vector<item> &ai, item &&i)
auto appendUnlessSet = [](row_initializer &ai, item &&i)
{
if (find_if(ai.begin(), ai.end(), [name = i.name()](item &ci)
{ return ci.name() == name; }) == ai.end())
ai.emplace_back(std::move(i));
};
for (auto &atom : atom_info)
for (auto &atom : atoms)
{
auto atom_id = atom_site.get_unique_id("");
......@@ -2156,7 +2224,7 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
auto row = atom_site.emplace(atom.begin(), atom.end());
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id, row));
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id));
res.add_atom(newAtom);
}
......@@ -2178,10 +2246,10 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
return asym_id;
}
branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
branch &structure::create_branch(std::vector<row_initializer> atoms)
{
// sanity check
for (auto &nag_atom : nag_atoms)
for (auto &nag_atom : atoms)
{
for (auto info : nag_atom)
{
......@@ -2201,14 +2269,14 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
auto &atom_site = m_db["atom_site"];
auto appendUnlessSet = [](std::vector<item> &ai, item &&i)
auto appendUnlessSet = [](row_initializer &ai, item &&i)
{
if (find_if(ai.begin(), ai.end(), [name = i.name()](item &ci)
{ return ci.name() == name; }) == ai.end())
ai.emplace_back(std::move(i));
};
for (auto &atom : nag_atoms)
for (auto &atom : atoms)
{
auto atom_id = atom_site.get_unique_id("");
......@@ -2226,7 +2294,7 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
auto row = atom_site.emplace(atom.begin(), atom.end());
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id, row));
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id));
sugar.add_atom(newAtom);
}
......@@ -2265,7 +2333,7 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
return branch;
}
branch &structure::extend_branch(const std::string &asym_id, std::vector<std::vector<item>> &atom_info,
branch &structure::extend_branch(const std::string &asym_id, std::vector<row_initializer> atom_info,
int link_sugar, const std::string &link_atom)
{
// sanity check
......
......@@ -69,7 +69,7 @@ row_initializer::row_initializer(row_handle rh)
auto &cat = *rh.m_category;
for (auto i = r->m_head; i != nullptr; i = i->m_next)
m_items.emplace_back(cat.get_column_name(i->m_column_ix), i->text());
emplace_back(cat.get_column_name(i->m_column_ix), i->text());
}
} // namespace cif
\ No newline at end of file
......@@ -177,6 +177,7 @@ _struct_asym.pdbx_blank_PDB_chainid_flag N
_struct_asym.pdbx_modified N
_struct_asym.details ?
#
_atom_type.symbol C
)"_cf;
expected.load_dictionary("mmcif_pdbx.dic");
......
#include "../include/cif++/Cif++.hpp"
#include "../include/cif++/PDB2Cif.hpp"
#include "../include/cif++/Structure.hpp"
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cif++.hpp>
#include <iostream>
#include <fstream>
......@@ -22,16 +46,16 @@ int main(int argc, char* argv[])
if (std::filesystem::exists(testdir / ".." / "rsrc" / "mmcif_pdbx.dic"))
cif::add_file_resource("mmcif_pdbx.dic", testdir / ".." / "rsrc" / "mmcif_pdbx.dic");
mmcif::CompoundFactory::instance().pushDictionary(testdir / "REA.cif");
mmcif::CompoundFactory::instance().pushDictionary(testdir / "RXA.cif");
cif::compound_factory::instance().push_dictionary(testdir / "REA.cif");
cif::compound_factory::instance().push_dictionary(testdir / "RXA.cif");
mmcif::file f(testdir / ".."/"examples"/"1cbs.cif.gz");
mmcif::Structure structure(f);
cif::file f(testdir / ".."/"examples"/"1cbs.cif.gz");
cif::mm::structure structure(f);
auto &res = structure.getResidue("B");
auto &res = structure.get_residue("B");
structure.change_residue(res, "RXA", {});
structure.cleanupEmptyCategories();
structure.cleanup_empty_categories();
f.save(std::cout);
}
......
......@@ -29,8 +29,7 @@
#include <stdexcept>
#include <cif++/cif.hpp>
#include <cif++/structure/Structure.hpp>
#include <cif++.hpp>
// --------------------------------------------------------------------
......@@ -66,7 +65,7 @@ bool init_unit_test()
// initialize CCD location
cif::add_file_resource("components.cif", gTestDir / ".." / "data" / "ccd-subset.cif");
mmcif::CompoundFactory::instance().pushDictionary(gTestDir / "HEM.cif");
cif::compound_factory::instance().push_dictionary(gTestDir / "HEM.cif");
return true;
}
......@@ -78,10 +77,10 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
using namespace cif::literals;
const std::filesystem::path example(gTestDir / "1juh.cif.gz");
mmcif::file file(example.string());
mmcif::Structure s(file);
cif::file file(example.string());
cif::mm::structure s(file);
auto &db = s.datablock();
auto &db = s.get_datablock();
auto &entity = db["entity"];
auto &branches = s.branches();
......@@ -90,7 +89,7 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
for (auto &branch : branches)
{
auto entityID = branch.front().entityID();
auto entityID = branch.front().get_entity_id();
auto name = entity.find1<std::string>("id"_key == entityID, "pdbx_description");
BOOST_CHECK_EQUAL(branch.name(), name);
......@@ -104,20 +103,20 @@ BOOST_AUTO_TEST_CASE(create_sugar_1)
using namespace cif::literals;
const std::filesystem::path example(gTestDir / "1juh.cif.gz");
mmcif::file file(example.string());
mmcif::Structure s(file);
cif::file file(example.string());
cif::mm::structure s(file);
// collect atoms from asym L first
auto &NAG = s.getResidue("L");
auto &NAG = s.get_residue("L");
auto nagAtoms = NAG.atoms();
std::vector<std::vector<cif::Item>> ai;
std::vector<cif::row_initializer> ai;
auto &db = s.datablock();
auto &db = s.get_datablock();
auto &as = db["atom_site"];
for (auto r : as.find("label_asym_id"_key == "L"))
ai.emplace_back(r.begin(), r.end());
ai.emplace_back(r);
s.remove_residue(NAG);
......@@ -136,36 +135,36 @@ BOOST_AUTO_TEST_CASE(create_sugar_2)
using namespace cif::literals;
const std::filesystem::path example(gTestDir / "1juh.cif.gz");
mmcif::file file(example.string());
mmcif::Structure s(file);
cif::file file(example.string());
cif::mm::structure s(file);
// Get branch for H
auto &bH = s.getBranchByAsymID("H");
auto &bH = s.get_branch_by_asym_id("H");
BOOST_CHECK_EQUAL(bH.size(), 2);
std::vector<std::vector<cif::Item>> ai[2];
std::vector<cif::row_initializer> ai[2];
auto &db = s.datablock();
auto &db = s.get_datablock();
auto &as = db["atom_site"];
for (size_t i = 0; i < 2; ++i)
{
for (auto r : as.find("label_asym_id"_key == "H" and "auth_seq_id"_key == i + 1))
ai[i].emplace_back(r.begin(), r.end());
ai[i].emplace_back(r);
}
s.remove_branch(bH);
auto &bN = s.create_branch(ai[0]);
s.extend_branch(bN.asymID(), ai[1], 1, "O4");
s.extend_branch(bN.get_asym_id(), ai[1], 1, "O4");
BOOST_CHECK_EQUAL(bN.name(), "2-acetamido-2-deoxy-beta-D-glucopyranose-(1-4)-2-acetamido-2-deoxy-beta-D-glucopyranose");
BOOST_CHECK_EQUAL(bN.size(), 2);
file.save(gTestDir / "test-create_sugar_2.cif");
BOOST_CHECK_NO_THROW(mmcif::Structure s2(file));
BOOST_CHECK_NO_THROW(cif::mm::structure s2(file));
}
// --------------------------------------------------------------------
......@@ -175,11 +174,11 @@ BOOST_AUTO_TEST_CASE(delete_sugar_1)
using namespace cif::literals;
const std::filesystem::path example(gTestDir / "1juh.cif.gz");
mmcif::file file(example.string());
mmcif::Structure s(file);
cif::file file(example.string());
cif::mm::structure s(file);
// Get branch for H
auto &bG = s.getBranchByAsymID("G");
auto &bG = s.get_branch_by_asym_id("G");
BOOST_CHECK_EQUAL(bG.size(), 4);
......@@ -187,12 +186,12 @@ BOOST_AUTO_TEST_CASE(delete_sugar_1)
BOOST_CHECK_EQUAL(bG.size(), 1);
auto &bN = s.getBranchByAsymID("G");
auto &bN = s.get_branch_by_asym_id("G");
BOOST_CHECK_EQUAL(bN.name(), "2-acetamido-2-deoxy-beta-D-glucopyranose");
BOOST_CHECK_EQUAL(bN.size(), 1);
file.save(gTestDir / "test-create_sugar_3.cif");
BOOST_CHECK_NO_THROW(mmcif::Structure s2(file));
BOOST_CHECK_NO_THROW(cif::mm::structure s2(file));
}
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