Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
34c7fd3f
Commit
34c7fd3f
authored
Jun 24, 2020
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes for DSSP
parent
fac1eb91
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
765 additions
and
127 deletions
+765
-127
include/cif++/Secondary.h
+112
-1
include/cif++/Structure.h
+4
-2
src/Secondary.cpp
+611
-121
src/Structure.cpp
+38
-3
No files found.
include/cif++/Secondary.h
View file @
34c7fd3f
...
@@ -13,7 +13,9 @@ namespace mmcif
...
@@ -13,7 +13,9 @@ namespace mmcif
class
Structure
;
class
Structure
;
class
Monomer
;
class
Monomer
;
extern
const
double
struct
Res
;
extern
const
float
kCouplingConstant
,
kMinHBondEnergy
,
kMaxHBondEnergy
;
kCouplingConstant
,
kMinHBondEnergy
,
kMaxHBondEnergy
;
enum
SecondaryStructureType
:
char
enum
SecondaryStructureType
:
char
...
@@ -28,6 +30,11 @@ enum SecondaryStructureType : char
...
@@ -28,6 +30,11 @@ enum SecondaryStructureType : char
ssBend
=
'S'
ssBend
=
'S'
};
};
enum
class
Helix
{
None
,
Start
,
End
,
StartAndEnd
,
Middle
};
//struct HBond
//struct HBond
//{
//{
// std::string labelAsymID;
// std::string labelAsymID;
...
@@ -54,6 +61,27 @@ struct SecondaryStructure
...
@@ -54,6 +61,27 @@ struct SecondaryStructure
//void CalculateSecondaryStructure(Structure& s);
//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
class
DSSP
{
{
public
:
public
:
...
@@ -66,9 +94,92 @@ class DSSP
...
@@ -66,9 +94,92 @@ class DSSP
SecondaryStructureType
operator
()(
const
std
::
string
&
inAsymID
,
int
inSeqID
)
const
;
SecondaryStructureType
operator
()(
const
std
::
string
&
inAsymID
,
int
inSeqID
)
const
;
SecondaryStructureType
operator
()(
const
Monomer
&
m
)
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
Monomer
&
m
)
const
;
bool
isAlphaHelixEndBeforeStart
(
const
std
::
string
&
inAsymID
,
int
inSeqID
)
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
:
private
:
struct
DSSPImpl
*
mImpl
;
struct
DSSPImpl
*
mImpl
;
};
};
...
...
include/cif++/Structure.h
View file @
34c7fd3f
...
@@ -226,8 +226,6 @@ class Residue
...
@@ -226,8 +226,6 @@ class Residue
friend
class
Polymer
;
friend
class
Polymer
;
void
calculateCenterAndRadius
();
const
Structure
*
mStructure
=
nullptr
;
const
Structure
*
mStructure
=
nullptr
;
std
::
string
mCompoundID
,
mAsymID
;
std
::
string
mCompoundID
,
mAsymID
;
int
mSeqID
=
0
;
int
mSeqID
=
0
;
...
@@ -258,6 +256,7 @@ class Monomer : public Residue
...
@@ -258,6 +256,7 @@ class Monomer : public Residue
float
psi
()
const
;
float
psi
()
const
;
float
alpha
()
const
;
float
alpha
()
const
;
float
kappa
()
const
;
float
kappa
()
const
;
float
tco
()
const
;
// torsion angles
// torsion angles
size_t
nrOfChis
()
const
;
size_t
nrOfChis
()
const
;
...
@@ -265,6 +264,9 @@ class Monomer : public Residue
...
@@ -265,6 +264,9 @@ class Monomer : public Residue
bool
isCis
()
const
;
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
CAlpha
()
const
{
return
atomByID
(
"CA"
);
}
Atom
C
()
const
{
return
atomByID
(
"C"
);
}
Atom
C
()
const
{
return
atomByID
(
"C"
);
}
Atom
N
()
const
{
return
atomByID
(
"N"
);
}
Atom
N
()
const
{
return
atomByID
(
"N"
);
}
...
...
src/Secondary.cpp
View file @
34c7fd3f
...
@@ -10,13 +10,13 @@
...
@@ -10,13 +10,13 @@
#include <numeric>
#include <numeric>
#include <chrono>
#include <chrono>
#include <iomanip>
#include <iomanip>
#include <future>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string.hpp>
#include "cif++/Structure.h"
#include "cif++/Structure.h"
#include "cif++/Secondary.h"
#include "cif++/Secondary.h"
using
namespace
std
;
namespace
ba
=
boost
::
algorithm
;
namespace
ba
=
boost
::
algorithm
;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
@@ -86,7 +86,7 @@ const ResidueInfo kResidueInfo[] = {
...
@@ -86,7 +86,7 @@ const ResidueInfo kResidueInfo[] = {
{
kValine
,
'V'
,
"VAL"
}
{
kValine
,
'V'
,
"VAL"
}
};
};
ResidueType
MapResidue
(
string
inName
)
ResidueType
MapResidue
(
st
d
::
st
ring
inName
)
{
{
ba
::
trim
(
inName
);
ba
::
trim
(
inName
);
...
@@ -119,9 +119,9 @@ struct Bridge
...
@@ -119,9 +119,9 @@ struct Bridge
{
{
BridgeType
type
;
BridgeType
type
;
uint32_t
sheet
,
ladder
;
uint32_t
sheet
,
ladder
;
s
et
<
Bridge
*>
link
;
s
td
::
set
<
Bridge
*>
link
;
deque
<
uint32_t
>
i
,
j
;
std
::
deque
<
uint32_t
>
i
,
j
;
st
ring
chainI
,
chainJ
;
st
d
::
string
chainI
,
chainJ
;
bool
operator
<
(
const
Bridge
&
b
)
const
{
return
chainI
<
b
.
chainI
or
(
chainI
==
b
.
chainI
and
i
.
front
()
<
b
.
i
.
front
());
}
bool
operator
<
(
const
Bridge
&
b
)
const
{
return
chainI
<
b
.
chainI
or
(
chainI
==
b
.
chainI
and
i
.
front
()
<
b
.
i
.
front
());
}
};
};
...
@@ -133,40 +133,75 @@ struct BridgeParner
...
@@ -133,40 +133,75 @@ struct BridgeParner
bool
parallel
;
bool
parallel
;
};
};
enum
HelixFlag
{
helixNone
,
helixStart
,
helixEnd
,
helixStartAndEnd
,
helixMiddle
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
const
double
const
float
// kSSBridgeDistance = 3.0,
// kSSBridgeDistance = 3.0,
kMinimalDistance
=
0.5
,
kMinimalDistance
=
0.5
,
kMinimalCADistance
=
9.0
,
kMinimalCADistance
=
9.0
,
kMinHBondEnergy
=
-
9.9
,
kMinHBondEnergy
=
-
9.9
,
kMaxHBondEnergy
=
-
0.5
,
kMaxHBondEnergy
=
-
0.5
,
kCouplingConstant
=
-
27.888
;
// = -332 * 0.42 * 0.2
kCouplingConstant
=
-
27.888
,
// = -332 * 0.42 * 0.2
//
kMaxPeptideBondLength = 2.5;
kMaxPeptideBondLength
=
2.5
;
// const uint32_t kHistogramSize = 30;
const
float
kRadiusN
=
1.65
,
kRadiusCA
=
1.87
,
kRadiusC
=
1.76
,
kRadiusO
=
1.4
,
kRadiusSideAtom
=
1.8
,
kRadiusWater
=
1.4
;
struct
Res
struct
Res
{
{
Res
(
const
Monomer
&
m
)
Res
(
const
Monomer
&
m
,
int
nr
)
:
mM
(
m
)
:
mM
(
m
)
,
mNumber
(
nr
)
,
mType
(
MapResidue
(
m
.
compoundID
()))
,
mType
(
MapResidue
(
m
.
compoundID
()))
{
{
// update the box containing all atoms
mBox
[
0
].
mX
=
mBox
[
0
].
mY
=
mBox
[
0
].
mZ
=
std
::
numeric_limits
<
double
>::
max
();
mBox
[
1
].
mX
=
mBox
[
1
].
mY
=
mBox
[
1
].
mZ
=
-
std
::
numeric_limits
<
double
>::
max
();
for
(
auto
&
a
:
mM
.
atoms
())
for
(
auto
&
a
:
mM
.
atoms
())
{
{
if
(
a
.
labelAtomId
()
==
"CA"
)
mCAlpha
=
a
.
location
();
if
(
a
.
labelAtomId
()
==
"CA"
)
else
if
(
a
.
labelAtomId
()
==
"C"
)
mC
=
a
.
location
();
{
else
if
(
a
.
labelAtomId
()
==
"N"
)
mN
=
a
.
location
();
mCAlpha
=
a
.
location
();
else
if
(
a
.
labelAtomId
()
==
"O"
)
mO
=
a
.
location
();
ExtendBox
(
mCAlpha
,
kRadiusCA
+
2
*
kRadiusWater
);
// else if (a.labelAtomId() == "H") mH = a.location();
}
else
if
(
a
.
labelAtomId
()
==
"C"
)
{
mC
=
a
.
location
();
ExtendBox
(
mC
,
kRadiusC
+
2
*
kRadiusWater
);
}
else
if
(
a
.
labelAtomId
()
==
"N"
)
{
mN
=
a
.
location
();
ExtendBox
(
mN
,
kRadiusN
+
2
*
kRadiusWater
);
}
else
if
(
a
.
labelAtomId
()
==
"O"
)
{
mO
=
a
.
location
();
ExtendBox
(
mO
,
kRadiusO
+
2
*
kRadiusWater
);
}
else
{
mSideChain
.
push_back
(
a
.
location
());
ExtendBox
(
a
.
location
(),
kRadiusSideAtom
+
2
*
kRadiusWater
);
}
}
}
}
mRadius
=
mBox
[
1
].
mX
-
mBox
[
0
].
mX
;
if
(
mRadius
<
mBox
[
1
].
mY
-
mBox
[
0
].
mY
)
mRadius
=
mBox
[
1
].
mY
-
mBox
[
0
].
mY
;
if
(
mRadius
<
mBox
[
1
].
mZ
-
mBox
[
0
].
mZ
)
mRadius
=
mBox
[
1
].
mZ
-
mBox
[
0
].
mZ
;
mCenter
.
mX
=
(
mBox
[
0
].
mX
+
mBox
[
1
].
mX
)
/
2
;
mCenter
.
mY
=
(
mBox
[
0
].
mY
+
mBox
[
1
].
mY
)
/
2
;
mCenter
.
mZ
=
(
mBox
[
0
].
mZ
+
mBox
[
1
].
mZ
)
/
2
;
}
void
assignHydrogen
()
void
assignHydrogen
()
{
{
// assign the Hydrogen
// assign the Hydrogen
...
@@ -209,7 +244,7 @@ struct Res
...
@@ -209,7 +244,7 @@ struct Res
bool
IsBend
()
const
{
return
mBend
;
}
bool
IsBend
()
const
{
return
mBend
;
}
void
SetBend
(
bool
inBend
)
{
mBend
=
inBend
;
}
void
SetBend
(
bool
inBend
)
{
mBend
=
inBend
;
}
Helix
Flag
GetHelixFlag
(
uint32_t
inHelixStride
)
const
Helix
GetHelixFlag
(
uint32_t
inHelixStride
)
const
{
{
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
return
mHelixFlags
[
inHelixStride
-
3
];
return
mHelixFlags
[
inHelixStride
-
3
];
...
@@ -218,10 +253,10 @@ struct Res
...
@@ -218,10 +253,10 @@ struct Res
bool
IsHelixStart
(
uint32_t
inHelixStride
)
const
bool
IsHelixStart
(
uint32_t
inHelixStride
)
const
{
{
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
return
mHelixFlags
[
inHelixStride
-
3
]
==
helixStart
or
mHelixFlags
[
inHelixStride
-
3
]
==
helix
StartAndEnd
;
return
mHelixFlags
[
inHelixStride
-
3
]
==
Helix
::
Start
or
mHelixFlags
[
inHelixStride
-
3
]
==
Helix
::
StartAndEnd
;
}
}
void
SetHelixFlag
(
uint32_t
inHelixStride
,
Helix
Flag
inHelixFlag
)
void
SetHelixFlag
(
uint32_t
inHelixStride
,
Helix
inHelixFlag
)
{
{
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
assert
(
inHelixStride
==
3
or
inHelixStride
==
4
or
inHelixStride
==
5
);
mHelixFlags
[
inHelixStride
-
3
]
=
inHelixFlag
;
mHelixFlags
[
inHelixStride
-
3
]
=
inHelixFlag
;
...
@@ -230,22 +265,60 @@ struct Res
...
@@ -230,22 +265,60 @@ struct Res
void
SetSSBridgeNr
(
uint8_t
inBridgeNr
)
void
SetSSBridgeNr
(
uint8_t
inBridgeNr
)
{
{
if
(
mType
!=
kCysteine
)
if
(
mType
!=
kCysteine
)
throw
runtime_error
(
"Only cysteine residues can form sulphur bridges"
);
throw
std
::
runtime_error
(
"Only cysteine residues can form sulphur bridges"
);
mSSBridgeNr
=
inBridgeNr
;
mSSBridgeNr
=
inBridgeNr
;
}
}
uint8_t
GetSSBridgeNr
()
const
uint8_t
GetSSBridgeNr
()
const
{
{
if
(
mType
!=
kCysteine
)
if
(
mType
!=
kCysteine
)
throw
runtime_error
(
"Only cysteine residues can form sulphur bridges"
);
throw
std
::
runtime_error
(
"Only cysteine residues can form sulphur bridges"
);
return
mSSBridgeNr
;
return
mSSBridgeNr
;
}
}
double
CalculateSurface
(
const
std
::
vector
<
Res
>&
inResidues
);
double
CalculateSurface
(
const
Point
&
inAtom
,
float
inRadius
,
const
std
::
vector
<
Res
*>&
inNeighbours
);
bool
AtomIntersectsBox
(
const
Point
&
atom
,
float
inRadius
)
const
{
return
atom
.
mX
+
inRadius
>=
mBox
[
0
].
mX
and
atom
.
mX
-
inRadius
<=
mBox
[
1
].
mX
and
atom
.
mY
+
inRadius
>=
mBox
[
0
].
mY
and
atom
.
mY
-
inRadius
<=
mBox
[
1
].
mY
and
atom
.
mZ
+
inRadius
>=
mBox
[
0
].
mZ
and
atom
.
mZ
-
inRadius
<=
mBox
[
1
].
mZ
;
}
void
ExtendBox
(
const
Point
&
atom
,
float
inRadius
)
{
if
(
mBox
[
0
].
mX
>
atom
.
mX
-
inRadius
)
mBox
[
0
].
mX
=
atom
.
mX
-
inRadius
;
if
(
mBox
[
0
].
mY
>
atom
.
mY
-
inRadius
)
mBox
[
0
].
mY
=
atom
.
mY
-
inRadius
;
if
(
mBox
[
0
].
mZ
>
atom
.
mZ
-
inRadius
)
mBox
[
0
].
mZ
=
atom
.
mZ
-
inRadius
;
if
(
mBox
[
1
].
mX
<
atom
.
mX
+
inRadius
)
mBox
[
1
].
mX
=
atom
.
mX
+
inRadius
;
if
(
mBox
[
1
].
mY
<
atom
.
mY
+
inRadius
)
mBox
[
1
].
mY
=
atom
.
mY
+
inRadius
;
if
(
mBox
[
1
].
mZ
<
atom
.
mZ
+
inRadius
)
mBox
[
1
].
mZ
=
atom
.
mZ
+
inRadius
;
}
Res
*
mNext
=
nullptr
;
Res
*
mNext
=
nullptr
;
Res
*
mPrev
=
nullptr
;
Res
*
mPrev
=
nullptr
;
const
Monomer
&
mM
;
const
Monomer
&
mM
;
int
mNumber
;
Point
mCAlpha
,
mC
,
mN
,
mO
,
mH
;
Point
mCAlpha
,
mC
,
mN
,
mO
,
mH
;
Point
mBox
[
2
]
=
{};
float
mRadius
;
Point
mCenter
;
std
::
vector
<
Point
>
mSideChain
;
double
mAccessibility
=
0
;
ResidueType
mType
;
ResidueType
mType
;
uint8_t
mSSBridgeNr
=
0
;
uint8_t
mSSBridgeNr
=
0
;
...
@@ -253,11 +326,196 @@ struct Res
...
@@ -253,11 +326,196 @@ struct Res
HBond
mHBondDonor
[
2
]
=
{},
mHBondAcceptor
[
2
]
=
{};
HBond
mHBondDonor
[
2
]
=
{},
mHBondAcceptor
[
2
]
=
{};
BridgeParner
mBetaPartner
[
2
]
=
{};
BridgeParner
mBetaPartner
[
2
]
=
{};
uint32_t
mSheet
=
0
;
uint32_t
mSheet
=
0
;
Helix
Flag
mHelixFlags
[
3
]
=
{
helixNone
,
helixNone
,
helix
None
};
//
Helix
mHelixFlags
[
3
]
=
{
Helix
::
None
,
Helix
::
None
,
Helix
::
None
};
//
bool
mBend
=
false
;
bool
mBend
=
false
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class
Accumulator
{
public
:
struct
candidate
{
Point
location
;
double
radius
;
double
distance
;
bool
operator
<
(
const
candidate
&
rhs
)
const
{
return
distance
<
rhs
.
distance
;
}
};
void
operator
()(
const
Point
&
a
,
const
Point
&
b
,
double
d
,
double
r
)
{
double
distance
=
DistanceSquared
(
a
,
b
);
d
+=
kRadiusWater
;
r
+=
kRadiusWater
;
double
test
=
d
+
r
;
test
*=
test
;
if
(
distance
<
test
and
distance
>
0.0001
)
{
candidate
c
=
{
b
-
a
,
r
*
r
,
distance
};
m_x
.
push_back
(
c
);
push_heap
(
m_x
.
begin
(),
m_x
.
end
());
}
}
void
sort
()
{
sort_heap
(
m_x
.
begin
(),
m_x
.
end
());
}
std
::
vector
<
candidate
>
m_x
;
};
// we use a fibonacci spheres to calculate the even distribution of the dots
class
MSurfaceDots
{
public
:
static
MSurfaceDots
&
Instance
();
size_t
size
()
const
{
return
mPoints
.
size
();
}
const
Point
&
operator
[](
size_t
inIx
)
const
{
return
mPoints
[
inIx
];
}
double
weight
()
const
{
return
mWeight
;
}
private
:
MSurfaceDots
(
int32_t
inN
);
std
::
vector
<
Point
>
mPoints
;
double
mWeight
;
};
MSurfaceDots
&
MSurfaceDots
::
Instance
()
{
const
int32_t
kN
=
200
;
static
MSurfaceDots
sInstance
(
kN
);
return
sInstance
;
}
MSurfaceDots
::
MSurfaceDots
(
int32_t
N
)
{
auto
P
=
2
*
N
+
1
;
const
double
kGoldenRatio
=
(
1
+
sqrt
(
5.0
))
/
2
;
mWeight
=
(
4
*
kPI
)
/
P
;
for
(
auto
i
=
-
N
;
i
<=
N
;
++
i
)
{
double
lat
=
asin
((
2.0
*
i
)
/
P
);
double
lon
=
fmod
(
i
,
kGoldenRatio
)
*
2
*
kPI
/
kGoldenRatio
;
mPoints
.
emplace_back
(
sin
(
lon
)
*
cos
(
lat
),
cos
(
lon
)
*
cos
(
lat
),
sin
(
lat
));
}
}
double
Res
::
CalculateSurface
(
const
Point
&
inAtom
,
float
inRadius
,
const
std
::
vector
<
Res
*>&
inNeighbours
)
{
Accumulator
accumulate
;
for
(
auto
r
:
inNeighbours
)
{
if
(
r
->
AtomIntersectsBox
(
inAtom
,
inRadius
))
{
accumulate
(
inAtom
,
r
->
mN
,
inRadius
,
kRadiusN
);
accumulate
(
inAtom
,
r
->
mCAlpha
,
inRadius
,
kRadiusCA
);
accumulate
(
inAtom
,
r
->
mC
,
inRadius
,
kRadiusC
);
accumulate
(
inAtom
,
r
->
mO
,
inRadius
,
kRadiusO
);
for
(
auto
&
atom
:
r
->
mSideChain
)
accumulate
(
inAtom
,
atom
,
inRadius
,
kRadiusSideAtom
);
}
}
accumulate
.
sort
();
float
radius
=
inRadius
+
kRadiusWater
;
double
surface
=
0
;
MSurfaceDots
&
surfaceDots
=
MSurfaceDots
::
Instance
();
for
(
size_t
i
=
0
;
i
<
surfaceDots
.
size
();
++
i
)
{
Point
xx
=
surfaceDots
[
i
]
*
radius
;
bool
free
=
true
;
for
(
size_t
k
=
0
;
free
and
k
<
accumulate
.
m_x
.
size
();
++
k
)
free
=
accumulate
.
m_x
[
k
].
radius
<
DistanceSquared
(
xx
,
accumulate
.
m_x
[
k
].
location
);
if
(
free
)
surface
+=
surfaceDots
.
weight
();
}
return
surface
*
radius
*
radius
;
}
double
Res
::
CalculateSurface
(
const
std
::
vector
<
Res
>&
inResidues
)
{
std
::
vector
<
Res
*>
neighbours
;
for
(
auto
&
r
:
inResidues
)
{
Point
center
=
r
.
mCenter
;
double
radius
=
r
.
mRadius
;
if
(
Distance
(
mCenter
,
center
)
<
mRadius
+
radius
)
neighbours
.
push_back
(
const_cast
<
Res
*>
(
&
r
));
}
mAccessibility
=
CalculateSurface
(
mN
,
kRadiusN
,
neighbours
)
+
CalculateSurface
(
mCAlpha
,
kRadiusCA
,
neighbours
)
+
CalculateSurface
(
mC
,
kRadiusC
,
neighbours
)
+
CalculateSurface
(
mO
,
kRadiusO
,
neighbours
);
for
(
auto
&
atom
:
mSideChain
)
mAccessibility
+=
CalculateSurface
(
atom
,
kRadiusSideAtom
,
neighbours
);
return
mAccessibility
;
}
void
CalculateAccessibilities
(
std
::
vector
<
Res
>&
inResidues
,
DSSP_Statistics
&
stats
)
{
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
"Calculate accessibilities"
<<
std
::
endl
;
stats
.
accessibleSurface
=
0
;
for
(
auto
&
residue
:
inResidues
)
stats
.
accessibleSurface
+=
residue
.
CalculateSurface
(
inResidues
);
// uint32_t nr_of_threads = boost::thread::hardware_concurrency();
// if (nr_of_threads <= 1)
// {
// foreach (MResidue* residue, inResidues)
// residue->CalculateSurface(inResidues);
// }
// else
// {
// MResidueQueue queue;
// boost::thread_group t;
// for (uint32 ti = 0; ti < nr_of_threads; ++ti)
// t.create_thread(boost::bind(&MProtein::CalculateAccessibility, this,
// boost::ref(queue), boost::ref(inResidues)));
// foreach (MResidue* residue, inResidues)
// queue.put(residue);
// queue.put(nullptr);
// t.join_all();
// }
}
// --------------------------------------------------------------------
// TODO: use the angle to improve bond energy calculation.
// TODO: use the angle to improve bond energy calculation.
double
CalculateHBondEnergy
(
Res
&
inDonor
,
Res
&
inAcceptor
)
double
CalculateHBondEnergy
(
Res
&
inDonor
,
Res
&
inAcceptor
)
...
@@ -315,7 +573,7 @@ double CalculateHBondEnergy(Res& inDonor, Res& inAcceptor)
...
@@ -315,7 +573,7 @@ double CalculateHBondEnergy(Res& inDonor, Res& inAcceptor)
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
CalculateHBondEnergies
(
vector
<
Res
>&
inResidues
)
void
CalculateHBondEnergies
(
std
::
vector
<
Res
>&
inResidues
)
{
{
// Calculate the HBond energies
// Calculate the HBond energies
for
(
uint32_t
i
=
0
;
i
+
1
<
inResidues
.
size
();
++
i
)
for
(
uint32_t
i
=
0
;
i
+
1
<
inResidues
.
size
();
++
i
)
...
@@ -396,10 +654,10 @@ bool Linked(const Bridge& a, const Bridge& b)
...
@@ -396,10 +654,10 @@ bool Linked(const Bridge& a, const Bridge& b)
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
CalculateBetaSheets
(
vector
<
Res
>&
inResidue
s
)
void
CalculateBetaSheets
(
std
::
vector
<
Res
>&
inResidues
,
DSSP_Statistics
&
stat
s
)
{
{
// Calculate Bridges
// Calculate Bridges
vector
<
Bridge
>
bridges
;
std
::
vector
<
Bridge
>
bridges
;
if
(
inResidues
.
size
()
>
4
)
if
(
inResidues
.
size
()
>
4
)
{
{
for
(
uint32_t
i
=
1
;
i
+
4
<
inResidues
.
size
();
++
i
)
for
(
uint32_t
i
=
1
;
i
+
4
<
inResidues
.
size
();
++
i
)
...
@@ -454,7 +712,7 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -454,7 +712,7 @@ void CalculateBetaSheets(vector<Res>& inResidues)
}
}
// extend ladders
// extend ladders
sort
(
bridges
.
begin
(),
bridges
.
end
());
s
td
::
s
ort
(
bridges
.
begin
(),
bridges
.
end
());
for
(
uint32_t
i
=
0
;
i
<
bridges
.
size
();
++
i
)
for
(
uint32_t
i
=
0
;
i
<
bridges
.
size
();
++
i
)
{
{
...
@@ -470,8 +728,8 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -470,8 +728,8 @@ void CalculateBetaSheets(vector<Res>& inResidues)
uint32_t
jej
=
bridges
[
j
].
j
.
back
();
uint32_t
jej
=
bridges
[
j
].
j
.
back
();
if
(
bridges
[
i
].
type
!=
bridges
[
j
].
type
or
if
(
bridges
[
i
].
type
!=
bridges
[
j
].
type
or
NoChainBreak
(
inResidues
[
min
(
ibi
,
ibj
)],
inResidues
[
max
(
iei
,
iej
)])
==
false
or
NoChainBreak
(
inResidues
[
std
::
min
(
ibi
,
ibj
)],
inResidues
[
std
::
max
(
iei
,
iej
)])
==
false
or
NoChainBreak
(
inResidues
[
min
(
jbi
,
jbj
)],
inResidues
[
max
(
jei
,
jej
)])
==
false
or
NoChainBreak
(
inResidues
[
std
::
min
(
jbi
,
jbj
)],
inResidues
[
std
::
max
(
jei
,
jej
)])
==
false
or
ibj
-
iei
>=
6
or
ibj
-
iei
>=
6
or
(
iei
>=
ibj
and
ibi
<=
iej
))
(
iei
>=
ibj
and
ibi
<=
iej
))
{
{
...
@@ -498,25 +756,25 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -498,25 +756,25 @@ void CalculateBetaSheets(vector<Res>& inResidues)
}
}
// Sheet
// Sheet
set
<
Bridge
*>
ladderset
;
s
td
::
s
et
<
Bridge
*>
ladderset
;
for
(
Bridge
&
bridge
:
bridges
)
for
(
Bridge
&
bridge
:
bridges
)
{
{
ladderset
.
insert
(
&
bridge
);
ladderset
.
insert
(
&
bridge
);
//
uint32_t n = bridge.i.size();
uint32_t
n
=
bridge
.
i
.
size
();
//
if (n > kHistogramSize)
if
(
n
>
kHistogramSize
)
//
n = kHistogramSize;
n
=
kHistogramSize
;
//
//
if (bridge.type == btParallel)
if
(
bridge
.
type
==
btParallel
)
// mP
arallelBridgesPerLadderHistogram[n - 1] += 1;
stats
.
p
arallelBridgesPerLadderHistogram
[
n
-
1
]
+=
1
;
//
else
else
// mA
ntiparallelBridgesPerLadderHistogram[n - 1] += 1;
stats
.
a
ntiparallelBridgesPerLadderHistogram
[
n
-
1
]
+=
1
;
}
}
uint32_t
sheet
=
1
,
ladder
=
0
;
uint32_t
sheet
=
1
,
ladder
=
0
;
while
(
not
ladderset
.
empty
())
while
(
not
ladderset
.
empty
())
{
{
set
<
Bridge
*>
sheetset
;
s
td
::
s
et
<
Bridge
*>
sheetset
;
sheetset
.
insert
(
*
ladderset
.
begin
());
sheetset
.
insert
(
*
ladderset
.
begin
());
ladderset
.
erase
(
ladderset
.
begin
());
ladderset
.
erase
(
ladderset
.
begin
());
...
@@ -550,13 +808,13 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -550,13 +808,13 @@ void CalculateBetaSheets(vector<Res>& inResidues)
++
ladder
;
++
ladder
;
}
}
//
uint32_t nrOfLaddersPerSheet = sheetset.size();
uint32_t
nrOfLaddersPerSheet
=
sheetset
.
size
();
//
if (nrOfLaddersPerSheet > kHistogramSize)
if
(
nrOfLaddersPerSheet
>
kHistogramSize
)
//
nrOfLaddersPerSheet = kHistogramSize;
nrOfLaddersPerSheet
=
kHistogramSize
;
//
if (nrOfLaddersPerSheet == 1 and (*sheetset.begin())->i.size() > 1)
if
(
nrOfLaddersPerSheet
==
1
and
(
*
sheetset
.
begin
())
->
i
.
size
()
>
1
)
// mL
addersPerSheetHistogram[0] += 1;
stats
.
l
addersPerSheetHistogram
[
0
]
+=
1
;
//
else if (nrOfLaddersPerSheet > 1)
else
if
(
nrOfLaddersPerSheet
>
1
)
// mL
addersPerSheetHistogram[nrOfLaddersPerSheet - 1] += 1;
stats
.
l
addersPerSheetHistogram
[
nrOfLaddersPerSheet
-
1
]
+=
1
;
++
sheet
;
++
sheet
;
}
}
...
@@ -592,9 +850,9 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -592,9 +850,9 @@ void CalculateBetaSheets(vector<Res>& inResidues)
if
(
bridge
.
type
==
btParallel
)
if
(
bridge
.
type
==
btParallel
)
{
{
// mN
rOfHBondsInParallelBridges += bridge.i.back() - bridge.i.front() + 2;
stats
.
n
rOfHBondsInParallelBridges
+=
bridge
.
i
.
back
()
-
bridge
.
i
.
front
()
+
2
;
deque
<
uint32_t
>::
iterator
j
=
bridge
.
j
.
begin
();
std
::
deque
<
uint32_t
>::
iterator
j
=
bridge
.
j
.
begin
();
for
(
uint32_t
i
:
bridge
.
i
)
for
(
uint32_t
i
:
bridge
.
i
)
inResidues
[
i
].
SetBetaPartner
(
betai
,
inResidues
[
*
j
++
],
bridge
.
ladder
,
true
);
inResidues
[
i
].
SetBetaPartner
(
betai
,
inResidues
[
*
j
++
],
bridge
.
ladder
,
true
);
...
@@ -604,9 +862,9 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -604,9 +862,9 @@ void CalculateBetaSheets(vector<Res>& inResidues)
}
}
else
else
{
{
// mN
rOfHBondsInAntiparallelBridges += bridge.i.back() - bridge.i.front() + 2;
stats
.
n
rOfHBondsInAntiparallelBridges
+=
bridge
.
i
.
back
()
-
bridge
.
i
.
front
()
+
2
;
deque
<
uint32_t
>::
reverse_iterator
j
=
bridge
.
j
.
rbegin
();
std
::
deque
<
uint32_t
>::
reverse_iterator
j
=
bridge
.
j
.
rbegin
();
for
(
uint32_t
i
:
bridge
.
i
)
for
(
uint32_t
i
:
bridge
.
i
)
inResidues
[
i
].
SetBetaPartner
(
betai
,
inResidues
[
*
j
++
],
bridge
.
ladder
,
false
);
inResidues
[
i
].
SetBetaPartner
(
betai
,
inResidues
[
*
j
++
],
bridge
.
ladder
,
false
);
...
@@ -634,7 +892,7 @@ void CalculateBetaSheets(vector<Res>& inResidues)
...
@@ -634,7 +892,7 @@ void CalculateBetaSheets(vector<Res>& inResidues)
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// TODO: improve alpha helix calculation by better recognizing pi-helices
// TODO: improve alpha helix calculation by better recognizing pi-helices
void
CalculateAlphaHelices
(
vector
<
Res
>&
inResidue
s
,
bool
inPreferPiHelices
=
true
)
void
CalculateAlphaHelices
(
std
::
vector
<
Res
>&
inResidues
,
DSSP_Statistics
&
stat
s
,
bool
inPreferPiHelices
=
true
)
{
{
// Helix and Turn
// Helix and Turn
for
(
uint32_t
stride
=
3
;
stride
<=
5
;
++
stride
)
for
(
uint32_t
stride
=
3
;
stride
<=
5
;
++
stride
)
...
@@ -643,17 +901,17 @@ void CalculateAlphaHelices(vector<Res>& inResidues, bool inPreferPiHelices = tru
...
@@ -643,17 +901,17 @@ void CalculateAlphaHelices(vector<Res>& inResidues, bool inPreferPiHelices = tru
{
{
if
(
NoChainBreak
(
inResidues
[
i
],
inResidues
[
i
+
stride
])
and
TestBond
(
&
inResidues
[
i
+
stride
],
&
inResidues
[
i
]))
if
(
NoChainBreak
(
inResidues
[
i
],
inResidues
[
i
+
stride
])
and
TestBond
(
&
inResidues
[
i
+
stride
],
&
inResidues
[
i
]))
{
{
inResidues
[
i
+
stride
].
SetHelixFlag
(
stride
,
helix
End
);
inResidues
[
i
+
stride
].
SetHelixFlag
(
stride
,
Helix
::
End
);
for
(
uint32_t
j
=
i
+
1
;
j
<
i
+
stride
;
++
j
)
for
(
uint32_t
j
=
i
+
1
;
j
<
i
+
stride
;
++
j
)
{
{
if
(
inResidues
[
j
].
GetHelixFlag
(
stride
)
==
helix
None
)
if
(
inResidues
[
j
].
GetHelixFlag
(
stride
)
==
Helix
::
None
)
inResidues
[
j
].
SetHelixFlag
(
stride
,
helix
Middle
);
inResidues
[
j
].
SetHelixFlag
(
stride
,
Helix
::
Middle
);
}
}
if
(
inResidues
[
i
].
GetHelixFlag
(
stride
)
==
helix
End
)
if
(
inResidues
[
i
].
GetHelixFlag
(
stride
)
==
Helix
::
End
)
inResidues
[
i
].
SetHelixFlag
(
stride
,
helix
StartAndEnd
);
inResidues
[
i
].
SetHelixFlag
(
stride
,
Helix
::
StartAndEnd
);
else
else
inResidues
[
i
].
SetHelixFlag
(
stride
,
helix
Start
);
inResidues
[
i
].
SetHelixFlag
(
stride
,
Helix
::
Start
);
}
}
}
}
}
}
...
@@ -721,50 +979,74 @@ void CalculateAlphaHelices(vector<Res>& inResidues, bool inPreferPiHelices = tru
...
@@ -721,50 +979,74 @@ void CalculateAlphaHelices(vector<Res>& inResidues, bool inPreferPiHelices = tru
inResidues
[
i
].
SetSecondaryStructure
(
ssBend
);
inResidues
[
i
].
SetSecondaryStructure
(
ssBend
);
}
}
}
}
std
::
string
asym
;
size_t
helixLength
=
0
;
for
(
auto
r
:
inResidues
)
{
if
(
r
.
mM
.
asymID
()
!=
asym
)
{
helixLength
=
0
;
asym
=
r
.
mM
.
asymID
();
}
if
(
r
.
GetSecondaryStructure
()
==
ssAlphahelix
)
++
helixLength
;
else
if
(
helixLength
>
0
)
{
if
(
helixLength
>
kHistogramSize
)
helixLength
=
kHistogramSize
;
stats
.
residuesPerAlphaHelixHistogram
[
helixLength
-
1
]
+=
1
;
helixLength
=
0
;
}
}
}
}
// --------------------------------------------------------------------
//
//
--------------------------------------------------------------------
void
CalculateSecondaryStructure
(
Structure
&
s
)
//
void CalculateSecondaryStructure(Structure& s)
{
//
{
auto
&
polymers
=
s
.
polymers
();
//
auto& polymers = s.polymers();
size_t
nRes
=
accumulate
(
polymers
.
begin
(),
polymers
.
end
(),
//
size_t nRes = accumulate(polymers.begin(), polymers.end(),
0.0
,
[](
double
s
,
auto
&
p
)
{
return
s
+
p
.
size
();
});
//
0.0, [](double s, auto& p) { return s + p.size(); });
vector
<
Res
>
residues
;
//
vector<Res> residues;
residues
.
reserve
(
nRes
);
//
residues.reserve(nRes);
for
(
auto
&
p
:
polymers
)
//
for (auto& p: polymers)
{
//
{
for
(
auto
&
m
:
p
)
//
for (auto& m: p)
residues
.
emplace_back
(
m
);
//
residues.emplace_back(m);
}
//
}
for
(
size_t
i
=
0
;
i
+
1
<
residues
.
size
();
++
i
)
// auto fa = std::async(std::launch::async, std::bind(&CalculateAccessibilities, std::ref(residues)));
{
residues
[
i
].
mNext
=
&
residues
[
i
+
1
];
residues
[
i
+
1
].
mPrev
=
&
residues
[
i
];
residues
[
i
+
1
].
assignHydrogen
();
// for (size_t i = 0; i + 1 < residues.size(); ++i)
}
// {
// residues[i].mNext = &residues[i + 1];
// residues[i + 1].mPrev = &residues[i];
CalculateHBondEnergies
(
residues
);
// residues[i + 1].assignHydrogen();
CalculateBetaSheets
(
residues
);
// }
CalculateAlphaHelices
(
residues
);
if
(
cif
::
VERBOSE
)
// CalculateHBondEnergies(residues);
{
// CalculateBetaSheets(residues);
for
(
auto
&
r
:
residues
)
// CalculateAlphaHelices(residues);
{
auto
&
m
=
r
.
mM
;
cout
<<
m
.
asymID
()
<<
':'
<<
m
.
seqID
()
<<
'/'
<<
m
.
compoundID
()
<<
'\t'
// if (cif::VERBOSE)
<<
char
(
r
.
mSecondaryStructure
)
// {
<<
endl
;
// for (auto& r: residues)
}
// {
}
// auto& m = r.mM;
}
// cout << m.asymID() << ':' << m.seqID() << '/' << m.compoundID() << '\t'
// << char(r.mSecondaryStructure)
// << endl;
// }
// }
// }
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
@@ -773,13 +1055,23 @@ struct DSSPImpl
...
@@ -773,13 +1055,23 @@ struct DSSPImpl
DSSPImpl
(
const
Structure
&
s
);
DSSPImpl
(
const
Structure
&
s
);
const
Structure
&
mStructure
;
const
Structure
&
mStructure
;
const
list
<
Polymer
>&
mPolymers
;
const
std
::
list
<
Polymer
>&
mPolymers
;
vector
<
Res
>
mResidues
;
std
::
vector
<
Res
>
mResidues
;
std
::
vector
<
std
::
pair
<
Res
*
,
Res
*>>
mSSBonds
;
auto
findRes
(
const
std
::
string
&
asymID
,
int
seqID
)
{
return
std
::
find_if
(
mResidues
.
begin
(),
mResidues
.
end
(),
[
&
](
auto
&
r
)
{
return
r
.
mM
.
asymID
()
==
asymID
and
r
.
mM
.
seqID
()
==
seqID
;
});
}
DSSP_Statistics
mStats
=
{};
};
};
ostream
&
operator
<<
(
ostream
&
os
,
const
chrono
::
duration
<
double
>&
t
)
// --------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
std
::
chrono
::
duration
<
double
>&
t
)
{
{
uint64_t
s
=
static_cast
<
uint64_t
>
(
trunc
(
t
.
count
()));
uint64_t
s
=
static_cast
<
uint64_t
>
(
std
::
trunc
(
t
.
count
()));
if
(
s
>
24
*
60
*
60
)
if
(
s
>
24
*
60
*
60
)
{
{
uint32_t
days
=
s
/
(
24
*
60
*
60
);
uint32_t
days
=
s
/
(
24
*
60
*
60
);
...
@@ -803,28 +1095,45 @@ ostream& operator<<(ostream& os, const chrono::duration<double>& t)
...
@@ -803,28 +1095,45 @@ ostream& operator<<(ostream& os, const chrono::duration<double>& t)
double
ss
=
s
+
1e-6
*
(
t
.
count
()
-
s
);
double
ss
=
s
+
1e-6
*
(
t
.
count
()
-
s
);
os
<<
fixed
<<
setprecision
(
1
)
<<
ss
<<
's'
;
os
<<
std
::
fixed
<<
std
::
setprecision
(
1
)
<<
ss
<<
's'
;
return
os
;
return
os
;
}
}
DSSPImpl
::
DSSPImpl
(
const
Structure
&
s
)
DSSPImpl
::
DSSPImpl
(
const
Structure
&
s
)
:
mStructure
(
s
)
:
mStructure
(
s
)
,
mPolymers
(
mStructure
.
polymers
())
,
mPolymers
(
mStructure
.
polymers
())
{
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
)
cerr
<<
"Calculating DSSP "
;
std
::
cerr
<<
"Calculating DSSP "
;
size_t
nRes
=
accumulate
(
mPolymers
.
begin
(),
mPolymers
.
end
(),
size_t
nRes
=
accumulate
(
mPolymers
.
begin
(),
mPolymers
.
end
(),
0.0
,
[](
double
s
,
auto
&
p
)
{
return
s
+
p
.
size
();
});
0.0
,
[](
double
s
,
auto
&
p
)
{
return
s
+
p
.
size
();
});
mStats
.
nrOfResidues
=
nRes
;
mStats
.
nrOfChains
=
mPolymers
.
size
();
mResidues
.
reserve
(
nRes
);
mResidues
.
reserve
(
nRes
);
int
resNumber
=
0
;
for
(
auto
&
p
:
mPolymers
)
for
(
auto
&
p
:
mPolymers
)
{
{
for
(
auto
&
m
:
p
)
for
(
auto
&
m
:
p
)
mResidues
.
emplace_back
(
m
);
{
if
(
not
m
.
isComplete
())
continue
;
++
resNumber
;
if
(
not
mResidues
.
empty
()
and
Distance
(
mResidues
.
back
().
mC
,
m
.
atomByID
(
"N"
).
location
())
>
kMaxPeptideBondLength
)
{
++
mStats
.
nrOfChains
;
++
resNumber
;
}
mResidues
.
emplace_back
(
m
,
resNumber
);
}
}
}
for
(
size_t
i
=
0
;
i
+
1
<
mResidues
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
+
1
<
mResidues
.
size
();
++
i
)
...
@@ -835,16 +1144,36 @@ DSSPImpl::DSSPImpl(const Structure& s)
...
@@ -835,16 +1144,36 @@ DSSPImpl::DSSPImpl(const Structure& s)
mResidues
[
i
+
1
].
assignHydrogen
();
mResidues
[
i
+
1
].
assignHydrogen
();
}
}
if
(
cif
::
VERBOSE
)
cerr
<<
"."
;
auto
a
=
std
::
async
(
std
::
launch
::
async
,
&
CalculateAccessibilities
,
std
::
ref
(
mResidues
),
std
::
ref
(
mStats
));
auto
&
db
=
s
.
getFile
().
data
();
for
(
auto
r
:
db
[
"struct_conn"
].
find
(
cif
::
Key
(
"conn_type_id"
)
==
"disulf"
))
{
std
::
string
asym1
,
asym2
;
int
seq1
,
seq2
;
cif
::
tie
(
asym1
,
seq1
,
asym2
,
seq2
)
=
r
.
get
(
"ptnr1_label_asym_id"
,
"ptnr1_label_seq_id"
,
"ptnr2_label_asym_id"
,
"ptnr2_label_seq_id"
);
auto
r1
=
findRes
(
asym1
,
seq1
);
if
(
r1
==
mResidues
.
end
())
throw
std
::
runtime_error
(
"Invalid file, missing residue for SS bond"
);
auto
r2
=
findRes
(
asym2
,
seq2
);
if
(
r2
==
mResidues
.
end
())
throw
std
::
runtime_error
(
"Invalid file, missing residue for SS bond"
);
mSSBonds
.
emplace_back
(
&*
r1
,
&*
r2
);
}
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
"."
;
CalculateHBondEnergies
(
mResidues
);
CalculateHBondEnergies
(
mResidues
);
if
(
cif
::
VERBOSE
)
cerr
<<
"."
;
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
"."
;
CalculateBetaSheets
(
mResidues
);
CalculateBetaSheets
(
mResidues
,
mStats
);
if
(
cif
::
VERBOSE
)
cerr
<<
"."
;
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
"."
;
CalculateAlphaHelices
(
mResidues
);
CalculateAlphaHelices
(
mResidues
,
mStats
);
if
(
cif
::
VERBOSE
)
cerr
<<
endl
;
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>
1
)
if
(
cif
::
VERBOSE
>
1
)
{
{
...
@@ -857,24 +1186,153 @@ DSSPImpl::DSSPImpl(const Structure& s)
...
@@ -857,24 +1186,153 @@ DSSPImpl::DSSPImpl(const Structure& s)
{
{
switch
(
r
.
GetHelixFlag
(
stride
))
switch
(
r
.
GetHelixFlag
(
stride
))
{
{
case
helixStart
:
helix
[
stride
-
3
]
=
'>'
;
break
;
case
Helix
:
:
Start
:
helix
[
stride
-
3
]
=
'>'
;
break
;
case
helixMiddle
:
helix
[
stride
-
3
]
=
'0'
+
stride
;
break
;
case
Helix
:
:
Middle
:
helix
[
stride
-
3
]
=
'0'
+
stride
;
break
;
case
helix
StartAndEnd
:
helix
[
stride
-
3
]
=
'X'
;
break
;
case
Helix
:
:
StartAndEnd
:
helix
[
stride
-
3
]
=
'X'
;
break
;
case
helix
End
:
helix
[
stride
-
3
]
=
'<'
;
break
;
case
Helix
:
:
End
:
helix
[
stride
-
3
]
=
'<'
;
break
;
case
helix
None
:
helix
[
stride
-
3
]
=
' '
;
break
;
case
Helix
:
:
None
:
helix
[
stride
-
3
]
=
' '
;
break
;
}
}
}
}
string
id
=
m
.
asymID
()
+
':'
+
to_string
(
m
.
seqID
())
+
'/'
+
m
.
compoundID
();
auto
id
=
m
.
asymID
()
+
':'
+
std
::
to_string
(
m
.
seqID
())
+
'/'
+
m
.
compoundID
();
cerr
<<
id
<<
string
(
12
-
id
.
length
(),
' '
)
std
::
cerr
<<
id
<<
std
::
string
(
12
-
id
.
length
(),
' '
)
<<
char
(
r
.
mSecondaryStructure
)
<<
' '
<<
char
(
r
.
mSecondaryStructure
)
<<
' '
<<
helix
<<
helix
<<
endl
;
<<
std
::
endl
;
}
}
}
}
// finish statistics
mStats
.
nrOfSSBridges
=
mSSBonds
.
size
();
mStats
.
nrOfIntraChainSSBridges
=
0
;
for
(
auto
&
ss
:
mSSBonds
)
{
const
auto
&
[
a
,
b
]
=
ss
;
if
(
a
->
mM
.
asymID
()
!=
b
->
mM
.
asymID
())
++
mStats
.
nrOfIntraChainSSBridges
;
}
mStats
.
nrOfHBonds
=
0
;
for
(
auto
&
r
:
mResidues
)
{
auto
donor
=
r
.
mHBondDonor
;
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
if
(
donor
[
i
].
residue
!=
nullptr
and
donor
[
i
].
energy
<
kMaxHBondEnergy
)
{
++
mStats
.
nrOfHBonds
;
auto
k
=
donor
[
i
].
residue
->
mNumber
-
r
.
mNumber
;
if
(
k
>=
-
5
and
k
<=
5
)
mStats
.
nrOfHBondsPerDistance
[
k
+
5
]
+=
1
;
}
}
}
a
.
get
();
}
}
// --------------------------------------------------------------------
DSSP
::
ResidueInfo
::
ResidueInfo
(
Res
*
res
)
:
mImpl
(
res
)
{
}
const
Monomer
&
DSSP
::
ResidueInfo
::
residue
()
const
{
return
mImpl
->
mM
;
}
ChainBreak
DSSP
::
ResidueInfo
::
chainBreak
()
const
{
return
ChainBreak
::
None
;
}
int
DSSP
::
ResidueInfo
::
nr
()
const
{
return
mImpl
->
mNumber
;
}
SecondaryStructureType
DSSP
::
ResidueInfo
::
ss
()
const
{
return
mImpl
->
mSecondaryStructure
;
}
int
DSSP
::
ResidueInfo
::
ssBridgeNr
()
const
{
return
0
;
}
Helix
DSSP
::
ResidueInfo
::
helix
(
int
stride
)
const
{
return
mImpl
->
GetHelixFlag
(
stride
);
}
bool
DSSP
::
ResidueInfo
::
bend
()
const
{
return
mImpl
->
IsBend
();
}
double
DSSP
::
ResidueInfo
::
accessibility
()
const
{
return
mImpl
->
mAccessibility
;
}
std
::
tuple
<
DSSP
::
ResidueInfo
,
int
,
bool
>
DSSP
::
ResidueInfo
::
bridgePartner
(
int
i
)
const
{
auto
bp
=
mImpl
->
GetBetaPartner
(
i
);
ResidueInfo
ri
(
bp
.
residue
);
return
std
::
make_tuple
(
std
::
move
(
ri
),
bp
.
ladder
,
bp
.
parallel
);
}
int
DSSP
::
ResidueInfo
::
sheet
()
const
{
return
mImpl
->
GetSheet
();
}
std
::
tuple
<
DSSP
::
ResidueInfo
,
double
>
DSSP
::
ResidueInfo
::
acceptor
(
int
i
)
const
{
auto
&
a
=
mImpl
->
mHBondAcceptor
[
i
];
return
{
ResidueInfo
(
a
.
residue
),
a
.
energy
};
}
std
::
tuple
<
DSSP
::
ResidueInfo
,
double
>
DSSP
::
ResidueInfo
::
donor
(
int
i
)
const
{
auto
&
d
=
mImpl
->
mHBondDonor
[
i
];
return
{
ResidueInfo
(
d
.
residue
),
d
.
energy
};
}
// --------------------------------------------------------------------
DSSP
::
iterator
::
iterator
(
res_iter
cur
)
:
mCurrent
(
&*
cur
)
{
}
DSSP
::
iterator
::
iterator
(
const
iterator
&
i
)
:
mCurrent
(
i
.
mCurrent
)
{
}
DSSP
::
iterator
&
DSSP
::
iterator
::
operator
=
(
const
iterator
&
i
)
{
mCurrent
=
i
.
mCurrent
;
return
*
this
;
}
DSSP
::
iterator
&
DSSP
::
iterator
::
operator
++
()
{
++
mCurrent
.
mImpl
;
return
*
this
;
}
// --------------------------------------------------------------------
DSSP
::
DSSP
(
const
Structure
&
s
)
DSSP
::
DSSP
(
const
Structure
&
s
)
:
mImpl
(
new
DSSPImpl
(
s
))
:
mImpl
(
new
DSSPImpl
(
s
))
{
{
...
@@ -885,7 +1343,17 @@ DSSP::~DSSP()
...
@@ -885,7 +1343,17 @@ DSSP::~DSSP()
delete
mImpl
;
delete
mImpl
;
}
}
SecondaryStructureType
DSSP
::
operator
()(
const
string
&
inAsymID
,
int
inSeqID
)
const
DSSP
::
iterator
DSSP
::
begin
()
const
{
return
iterator
(
mImpl
->
mResidues
.
begin
());
}
DSSP
::
iterator
DSSP
::
end
()
const
{
return
iterator
(
mImpl
->
mResidues
.
end
());
}
SecondaryStructureType
DSSP
::
operator
()(
const
std
::
string
&
inAsymID
,
int
inSeqID
)
const
{
{
SecondaryStructureType
result
=
ssLoop
;
SecondaryStructureType
result
=
ssLoop
;
auto
i
=
find_if
(
mImpl
->
mResidues
.
begin
(),
mImpl
->
mResidues
.
end
(),
auto
i
=
find_if
(
mImpl
->
mResidues
.
begin
(),
mImpl
->
mResidues
.
end
(),
...
@@ -893,7 +1361,7 @@ SecondaryStructureType DSSP::operator()(const string& inAsymID, int inSeqID) con
...
@@ -893,7 +1361,7 @@ SecondaryStructureType DSSP::operator()(const string& inAsymID, int inSeqID) con
if
(
i
!=
mImpl
->
mResidues
.
end
())
if
(
i
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
mSecondaryStructure
;
result
=
i
->
mSecondaryStructure
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
)
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
endl
;
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
return
result
;
}
}
...
@@ -902,12 +1370,29 @@ SecondaryStructureType DSSP::operator()(const Monomer& m) const
...
@@ -902,12 +1370,29 @@ SecondaryStructureType DSSP::operator()(const Monomer& m) const
return
operator
()(
m
.
asymID
(),
m
.
seqID
());
return
operator
()(
m
.
asymID
(),
m
.
seqID
());
}
}
double
DSSP
::
accessibility
(
const
std
::
string
&
inAsymID
,
int
inSeqID
)
const
{
SecondaryStructureType
result
=
ssLoop
;
auto
i
=
find_if
(
mImpl
->
mResidues
.
begin
(),
mImpl
->
mResidues
.
end
(),
[
&
](
auto
&
r
)
{
return
r
.
mM
.
asymID
()
==
inAsymID
and
r
.
mM
.
seqID
()
==
inSeqID
;
});
if
(
i
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
mSecondaryStructure
;
else
if
(
cif
::
VERBOSE
)
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
}
double
DSSP
::
accessibility
(
const
Monomer
&
m
)
const
{
return
accessibility
(
m
.
asymID
(),
m
.
seqID
());
}
bool
DSSP
::
isAlphaHelixEndBeforeStart
(
const
Monomer
&
m
)
const
bool
DSSP
::
isAlphaHelixEndBeforeStart
(
const
Monomer
&
m
)
const
{
{
return
isAlphaHelixEndBeforeStart
(
m
.
asymID
(),
m
.
seqID
());
return
isAlphaHelixEndBeforeStart
(
m
.
asymID
(),
m
.
seqID
());
}
}
bool
DSSP
::
isAlphaHelixEndBeforeStart
(
const
string
&
inAsymID
,
int
inSeqID
)
const
bool
DSSP
::
isAlphaHelixEndBeforeStart
(
const
st
d
::
st
ring
&
inAsymID
,
int
inSeqID
)
const
{
{
auto
i
=
find_if
(
mImpl
->
mResidues
.
begin
(),
mImpl
->
mResidues
.
end
(),
auto
i
=
find_if
(
mImpl
->
mResidues
.
begin
(),
mImpl
->
mResidues
.
end
(),
[
&
](
auto
&
r
)
{
return
r
.
mM
.
asymID
()
==
inAsymID
and
r
.
mM
.
seqID
()
==
inSeqID
;
});
[
&
](
auto
&
r
)
{
return
r
.
mM
.
asymID
()
==
inAsymID
and
r
.
mM
.
seqID
()
==
inSeqID
;
});
...
@@ -915,11 +1400,16 @@ bool DSSP::isAlphaHelixEndBeforeStart(const string& inAsymID, int inSeqID) const
...
@@ -915,11 +1400,16 @@ bool DSSP::isAlphaHelixEndBeforeStart(const string& inAsymID, int inSeqID) const
bool
result
=
false
;
bool
result
=
false
;
if
(
i
!=
mImpl
->
mResidues
.
end
()
and
i
+
1
!=
mImpl
->
mResidues
.
end
())
if
(
i
!=
mImpl
->
mResidues
.
end
()
and
i
+
1
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
GetHelixFlag
(
4
)
==
helixEnd
and
(
i
+
1
)
->
GetHelixFlag
(
4
)
==
helix
Start
;
result
=
i
->
GetHelixFlag
(
4
)
==
Helix
::
End
and
(
i
+
1
)
->
GetHelixFlag
(
4
)
==
Helix
::
Start
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
)
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
endl
;
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
return
result
;
}
}
DSSP_Statistics
DSSP
::
GetStatistics
()
const
{
return
mImpl
->
mStats
;
}
}
}
src/Structure.cpp
View file @
34c7fd3f
...
@@ -920,7 +920,6 @@ float Monomer::phi() const
...
@@ -920,7 +920,6 @@ float Monomer::phi() const
cerr
<<
ex
.
what
()
<<
endl
;
cerr
<<
ex
.
what
()
<<
endl
;
}
}
return
result
;
return
result
;
}
}
...
@@ -952,7 +951,7 @@ float Monomer::alpha() const
...
@@ -952,7 +951,7 @@ float Monomer::alpha() const
try
try
{
{
if
(
mIndex
>
1
and
mIndex
+
2
<
mPolymer
->
size
())
if
(
mIndex
>
=
1
and
mIndex
+
2
<
mPolymer
->
size
())
{
{
auto
&
prev
=
mPolymer
->
operator
[](
mIndex
-
1
);
auto
&
prev
=
mPolymer
->
operator
[](
mIndex
-
1
);
auto
&
next
=
mPolymer
->
operator
[](
mIndex
+
1
);
auto
&
next
=
mPolymer
->
operator
[](
mIndex
+
1
);
...
@@ -976,7 +975,7 @@ float Monomer::kappa() const
...
@@ -976,7 +975,7 @@ float Monomer::kappa() const
try
try
{
{
if
(
mIndex
>
2
and
mIndex
+
2
<
mPolymer
->
size
())
if
(
mIndex
>
=
2
and
mIndex
+
2
<
mPolymer
->
size
())
{
{
auto
&
prevPrev
=
mPolymer
->
operator
[](
mIndex
-
2
);
auto
&
prevPrev
=
mPolymer
->
operator
[](
mIndex
-
2
);
auto
&
nextNext
=
mPolymer
->
operator
[](
mIndex
+
2
);
auto
&
nextNext
=
mPolymer
->
operator
[](
mIndex
+
2
);
...
@@ -999,6 +998,29 @@ float Monomer::kappa() const
...
@@ -999,6 +998,29 @@ float Monomer::kappa() const
return
result
;
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
=
{
const
map
<
string
,
vector
<
string
>>
kChiAtomsMap
=
{
{
"ASP"
,
{
"CG"
,
"OD1"
}
},
{
"ASP"
,
{
"CG"
,
"OD1"
}
},
{
"ASN"
,
{
"CG"
,
"OD1"
}
},
{
"ASN"
,
{
"CG"
,
"OD1"
}
},
...
@@ -1084,6 +1106,19 @@ bool Monomer::isCis() const
...
@@ -1084,6 +1106,19 @@ bool Monomer::isCis() const
return
result
;
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
Monomer
::
chiralVolume
()
const
{
{
float
result
=
0
;
float
result
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment