diff --git a/sidechain/doc/rotamer_lib.rst b/sidechain/doc/rotamer_lib.rst index 912da399940daa6a8ebccb2a4c5c95a0de1d0709..007a26b5c7327df13b5f76e4664240f2f5a5b34b 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 20bbe7ee31b36798e84440f46939eef176d00b86..1a2dc5991677b3bdee3101598edaae87d0a7bd5c 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 2c3d100ff14653388adbf6db2855ca6467b6246c..2dd070d1110a195b91844357f6328c3f970c0025 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 a25b90f27449655f18ca80827ebed79805476590..b3247c9d09c50b5e032ae0d188b9e5be83fe4ccc 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,