Commit 34c7fd3f by Maarten L. Hekkelman

Changes for DSSP

parent fac1eb91
......@@ -13,7 +13,9 @@ namespace mmcif
class Structure;
class Monomer;
extern const double
struct Res;
extern const float
kCouplingConstant, kMinHBondEnergy, kMaxHBondEnergy;
enum SecondaryStructureType : char
......@@ -28,6 +30,11 @@ enum SecondaryStructureType : char
ssBend = 'S'
};
enum class Helix
{
None, Start, End, StartAndEnd, Middle
};
//struct HBond
//{
// std::string labelAsymID;
......@@ -54,6 +61,27 @@ struct SecondaryStructure
//void CalculateSecondaryStructure(Structure& s);
const size_t
kHistogramSize = 30;
struct DSSP_Statistics
{
uint32_t nrOfResidues, nrOfChains, nrOfSSBridges, nrOfIntraChainSSBridges, nrOfHBonds;
uint32_t nrOfHBondsInAntiparallelBridges, nrOfHBondsInParallelBridges;
uint32_t nrOfHBondsPerDistance[11] = {};
double accessibleSurface = 0;
uint32_t residuesPerAlphaHelixHistogram[kHistogramSize] = {};
uint32_t parallelBridgesPerLadderHistogram[kHistogramSize] = {};
uint32_t antiparallelBridgesPerLadderHistogram[kHistogramSize] = {};
uint32_t laddersPerSheetHistogram[kHistogramSize] = {};
};
enum class ChainBreak
{
None, NewChain, Gap
};
class DSSP
{
public:
......@@ -66,9 +94,92 @@ class DSSP
SecondaryStructureType operator()(const std::string& inAsymID, int inSeqID) const;
SecondaryStructureType operator()(const Monomer& m) const;
double accessibility(const std::string& inAsymID, int inSeqID) const;
double accessibility(const Monomer& m) const;
bool isAlphaHelixEndBeforeStart(const Monomer& m) const;
bool isAlphaHelixEndBeforeStart(const std::string& inAsymID, int inSeqID) const;
DSSP_Statistics GetStatistics() const;
class iterator;
using res_iter = typename std::vector<Res>::iterator;
class ResidueInfo
{
public:
friend class iterator;
explicit operator bool() const { return not empty(); }
bool empty() const { return mImpl == nullptr; }
const Monomer& residue() const;
/// \brief return 0 if not a break, ' ' in case of a new chain and '*' in case of a broken chain
ChainBreak chainBreak() const;
/// \brief the internal number in DSSP
int nr() const;
SecondaryStructureType ss() const;
int ssBridgeNr() const;
Helix helix(int stride) const;
bool bend() const;
double accessibility() const;
/// \brief returns resinfo, ladder and parallel
std::tuple<ResidueInfo,int,bool> bridgePartner(int i) const;
int sheet() const;
/// \brief return resinfo and the energy of the bond
std::tuple<ResidueInfo,double> acceptor(int i) const;
std::tuple<ResidueInfo,double> donor(int i) const;
private:
ResidueInfo(Res* res);
Res* mImpl;
};
class iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = ResidueInfo;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
iterator(const iterator& i);
iterator(res_iter cur);
iterator& operator=(const iterator& i);
reference operator*() { return mCurrent; }
pointer operator->() { return &mCurrent; }
iterator& operator++();
iterator operator++(int)
{
auto tmp(*this);
this->operator++();
return tmp;
}
bool operator==(const iterator& rhs) const { return mCurrent.mImpl == rhs.mCurrent.mImpl; }
bool operator!=(const iterator& rhs) const { return mCurrent.mImpl != rhs.mCurrent.mImpl; }
private:
ResidueInfo mCurrent;
};
iterator begin() const;
iterator end() const;
private:
struct DSSPImpl* mImpl;
};
......
......@@ -226,8 +226,6 @@ class Residue
friend class Polymer;
void calculateCenterAndRadius();
const Structure* mStructure = nullptr;
std::string mCompoundID, mAsymID;
int mSeqID = 0;
......@@ -258,6 +256,7 @@ class Monomer : public Residue
float psi() const;
float alpha() const;
float kappa() const;
float tco() const;
// torsion angles
size_t nrOfChis() const;
......@@ -265,6 +264,9 @@ class Monomer : public Residue
bool isCis() const;
/// \brief Returns true if the four atoms C, CA, N and O are present
bool isComplete() const;
Atom CAlpha() const { return atomByID("CA"); }
Atom C() const { return atomByID("C"); }
Atom N() const { return atomByID("N"); }
......
......@@ -920,7 +920,6 @@ float Monomer::phi() const
cerr << ex.what() << endl;
}
return result;
}
......@@ -952,7 +951,7 @@ float Monomer::alpha() const
try
{
if (mIndex > 1 and mIndex + 2 < mPolymer->size())
if (mIndex >= 1 and mIndex + 2 < mPolymer->size())
{
auto& prev = mPolymer->operator[](mIndex - 1);
auto& next = mPolymer->operator[](mIndex + 1);
......@@ -976,7 +975,7 @@ float Monomer::kappa() const
try
{
if (mIndex > 2 and mIndex + 2 < mPolymer->size())
if (mIndex >= 2 and mIndex + 2 < mPolymer->size())
{
auto& prevPrev = mPolymer->operator[](mIndex - 2);
auto& nextNext = mPolymer->operator[](mIndex + 2);
......@@ -999,6 +998,29 @@ float Monomer::kappa() const
return result;
}
float Monomer::tco() const
{
double result = 0.0;
try
{
if (mIndex > 0)
{
auto& prev = mPolymer->operator[](mIndex - 1);
if (prev.mSeqID + 1 == mSeqID)
result = CosinusAngle(C().location(), O().location(), prev.C().location(), prev.O().location());
}
}
catch (const exception& ex)
{
if (cif::VERBOSE)
cerr << "When trying to calculate kappa for " << asymID() << ':' << seqID() << ": "
<< ex.what() << endl;
}
return result;
}
const map<string,vector<string>> kChiAtomsMap = {
{ "ASP", {"CG", "OD1"} },
{ "ASN", {"CG", "OD1"} },
......@@ -1084,6 +1106,19 @@ bool Monomer::isCis() const
return result;
}
bool Monomer::isComplete() const
{
int seen = 0;
for (auto& a: mAtoms)
{
if (a.labelAtomId() == "CA") seen |= 1;
else if (a.labelAtomId() == "C") seen |= 2;
else if (a.labelAtomId() == "N") seen |= 4;
else if (a.labelAtomId() == "O") seen |= 8;
}
return seen == 15;
}
float Monomer::chiralVolume() const
{
float result = 0;
......
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