Commit f4506438 by Maarten L. Hekkelman

Added remove column

parent fc14a655
......@@ -31,8 +31,8 @@
#include "cif++/condition.hpp"
#include "cif++/iterator.hpp"
#include "cif++/row.hpp"
#include "cif++/validate.hpp"
#include "cif++/text.hpp"
#include "cif++/validate.hpp"
#include <array>
......@@ -776,8 +776,7 @@ class category
/// @brief Return whether a row exists that matches condition @a cond
/// @param cond The condition to match
/// @return True if a row exists
[[deprecated("Use contains instead")]]
bool exists(condition &&cond) const
[[deprecated("Use contains instead")]] bool exists(condition &&cond) const
{
return contains(std::move(cond));
}
......@@ -941,7 +940,6 @@ class category
/// result is unique in the context of this category
std::string get_unique_id(std::function<std::string(int)> generator = cif::cif_id_for_number);
/// @brief Generate a new, unique ID based on a string prefix followed by a number
/// @param prefix The string prefix
/// @return a new unique ID
......@@ -1038,6 +1036,11 @@ class category
return result;
}
/** @brief Remove column name @a colum_name
* @param column_name The column to be removed
*/
void remove_column(std::string_view column_name);
/// @brief Return whether a column with name @a name exists in this category
/// @param name The name of the column
/// @return True if the column exists
......@@ -1082,7 +1085,6 @@ class category
void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const;
public:
/// friend function to make it possible to do:
/// @code {.cpp}
/// std::cout << my_category;
......
......@@ -360,7 +360,8 @@ row *category_index::find_by_value(const category &cat, row_initializer k) const
{
auto fld = cat.get_column_name(f);
auto ki = find_if(k.begin(), k.end(), [&fld](auto &i) { return i.name() == fld; });
auto ki = find_if(k.begin(), k.end(), [&fld](auto &i)
{ return i.name() == fld; });
if (ki == k.end())
k2.emplace_back(fld, "");
else
......@@ -594,6 +595,25 @@ category::~category()
// --------------------------------------------------------------------
void category::remove_column(std::string_view column_name)
{
for (size_t ix = 0; ix < m_columns.size(); ++ix)
{
if (not iequals(column_name, m_columns[ix].m_name))
continue;
for (row *r = m_head; r != nullptr; r = r->m_next)
{
if (r->size() > ix)
r->erase(r->begin() + ix);
}
m_columns.erase(m_columns.begin() + ix);
break;
}
}
iset category::get_columns() const
{
iset result;
......@@ -919,7 +939,9 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
condition result;
auto links = m_validator->get_links_for_child(m_name);
links.erase(remove_if(links.begin(), links.end(), [n=parentCat.m_name](auto &l) { return l->m_parent_category != n; }), links.end());
links.erase(remove_if(links.begin(), links.end(), [n = parentCat.m_name](auto &l)
{ return l->m_parent_category != n; }),
links.end());
if (not links.empty())
{
......@@ -959,7 +981,9 @@ condition category::get_children_condition(row_handle rh, const category &childC
mandatoryChildFields = childCatValidator->m_mandatory_fields;
auto links = m_validator->get_links_for_parent(m_name);
links.erase(remove_if(links.begin(), links.end(), [n=childCat.m_name](auto &l) { return l->m_child_category != n; }), links.end());
links.erase(remove_if(links.begin(), links.end(), [n = childCat.m_name](auto &l)
{ return l->m_child_category != n; }),
links.end());
if (not links.empty())
{
......@@ -1123,7 +1147,7 @@ category::iterator category::erase(iterator pos)
return result;
}
template<typename T>
template <typename T>
class save_value
{
public:
......@@ -1224,7 +1248,6 @@ void category::erase_orphans(condition &&cond, category &parent)
std::cerr << "Removing orphaned record: \n"
<< c << '\n'
<< '\n';
}
remove.emplace_back(r.m_row);
......@@ -1254,7 +1277,7 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
for (;;)
{
if (m_index->find_by_value(*this, {{ id_tag, result }}) == nullptr)
if (m_index->find_by_value(*this, { { id_tag, result } }) == nullptr)
break;
result = generator(static_cast<int>(m_last_unique_num++));
}
......@@ -1572,7 +1595,7 @@ row *category::clone_row(const row &r)
if (not i)
continue;
result->append( ix, { i.text() });
result->append(ix, { i.text() });
}
}
catch (...)
......@@ -1639,10 +1662,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
if (n == nullptr)
throw std::runtime_error("Invalid pointer passed to insert");
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
try
{
......@@ -1699,10 +1722,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
throw;
}
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
}
void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
......@@ -1716,7 +1739,7 @@ void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
std::swap(ra.at(column_ix), rb.at(column_ix));
}
void category::sort(std::function<int(row_handle,row_handle)> f)
void category::sort(std::function<int(row_handle, row_handle)> f)
{
if (m_head == nullptr)
return;
......@@ -2062,15 +2085,19 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
bool category::operator==(const category &rhs) const
{
// shortcut
if (this == &rhs)
return true;
auto &a = *this;
auto &b = rhs;
using namespace std::placeholders;
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields\n";
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields\n";
const category_validator *catValidator = nullptr;
......@@ -2078,16 +2105,17 @@ bool category::operator==(const category &rhs) const
if (validator != nullptr)
catValidator = validator->get_validator_for_category(a.name());
typedef std::function<int(std::string_view,std::string_view)> compType;
std::vector<std::tuple<std::string,compType>> tags;
typedef std::function<int(std::string_view, std::string_view)> compType;
std::vector<std::tuple<std::string, compType>> tags;
std::vector<std::string> keys;
std::vector<size_t> keyIx;
if (catValidator == nullptr)
{
for (auto& tag: a.get_columns())
for (auto &tag : a.get_columns())
{
tags.push_back(std::make_tuple(tag, [](std::string_view va, std::string_view vb) { return va.compare(vb); }));
tags.push_back(std::make_tuple(tag, [](std::string_view va, std::string_view vb)
{ return va.compare(vb); }));
keyIx.push_back(keys.size());
keys.push_back(tag);
}
......@@ -2096,7 +2124,7 @@ bool category::operator==(const category &rhs) const
{
keys = catValidator->m_keys;
for (auto& tag: a.key_fields())
for (auto &tag : a.key_fields())
{
auto iv = catValidator->get_validator_for_item(tag);
if (iv == nullptr)
......@@ -2106,7 +2134,10 @@ bool category::operator==(const category &rhs) const
throw std::runtime_error("missing type validator");
tags.push_back(std::make_tuple(tag, std::bind(&cif::type_validator::compare, tv, std::placeholders::_1, std::placeholders::_2)));
auto pred = [tag](const std::string& s) -> bool { return cif::iequals(tag, s) == 0; };
auto pred = [tag](const std::string &s) -> bool
{
return cif::iequals(tag, s) == 0;
};
if (find_if(keys.begin(), keys.end(), pred) == keys.end())
keyIx.push_back(tags.size() - 1);
}
......@@ -2115,11 +2146,11 @@ bool category::operator==(const category &rhs) const
// a.reorderByIndex();
// b.reorderByIndex();
auto rowEqual = [&](const row_handle& a, const row_handle& b)
auto rowEqual = [&](const row_handle &a, const row_handle &b)
{
int d = 0;
for (auto kix: keyIx)
for (auto kix : keyIx)
{
std::string tag;
compType compare;
......@@ -2148,7 +2179,7 @@ bool category::operator==(const category &rhs) const
std::vector<std::string> missingA, missingB, different;
for (auto& tt: tags)
for (auto &tt : tags)
{
std::string tag;
compType compare;
......@@ -2157,8 +2188,12 @@ bool category::operator==(const category &rhs) const
// make it an option to compare unapplicable to empty or something
auto ta = ra[tag].text(); if (ta == "." or ta == "?") ta = "";
auto tb = rb[tag].text(); if (tb == "." or tb == "?") tb = "";
auto ta = ra[tag].text();
if (ta == "." or ta == "?")
ta = "";
auto tb = rb[tag].text();
if (tb == "." or tb == "?")
tb = "";
if (compare(ta, tb) != 0)
return false;
......
......@@ -374,6 +374,10 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &tag_orde
bool datablock::operator==(const datablock &rhs) const
{
// shortcut
if (this == &rhs)
return true;
auto &dbA = *this;
auto &dbB = rhs;
......
......@@ -239,13 +239,12 @@ void checkAtomRecords(datablock &db)
// Rewrite the coordinates and other fields that look better in a fixed format
// Be careful not to nuke invalidly formatted data here
for (auto [tag, prec] : std::vector<std::tuple<std::string_view,std::string::size_type>>{
for (auto [tag, prec] : std::vector<std::tuple<std::string_view, std::string::size_type>>{
{ "cartn_x", 3 },
{ "cartn_y", 3 },
{ "cartn_z", 3 },
{ "occupancy", 2 },
{ "b_iso_or_equiv", 2 }
})
{ "b_iso_or_equiv", 2 } })
{
if (row[tag].empty())
continue;
......@@ -260,10 +259,32 @@ void checkAtomRecords(datablock &db)
char b[12];
if (auto [ptr, ec] = cif::to_chars(b, b + sizeof(b), v, cif::chars_format::fixed, prec); ec == std::errc())
row.assign(tag, {b, static_cast<std::string::size_type>(ptr - b)}, false, false);
row.assign(tag, { b, static_cast<std::string::size_type>(ptr - b) }, false, false);
}
}
}
auto *cv = atom_site.get_cat_validator();
if (cv)
{
// See if there are columns that are no longer known
for (auto tag : atom_site.get_columns())
{
if (cv->get_validator_for_item(tag) != nullptr)
continue;
auto r = atom_site.find_first(key(tag) != null);
if (not r)
{
if (cif::VERBOSE > 0)
std::clog << "Dropping unknown column " << tag << '\n';
atom_site.remove_column(tag);
}
else if (cif::VERBOSE > 0)
std::clog << "Keeping unknown column " << std::quoted(tag) << " in atom_site since it is not empty\n";
}
}
}
void createStructAsym(datablock &db)
......@@ -662,6 +683,9 @@ void comparePolySeqSchemes(datablock &db)
}
}
}
if (ndb_poly_seq_scheme.empty())
db.erase(std::remove(db.begin(), db.end(), ndb_poly_seq_scheme), db.end());
}
void reconstruct_pdbx(file &file, std::string_view dictionary)
......
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