mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 22:14:24 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaa5032e11 | ||
|
|
8400247674 | ||
|
|
08e1b197ac |
@@ -122,7 +122,7 @@ class atom
|
||||
|
||||
// const compound *compound() const;
|
||||
|
||||
[[nodiscard]] const item_value &get_property(std::string_view name) const;
|
||||
[[nodiscard]] const item_handle get_property(std::string_view name) const;
|
||||
void set_property(const std::string_view name, item_value value);
|
||||
|
||||
row_handle row()
|
||||
@@ -227,7 +227,7 @@ class atom
|
||||
explicit operator bool() const { return m_impl.operator bool(); }
|
||||
|
||||
/// \brief Return the item named @a name in the _atom_site category for this atom
|
||||
[[nodiscard]] const item_value &get_property_value(std::string_view name) const
|
||||
[[nodiscard]] const item_handle get_property_value(std::string_view name) const
|
||||
{
|
||||
if (not m_impl)
|
||||
throw std::logic_error("Error trying to fetch a property from an uninitialized atom");
|
||||
|
||||
@@ -614,11 +614,11 @@ void category::drop_empty_items()
|
||||
{
|
||||
std::vector<bool> is_empty(get_item_count(), true);
|
||||
|
||||
for (auto row : *this)
|
||||
for (size_t ix = 0; ix < get_item_count(); ++ix)
|
||||
{
|
||||
for (size_t ix = 0; ix < get_item_count(); ++ix)
|
||||
for (auto row : *this)
|
||||
{
|
||||
if (is_empty[ix] and not row[ix].empty())
|
||||
if (not row[ix].empty())
|
||||
{
|
||||
is_empty[ix] = false;
|
||||
break;
|
||||
@@ -1612,7 +1612,6 @@ void category::update_value(row *row, uint16_t item, item_value value, bool upda
|
||||
}
|
||||
else if (ec)
|
||||
throw validation_exception(ec, m_name, m_items[item].m_name);
|
||||
|
||||
}
|
||||
|
||||
// If the item is part of the Key for this category, remove it from the index
|
||||
@@ -2200,7 +2199,7 @@ void category::write_cif(std::ostream &os, const std::vector<uint16_t> &order, b
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
offset = detail::write_value(os, s, offset, w, right_aligned[cix]/* iv->is_number() */);
|
||||
offset = detail::write_value(os, s, offset, w, right_aligned[cix] /* iv->is_number() */);
|
||||
|
||||
if (offset > 132)
|
||||
{
|
||||
@@ -2722,70 +2721,20 @@ bool category::operator==(const category &rhs) const
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
// set<std::string> item_namesA(a.items()), item_namesB(b.items());
|
||||
//
|
||||
// if (item_namesA != item_namesB)
|
||||
// std::cout << "Unequal number of items\n";
|
||||
std::set<std::string> keys;
|
||||
|
||||
const category_validator *catValidator = nullptr;
|
||||
|
||||
auto validator = a.get_validator();
|
||||
if (validator != nullptr)
|
||||
catValidator = validator->get_validator_for_category(a.name());
|
||||
|
||||
using compType = std::function<int(std::string_view, std::string_view)>;
|
||||
std::vector<std::tuple<std::string, compType>> item_names;
|
||||
std::vector<std::string> keys;
|
||||
std::vector<std::size_t> keyIx;
|
||||
|
||||
if (catValidator == nullptr)
|
||||
for (const auto &items : { a.get_items(), b.get_items()})
|
||||
{
|
||||
for (auto &item_name : a.get_items())
|
||||
{
|
||||
item_names.emplace_back(item_name, [](std::string_view va, std::string_view vb)
|
||||
{ return va.compare(vb); });
|
||||
keyIx.push_back(keys.size());
|
||||
keys.push_back(item_name);
|
||||
}
|
||||
for (auto &item_name : items)
|
||||
keys.insert(item_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
keys = catValidator->m_keys;
|
||||
|
||||
for (auto &item_name : a.key_items())
|
||||
{
|
||||
auto iv = catValidator->get_validator_for_item(item_name);
|
||||
if (iv == nullptr)
|
||||
throw std::runtime_error("missing item validator");
|
||||
auto tv = iv->m_type;
|
||||
if (tv == nullptr)
|
||||
throw std::runtime_error("missing type validator");
|
||||
item_names.emplace_back(item_name, [tv](auto &&a1, auto &&a2)
|
||||
{ return tv->compare(std::forward<decltype(a1)>(a1), std::forward<decltype(a2)>(a2)); });
|
||||
|
||||
auto pred = [item_name](const std::string &s) -> bool
|
||||
{
|
||||
return cif::iequals(item_name, s) == 0;
|
||||
};
|
||||
if (std::ranges::find_if(keys, pred) == keys.end())
|
||||
keyIx.push_back(item_names.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// a.reorderByIndex();
|
||||
// b.reorderByIndex();
|
||||
|
||||
auto rowEqual = [&](const_row_handle &a, const_row_handle &b)
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
for (auto kix : keyIx)
|
||||
for (const auto &item_name : keys)
|
||||
{
|
||||
std::string item_name;
|
||||
compType compare;
|
||||
|
||||
std::tie(item_name, compare) = item_names[kix];
|
||||
|
||||
d = a[item_name].compare(b[item_name]);
|
||||
|
||||
if (d != 0)
|
||||
@@ -2806,28 +2755,6 @@ bool category::operator==(const category &rhs) const
|
||||
if (not rowEqual(ra, rb))
|
||||
return false;
|
||||
|
||||
std::vector<std::string> missingA, missingB, different;
|
||||
|
||||
for (auto &tt : item_names)
|
||||
{
|
||||
std::string item_name;
|
||||
compType compare;
|
||||
|
||||
std::tie(item_name, compare) = tt;
|
||||
|
||||
// make it an option to compare unapplicable to empty or something
|
||||
|
||||
// auto ta = ra[item_name].text();
|
||||
// if (ta == "." or ta == "?")
|
||||
// ta = "";
|
||||
// auto tb = rb[item_name].text();
|
||||
// if (tb == "." or tb == "?")
|
||||
// tb = "";
|
||||
|
||||
if (ra[item_name].compare(rb[item_name]) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "cif++/cif++.hpp"
|
||||
#include "cif++/item.hpp"
|
||||
#include "cif++/row.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -76,10 +77,10 @@ void atom::atom_impl::moveTo(const point &p)
|
||||
|
||||
// const compound *compound() const;
|
||||
|
||||
const item_value &atom::atom_impl::get_property(std::string_view name) const
|
||||
const item_handle atom::atom_impl::get_property(std::string_view name) const
|
||||
{
|
||||
if (auto rh = row(); rh)
|
||||
return rh[name].value();
|
||||
return rh[name];
|
||||
throw std::runtime_error(std::format("Missing property {} for atom", name));
|
||||
}
|
||||
|
||||
@@ -1911,7 +1912,13 @@ void structure::change_residue(residue &res, const std::string &newCompound,
|
||||
for (const auto &[a1, a2] : remappedAtoms)
|
||||
{
|
||||
auto i = std::ranges::find_if(atoms, [id = a1](const atom &a)
|
||||
{ return a.get_label_atom_id() == id; });
|
||||
{
|
||||
if (a.get_row())
|
||||
{
|
||||
auto ih = a.get_property_value("label_atom_id");
|
||||
return not ih.empty() and ih.get<std::string>() == id;
|
||||
}
|
||||
return false; });
|
||||
if (i == atoms.end())
|
||||
{
|
||||
if (VERBOSE >= 0)
|
||||
@@ -2170,29 +2177,50 @@ std::string structure::create_non_poly(const std::string &entity_id, const std::
|
||||
{
|
||||
auto atom_id = atom_site.get_unique_id("");
|
||||
|
||||
auto row = atom_site.emplace({ { "group_PDB", atom.get_property("group_PDB") },
|
||||
{ "id", atom_id },
|
||||
{ "type_symbol", atom.get_property_value("type_symbol") },
|
||||
{ "label_atom_id", atom.get_property_value("label_atom_id") },
|
||||
{ "label_alt_id", atom.get_property_value("label_alt_id") },
|
||||
{ "label_comp_id", comp_id },
|
||||
{ "label_asym_id", asym_id },
|
||||
{ "label_entity_id", entity_id },
|
||||
{ "label_seq_id", cif::item_value_type::INAPPLICABLE },
|
||||
{ "pdbx_PDB_ins_code", cif::item_value_type::MISSING },
|
||||
{ "Cartn_x", atom.get_property_value("Cartn_x") },
|
||||
{ "Cartn_y", atom.get_property_value("Cartn_y") },
|
||||
{ "Cartn_z", atom.get_property_value("Cartn_z") },
|
||||
{ "occupancy", atom.get_property_value("occupancy") },
|
||||
{ "B_iso_or_equiv", atom.get_property_value("B_iso_or_equiv") },
|
||||
{ "pdbx_formal_charge", atom.get_property_value("pdbx_formal_charge") },
|
||||
{ "auth_seq_id", "1" },
|
||||
{ "auth_comp_id", comp_id },
|
||||
{ "auth_asym_id", asym_id },
|
||||
{ "auth_atom_id", atom.get_property_value("label_atom_id") },
|
||||
{ "pdbx_PDB_model_num", m_model_nr } });
|
||||
cif::row_initializer data //
|
||||
{
|
||||
{ "id", atom_id },
|
||||
{ "label_comp_id", comp_id },
|
||||
{ "label_asym_id", asym_id },
|
||||
{ "label_entity_id", entity_id },
|
||||
{ "label_seq_id", cif::item_value_type::INAPPLICABLE },
|
||||
{ "pdbx_PDB_ins_code", cif::item_value_type::MISSING },
|
||||
{ "auth_seq_id", "1" },
|
||||
{ "auth_comp_id", comp_id },
|
||||
{ "auth_asym_id", asym_id },
|
||||
{ "pdbx_PDB_model_num", m_model_nr } //
|
||||
};
|
||||
|
||||
for (auto item : std::initializer_list<std::string>{
|
||||
// clang-format off
|
||||
"group_PDB",
|
||||
"type_symbol",
|
||||
"label_atom_id",
|
||||
"label_alt_id",
|
||||
"auth_atom_id",
|
||||
"Cartn_x",
|
||||
"Cartn_y",
|
||||
"Cartn_z",
|
||||
"occupancy",
|
||||
"B_iso_or_equiv",
|
||||
"pdbx_formal_charge"
|
||||
// clang-format on
|
||||
})
|
||||
{
|
||||
auto v = atom.get_property_value(item);
|
||||
if (not v.empty())
|
||||
data.push_back({ item, v.value() });
|
||||
else
|
||||
data.push_back({ item, cif::item_value_type::INAPPLICABLE });
|
||||
}
|
||||
|
||||
auto row = atom_site.emplace(std::move(data));
|
||||
|
||||
auto &newAtom = emplace_atom(std::make_shared<atom::atom_impl>(m_db, atom_id));
|
||||
|
||||
if (newAtom.get_property_value("auth_atom_id").empty() and not newAtom.get_property_value("label_atom_id").empty())
|
||||
newAtom.set_property("auth_atom_id", newAtom.get_property("label_atom_id"));
|
||||
|
||||
res.add_atom(newAtom);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user