Commit edf132c4 by maarten

backup

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@172 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent f3878b37
// copyright
#include <unordered_map>
#include "cif++/Structure.h"
namespace libcif
{
class BondMap
{
public:
BondMap(const Structure& p);
BondMap(const BondMap&) = delete;
BondMap& operator=(const BondMap&) = delete;
bool operator()(const Atom& a, const Atom& b) const;
private:
uint32 dim;
std::vector<bool> bond;
std::unordered_map<std::string,size_t> index;
};
}
......@@ -7,6 +7,7 @@
#include <regex>
#include <iostream>
#include <set>
#include <list>
#include <boost/lexical_cast.hpp>
#include <boost/any.hpp>
......@@ -211,12 +212,11 @@ class Datablock
Category* get(const string& name);
void getTagOrder(vector<string>& tags) const;
void write(std::ostream& os, const vector<string>& order);
void write(std::ostream& os);
private:
void write(std::ostream& os);
void write(std::ostream& os, const vector<string>& order);
std::list<Category> mCategories;
string mName;
Validator* mValidator;
......@@ -451,7 +451,7 @@ class Row
{
public:
friend class Category;
friend class catIndex;
friend class CatIndex;
friend class RowComparator;
friend struct detail::ItemReference;
......@@ -995,7 +995,7 @@ class Category
vector<ItemColumn> mColumns;
ItemRow* mHead;
ItemRow* mTail;
class catIndex* mIndex;
class CatIndex* mIndex;
};
// --------------------------------------------------------------------
......
......@@ -53,4 +53,30 @@ std::tuple<std::string,std::string> splitTagName(const std::string& tag);
std::vector<std::string> wordWrap(const std::string& text, unsigned int width);
// --------------------------------------------------------------------
// Code helping with terminal i/o
uint32 get_terminal_width();
// --------------------------------------------------------------------
// A progress bar
class Progress
{
public:
Progress(int64 inMax, const std::string& inAction);
virtual ~Progress();
void consumed(int64 inConsumed); // consumed is relative
void progress(int64 inProgress); // progress is absolute
void message(const std::string& inMessage);
private:
Progress(const Progress&);
Progress& operator=(const Progress&);
struct ProgressImpl* mImpl;
};
}
// copyright
#pragma once
#include <unordered_map>
#include <clipper/clipper.h>
#include "cif++/Structure.h"
namespace libcif
{
class DistanceMap
{
public:
DistanceMap(const Structure& p, const clipper::Spacegroup& spacegroup, const clipper::Cell& cell);
DistanceMap(const DistanceMap&) = delete;
DistanceMap& operator=(const DistanceMap&) = delete;
float operator()(const Atom& a, const Atom& b) const;
std::vector<Atom> near(const Atom& a, float maxDistance = 3.5f) const;
private:
uint32 dim;
std::vector<float> dist;
std::unordered_map<std::string,size_t> index;
};
}
#pragma once
#include "pdb2cif.h"
#include "cif++/PDB2Cif.h"
// --------------------------------------------------------------------
......@@ -11,30 +11,30 @@ class Remark3Parser
public:
virtual ~Remark3Parser() {}
static bool parse(const std::string& expMethod, PDBRecord* r, cif::datablock& db);
static bool parse(const std::string& expMethod, PDBRecord* r, cif::Datablock& db);
virtual std::string program();
virtual std::string version();
protected:
Remark3Parser(const std::string& name, const std::string& expMethod, PDBRecord* r, cif::datablock& db,
Remark3Parser(const std::string& name, const std::string& expMethod, PDBRecord* r, cif::Datablock& db,
const TemplateLine templatelines[], uint32 templateLineCount, std::regex programVersion);
virtual float Parse();
std::string NextLine();
virtual float parse();
std::string nextLine();
bool Match(const char* expr, int nextState);
void StoreCapture(const char* category, std::initializer_list<const char*> items, bool createNew = false);
void StoreRefineLsRestr(const char* type, std::initializer_list<const char*> values);
void UpdateRefineLsRestr(const char* type, std::initializer_list<const char*> values);
bool match(const char* expr, int nextState);
void storeCapture(const char* category, std::initializer_list<const char*> items, bool createNew = false);
void storeRefineLsRestr(const char* type, std::initializer_list<const char*> values);
void updateRefineLsRestr(const char* type, std::initializer_list<const char*> values);
virtual void Fixup() {}
virtual void fixup() {}
std::string mName;
std::string mExpMethod;
PDBRecord* mRec;
cif::datablock mDb;
cif::Datablock mDb;
std::string mLine;
std::smatch mM;
uint32 mState;
......
......@@ -12,15 +12,15 @@ class PeptideDB
public:
static PeptideDB& Instance();
void PushDictionary(boost::filesystem::path dict);
void PopDictionary();
void pushDictionary(boost::filesystem::path dict);
void popDictionary();
bool IsKnownPeptide(const std::string& res_name) const;
bool IsKnownBase(const std::string& res_name) const;
bool isKnownPeptide(const std::string& res_name) const;
bool isKnownBase(const std::string& res_name) const;
std::string GetNameForResidue(const std::string& res_name) const;
std::string GetFormulaForResidue(const std::string& res_name) const;
std::string Unalias(const std::string& res_name) const;
std::string nameForResidue(const std::string& res_name) const;
std::string formulaForResidue(const std::string& res_name) const;
std::string unalias(const std::string& res_name) const;
private:
PeptideDB();
......
......@@ -231,9 +231,9 @@ class SphericalDots
double lat = std::asin((2.0 * i) / P);
double lon = std::fmod(i, kGoldenRatio) * 2 * kPI / kGoldenRatio;
p->x(sin(lon) * cos(lat));
p->y(cos(lon) * cos(lat));
p->z( sin(lat));
p->setX(sin(lon) * cos(lat));
p->setY(cos(lon) * cos(lat));
p->setZ( sin(lat));
++p;
}
......
......@@ -37,9 +37,9 @@
namespace cif
{
class Datablock;
class File;
};
namespace libcif
{
......@@ -218,6 +218,7 @@ class File : public std::enable_shared_from_this<File>
std::vector<const Entity*> entities();
cif::Datablock& data();
cif::File& file();
private:
......
// copyright
#include "cif++/Config.h"
#include "cif++/Cif++.h"
#include "cif++/BondMap.h"
#include "cif++/Compound.h"
#include "cif++/CifUtils.h"
using namespace std;
namespace libcif
{
// --------------------------------------------------------------------
BondMap::BondMap(const Structure& p)
: dim(0)
{
auto atoms = p.atoms();
dim = atoms.size();
bond = vector<bool>(dim * (dim - 1), false);
for (auto& atom: atoms)
{
size_t ix = index.size();
index[atom.id()] = ix;
};
auto bindAtoms = [this](const string& a, const string& b)
{
size_t ixa = index[a];
size_t ixb = index[b];
if (ixb < ixa)
swap(ixa, ixb);
uint32 ix = ixb + ixa * dim - ixa * (ixa + 1) / 2;
assert(ix < bond.size());
bond[ix] = true;
};
cif::Datablock& db = p.getFile().data();
// collect all compounds first
set<string> compounds;
for (auto c: db["chem_comp"])
compounds.insert(c["id"].as<string>());
// make sure we also have all residues in the polyseq
for (auto m: db["entity_poly_seq"])
{
string c = m["mon_id"].as<string>();
if (compounds.count(c))
continue;
cerr << "Warning: mon_id " << c << " is missing in the chem_comp category" << endl;
compounds.insert(c);
}
// first link all residues in a polyseq
string lastAsymID;
int lastSeqID;
for (auto r: db["pdbx_poly_seq_scheme"])
{
string asymId;
int seqId;
cif::tie(asymId, seqId) = r.get("asym_id", "seq_id");
if (asymId != lastAsymID) // first in a new sequece
{
lastAsymID = asymId;
lastSeqID = seqId;
continue;
}
auto c = db["atom_site"].find(cif::Key("label_asym_id") == asymId and cif::Key("label_seq_id") == lastSeqID and cif::Key("label_atom_id") == "C");
if (c.size() != 1)
cerr << "Unexpected number (" << c.size() << ") of atoms with atom ID C in asym_id " << asymId << " with seq id " << lastSeqID << endl;
auto n = db["atom_site"].find(cif::Key("label_asym_id") == asymId and cif::Key("label_seq_id") == seqId and cif::Key("label_atom_id") == "N");
if (n.size() != 1)
cerr << "Unexpected number (" << n.size() << ") of atoms with atom ID N in asym_id " << asymId << " with seq id " << seqId << endl;
if (not (c.empty() or n.empty()))
bindAtoms(c.front()["id"].as<string>(), n.front()["id"].as<string>());
lastSeqID = seqId;
}
for (auto l: db["struct_conn"])
{
string asym1, asym2, atomId1, atomId2;
int seqId1, seqId2;
cif::tie(asym1, asym2, atomId1, atomId2, seqId1, seqId2) =
l.get("ptnr1_label_asym_id", "ptnr2_label_asym_id",
"ptnr1_label_atom_id", "ptnr2_label_atom_id",
"ptnr1_label_seq_id", "ptnr2_label_seq_id");
auto a = db["atom_site"].find(cif::Key("label_asym_id") == asym1 and cif::Key("label_seq_id") == seqId1 and cif::Key("label_atom_id") == atomId1);
if (a.size() != 1)
cerr << "Unexpected number (" << a.size() << ") of atoms for link with asym_id " << asym1 << " seq_id " << seqId1 << " atom_id " << atomId1 << endl;
auto b = db["atom_site"].find(cif::Key("label_asym_id") == asym2 and cif::Key("label_seq_id") == seqId2 and cif::Key("label_atom_id") == atomId2);
if (b.size() != 1)
cerr << "Unexpected number (" << b.size() << ") of atoms for link with asym_id " << asym2 << " seq_id " << seqId2 << " atom_id " << atomId2 << endl;
if (not (a.empty() or b.empty()))
bindAtoms(a.front()["id"].as<string>(), b.front()["id"].as<string>());
}
// then link all atoms in the compounds
cif::Progress progress(compounds.size(), "Creating bond map");
for (auto c: compounds)
{
auto* compound = libcif::Compound::create(c);
if (not compound)
{
cerr << "Missing compound information for " << c << endl;
continue;
}
if (compound->isWater())
{
if (VERBOSE)
cerr << "skipping water in bond map calculation" << endl;
continue;
}
// loop over poly_seq_scheme
for (auto r: db["pdbx_poly_seq_scheme"].find(cif::Key("mon_id") == c))
{
string asymId;
int seqId;
cif::tie(asymId, seqId) = r.get("asym_id", "seq_id");
vector<Atom> rAtoms;
for (auto a: db["atom_site"].find(cif::Key("label_asym_id") == asymId and cif::Key("label_seq_id") == seqId))
rAtoms.push_back(p.getAtomById(a["id"].as<string>()));
for (size_t i = 0; i + 1 < rAtoms.size(); ++i)
{
for (size_t j = i + 1; j < rAtoms.size(); ++j)
{
if (compound->atomsBonded(rAtoms[i].labelAtomId(), rAtoms[j].labelAtomId()))
bindAtoms(rAtoms[i].id(), rAtoms[j].id());
}
}
}
// loop over pdbx_nonpoly_scheme
for (auto r: db["pdbx_nonpoly_scheme"].find(cif::Key("mon_id") == c))
{
string asymId;
cif::tie(asymId) = r.get("asym_id");
vector<Atom> rAtoms;
for (auto a: db["atom_site"].find(cif::Key("label_asym_id") == asymId))
rAtoms.push_back(p.getAtomById(a["id"].as<string>()));
for (size_t i = 0; i + 1 < rAtoms.size(); ++i)
{
for (size_t j = i + 1; j < rAtoms.size(); ++j)
{
if (compound->atomsBonded(rAtoms[i].labelAtomId(), rAtoms[j].labelAtomId()))
{
size_t ixa = index[rAtoms[i].id()];
size_t ixb = index[rAtoms[j].id()];
if (ixb < ixa)
swap(ixa, ixb);
uint32 ix = ixb + ixa * dim - ixa * (ixa + 1) / 2;
assert(ix < bond.size());
bond[ix] = true;
}
}
}
}
progress.consumed(1);
}
}
bool BondMap::operator()(const Atom& a, const Atom& b) const
{
uint32 ixa = index.at(a.id());
uint32 ixb = index.at(b.id());
if (ixb < ixa)
swap(ixa, ixb);
uint32 ix = ixb + ixa * dim - ixa * (ixa + 1) / 2;
assert(ix < bond.size());
return bond[ix];
}
}
......@@ -525,11 +525,11 @@ int RowComparator::operator()(const ItemRow* a, const ItemRow* b) const
// class to keep an index on the keys of a Category. This is a red/black
// tree implementation.
class catIndex
class CatIndex
{
public:
catIndex(Category* cat);
~catIndex();
CatIndex(Category* cat);
~CatIndex();
ItemRow* find(ItemRow* k) const;
......@@ -716,17 +716,17 @@ class catIndex
entry* mRoot;
};
catIndex::catIndex(Category* cat)
CatIndex::CatIndex(Category* cat)
: mCat(*cat), mComp(cat), mRoot(nullptr)
{
}
catIndex::~catIndex()
CatIndex::~CatIndex()
{
delete mRoot;
}
ItemRow* catIndex::find(ItemRow* k) const
ItemRow* CatIndex::find(ItemRow* k) const
{
const entry* r = mRoot;
while (r != nullptr)
......@@ -743,13 +743,13 @@ ItemRow* catIndex::find(ItemRow* k) const
return r ? r->mRow : nullptr;
}
void catIndex::insert(ItemRow* k)
void CatIndex::insert(ItemRow* k)
{
mRoot = insert(mRoot, k);
mRoot->mRed = false;
}
catIndex::entry* catIndex::insert(entry* h, ItemRow* v)
CatIndex::entry* CatIndex::insert(entry* h, ItemRow* v)
{
if (h == nullptr)
return new entry(v);
......@@ -772,14 +772,14 @@ catIndex::entry* catIndex::insert(entry* h, ItemRow* v)
return h;
}
void catIndex::erase(ItemRow* k)
void CatIndex::erase(ItemRow* k)
{
mRoot = erase(mRoot, k);
if (mRoot != nullptr)
mRoot->mRed = false;
}
catIndex::entry* catIndex::erase(entry* h, ItemRow* k)
CatIndex::entry* CatIndex::erase(entry* h, ItemRow* k)
{
if (mComp(k, h->mRow) < 0)
{
......@@ -820,7 +820,7 @@ catIndex::entry* catIndex::erase(entry* h, ItemRow* k)
return fixUp(h);
}
void catIndex::reconstruct()
void CatIndex::reconstruct()
{
delete mRoot;
mRoot = nullptr;
......@@ -897,7 +897,7 @@ void catIndex::reconstruct()
// mRoot = e.front();
}
size_t catIndex::size() const
size_t CatIndex::size() const
{
stack<entry*> s;
s.push(mRoot);
......@@ -921,7 +921,7 @@ size_t catIndex::size() const
return result;
}
void catIndex::validate() const
void CatIndex::validate() const
{
if (mRoot != nullptr)
{
......@@ -935,7 +935,7 @@ void catIndex::validate() const
}
}
void catIndex::validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const
void CatIndex::validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const
{
if (h->mRed)
assert(not isParentRed);
......@@ -1018,7 +1018,7 @@ Category::Category(Datablock& db, const string& name, Validator* Validator)
for (auto& k: mCatValidator->mMandatoryFields)
addColumn(k);
mIndex = new catIndex(this);
mIndex = new CatIndex(this);
}
}
}
......@@ -1044,7 +1044,7 @@ void Category::setValidator(Validator* v)
mCatValidator = mValidator->getValidatorForCategory(mName);
if (mCatValidator != nullptr)
{
mIndex = new catIndex(this);
mIndex = new CatIndex(this);
mIndex->reconstruct();
#if DEBUG
assert(mIndex->size() == size());
......@@ -1192,7 +1192,7 @@ void Category::clear()
if (mIndex != nullptr)
{
delete mIndex;
mIndex = new catIndex(this);
mIndex = new CatIndex(this);
}
}
......
......@@ -762,11 +762,11 @@ void DictParser::parseSaveFrame()
string category = dict.firstItem("_category.id");
vector<string> keys;
for (auto k: dict["categoryKey"])
for (auto k: dict["category_key"])
keys.push_back(get<1>(splitTagName(k["name"].as<string>())));
iset groups;
for (auto g: dict["categoryGroup"])
for (auto g: dict["category_group"])
groups.insert(g["id"].as<string>());
mImpl->mCategoryValidators.push_back(ValidateCategory{category, keys, groups});
......
......@@ -4,8 +4,21 @@
#include <tuple>
#include <iostream>
#include <cstdio>
#include <atomic>
#if defined(_MSC_VER)
#define TERM_WIDTH 80
#else
#include <termios.h>
#include <sys/ioctl.h>
#endif
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#if BOOST_VERSION >= 104800
#include <boost/timer/timer.hpp>
#endif
#include "cif++/CifUtils.h"
......@@ -94,13 +107,13 @@ int icompare(const char* a, const char* b)
return d;
}
void to_lower(string& s)
void toLower(string& s)
{
for (auto& c: s)
c = tolower(c);
}
string to_lower_copy(const string& s)
string toLowerCopy(const string& s)
{
string result(s);
for (auto& c: result)
......@@ -110,7 +123,7 @@ string to_lower_copy(const string& s)
// --------------------------------------------------------------------
tuple<string,string> split_tag_name(const string& tag)
tuple<string,string> splitTagName(const string& tag)
{
if (tag.empty())
throw runtime_error("empty tag");
......@@ -196,12 +209,12 @@ const LineBreakClass kASCII_LBTable[128] =
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_BreakAfter, kLBC_ClosePunctuation, kLBC_Alphabetic, kLBC_CombiningMark
};
string::const_iterator next_line_break(string::const_iterator text, string::const_iterator end)
string::const_iterator nextLineBreak(string::const_iterator text, string::const_iterator end)
{
if (text == end)
return text;
enum break_action
enum breakAction
{
DBK = 0, // direct break (blank in table)
IBK, // indirect break (% in table)
......@@ -210,7 +223,7 @@ string::const_iterator next_line_break(string::const_iterator text, string::cons
CPB // combining prohibited break
};
const break_action brkTable[27][27] = {
const breakAction brkTable[27][27] = {
// OP CL CP QU GL NS EX SY IS PR PO NU AL ID IN HY BA BB B2 ZW CM WJ H2 H3 JL JV JT
/* OP */ { PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, CPB, PBK, PBK, PBK, PBK, PBK, PBK },
/* CL */ { DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
......@@ -278,7 +291,7 @@ string::const_iterator next_line_break(string::const_iterator text, string::cons
if (ncls == kLBC_Space)
continue;
break_action brk = brkTable[cls][ncls];
breakAction brk = brkTable[cls][ncls];
if (brk == DBK or (brk == IBK and lcls == kLBC_Space))
break;
......@@ -289,7 +302,7 @@ string::const_iterator next_line_break(string::const_iterator text, string::cons
return text;
}
vector<string> wrap_line(const string& text, unsigned int width)
vector<string> wrapLine(const string& text, unsigned int width)
{
vector<string> result;
vector<size_t> offsets = { 0 };
......@@ -297,7 +310,7 @@ vector<string> wrap_line(const string& text, unsigned int width)
auto b = text.begin();
while (b != text.end())
{
auto e = next_line_break(b, text.end());
auto e = nextLineBreak(b, text.end());
offsets.push_back(e - text.begin());
......@@ -350,7 +363,7 @@ vector<string> wrap_line(const string& text, unsigned int width)
return result;
}
vector<string> word_wrap(const string& text, unsigned int width)
vector<string> wordWrap(const string& text, unsigned int width)
{
vector<string> paragraphs;
ba::split(paragraphs, text, ba::is_any_of("\n"));
......@@ -364,11 +377,168 @@ vector<string> word_wrap(const string& text, unsigned int width)
continue;
}
auto lines = wrap_line(p, width);
auto lines = wrapLine(p, width);
result.insert(result.end(), lines.begin(), lines.end());
}
return result;
}
// --------------------------------------------------------------------
#ifdef _MSC_VER
uint32 get_terminal_width()
{
return TERM_WIDTH;
}
#else
uint32 get_terminal_width()
{
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
return w.ws_col;
}
#endif
// --------------------------------------------------------------------
struct ProgressImpl
{
ProgressImpl(int64 inMax, const string& inAction)
: mMax(inMax), mConsumed(0), mAction(inAction), mMessage(inAction)
, mThread(boost::bind(&ProgressImpl::Run, this)) {}
void Run();
void PrintProgress();
void PrintDone();
int64 mMax;
atomic<int64> mConsumed;
string mAction, mMessage;
boost::mutex mMutex;
boost::thread mThread;
boost::timer::cpu_timer
mTimer;
};
void ProgressImpl::Run()
{
try
{
for (;;)
{
boost::this_thread::sleep(boost::posix_time::seconds(1));
boost::mutex::scoped_lock lock(mMutex);
if (mConsumed == mMax)
break;
PrintProgress();
}
}
catch (...) {}
PrintDone();
}
void ProgressImpl::PrintProgress()
{
uint32 width = get_terminal_width();
string msg;
msg.reserve(width + 1);
if (mMessage.length() <= 20)
{
msg = mMessage;
if (msg.length() < 20)
msg.append(20 - msg.length(), ' ');
}
else
msg = mMessage.substr(0, 17) + "...";
msg += " [";
float progress = static_cast<float>(mConsumed) / mMax;
int tw = width - 28;
int twd = static_cast<int>(tw * progress + 0.5f);
msg.append(twd, '=');
msg.append(tw - twd, ' ');
msg.append("] ");
int perc = static_cast<int>(100 * progress);
if (perc < 100)
msg += ' ';
if (perc < 10)
msg += ' ';
msg += to_string(perc);
msg += '%';
cout << '\r' << msg;
cout.flush();
}
void ProgressImpl::PrintDone()
{
string msg = mAction + " done in " + mTimer.format(0, "%ts cpu / %ws wall");
uint32 width = get_terminal_width();
if (msg.length() < width)
msg += string(width - msg.length(), ' ');
cout << '\r' << msg << endl;
}
Progress::Progress(int64 inMax, const string& inAction)
: mImpl(nullptr)
{
if (isatty(STDOUT_FILENO))
mImpl = new ProgressImpl(inMax, inAction);
}
Progress::~Progress()
{
if (mImpl != nullptr and mImpl->mThread.joinable())
{
mImpl->mThread.interrupt();
mImpl->mThread.join();
}
delete mImpl;
}
void Progress::consumed(int64 inConsumed)
{
if (mImpl != nullptr and
(mImpl->mConsumed += inConsumed) >= mImpl->mMax and
mImpl->mThread.joinable())
{
mImpl->mThread.interrupt();
mImpl->mThread.join();
}
}
void Progress::progress(int64 inProgress)
{
if (mImpl != nullptr and
(mImpl->mConsumed = inProgress) >= mImpl->mMax and
mImpl->mThread.joinable())
{
mImpl->mThread.interrupt();
mImpl->mThread.join();
}
}
void Progress::message(const std::string& inMessage)
{
if (mImpl != nullptr)
{
boost::mutex::scoped_lock lock(mImpl->mMutex);
mImpl->mMessage = inMessage;
}
}
}
// copyright
#include "cif++/Config.h"
#include <atomic>
#include <boost/thread.hpp>
#include "cif++/DistanceMap.h"
#include "cif++/CifUtils.h"
using namespace std;
namespace libcif
{
// --------------------------------------------------------------------
vector<clipper::RTop_orth> AlternativeSites(const clipper::Spacegroup& spacegroup,
const clipper::Cell& cell)
{
vector<clipper::RTop_orth> result;
for (int i = 0; i < spacegroup.num_symops(); ++i)
{
const auto& symop = spacegroup.symop(i);
for (int u: { -1, 0, 1})
for (int v: { -1, 0, 1})
for (int w: { -1, 0, 1})
{
result.push_back(
clipper::RTop_frac(
symop.rot(), symop.trn() + clipper::Vec3<>(u, v, w)
).rtop_orth(cell));
}
}
return result;
}
// --------------------------------------------------------------------
DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegroup, const clipper::Cell& cell)
: dim(0)
{
auto atoms = p.atoms();
dim = atoms.size();
dist = vector<float>(dim * (dim - 1), 0.f);
vector<clipper::Coord_orth> locations(dim);
vector<bool> isWater(dim, false);
for (auto& atom: atoms)
{
size_t ix = index.size();
index[atom.id()] = ix;
locations[ix] = atom.location();
isWater[ix] = atom.isWater();
};
vector<clipper::RTop_orth> rtOrth = AlternativeSites(spacegroup, cell);
cif::Progress progress(locations.size() - 1, "Creating distance map");
boost::thread_group t;
size_t N = boost::thread::hardware_concurrency();
atomic<size_t> next(0);
for (size_t i = 0; i < N; ++i)
t.create_thread([&]()
{
for (;;)
{
size_t i = next++;
if (i >= locations.size())
break;
for (size_t j = i + 1; j < locations.size(); ++j)
{
// if (not (isWater[i] or isWater[j]))
// continue;
// find nearest location based on spacegroup/cell
double minR2 = numeric_limits<double>::max();
for (const auto& rt: rtOrth)
{
auto p = locations[j].transform(rt);
double r2 = (locations[i] - p).lengthsq();
if (minR2 > r2)
minR2 = r2;
}
uint32 ix = j + i * dim - i * (i + 1) / 2;
assert(ix < dist.size());
dist[ix] = sqrt(minR2);
}
progress.consumed(1);
}
});
t.join_all();
}
float DistanceMap::operator()(const Atom& a, const Atom& b) const
{
uint32 ixa = index.at(a.id());
uint32 ixb = index.at(b.id());
if (ixb < ixa)
swap(ixa, ixb);
uint32 ix = ixb + ixa * dim - ixa * (ixa + 1) / 2;
assert(ix < dist.size());
return dist[ix];
}
vector<Atom> DistanceMap::near(const Atom& a, float maxDistance) const
{
vector<Atom> result;
const File& f = a.getFile();
uint32 ixa = index.at(a.id());
for (auto& i: index)
{
uint32 ixb = i.second;
if (ixb == ixa)
continue;
uint32 ix;
if (ixa < ixb)
ix = ixb + ixa * dim - ixa * (ixa + 1) / 2;
else
ix = ixa + ixb * dim - ixb * (ixb + 1) / 2;
assert(ix < dist.size());
if (dist[ix] != 0 and dist[ix] <= maxDistance)
result.emplace_back(f, i.first);
}
return result;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
#include "libpr.h"
#include "cif++/Config.h"
#include <map>
#include <set>
......@@ -8,19 +8,18 @@
#include <boost/format.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include "peptidedb.h"
#include "pdb2cif.h"
#include "libcif/atom_type.h"
#include "libcif/compound.h"
#include "libcif/pdb2cif-remark3.h"
#include "cif++/AtomType.h"
#include "cif++/Compound.h"
#include "cif++/PDB2CifRemark3.h"
#include "cif++/PeptideDB.h"
using namespace std;
namespace ba = boost::algorithm;
using cif::datablock;
using cif::category;
using cif::row;
using cif::key;
using cif::Datablock;
using cif::Category;
using cif::Row;
using cif::Key;
using cif::iequals;
static const char* kRedOn = "\033[37;1;41m";
......@@ -31,11 +30,11 @@ static const char* kRedOff = "\033[0m";
struct TemplateLine
{
const char* rx;
int next_state_offset;
int nextStateOffset;
const char* category;
initializer_list<const char*> items;
const char* ls_restr_type = nullptr;
bool create_new;
const char* lsRestrType = nullptr;
bool createNew;
};
// --------------------------------------------------------------------
......@@ -139,7 +138,7 @@ const TemplateLine kBusterTNT_Template[] = {
class BUSTER_TNT_Remark3Parser : public Remark3Parser
{
public:
BUSTER_TNT_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
BUSTER_TNT_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db,
kBusterTNT_Template, sizeof(kBusterTNT_Template) / sizeof(TemplateLine),
regex(R"((BUSTER(?:-TNT)?)(?: (\d+(?:\..+)?))?)")) {}
......@@ -232,7 +231,7 @@ const TemplateLine kCNS_Template[] = {
class CNS_Remark3Parser : public Remark3Parser
{
public:
CNS_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
CNS_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kCNS_Template,
sizeof(kCNS_Template) / sizeof(TemplateLine), regex(R"((CN[SX])(?: (\d+(?:\.\d+)?))?)")) {}
};
......@@ -310,16 +309,16 @@ const TemplateLine kPHENIX_Template[] = {
class PHENIX_Remark3Parser : public Remark3Parser
{
public:
PHENIX_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
PHENIX_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kPHENIX_Template, sizeof(kPHENIX_Template) / sizeof(TemplateLine),
regex(R"((PHENIX)(?: \(PHENIX\.REFINE:) (\d+(?:\.[^)]+)?)\)?)")) {}
virtual void Fixup();
virtual void fixup();
};
void PHENIX_Remark3Parser::Fixup()
void PHENIX_Remark3Parser::fixup()
{
for (auto r: m_db["refine_ls_shell"])
for (auto r: mDb["refine_ls_shell"])
{
try
{
......@@ -401,7 +400,7 @@ const TemplateLine kPROLSQ_Template[] = {
class PROLSQ_Remark3Parser : public Remark3Parser
{
public:
PROLSQ_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
PROLSQ_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kPROLSQ_Template, sizeof(kPROLSQ_Template) / sizeof(TemplateLine),
regex(R"((PROLSQ|NUCLSQ)(?: (\d+(?:\.\d+)?))?)")) {}
};
......@@ -472,12 +471,12 @@ const TemplateLine kREFMAC_Template[] = {
class REFMAC_Remark3Parser : public Remark3Parser
{
public:
REFMAC_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
REFMAC_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kREFMAC_Template, sizeof(kREFMAC_Template) / sizeof(TemplateLine),
regex(".+")) {}
virtual string Program() { return "REFMAC"; }
virtual string Version() { return ""; }
virtual string program() { return "REFMAC"; }
virtual string version() { return ""; }
};
const TemplateLine kREFMAC5_Template[] = {
......@@ -624,7 +623,7 @@ const TemplateLine kREFMAC5_Template[] = {
class REFMAC5_Remark3Parser : public Remark3Parser
{
public:
REFMAC5_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
REFMAC5_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kREFMAC5_Template, sizeof(kREFMAC5_Template) / sizeof(TemplateLine),
regex(R"((REFMAC)(?: (\d+(?:\..+)?))?)")) {}
};
......@@ -682,7 +681,7 @@ const TemplateLine kSHELXL_Template[] = {
class SHELXL_Remark3Parser : public Remark3Parser
{
public:
SHELXL_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
SHELXL_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kSHELXL_Template, sizeof(kSHELXL_Template) / sizeof(TemplateLine),
regex(R"((SHELXL)(?:-(\d+(?:\..+)?)))")) {}
};
......@@ -737,7 +736,7 @@ const TemplateLine kTNT_Template[] = {
class TNT_Remark3Parser : public Remark3Parser
{
public:
TNT_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
TNT_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kTNT_Template, sizeof(kTNT_Template) / sizeof(TemplateLine),
regex(R"((TNT)(?: V. (\d+.+)?)?)")) {}
};
......@@ -815,45 +814,45 @@ const TemplateLine kXPLOR_Template[] = {
class XPLOR_Remark3Parser : public Remark3Parser
{
public:
XPLOR_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::datablock& db)
XPLOR_Remark3Parser(const string& name, const string& expMethod, PDBRecord* r, cif::Datablock& db)
: Remark3Parser(name, expMethod, r, db, kXPLOR_Template, sizeof(kXPLOR_Template) / sizeof(TemplateLine),
regex(R"((X-PLOR)(?: (\d+(?:\.\d+)?))?)")) {}
};
// --------------------------------------------------------------------
Remark3Parser::Remark3Parser(const std::string& name, const std::string& expMethod, PDBRecord* r, cif::datablock& db,
const TemplateLine templatelines[], uint32 templateLineCount, std::regex program_version)
: m_name(name), m_expMethod(expMethod), m_rec(r), m_db(db.name())
, m_template(templatelines), m_templateCount(templateLineCount), m_program_version(program_version)
Remark3Parser::Remark3Parser(const std::string& name, const std::string& expMethod, PDBRecord* r, cif::Datablock& db,
const TemplateLine templatelines[], uint32 templateLineCount, std::regex programversion)
: mName(name), mExpMethod(expMethod), mRec(r), mDb(db.getName())
, mTemplate(templatelines), mTemplateCount(templateLineCount), mProgramVersion(programversion)
{
}
string Remark3Parser::NextLine()
string Remark3Parser::nextLine()
{
m_line.clear();
mLine.clear();
while (m_rec != nullptr and m_rec->is("REMARK 3"))
while (mRec != nullptr and mRec->is("REMARK 3"))
{
size_t valueIndent = 0;
for (size_t i = 4; i < m_rec->m_vlen; ++i)
for (size_t i = 4; i < mRec->mVlen; ++i)
{
if (m_rec->m_value[i] == ' ')
if (mRec->mValue[i] == ' ')
continue;
if (m_rec->m_value[i] == ':')
if (mRec->mValue[i] == ':')
{
valueIndent = i;
while (valueIndent < m_rec->m_vlen and m_rec->m_value[i] == ' ')
while (valueIndent < mRec->mVlen and mRec->mValue[i] == ' ')
++valueIndent;
break;
}
}
m_line = m_rec->v_s(12);
m_rec = m_rec->m_next;
mLine = mRec->vS(12);
mRec = mRec->mNext;
if (m_line.empty())
if (mLine.empty())
continue;
// concatenate value that is wrapped over multiple lines (tricky code...)
......@@ -862,25 +861,25 @@ string Remark3Parser::NextLine()
{
string indent(valueIndent - 4, ' ');
while (m_rec->is("REMARK 3") and m_rec->m_vlen > valueIndent)
while (mRec->is("REMARK 3") and mRec->mVlen > valueIndent)
{
string v(m_rec->m_value + 4, m_rec->m_value + m_rec->m_vlen);
string v(mRec->mValue + 4, mRec->mValue + mRec->mVlen);
if (not ba::starts_with(v, indent))
break;
m_line += ' ';
m_line.append(m_rec->m_value + valueIndent, m_rec->m_value + m_rec->m_vlen);
mLine += ' ';
mLine.append(mRec->mValue + valueIndent, mRec->mValue + mRec->mVlen);
m_rec = m_rec->m_next;
mRec = mRec->mNext;
}
}
// collapse multiple spaces
bool space = false;
auto i = m_line.begin(), j = i;
auto i = mLine.begin(), j = i;
while (i != m_line.end())
while (i != mLine.end())
{
bool nspace = isspace(*i);
......@@ -893,129 +892,129 @@ string Remark3Parser::NextLine()
space = nspace;
++i;
}
m_line.erase(j, m_line.end());
mLine.erase(j, mLine.end());
break;
}
if (VERBOSE >= 2)
cerr << "RM3: " << m_line << endl;
cerr << "RM3: " << mLine << endl;
return m_line;
return mLine;
}
bool Remark3Parser::Match(const char* expr, int nextState)
bool Remark3Parser::match(const char* expr, int nextState)
{
regex rx(expr);
bool result = regex_match(m_line, m_m, rx);
bool result = regex_match(mLine, mM, rx);
if (result)
m_state = nextState;
mState = nextState;
else if (VERBOSE >= 3)
cerr << kRedOn << "No Match:" << kRedOff << " '" << expr << '\'' << endl;
cerr << kRedOn << "No match:" << kRedOff << " '" << expr << '\'' << endl;
return result;
}
float Remark3Parser::Parse()
float Remark3Parser::parse()
{
int lineCount = 0, dropped = 0;
string remarks;
m_state = 0;
mState = 0;
while (m_rec != nullptr)
while (mRec != nullptr)
{
NextLine();
nextLine();
if (m_line.empty())
if (mLine.empty())
break;
++lineCount;
// Skip over AUTHORS lines
if (m_state == 0 and Match(R"(AUTHORS\s*:.+)", 0))
if (mState == 0 and match(R"(AUTHORS\s*:.+)", 0))
continue;
auto state = m_state;
for (state = m_state; state < m_templateCount; ++state)
auto state = mState;
for (state = mState; state < mTemplateCount; ++state)
{
const TemplateLine& tmpl = m_template[state];
const TemplateLine& tmpl = mTemplate[state];
if (Match(tmpl.rx, state + tmpl.next_state_offset))
if (match(tmpl.rx, state + tmpl.nextStateOffset))
{
if (not (tmpl.category == nullptr or tmpl.items.size() == 0))
{
if (tmpl.ls_restr_type == nullptr)
StoreCapture(tmpl.category, tmpl.items, tmpl.create_new);
else if (tmpl.create_new)
StoreRefineLsRestr(tmpl.ls_restr_type, tmpl.items);
if (tmpl.lsRestrType == nullptr)
storeCapture(tmpl.category, tmpl.items, tmpl.createNew);
else if (tmpl.createNew)
storeRefineLsRestr(tmpl.lsRestrType, tmpl.items);
else
UpdateRefineLsRestr(tmpl.ls_restr_type, tmpl.items);
updateRefineLsRestr(tmpl.lsRestrType, tmpl.items);
}
break;
}
}
if (state < m_templateCount)
if (state < mTemplateCount)
continue;
if (state == m_templateCount and Match(R"(OTHER REFINEMENT REMARKS\s*:\s*(.*))", m_templateCount + 1))
if (state == mTemplateCount and match(R"(OTHER REFINEMENT REMARKS\s*:\s*(.*))", mTemplateCount + 1))
{
remarks = m_m[1].str();
remarks = mM[1].str();
continue;
}
if (state == m_templateCount + 1)
if (state == mTemplateCount + 1)
{
remarks = remarks + '\n' + m_line;
remarks = remarks + '\n' + mLine;
continue;
}
if (VERBOSE >= 2)
cerr << kRedOn << "Dropping line:" << kRedOff << " '" << m_line << '\'' << endl;
cerr << kRedOn << "Dropping line:" << kRedOff << " '" << mLine << '\'' << endl;
++dropped;
}
if (not remarks.empty() and not iequals(remarks, "NULL"))
m_db["refine"].front()["details"] = remarks;
mDb["refine"].front()["details"] = remarks;
float score = float(lineCount - dropped) / lineCount;
return score;
}
string Remark3Parser::Program()
string Remark3Parser::program()
{
string result = m_name;
string result = mName;
smatch m;
if (regex_match(m_name, m, m_program_version))
if (regex_match(mName, m, mProgramVersion))
result = m[1].str();
return result;
}
string Remark3Parser::Version()
string Remark3Parser::version()
{
string result;
smatch m;
if (regex_match(m_name, m, m_program_version))
if (regex_match(mName, m, mProgramVersion))
result = m[2].str();
return result;
}
void Remark3Parser::StoreCapture(const char* category, initializer_list<const char*> items, bool createNew)
void Remark3Parser::storeCapture(const char* category, initializer_list<const char*> items, bool createNew)
{
int capture = 0;
for (auto item: items)
{
++capture;
string value = m_m[capture].str();
string value = mM[capture].str();
ba::trim(value);
if (iequals(value, "NULL") or iequals(value, "NONE"))
......@@ -1024,60 +1023,60 @@ void Remark3Parser::StoreCapture(const char* category, initializer_list<const ch
if (VERBOSE >= 3)
cerr << "storing: '" << value << "' in _" << category << '.' << item << endl;
auto& cat = m_db[category];
auto& cat = mDb[category];
if (cat.empty() or createNew)
{
if (iequals(category, "refine"))
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "entry_id", m_db.name() },
{ "pdbx_refine_id", mExpMethod },
{ "entry_id", mDb.getName() },
#warning("???")
{ "pdbx_diffrn_id", 1 }
});
else if (iequals(category, "refine_analyze") or iequals(category, "pdbx_refine"))
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "entry_id", m_db.name() },
{ "pdbx_refine_id", mExpMethod },
{ "entry_id", mDb.getName() },
// { "pdbx_diffrn_id", 1 }
});
else if (iequals(category, "refine_hist"))
{
string d_res_high, d_res_low;
for (auto r: m_db["refine"])
string dResHigh, dResLow;
for (auto r: mDb["refine"])
{
cif::tie(d_res_high, d_res_low) = r.get("ls_d_res_high", "ls_d_res_low");
cif::tie(dResHigh, dResLow) = r.get("ls_d_res_high", "ls_d_res_low");
break;
}
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "pdbx_refine_id", mExpMethod },
{ "cycle_id", "LAST" },
{ "d_res_high", d_res_high.empty() ? "." : d_res_high },
{ "d_res_low", d_res_low.empty() ? "." : d_res_low }
{ "d_res_high", dResHigh.empty() ? "." : dResHigh },
{ "d_res_low", dResLow.empty() ? "." : dResLow }
});
}
else if (iequals(category, "refine_ls_shell"))
{
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "pdbx_refine_id", mExpMethod },
});
}
else if (iequals(category, "pdbx_refine_tls_group"))
{
string tls_group_id;
if (not m_db["pdbx_refine_tls"].empty())
tls_group_id = m_db["pdbx_refine_tls"].back()["id"].as<string>();
string tlsGroupId;
if (not mDb["pdbx_refine_tls"].empty())
tlsGroupId = mDb["pdbx_refine_tls"].back()["id"].as<string>();
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "id", tls_group_id },
{ "refine_tls_id", tls_group_id }
{ "pdbx_refine_id", mExpMethod },
{ "id", tlsGroupId },
{ "refine_tls_id", tlsGroupId }
});
}
else if (iequals(category, "pdbx_refine_tls"))
{
cat.emplace({
{ "pdbx_refine_id", m_expMethod },
{ "pdbx_refine_id", mExpMethod },
{ "method", "refined" }
});
}
......@@ -1107,25 +1106,25 @@ void Remark3Parser::StoreCapture(const char* category, initializer_list<const ch
}
}
void Remark3Parser::StoreRefineLsRestr(const char* type, initializer_list<const char*> items)
void Remark3Parser::storeRefineLsRestr(const char* type, initializer_list<const char*> items)
{
row r;
Row r;
int capture = 0;
for (auto item: items)
{
++capture;
string value = m_m[capture].str();
string value = mM[capture].str();
ba::trim(value);
if (value.empty() or iequals(value, "NULL"))
continue;
if (not r)
{
std::tie(r, std::ignore) = m_db["refine_ls_restr"].emplace({});
std::tie(r, std::ignore) = mDb["refine_ls_restr"].emplace({});
r["pdbx_refine_id"] = m_expMethod;
r["pdbx_refine_id"] = mExpMethod;
r["type"] = type;
}
......@@ -1133,21 +1132,21 @@ void Remark3Parser::StoreRefineLsRestr(const char* type, initializer_list<const
}
}
void Remark3Parser::UpdateRefineLsRestr(const char* type, initializer_list<const char*> items)
void Remark3Parser::updateRefineLsRestr(const char* type, initializer_list<const char*> items)
{
auto rows = m_db["refine_ls_restr"].find(cif::key("type") == type and cif::key("pdbx_refine_id") == m_expMethod);
auto rows = mDb["refine_ls_restr"].find(cif::Key("type") == type and cif::Key("pdbx_refine_id") == mExpMethod);
if (rows.empty())
StoreRefineLsRestr(type, items);
storeRefineLsRestr(type, items);
else
{
for (row r: rows)
for (Row r: rows)
{
int capture = 0;
for (auto item: items)
{
++capture;
string value = m_m[capture].str();
string value = mM[capture].str();
ba::trim(value);
if (iequals(value, "NULL"))
value.clear();
......@@ -1162,17 +1161,17 @@ void Remark3Parser::UpdateRefineLsRestr(const char* type, initializer_list<const
// --------------------------------------------------------------------
bool Remark3Parser::Parse(const string& expMethod, PDBRecord* r, cif::datablock& db)
bool Remark3Parser::parse(const string& expMethod, PDBRecord* r, cif::Datablock& db)
{
// simple version, only for the first few lines
auto GetNextLine = [&]()
auto getNextLine = [&]()
{
string result;
while (result.empty() and r != nullptr and r->is("REMARK 3"))
{
result = r->v_s(12);
r = r->m_next;
result = r->vS(12);
r = r->mNext;
}
return result;
......@@ -1180,12 +1179,12 @@ bool Remark3Parser::Parse(const string& expMethod, PDBRecord* r, cif::datablock&
// All remark 3 records should start with the same data.
string line = GetNextLine();
string line = getNextLine();
if (line != "REFINEMENT.")
throw runtime_error("Unexpected data in REMARK 3");
line = GetNextLine();
line = getNextLine();
regex rxp(R"(^PROGRAM\s*:\s*(.+))");
smatch m;
......@@ -1194,36 +1193,36 @@ bool Remark3Parser::Parse(const string& expMethod, PDBRecord* r, cif::datablock&
throw runtime_error("Expected valid PROGRAM line in REMARK 3");
line = m[1].str();
struct program_score
struct programScore
{
program_score(const string& program, Remark3Parser* parser, float score)
programScore(const string& program, Remark3Parser* parser, float score)
: program(program), parser(parser), score(score) {}
string program;
unique_ptr<Remark3Parser> parser;
float score;
bool operator<(const program_score& rhs) const
bool operator<(const programScore& rhs) const
{
return score > rhs.score;
}
};
vector<program_score> scores;
vector<programScore> scores;
auto tryParser = [&](Remark3Parser* p)
{
unique_ptr<Remark3Parser> parser(p);
float score = parser->Parse();
float score = parser->parse();
if (VERBOSE >= 2)
cerr << "Score for " << parser->Program() << ": " << score << endl;
cerr << "Score for " << parser->program() << ": " << score << endl;
if (score > 0)
{
auto& software = db["software"];
string program = parser->Program();
string version = parser->Version();
string program = parser->program();
string version = parser->version();
software.emplace({
{ "name", program },
......@@ -1278,11 +1277,11 @@ bool Remark3Parser::Parse(const string& expMethod, PDBRecord* r, cif::datablock&
auto& best = scores.front();
if (VERBOSE >= 2)
cerr << "Choosing " << best.parser->Program() << " version '" << best.parser->Version() << "' as refinement program. Score = " << best.score << endl;
cerr << "Choosing " << best.parser->program() << " version '" << best.parser->version() << "' as refinement program. Score = " << best.score << endl;
best.parser->Fixup();
best.parser->fixup();
for (auto& cat1: best.parser->m_db)
for (auto& cat1: best.parser->mDb)
{
auto& cat2 = db[cat1.name()];
......@@ -1292,8 +1291,8 @@ bool Remark3Parser::Parse(const string& expMethod, PDBRecord* r, cif::datablock&
if (cat2.empty()) // duh... this will generate a validation error anyway...
cat2.emplace({});
row r1 = cat1.front();
row r2 = cat2.front();
Row r1 = cat1.front();
Row r2 = cat2.front();
for (auto& i: r1)
r2[i.name()] = i.value();
......
#include "libpr.h"
#include "cif++/Config.h"
#include <set>
#include <map>
......@@ -8,9 +8,8 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp>
#include "cif++.h"
#include "peptidedb.h"
#include "cif++/Cif++.h"
#include "cif++/PeptideDB.h"
using namespace std;
namespace fs = boost::filesystem;
......@@ -62,46 +61,46 @@ struct PeptideDBImpl
~PeptideDBImpl()
{
delete m_next;
delete mNext;
}
/*unordered_*/set<string> m_known_peptides;
set<string> m_known_bases;
cif::file m_file;
cif::category& m_chem_comp;
PeptideDBImpl* m_next;
/*unordered_*/set<string> mKnownPeptides;
set<string> mKnownBases;
cif::File mFile;
cif::Category& mChemComp;
PeptideDBImpl* mNext;
string name_for(const string& res_name) const
string nameFor(const string& resName) const
{
string result;
for (auto& chem_comp: m_chem_comp)
for (auto& chemComp: mChemComp)
{
if (ba::iequals(chem_comp["three_letter_code"].as<string>(), res_name) == false)
if (ba::iequals(chemComp["three_letter_code"].as<string>(), resName) == false)
continue;
result = chem_comp["name"].as<string>();
result = chemComp["name"].as<string>();
ba::trim(result);
break;
}
if (result.empty() and m_next)
result = m_next->name_for(res_name);
if (result.empty() and mNext)
result = mNext->nameFor(resName);
return result;
}
string formula_for(string res_name) const;
string formulaFor(string resName) const;
string unalias(const string& res_name) const
string unalias(const string& resName) const
{
string result = res_name;
string result = resName;
auto& e = const_cast<cif::file&>(m_file)["comp_synonym_list"];
auto& e = const_cast<cif::File&>(mFile)["comp_synonym_list"];
for (auto& synonym: e["chem_comp_synonyms"])
{
if (ba::iequals(synonym["comp_alternative_id"].as<string>(), res_name) == false)
if (ba::iequals(synonym["comp_alternative_id"].as<string>(), resName) == false)
continue;
result = synonym["comp_id"].as<string>();
......@@ -109,38 +108,38 @@ struct PeptideDBImpl
break;
}
if (result.empty() and m_next)
result = m_next->unalias(res_name);
if (result.empty() and mNext)
result = mNext->unalias(resName);
return result;
}
};
PeptideDBImpl::PeptideDBImpl(istream& data, PeptideDBImpl* next)
: m_file(data), m_chem_comp(m_file.first_datablock()["chem_comp"]), m_next(next)
: mFile(data), mChemComp(mFile.firstDatablock()["chem_comp"]), mNext(next)
{
for (auto& chem_comp: m_chem_comp)
for (auto& chemComp: mChemComp)
{
string group, three_letter_code;
string group, threeLetterCode;
cif::tie(group, three_letter_code) = chem_comp.get("group", "three_letter_code");
cif::tie(group, threeLetterCode) = chemComp.get("group", "three_letter_code");
if (group == "peptide" or group == "M-peptide" or group == "P-peptide")
m_known_peptides.insert(three_letter_code);
mKnownPeptides.insert(threeLetterCode);
else if (group == "DNA" or group == "RNA")
m_known_bases.insert(three_letter_code);
mKnownBases.insert(threeLetterCode);
}
}
string PeptideDBImpl::formula_for(string res) const
string PeptideDBImpl::formulaFor(string res) const
{
string result;
ba::to_upper(res);
for (auto& db: m_file)
for (auto& db: mFile)
{
if (db.name() != "comp_" + res)
if (db.getName() != "comp_" + res)
continue;
auto& cat = db["chem_comp_atom"];
......@@ -162,15 +161,15 @@ string PeptideDBImpl::formula_for(string res) const
if (result.empty())
{
if (m_next != nullptr)
result = m_next->formula_for(res);
if (mNext != nullptr)
result = mNext->formulaFor(res);
else
{
const char* clibd_mon = getenv("CLIBD_MON");
if (clibd_mon == nullptr)
const char* clibdMon = getenv("CLIBD_MON");
if (clibdMon == nullptr)
throw runtime_error("Cannot locate peptide list, please souce the CCP4 environment");
fs::path resFile = fs::path(clibd_mon) / ba::to_lower_copy(res.substr(0, 1)) / (res + ".cif");
fs::path resFile = fs::path(clibdMon) / ba::to_lower_copy(res.substr(0, 1)) / (res + ".cif");
if (fs::exists(resFile))
{
fs::ifstream file(resFile);
......@@ -178,7 +177,7 @@ string PeptideDBImpl::formula_for(string res) const
{
try
{
cif::file cf(file);
cif::File cf(file);
auto& cat = cf["comp_" + res]["chem_comp_atom"];
......@@ -223,18 +222,18 @@ PeptideDB& PeptideDB::Instance()
PeptideDB::PeptideDB()
{
const char* clibd_mon = getenv("CLIBD_MON");
if (clibd_mon == nullptr)
const char* clibdMon = getenv("CLIBD_MON");
if (clibdMon == nullptr)
throw runtime_error("Cannot locate peptide list, please souce the CCP4 environment");
fs::path db = fs::path(clibd_mon) / "list" / "mon_lib_list.cif";
fs::path db = fs::path(clibdMon) / "list" / "mon_lib_list.cif";
PushDictionary(db);
pushDictionary(db);
sInstance = this;
}
void PeptideDB::PushDictionary(boost::filesystem::path dict)
void PeptideDB::pushDictionary(boost::filesystem::path dict)
{
if (not fs::exists(dict))
throw runtime_error("file not found: " + dict.string());
......@@ -246,13 +245,13 @@ void PeptideDB::PushDictionary(boost::filesystem::path dict)
mImpl = new PeptideDBImpl(file, mImpl);
}
void PeptideDB::PopDictionary()
void PeptideDB::popDictionary()
{
if (mImpl != nullptr)
{
auto i = mImpl;
mImpl = i->m_next;
i->m_next = nullptr;
mImpl = i->mNext;
i->mNext = nullptr;
delete i;
}
}
......@@ -262,27 +261,27 @@ PeptideDB::~PeptideDB()
delete mImpl;
}
bool PeptideDB::IsKnownPeptide(const string& res_name) const
bool PeptideDB::isKnownPeptide(const string& resName) const
{
return mImpl->m_known_peptides.count(res_name) > 0;
return mImpl->mKnownPeptides.count(resName) > 0;
}
bool PeptideDB::IsKnownBase(const string& res_name) const
bool PeptideDB::isKnownBase(const string& resName) const
{
return mImpl->m_known_bases.count(res_name) > 0;
return mImpl->mKnownBases.count(resName) > 0;
}
string PeptideDB::GetNameForResidue(const string& res_name) const
string PeptideDB::nameForResidue(const string& resName) const
{
return mImpl->name_for(res_name);
return mImpl->nameFor(resName);
}
string PeptideDB::GetFormulaForResidue(const string& res_name) const
string PeptideDB::formulaForResidue(const string& resName) const
{
return mImpl->formula_for(res_name);
return mImpl->formulaFor(resName);
}
string PeptideDB::Unalias(const string& res_name) const
string PeptideDB::unalias(const string& resName) const
{
return mImpl->unalias(res_name);
return mImpl->unalias(resName);
}
......@@ -457,6 +457,16 @@ cif::Datablock& File::data()
return *mImpl->mDb;
}
cif::File& File::file()
{
assert(mImpl);
if (mImpl == nullptr)
throw runtime_error("No data loaded");
return mImpl->mData;
}
// --------------------------------------------------------------------
// Structure
......
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