Commit 4632a417 by maarten

chiron started

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@215 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent 16492f6f
...@@ -597,6 +597,24 @@ struct Condition ...@@ -597,6 +597,24 @@ struct Condition
namespace detail namespace detail
{ {
struct KeyIsEmptyConditionImpl : public ConditionImpl
{
KeyIsEmptyConditionImpl(const string& ItemTag)
: mItemTag(ItemTag) {}
virtual bool test(const Category& c, const Row& r) const
{
return r[mItemTag].empty();
}
virtual std::string str() const
{
return mItemTag + " == <empty>";
}
string mItemTag;
};
template<typename T> template<typename T>
struct KeyIsConditionImpl : public ConditionImpl struct KeyIsConditionImpl : public ConditionImpl
{ {
...@@ -782,7 +800,9 @@ inline Condition operator||(Condition&& a, Condition&& b) ...@@ -782,7 +800,9 @@ inline Condition operator||(Condition&& a, Condition&& b)
{ {
return Condition(new detail::orConditionImpl(std::move(a), std::move(b))); return Condition(new detail::orConditionImpl(std::move(a), std::move(b)));
} }
struct Empty {};
struct Key struct Key
{ {
Key(const string& ItemTag) : mItemTag(ItemTag) {} Key(const string& ItemTag) : mItemTag(ItemTag) {}
...@@ -800,6 +820,11 @@ struct Key ...@@ -800,6 +820,11 @@ struct Key
return Condition(new detail::KeyIsConditionImpl<std::string>(mItemTag, value)); return Condition(new detail::KeyIsConditionImpl<std::string>(mItemTag, value));
} }
Condition operator==(Empty&) const
{
return Condition(new detail::KeyIsEmptyConditionImpl(mItemTag));
}
template<typename T> template<typename T>
Condition operator!=(const T& v) const Condition operator!=(const T& v) const
{ {
......
...@@ -42,15 +42,21 @@ struct CompoundAtom ...@@ -42,15 +42,21 @@ struct CompoundAtom
// This information is derived from the ccp4 monomer library by default. // This information is derived from the ccp4 monomer library by default.
// To create compounds, you'd best use the factory method. // To create compounds, you'd best use the factory method.
enum ChiralVolumeSign { negativ, positiv, both };
class Compound class Compound
{ {
public: public:
struct ChiralCentre;
Compound(const std::string& id, const std::string& name, Compound(const std::string& id, const std::string& name,
const std::string& group, std::vector<CompoundAtom>&& atoms, const std::string& group, std::vector<CompoundAtom>&& atoms,
std::map<std::tuple<std::string,std::string>,float>&& bonds) std::map<std::tuple<std::string,std::string>,float>&& bonds,
std::vector<ChiralCentre>&& chiralCentres)
: mId(id), mName(name), mGroup(group) : mId(id), mName(name), mGroup(group)
, mAtoms(std::move(atoms)), mBonds(std::move(bonds)) , mAtoms(std::move(atoms)), mBonds(std::move(bonds))
, mChiralCentres(std::move(chiralCentres))
{ {
} }
...@@ -88,13 +94,24 @@ class Compound ...@@ -88,13 +94,24 @@ class Compound
int charge() const; int charge() const;
bool isWater() const; bool isWater() const;
struct ChiralCentre
{
std::string mID;
std::string mAtomIDCentre;
std::string mAtomID[3];
ChiralVolumeSign mVolumeSign;
};
std::vector<ChiralCentre> chiralCentres() const { return mChiralCentres; }
private: private:
// Entity& mEntity; // Entity& mEntity;
std::string mId; std::string mId;
std::string mName; std::string mName;
std::string mGroup; std::string mGroup;
std::vector<CompoundAtom> mAtoms; std::vector<CompoundAtom> mAtoms;
std::map<std::tuple<std::string,std::string>,float> mBonds; std::map<std::tuple<std::string,std::string>,float> mBonds;
std::vector<ChiralCentre> mChiralCentres;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "cif++/AtomType.h" #include "cif++/AtomType.h"
#include "cif++/Point.h" #include "cif++/Point.h"
#include "cif++/Compound.h" #include "cif++/Compound.h"
#include "cif++/Cif++.h"
/* /*
To modify a structure, you will have to use actions. To modify a structure, you will have to use actions.
...@@ -35,12 +36,14 @@ ...@@ -35,12 +36,14 @@
*/ */
// forward declaration //// forward declaration
namespace cif //namespace cif
{ //{
class Datablock; // class Category;
class File; // class Datablock;
}; // class File;
// class RowSet;
//};
namespace libcif namespace libcif
{ {
...@@ -137,77 +140,121 @@ typedef std::vector<Atom> AtomView; ...@@ -137,77 +140,121 @@ typedef std::vector<Atom> AtomView;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
class Residue : public std::enable_shared_from_this<Residue> class Residue
{
public:
Residue(const Residue& rhs);
Residue& operator=(const Residue& rhs);
Residue(const Structure& structure)
: mStructure(&structure) {}
Residue(const Structure& structure, const std::string& compoundID,
const std::string& asymID, const std::string& seqID = "",
const std::string& altID = "")
: mStructure(&structure), mCompoundID(compoundID)
, mAsymID(asymID), mSeqID(seqID), mAltID(altID) {}
const Compound& comp() const;
AtomView atoms() const;
Atom atomByID(const std::string& atomID) const;
const std::string& compoundID() const { return mCompoundID; }
const std::string& asymID() const { return mAsymID; }
const std::string& seqID() const { return mSeqID; }
const std::string& altID() const { return mAltID; }
protected:
const Structure* mStructure;
std::string mCompoundID, mAsymID, mSeqID, mAltID;
mutable AtomView mAtoms;
};
// --------------------------------------------------------------------
// a monomer models a single Residue in a protein chain
class Monomer : public Residue
{ {
public: public:
Residue(const Compound& cmp) : mCompound(cmp) {} Monomer(const Monomer& rhs);
Monomer& operator=(const Monomer& rhs);
const Compound& comp() const { return mCompound; } Monomer(Polymer& polymer);
virtual AtomView atoms(); Monomer(Polymer& polymer, uint32 seqID,
const std::string& compoundID, const std::string& altID);
private: private:
const Compound& mCompound; Polymer* mPolymer;
}; };
//// -------------------------------------------------------------------- // --------------------------------------------------------------------
//// a monomer models a single Residue in a protein chain
// class Polymer
//class monomer : public Residue {
//{ public:
// public: Polymer(const Structure& s, const std::string& entityID, const std::string& asymID);
// monomer(polymer& polymer, size_t seqId, const std::string& compId, Polymer(const Polymer&);
// const std::string& altId); Polymer& operator=(const Polymer&);
//
// int num() const { return mNum; } struct iterator : public std::iterator<std::random_access_iterator_tag, Monomer>
//// polymer& getPolymer(); {
// typedef std::iterator<std::bidirectional_iterator_tag, Monomer> base_type;
//// std::vector<monomer_ptr> alternates(); typedef base_type::reference reference;
// typedef base_type::pointer pointer;
// private:
// polymer_ptr mPolymer; iterator(Polymer& p, uint32 index);
// int mNum; iterator(iterator&& rhs);
//};
// iterator(const iterator& rhs);
//// -------------------------------------------------------------------- iterator& operator=(const iterator& rhs);
//
//class polymer : public std::enable_shared_from_this<polymer>
//{
// public:
// polymer(const polymerEntity& pe, const std::string& asymId);
//
// struct iterator : public std::iterator<std::random_access_iterator_tag, monomer>
// {
// typedef std::iterator<std::bidirectional_iterator_tag, monomer> base_type;
// typedef base_type::reference reference;
// typedef base_type::pointer pointer;
//
// iterator(polymer& list, uint32 index);
// iterator(iterator&& rhs);
// iterator(const iterator& rhs);
// iterator& operator=(const iterator& rhs);
// iterator& operator=(iterator&& rhs); // iterator& operator=(iterator&& rhs);
//
// reference operator*(); reference operator*() { return mCurrent; }
// pointer operator->(); pointer operator->() { return &mCurrent; }
//
// iterator& operator++(); iterator& operator++();
// iterator operator++(int); iterator operator++(int)
// {
// iterator& operator--(); iterator result(*this);
// iterator operator--(int); operator++();
// return result;
// bool operator==(const iterator& rhs) const; }
// bool operator!=(const iterator& rhs) const;
// }; iterator& operator--();
// iterator operator--(int)
// iterator begin(); {
// iterator end(); iterator result(*this);
// operator--();
// private: return result;
// polymer_entity mEntity; }
// std::string mAsymId;
// std::vector<Residue_ptr> mMonomers; bool operator==(const iterator& rhs) const { return mPolymer == rhs.mPolymer and mIndex == rhs.mIndex; }
//}; bool operator!=(const iterator& rhs) const { return mPolymer != rhs.mPolymer or mIndex != rhs.mIndex; }
private:
Polymer* mPolymer;
uint32 mIndex;
Monomer mCurrent;
};
iterator begin();
iterator end();
Structure* structure() const { return mStructure; }
std::string asymID() const { return mAsymID; }
std::string entityID() const { return mEntityID; }
private:
friend struct iterator;
Structure* mStructure;
std::string mEntityID;
std::string mAsymID;
cif::RowSet mPolySeq;
};
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// file is a reference to the data stored in e.g. the cif file. // file is a reference to the data stored in e.g. the cif file.
...@@ -254,6 +301,9 @@ class Structure ...@@ -254,6 +301,9 @@ class Structure
AtomView atoms() const; AtomView atoms() const;
AtomView waters() const; AtomView waters() const;
std::vector<Polymer> polymers() const;
std::vector<Residue> nonPolymers() const;
Atom getAtomById(std::string id) const; Atom getAtomById(std::string id) const;
Atom getAtomByLocation(Point pt, float maxDistance) const; Atom getAtomByLocation(Point pt, float maxDistance) const;
...@@ -286,8 +336,13 @@ class Structure ...@@ -286,8 +336,13 @@ class Structure
// Actions // Actions
void removeAtom(Atom& a); void removeAtom(Atom& a);
private: private:
friend Polymer;
friend Residue;
cif::Category& category(const char* name) const;
struct StructureImpl* mImpl; struct StructureImpl* mImpl;
}; };
......
...@@ -271,8 +271,38 @@ const Compound* CompoundFactory::create(std::string id) ...@@ -271,8 +271,38 @@ const Compound* CompoundFactory::create(std::string id)
bonds[make_tuple(atomId_1, atomId_2)] = value; bonds[make_tuple(atomId_1, atomId_2)] = value;
} }
auto& compChir = cf["comp_" + id]["chem_comp_chir"];
vector<Compound::ChiralCentre> chiralCentres;
for (auto row: compChir)
{
Compound::ChiralCentre cc;
string volumeSign;
cif::tie(cc.mID, cc.mAtomIDCentre, cc.mAtomID[0],
cc.mAtomID[1], cc.mAtomID[2], volumeSign) =
row.get("id", "atom_id_centre", "atom_id_1",
"atom_id_2", "atom_id_3", "volume_sign");
if (volumeSign == "negativ")
cc.mVolumeSign = negativ;
else if (volumeSign == "positiv")
cc.mVolumeSign = positiv;
else if (volumeSign == "both")
cc.mVolumeSign = both;
else
{
if (VERBOSE)
cerr << "Unimplemented chem_comp_chir.volume_sign " << volumeSign << " in file " << resFile << endl;
continue;
}
chiralCentres.push_back(cc);
}
result = new Compound(id, name, group, move(atoms), move(bonds)); result = new Compound(id, name, group, move(atoms), move(bonds),
move(chiralCentres));
mCompounds.push_back(result); mCompounds.push_back(result);
} }
} }
......
...@@ -451,17 +451,200 @@ float Atom::radius() const ...@@ -451,17 +451,200 @@ float Atom::radius() const
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// residue // residue
//AtomView residue::Atoms() Residue::Residue(const Residue& rhs)
//{ : mStructure(rhs.mStructure)
// assert(false); , mCompoundID(rhs.mCompoundID), mAsymID(rhs.mAsymID), mSeqID(rhs.mSeqID), mAltID(rhs.mAltID)
//} {
}
Residue& Residue::operator=(const Residue& rhs)
{
if (this != &rhs)
{
mStructure = rhs.mStructure;
mCompoundID = rhs.mCompoundID;
mAsymID = rhs.mAsymID;
mSeqID = rhs.mSeqID;
mAltID = rhs.mAltID;
}
return *this;
}
const Compound& Residue::comp() const
{
auto compound = Compound::create(mCompoundID);
if (compound == nullptr)
throw runtime_error("Failed to create compound " + mCompoundID);
return *compound;
}
AtomView Residue::atoms() const
{
if (mStructure == nullptr)
throw runtime_error("Invalid Residue object");
if (mAtoms.empty())
{
for (auto& a: mStructure->atoms())
{
if (a.property<string>("label_asym_id") != mAsymID or
a.property<string>("label_comp_id") != mCompoundID)
continue;
if (not mSeqID.empty() and a.property<string>("label_seq_id") != mSeqID)
continue;
if (not mAltID.empty() and a.property<string>("label_alt_id") != mAltID)
continue;
mAtoms.push_back(a);
}
}
return mAtoms;
// auto& atomSites = mStructure->category("atom_site");
//
// auto query = cif::Key("label_asym_id") == mAsymID and cif::Key("label_comp_id") == mCompoundID;
//
// if (not mSeqID.empty())
// query = move(query) and cif::Key("label_seq_id") == mSeqID;
//
// if (not mAltID.empty())
// query = move(query) and (cif::Key("label_alt_id") == cif::Empty() or cif::Key("label_alt_id") == mAltID);
//
// return atomSites.find(move(query));
}
Atom Residue::atomByID(const string& atomID) const
{
for (auto& a: atoms())
{
if (a.property<string>("label_atom_id") == atomID)
return a;
}
throw runtime_error("Atom with atom_id " + atomID + " not found in residue " + mAsymID + ':' + mSeqID);
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// monomer // monomer
Monomer::Monomer(const Monomer& rhs)
: Residue(rhs), mPolymer(rhs.mPolymer)
{
}
Monomer& Monomer::operator=(const Monomer& rhs)
{
if (this != &rhs)
{
Residue::operator=(rhs);
mPolymer = rhs.mPolymer;
}
return *this;
}
Monomer::Monomer(Polymer& polymer)
: Residue(*polymer.structure())
, mPolymer(&polymer)
{
}
Monomer::Monomer(Polymer& polymer, uint32 seqID, const string& compoundID, const string& altID)
: Residue(*polymer.structure(), compoundID, polymer.asymID(), to_string(seqID), altID)
, mPolymer(&polymer)
{
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// polymer // polymer
Polymer::iterator::iterator(Polymer& p, uint32 index)
: mPolymer(&p), mIndex(index), mCurrent(p)
{
auto& polySeq = mPolymer->mPolySeq;
if (index < polySeq.size())
{
int seqID;
string asymID, monID;
cif::tie(asymID, seqID, monID) =
polySeq[mIndex].get("asym_id", "seq_id", "mon_id");
mCurrent = Monomer(*mPolymer, seqID, monID, "");
}
}
Polymer::iterator::iterator(const iterator& rhs)
: mPolymer(rhs.mPolymer), mIndex(rhs.mIndex), mCurrent(rhs.mCurrent)
{
}
Polymer::iterator& Polymer::iterator::operator=(const iterator& rhs)
{
if (this != &rhs)
{
mPolymer = rhs.mPolymer;
mIndex = rhs.mIndex;
mCurrent = rhs.mCurrent;
}
return *this;
}
Polymer::iterator& Polymer::iterator::operator++()
{
auto& polySeq = mPolymer->mPolySeq;
if (mIndex < polySeq.size())
++mIndex;
if (mIndex < polySeq.size())
{
int seqID;
string asymID, monID;
cif::tie(asymID, seqID, monID) =
polySeq[mIndex].get("asym_id", "seq_id", "mon_id");
mCurrent = Monomer(*mPolymer, seqID, monID, "");
}
return *this;
}
Polymer::Polymer(const Polymer& rhs)
: mStructure(rhs.mStructure), mEntityID(rhs.mEntityID), mAsymID(rhs.mAsymID), mPolySeq(rhs.mPolySeq)
{
}
Polymer::Polymer(const Structure& s, const string& entityID, const string& asymID)
: mStructure(const_cast<Structure*>(&s)), mEntityID(entityID), mAsymID(asymID)
, mPolySeq(s.category("pdbx_poly_seq_scheme").find(cif::Key("asym_id") == mAsymID and cif::Key("entity_id") == mEntityID))
{
}
Polymer::iterator Polymer::begin()
{
return iterator(*this, 0);
}
Polymer::iterator Polymer::end()
{
return iterator(*this, mPolySeq.size());
}
//cif::RowSet Polymer::polySeqRows() const
//{
// auto& cat = mStructure->category("pdbx_poly_seq_scheme");
//
// return cat.find(cif::Key("asym_id") == mAsymID and cif::Key("entityID") == mEntityID);
//}
//
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// File // File
...@@ -655,6 +838,44 @@ AtomView Structure::waters() const ...@@ -655,6 +838,44 @@ AtomView Structure::waters() const
return result; return result;
} }
vector<Polymer> Structure::polymers() const
{
vector<Polymer> result;
auto& polySeqScheme = category("pdbx_poly_seq_scheme");
for (auto& r: polySeqScheme)
{
string asymID, entityID, seqID, monID;
cif::tie(asymID, entityID, seqID, monID) =
r.get("asym_id", "entity_id", "seq_id", "mon_id");
if (result.empty() or result.back().asymID() != asymID or result.back().entityID() != entityID)
result.emplace_back(*this, entityID, asymID);
}
return result;
}
vector<Residue> Structure::nonPolymers() const
{
vector<Residue> result;
auto& nonPolyScheme = category("pdbx_nonpoly_scheme");
for (auto& r: nonPolyScheme)
{
string asymID, monID;
cif::tie(asymID, monID) =
r.get("asym_id", "mon_id");
if (result.empty() or result.back().asymID() != asymID)
result.emplace_back(*this, monID, asymID);
}
return result;
}
Atom Structure::getAtomById(string id) const Atom Structure::getAtomById(string id) const
{ {
for (auto& a: mImpl->mAtoms) for (auto& a: mImpl->mAtoms)
...@@ -671,6 +892,12 @@ File& Structure::getFile() const ...@@ -671,6 +892,12 @@ File& Structure::getFile() const
return *mImpl->mFile; return *mImpl->mFile;
} }
cif::Category& Structure::category(const char* name) const
{
auto& db = *getFile().impl().mDb;
return db[name];
}
//tuple<string,string> Structure::MapLabelToAuth( //tuple<string,string> Structure::MapLabelToAuth(
// const string& asymId, int seqId) // const string& asymId, int seqId)
//{ //{
......
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