Source code for pbxplore.assign
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Protrein Block assignation --- :mod:`pbxplore.assign`
=====================================================
.. autofunction:: assign
"""
from __future__ import print_function, absolute_import
# Third-party module
import numpy
# Local module
from . import PB
def _angle_modulo_360(angle):
"""
Keep angle in the range -180 / +180 [degrees]
"""
if angle > 180.0:
return angle - 360.0
elif angle < -180.0:
return angle + 360.0
else:
return angle
[docs]def assign(dihedrals, pb_ref=PB.REFERENCES):
"""
Assign Protein Blocks.
Dihedral angles are provided as a dictionnary with one item per residue.
The key is the residue number, and the value is a dictionnary with phi and
psi as keys, and the dihedral angles as values.
The protein block definitions are provided as a dictionnary. Each key is a
block name, the values are lists of dihedral angles.
Parameters
----------
dihedrals : dict
Phi and psi dihedral angles for each residue.
pb_ref : dict
The definition of the protein blocks.
"""
pb_seq = ""
# iterate over all residues
for res in sorted(dihedrals):
angles = []
# try to get all eight angles required for PB assignement
try:
angles.append(dihedrals[res-2]["psi"])
angles.append(dihedrals[res-1]["phi"])
angles.append(dihedrals[res-1]["psi"])
angles.append(dihedrals[res ]["phi"])
angles.append(dihedrals[res ]["psi"])
angles.append(dihedrals[res+1]["phi"])
angles.append(dihedrals[res+1]["psi"])
angles.append(dihedrals[res+2]["phi"])
# check for bad angles
# (error while calculating torsion: missing atoms)
if None in angles:
pb_seq += "Z"
continue
# cannot get required angles (Nter, Cter or missign residues)
# -> cannot assign PB
# jump to next residue
except KeyError:
pb_seq += "Z"
continue
# convert to array
angles = numpy.array(angles)
# compare to reference PB angles
rmsda_lst = {}
for block in pb_ref:
diff = pb_ref[block] - angles
diff2 = _angle_modulo_360_vect(diff)
rmsda = numpy.sum(diff2**2)
rmsda_lst[rmsda] = block
pb_seq += rmsda_lst[min(rmsda_lst)]
return pb_seq
# vertorize function
_angle_modulo_360_vect = numpy.vectorize(_angle_modulo_360)
_angle_modulo_360_vect.__doc__ = _angle_modulo_360.__doc__