Commit f77bbfed by Maarten L. Hekkelman

updates

parent 3aa3fe19
...@@ -370,7 +370,9 @@ if(ENABLE_TESTING) ...@@ -370,7 +370,9 @@ if(ENABLE_TESTING)
find_package(Boost REQUIRED headers) 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) foreach(CIFPP_TEST IN LISTS CIFPP_tests)
set(CIFPP_TEST "${CIFPP_TEST}-test") set(CIFPP_TEST "${CIFPP_TEST}-test")
......
...@@ -286,14 +286,17 @@ class category ...@@ -286,14 +286,17 @@ class category
{ {
bool result = false; bool result = false;
cond.prepare(*this); if (cond)
for (auto r : *this)
{ {
if (cond(r)) cond.prepare(*this);
for (auto r : *this)
{ {
result = true; if (cond(r))
break; {
result = true;
break;
}
} }
} }
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <numeric> #include <numeric>
#include <cif++/atom_type.hpp>
#if __cpp_lib_format #if __cpp_lib_format
#include <format> #include <format>
#endif #endif
...@@ -80,7 +82,7 @@ class atom ...@@ -80,7 +82,7 @@ class atom
// bool getAnisoU(float anisou[6]) const; // bool getAnisoU(float anisou[6]) const;
// int charge() const; int charge() const;
void moveTo(const point &p) void moveTo(const point &p)
{ {
...@@ -128,6 +130,20 @@ class atom ...@@ -128,6 +130,20 @@ class atom
return result; 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) void set_property(const std::string_view name, const std::string &value)
{ {
m_row.assign(name, value, true, true); m_row.assign(name, value, true, true);
...@@ -214,6 +230,13 @@ class atom ...@@ -214,6 +230,13 @@ class atom
return m_impl->get_property_int(name); return m_impl->get_property_int(name);
} }
float get_property_float(std::string_view name) const
{
if (not m_impl)
throw std::logic_error("Error trying to fetch a property from an uninitialized atom");
return m_impl->get_property_float(name);
}
void set_property(const std::string_view name, const std::string &value) void set_property(const std::string_view name, const std::string &value)
{ {
if (not m_impl) if (not m_impl)
...@@ -228,7 +251,8 @@ class atom ...@@ -228,7 +251,8 @@ class atom
} }
const std::string &id() const { return impl().m_id; } const std::string &id() const { return impl().m_id; }
// AtomType type() const { return impl().mType; }
cif::atom_type get_type() const { return atom_type_traits(get_property("type_symbol")).type(); }
point get_location() const { return impl().m_location; } point get_location() const { return impl().m_location; }
void set_location(point p) void set_location(point p)
...@@ -280,7 +304,7 @@ class atom ...@@ -280,7 +304,7 @@ class atom
// const compound &compound() const; // const compound &compound() const;
// bool isWater() const { return impl().mCompID == "HOH" or impl().mCompID == "H2O" or impl().mCompID == "WAT"; } // bool isWater() const { return impl().mCompID == "HOH" or impl().mCompID == "H2O" or impl().mCompID == "WAT"; }
// int charge() const; int get_charge() const;
// float uIso() const; // float uIso() const;
// bool getAnisoU(float anisou[6]) const { return impl().getAnisoU(anisou); } // bool getAnisoU(float anisou[6]) const { return impl().getAnisoU(anisou); }
...@@ -297,6 +321,7 @@ class atom ...@@ -297,6 +321,7 @@ class atom
std::string get_auth_asym_id() const { return get_property("auth_asym_id"); } std::string get_auth_asym_id() const { return get_property("auth_asym_id"); }
std::string get_auth_seq_id() const { return get_property("auth_seq_id"); } std::string get_auth_seq_id() const { return get_property("auth_seq_id"); }
std::string get_auth_atom_id() const { return get_property("auth_atom_id"); }
std::string get_pdb_ins_code() const { return get_property("pdbx_PDB_ins_code"); } std::string get_pdb_ins_code() const { return get_property("pdbx_PDB_ins_code"); }
// const std::string &labelAtomID() const { return impl().mAtomID; } // const std::string &labelAtomID() const { return impl().mAtomID; }
...@@ -457,6 +482,11 @@ class residue ...@@ -457,6 +482,11 @@ class residue
} }
const std::string get_auth_seq_id() const { return m_auth_seq_id; } const std::string get_auth_seq_id() const { return m_auth_seq_id; }
std::string get_pdb_ins_code() const
{
return m_atoms.empty() ? "" : m_atoms.front().get_pdb_ins_code();
}
const std::string &get_compound_id() const { return m_compound_id; } const std::string &get_compound_id() const { return m_compound_id; }
void set_compound_id(const std::string &id) { m_compound_id = id; } void set_compound_id(const std::string &id) { m_compound_id = id; }
...@@ -476,8 +506,8 @@ class residue ...@@ -476,8 +506,8 @@ class residue
void add_atom(atom &atom); void add_atom(atom &atom);
// /// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id. /// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
// std::vector<atom> unique_atoms() const; std::vector<atom> unique_atoms() const;
// /// \brief The alt ID used for the unique atoms // /// \brief The alt ID used for the unique atoms
// std::string unique_alt_id() const; // std::string unique_alt_id() const;
...@@ -773,12 +803,12 @@ class structure ...@@ -773,12 +803,12 @@ class structure
const std::list<polymer> &polymers() const { return m_polymers; } const std::list<polymer> &polymers() const { return m_polymers; }
std::list<polymer> &polymers() { return m_polymers; } std::list<polymer> &polymers() { return m_polymers; }
// polymer &getPolymerByAsymID(const std::string &asymID); polymer &get_polymer_by_asym_id(const std::string &asymID);
// const polymer &getPolymerByAsymID(const std::string &asymID) const const polymer &get_polymer_by_asym_id(const std::string &asymID) const
// { {
// return const_cast<structure *>(this)->getPolymerByAsymID(asymID); return const_cast<structure *>(this)->get_polymer_by_asym_id(asymID);
// } }
const std::list<branch> &branches() const { return m_branches; } const std::list<branch> &branches() const { return m_branches; }
std::list<branch> &branches() { return m_branches; } std::list<branch> &branches() { return m_branches; }
...@@ -797,8 +827,8 @@ class structure ...@@ -797,8 +827,8 @@ class structure
// /// \brief Return the atom closest to point \a p // /// \brief Return the atom closest to point \a p
// atom getAtomByPosition(point p) const; // atom getAtomByPosition(point p) const;
// /// \brief Return the atom closest to point \a p with atom type \a type in a residue of type \a res_type /// \brief Return the atom closest to point \a p with atom type \a type in a residue of type \a res_type
// atom getAtomByPositionAndType(point p, std::string_view type, std::string_view res_type) const; atom get_atom_by_position_and_type(point p, std::string_view type, std::string_view res_type) const;
/// \brief Get a non-poly residue for an asym with id \a asymID /// \brief Get a non-poly residue for an asym with id \a asymID
residue &get_residue(const std::string &asymID) residue &get_residue(const std::string &asymID)
...@@ -917,11 +947,11 @@ class structure ...@@ -917,11 +947,11 @@ class structure
void cleanup_empty_categories(); void cleanup_empty_categories();
// /// \brief Direct access to underlying data /// \brief Direct access to underlying data
// category &category(std::string_view name) const category &get_category(std::string_view name) const
// { {
// return m_db[name]; return m_db[name];
// } }
datablock &get_datablock() const datablock &get_datablock() const
{ {
......
...@@ -885,10 +885,7 @@ condition category::get_parents_condition(row_handle rh, const category &parentC ...@@ -885,10 +885,7 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
cond = std::move(cond) and key(link->m_parent_keys[ix]) == childValue.text(); cond = std::move(cond) and key(link->m_parent_keys[ix]) == childValue.text();
} }
if (result) result = std::move(result) or std::move(cond);
result = std::move(result) or std::move(cond);
else
result = std::move(cond);
} }
return result; return result;
......
...@@ -393,37 +393,37 @@ void residue::add_atom(atom &atom) ...@@ -393,37 +393,37 @@ void residue::add_atom(atom &atom)
m_atoms.push_back(atom); m_atoms.push_back(atom);
} }
// std::vector<atom> residue::unique_atoms() const std::vector<atom> residue::unique_atoms() const
// { {
// if (m_structure == nullptr) // if (m_structure == nullptr)
// throw std::runtime_error("Invalid residue object"); // throw std::runtime_error("Invalid residue object");
// std::vector<atom> result; std::vector<atom> result;
// std::string firstAlt; std::string firstAlt;
// for (auto &atom : m_atoms) for (auto &atom : m_atoms)
// { {
// auto alt = atom.get_label_alt_id(); auto alt = atom.get_label_alt_id();
// if (alt.empty()) if (alt.empty())
// { {
// result.push_back(atom); result.push_back(atom);
// continue; continue;
// } }
// if (firstAlt.empty()) if (firstAlt.empty())
// firstAlt = alt; firstAlt = alt;
// else if (alt != firstAlt) else if (alt != firstAlt)
// { {
// if (VERBOSE > 0) if (VERBOSE > 0)
// std::cerr << "skipping alternate atom " << atom << std::endl; std::cerr << "skipping alternate atom " << atom << std::endl;
// continue; continue;
// } }
// result.push_back(atom); result.push_back(atom);
// } }
// return result; return result;
// } }
// std::set<std::string> residue::getAlternateIDs() const // std::set<std::string> residue::getAlternateIDs() const
// { // {
...@@ -1489,47 +1489,47 @@ atom structure::get_atom_by_id(const std::string &id) const ...@@ -1489,47 +1489,47 @@ atom structure::get_atom_by_id(const std::string &id) const
// return {}; // return {};
// } // }
// atom structure::getAtomByPositionAndType(point p, std::string_view type, std::string_view res_type) const atom structure::get_atom_by_position_and_type(point p, std::string_view type, std::string_view res_type) const
// { {
// double distance = std::numeric_limits<double>::max(); double dist = std::numeric_limits<double>::max();
// size_t index = std::numeric_limits<size_t>::max(); size_t index = std::numeric_limits<size_t>::max();
// for (size_t i = 0; i < m_atoms.size(); ++i) for (size_t i = 0; i < m_atoms.size(); ++i)
// { {
// auto &a = m_atoms.at(i); auto &a = m_atoms.at(i);
// if (a.labelCompID() != res_type) if (a.get_label_comp_id() != res_type)
// continue; continue;
// if (a.get_label_atom_id() != type) if (a.get_label_atom_id() != type)
// continue; continue;
// auto d = Distance(a.location(), p); auto d = distance(a.get_location(), p);
// if (d < distance) if (dist > d)
// { {
// distance = d; dist = d;
// index = i; index = i;
// } }
// } }
// if (index < m_atoms.size()) if (index < m_atoms.size())
// return m_atoms.at(index); return m_atoms.at(index);
// return {}; return {};
// } }
// polymer &structure::getPolymerByAsym_id(const std::string &asym_id) polymer &structure::get_polymer_by_asym_id(const std::string &asym_id)
// { {
// for (auto &poly : m_polymers) for (auto &poly : m_polymers)
// { {
// if (poly.get_asym_id() != asym_id) if (poly.get_asym_id() != asym_id)
// continue; continue;
// return poly; return poly;
// } }
// throw std::runtime_error("polymer with asym id " + asym_id + " not found"); throw std::runtime_error("polymer with asym id " + asym_id + " not found");
// } }
residue &structure::get_residue(const std::string &asym_id, int seqID, const std::string &authSeqID) residue &structure::get_residue(const std::string &asym_id, int seqID, const std::string &authSeqID)
{ {
......
...@@ -1514,6 +1514,170 @@ _cat_2.parent_id3 ...@@ -1514,6 +1514,170 @@ _cat_2.parent_id3
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(d6)
{
const char dict[] = R"(
data_test_dict.dic
_datablock.id test_dict.dic
_datablock.description
;
A test dictionary
;
_dictionary.title test_dict.dic
_dictionary.datablock_id test_dict.dic
_dictionary.version 1.0
loop_
_item_type_list.code
_item_type_list.primitive_code
_item_type_list.construct
code char
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
text char
'[][ \n\t()_,.;:"&<>/\{}'`~!@#$%?+=*A-Za-z0-9|^-]*'
int numb
'[+-]?[0-9]+'
save_cat_1
_category.description 'A simple test category'
_category.id cat_1
_category.mandatory_code yes
_category_key.name '_cat_1.id'
save_
save__cat_1.id
_item.name '_cat_1.id'
_item.category_id cat_1
_item.mandatory_code yes
_item_type.code int
save_
save__cat_1.id_2
_item.name '_cat_1.id_2'
_item.category_id cat_1
_item.mandatory_code no
_item_type.code int
save_
save_cat_2
_category.description 'A second simple test category'
_category.id cat_2
_category.mandatory_code no
_category_key.name '_cat_2.id'
save_
save__cat_2.id
_item.name '_cat_2.id'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.parent_id
_item.name '_cat_2.parent_id'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.parent_id_2
_item.name '_cat_2.parent_id_2'
_item.category_id cat_2
_item.mandatory_code no
_item_type.code code
save_
loop_
_pdbx_item_linked_group_list.child_category_id
_pdbx_item_linked_group_list.link_group_id
_pdbx_item_linked_group_list.child_name
_pdbx_item_linked_group_list.parent_name
_pdbx_item_linked_group_list.parent_category_id
cat_2 1 '_cat_2.parent_id' '_cat_1.id' cat_1
cat_2 1 '_cat_2.parent_id_2' '_cat_1.id_2' cat_1
loop_
_pdbx_item_linked_group.category_id
_pdbx_item_linked_group.link_group_id
_pdbx_item_linked_group.label
cat_2 1 cat_2:cat_1:1
)";
struct membuf : public std::streambuf
{
membuf(char *text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char *>(dict), sizeof(dict) - 1);
std::istream is_dict(&buffer);
auto validator = cif::parse_dictionary("test", is_dict);
cif::file f;
f.set_validator(&validator);
// --------------------------------------------------------------------
const char data[] = R"(
data_test
loop_
_cat_1.id
_cat_1.id_2
1 1
2 2
3 ?
loop_
_cat_2.id
_cat_2.parent_id
_cat_2.parent_id_2
0 1 1
1 1 ?
2 ? 1
3 ? ?
4 2 2
5 3 1
6 3 ?
)";
// --------------------------------------------------------------------
struct data_membuf : public std::streambuf
{
data_membuf(char *text, size_t length)
{
this->setg(text, text, text + length);
}
} data_buffer(const_cast<char *>(data), sizeof(data) - 1);
std::istream is_data(&data_buffer);
f.load(is_data);
auto &cat1 = f.front()["cat_1"];
auto &cat2 = f.front()["cat_2"];
// f.front().validate_links();
// BOOST_CHECK(not );
using namespace cif::literals;
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 0)));
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 1)));
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 2)));
BOOST_CHECK(not cat2.has_parents(cat2.find1("id"_key == 3)));
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 4)));
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 5)));
BOOST_CHECK( cat2.has_parents(cat2.find1("id"_key == 6)));
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(c1) BOOST_AUTO_TEST_CASE(c1)
{ {
cif::VERBOSE = 1; cif::VERBOSE = 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