From eddd11f151aff768fb6e5a5148ec409d5703e8a0 Mon Sep 17 00:00:00 2001
From: Gabriel Studer <gabriel.studer@unibas.ch>
Date: Thu, 27 Sep 2018 09:21:56 +0200
Subject: [PATCH] only interpolate rotameric dihedral angles
For rotameric dihedral angles we have clear conformations: GAUCHE_MINUS
GAUCHE_MINUS and TRANS. I can therefore interpolate between several values
of one of the conformations. For non-rotameric dihedral angles we just
sample the dihedral space. If you not carefully do the assignment, the
interpolation will be crap.
---
sidechain/doc/rotamer_lib.rst | 13 ++-
sidechain/src/bb_dep_rotamer_lib.cc | 156 ++++++++++++++++++++--------
sidechain/src/rotamer_lib_entry.cc | 23 +++-
sidechain/src/rotamer_lib_entry.hh | 2 +
4 files changed, 146 insertions(+), 48 deletions(-)
diff --git a/sidechain/doc/rotamer_lib.rst b/sidechain/doc/rotamer_lib.rst
index 912da399..007a26b5 100644
--- a/sidechain/doc/rotamer_lib.rst
+++ b/sidechain/doc/rotamer_lib.rst
@@ -168,10 +168,12 @@ The Backbone Dependent Rotamer Library
added to the library or can be interpolated.
In the first option, *phi* and *psi* simply get transformed to the
according bin using following formalism: bin = round((angle + pi)/bin_size).
- In case of interpolation, the chi angles and the according standard
- deviations of the rotamers get bilinearly interpolated using the
- corresponding rotamers with same configuration from the neighbouring bins.
- This behaviour can be controlled with the SetInterpolate function.
+ In case of interpolation, the chi angles of rotameric dihedral angles and the
+ according standard deviations of the rotamers get bilinearly interpolated
+ using the corresponding rotamers with same configuration from the
+ neighbouring bins. No interplation is applied to non-rotameric dihedral
+ angles (chi2 in ASP, ASN, HIS, PHE, TRP, TYR; chi3 in GLU, GLN).
+ This behaviour can be controlled with :meth:`SetInterpolate`.
The query function follows following strategies in case of
special *id* requests.
@@ -220,7 +222,8 @@ The Backbone Dependent Rotamer Library
.. method:: SetInterpolate(interpolate)
- :param interpolate: Controls behaviour when QueryLib function gets called
+ :param interpolate: Controls behaviour when :meth:`QueryLib`
+ gets called
:type interpolate: :class:`bool`
diff --git a/sidechain/src/bb_dep_rotamer_lib.cc b/sidechain/src/bb_dep_rotamer_lib.cc
index 20bbe7ee..1a2dc599 100644
--- a/sidechain/src/bb_dep_rotamer_lib.cc
+++ b/sidechain/src/bb_dep_rotamer_lib.cc
@@ -8,7 +8,8 @@ namespace{
return a.probability > b.probability;
}
- inline Real BilinearInterpolation(Real f00, Real f10, Real f01, Real f11, Real x, Real y){
+ inline Real BilinearInterpolation(Real f00, Real f10, Real f01, Real f11,
+ Real x, Real y) {
return f00 + (f10-f00)*x + (f01-f00)*y + (f00-f10-f01+f11)*x*y;
}
@@ -18,7 +19,8 @@ namespace{
return a;
}
- inline Real CircularBilinearInterpolation(Real f00, Real f10, Real f01, Real f11, Real x, Real y){
+ inline Real CircularBilinearInterpolation(Real f00, Real f10, Real f01, Real f11,
+ Real x, Real y) {
Real interpol_one;
Real interpol_two;
@@ -33,6 +35,20 @@ namespace{
diff = BoundAngle(interpol_two-interpol_one);
return BoundAngle(interpol_one + diff*y);
}
+
+ inline Real NearestNeighbourInterpolation(Real f00, Real f10, Real f01, Real f11,
+ Real x, Real y) {
+ if(x > Real(0.5) && y > Real(0.5)) {
+ return f11;
+ }
+ if(x > Real(0.5)) {
+ return f10;
+ }
+ if(y > Real(0.5)) {
+ return f01;
+ }
+ return f00;
+ }
}
@@ -431,46 +447,102 @@ std::pair<RotamerLibEntry*,uint> BBDepRotamerLib::QueryLib(RotamerID id, Real ph
static_data_[pos11].probability,
x,y);
summed_probability += probability;
- chi1 = CircularBilinearInterpolation(static_data_[pos00].chi1,
- static_data_[pos10].chi1,
- static_data_[pos01].chi1,
- static_data_[pos11].chi1,
- x,y);
- chi2 = CircularBilinearInterpolation(static_data_[pos00].chi2,
- static_data_[pos10].chi2,
- static_data_[pos01].chi2,
- static_data_[pos11].chi2,
- x,y);
- chi3 = CircularBilinearInterpolation(static_data_[pos00].chi3,
- static_data_[pos10].chi3,
- static_data_[pos01].chi3,
- static_data_[pos11].chi3,
- x,y);
- chi4 = CircularBilinearInterpolation(static_data_[pos00].chi4,
- static_data_[pos10].chi4,
- static_data_[pos01].chi4,
- static_data_[pos11].chi4,
- x,y);
- sig1 = BilinearInterpolation(static_data_[pos00].sig1,
- static_data_[pos10].sig1,
- static_data_[pos01].sig1,
- static_data_[pos11].sig1,
- x,y);
- sig2 = BilinearInterpolation(static_data_[pos00].sig2,
- static_data_[pos10].sig2,
- static_data_[pos01].sig2,
- static_data_[pos11].sig2,
- x,y);
- sig3 = BilinearInterpolation(static_data_[pos00].sig3,
- static_data_[pos10].sig3,
- static_data_[pos01].sig3,
- static_data_[pos11].sig3,
- x,y);
- sig4 = BilinearInterpolation(static_data_[pos00].sig4,
- static_data_[pos10].sig4,
- static_data_[pos01].sig4,
- static_data_[pos11].sig4,
- x,y);
+
+ if(IsRotameric(id, 0)) {
+ chi1 = CircularBilinearInterpolation(static_data_[pos00].chi1,
+ static_data_[pos10].chi1,
+ static_data_[pos01].chi1,
+ static_data_[pos11].chi1,
+ x,y);
+ sig1 = BilinearInterpolation(static_data_[pos00].sig1,
+ static_data_[pos10].sig1,
+ static_data_[pos01].sig1,
+ static_data_[pos11].sig1,
+ x,y);
+ } else {
+ chi1 = NearestNeighbourInterpolation(static_data_[pos00].chi1,
+ static_data_[pos10].chi1,
+ static_data_[pos01].chi1,
+ static_data_[pos11].chi1,
+ x,y);
+ sig1 = NearestNeighbourInterpolation(static_data_[pos00].sig1,
+ static_data_[pos10].sig1,
+ static_data_[pos01].sig1,
+ static_data_[pos11].sig1,
+ x,y);
+ }
+
+ if(IsRotameric(id, 1)) {
+ chi2 = CircularBilinearInterpolation(static_data_[pos00].chi2,
+ static_data_[pos10].chi2,
+ static_data_[pos01].chi2,
+ static_data_[pos11].chi2,
+ x,y);
+ sig2 = BilinearInterpolation(static_data_[pos00].sig2,
+ static_data_[pos10].sig2,
+ static_data_[pos01].sig2,
+ static_data_[pos11].sig2,
+ x,y);
+ } else {
+ chi2 = NearestNeighbourInterpolation(static_data_[pos00].chi2,
+ static_data_[pos10].chi2,
+ static_data_[pos01].chi2,
+ static_data_[pos11].chi2,
+ x,y);
+ sig2 = NearestNeighbourInterpolation(static_data_[pos00].sig2,
+ static_data_[pos10].sig2,
+ static_data_[pos01].sig2,
+ static_data_[pos11].sig2,
+ x,y);
+ }
+
+ if(IsRotameric(id, 2)) {
+ chi3 = CircularBilinearInterpolation(static_data_[pos00].chi3,
+ static_data_[pos10].chi3,
+ static_data_[pos01].chi3,
+ static_data_[pos11].chi3,
+ x,y);
+ sig3 = BilinearInterpolation(static_data_[pos00].sig3,
+ static_data_[pos10].sig3,
+ static_data_[pos01].sig3,
+ static_data_[pos11].sig3,
+ x,y);
+ } else {
+ chi3 = NearestNeighbourInterpolation(static_data_[pos00].chi3,
+ static_data_[pos10].chi3,
+ static_data_[pos01].chi3,
+ static_data_[pos11].chi3,
+ x,y);
+ sig3 = NearestNeighbourInterpolation(static_data_[pos00].sig3,
+ static_data_[pos10].sig3,
+ static_data_[pos01].sig3,
+ static_data_[pos11].sig3,
+ x,y);
+ }
+
+ if(IsRotameric(id, 3)) {
+ chi4 = CircularBilinearInterpolation(static_data_[pos00].chi4,
+ static_data_[pos10].chi4,
+ static_data_[pos01].chi4,
+ static_data_[pos11].chi4,
+ x,y);
+ sig4 = BilinearInterpolation(static_data_[pos00].sig4,
+ static_data_[pos10].sig4,
+ static_data_[pos01].sig4,
+ static_data_[pos11].sig4,
+ x,y);
+ } else {
+ chi4 = NearestNeighbourInterpolation(static_data_[pos00].chi4,
+ static_data_[pos10].chi4,
+ static_data_[pos01].chi4,
+ static_data_[pos11].chi4,
+ x,y);
+ sig4 = NearestNeighbourInterpolation(static_data_[pos00].sig4,
+ static_data_[pos10].sig4,
+ static_data_[pos01].sig4,
+ static_data_[pos11].sig4,
+ x,y);
+ }
++pos00;
++pos01;
diff --git a/sidechain/src/rotamer_lib_entry.cc b/sidechain/src/rotamer_lib_entry.cc
index 2c3d100f..2dd070d1 100644
--- a/sidechain/src/rotamer_lib_entry.cc
+++ b/sidechain/src/rotamer_lib_entry.cc
@@ -698,6 +698,28 @@ bool RotamerLibEntry::SimilarDihedral(RotamerLibEntryPtr other, uint dihedral_id
return this->SimilarDihedral(other,dihedral_idx,thresh,id);
}
+bool IsRotameric(RotamerID id, int dihedral_idx) {
+
+ if(dihedral_idx == 0) {
+ return id!=GLY && id!=ALA && id!=XXX; // all others are rotameric
+ }
+
+ if(dihedral_idx == 1) {
+ return id == ARG || id == GLN || id == GLU || id == ILE || id == LEU ||
+ id == LYS || id == MET;
+ }
+
+ if(dihedral_idx == 2) {
+ return id == ARG || id == LYS || id == MET;
+ }
+
+ if(dihedral_idx == 3) {
+ return id == ARG || id == LYS;
+ }
+
+ return false;
+}
+
DihedralConfiguration GetRotamericConfiguration(Real angle) {
if(angle != angle) {
@@ -758,7 +780,6 @@ DihedralConfiguration GetDihedralConfiguration(const RotamerLibEntry& entry,
return GetRotamericConfiguration(entry.chi3);
}
if(id == GLN || id == GLU) {
-
return NON_ROTAMERIC;
}
return INVALID;
diff --git a/sidechain/src/rotamer_lib_entry.hh b/sidechain/src/rotamer_lib_entry.hh
index a25b90f2..b3247c9d 100644
--- a/sidechain/src/rotamer_lib_entry.hh
+++ b/sidechain/src/rotamer_lib_entry.hh
@@ -101,6 +101,8 @@ enum DihedralConfiguration {
TRANS, GAUCHE_MINUS, GAUCHE_PLUS, NON_ROTAMERIC, INVALID
};
+bool IsRotameric(RotamerID id, int dihedral_idx);
+
DihedralConfiguration GetRotamericConfiguration(Real angle);
DihedralConfiguration GetDihedralConfiguration(const RotamerLibEntry& entry,
--
GitLab