## TEMPY is a Python library designed to help the user manipulate and analyse atomic structures and density maps from 3D EM.
## Copyright (c) 2013 Daven Vasishtan,Irene Farabella, Arun Prasad Pandurangan, Harpal Sahota, Frank Alber and Maya Topf
# -- Global imports -- #
# Modify by Irene Farabella.
# This module runs as part of the TEMpy library
from numpy import ndarray,array,append
from math import *
from random import randrange
from os import system
import os
from time import time
import urllib
import numpy
# -- Local imports -- #
from Vector import *
from EMMap import *
# Useful global constants
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ12345676890abcdefghijklmnopqrstuvwxyz'
atomicMasses = {'H':1, 'C': 12, 'N':14, 'O':16, 'S':32}
vdw_radii = {'H':1.09, 'C': 1.7, 'N':1.55, 'O':1.52, 'S':1.8} # Taken from http://www.ccdc.cam.ac.uk/products/csd/radii/table.php4
sequenceConsts = {'GLY':'G', 'ALA':'A', 'VAL':'V', 'LEU':'L', 'ILE':'I', 'MET':'M', 'PHE':'F', 'TRP':'W',\
'PRO':'P', 'SER':'S', 'THR':'T', 'CYS':'C', 'TYR':'Y', 'ASN':'N', 'GLN':'Q', 'ASP':'D',\
'GLU':'E', 'LYS':'K', 'ARG':'R', 'HIS':'H'}
root2Pi = (2*pi)**0.5
aa_mass = {'A':71.0788,'R':156.1875,'N':114.1038,'D':115.0886,'C':103.1388,'E':129.1155,'Q':128.1307,'G':57.0519,'H':137.1411,'I':113.1594,'L':113.1594,'K':128.1741,'M':131.1926,'F':147.1766,'P':97.1167,'S':87.0782,'T':101.1051,'W':186.2132,'Y':163.1760,'V':99.1326}
[docs]class BioPyAtom:
"""
A class representing an atom, as read from a PDB file using Biopython.
"""
def __init__(self, atom,surface=False):
"""Atom from BioPython"""
if atom == []:
return
#http://deposit.rcsb.org/adit/docs/pdb_atom_format.html
#print "bioatom",atom#'bioatom <Atom O>'
self.record_name = "ATOM" # was pdbString[:6].strip() as "ATOM"
# res.id[0] == "W" or res.id[0][0]=="H": #skip water and hetero residues
self.serial = atom.get_serial_number()
self.atom_name = atom.get_name()
self.alt_loc = atom.get_altloc() #Return alternative location specifier.
self.fullid=atom.get_full_id()
#('3ukr_test', 0, 'G', (' ', 113, ' '), ('CA', ' '))
self.res = atom.get_parent().get_resname()
self.chain = atom.get_full_id()[2]
self.res_no = int(self.fullid[3][1])
self.icode = atom.is_disordered() # 1 if the residue has disordered atoms
# self.icode = pdbString[26].strip()#code for insertion residues
# # Starting co-ordinates of atom.
self.init_x = atom.get_coord()[0]
self.init_y = atom.get_coord()[1]
self.init_z = atom.get_coord()[2]
# # Current co-ordinates of atom.
self.x = float(atom.get_coord()[0])
self.y = float(atom.get_coord()[1])
self.z = float(atom.get_coord()[2])
#
self.occ = atom.get_occupancy()
self.temp_fac = atom.get_bfactor()
#From here need to think alternative way
# Surface accessibility as given by Modeller (converted to float only if surface=True)
self.access= ""
if surface:
self.access = float(self.access)
try:
self.elem = atom.get_element()
except:
self.elem=""
self.charge=""
#Mass of atom as given by atomicMasses global constant. Defaults to 1.
self.mass = atomicMasses.get(self.atom_name[0])
if not self.mass:
self.mass = 1.0
# # True if atom is the terminal of a chain. Automatically false until modified.
self.isTerm = False
def __repr__(self):
return '('+ self.get_res() +' '+ str(self.res_no) + ' '+self.chain + ': ' + str(self.x) + ', ' + str(self.y) + ', ' + str(self.z) + ')'
[docs] def copy(self):
"""Return a copy of the Atom instance."""
atom = BioPyAtom([])
atom.record_name = self.record_name
atom.serial = self.serial
atom.atom_name = self.atom_name
atom.alt_loc = self.alt_loc
atom.res = self.res
atom.chain = self.chain
atom.res_no = self.res_no
atom.icode = self.icode
atom.init_x = self.init_x
atom.init_y = self.init_y
atom.init_z = self.init_z
atom.x = self.x
atom.y = self.y
atom.z = self.z
atom.occ =self.occ
atom.temp_fac = self.temp_fac
atom.elem = self.elem
atom.charge = self.charge
atom.mass = self.mass
atom.isTerm = self.isTerm
return atom
[docs] def get_mass(self):
"""Return atom mass."""
return self.mass
[docs] def distance_from_init_position(self):
"""Return distance from initial position."""
return ((self.x - self.init_x)**2 + (self.y - self.init_y)**2 + (self.z - self.init_z)**2)**0.5
# Was 'distance_from_atom'
[docs] def dist(self, atom):
"""Return distance from another atom."""
return ((self.x - atom.x)**2 + (self.y - atom.y)**2 + (self.z - atom.z)**2)**0.5
[docs] def reset_position(self):
"""Put atom back in its initial position."""
self.x = self.init_x
self.y = self.init_y
self.z = self.init_z
[docs] def change_init_position(self):
"""Change initial position co-ordinates of atom to current position."""
self.init_x = self.x
self.init_y = self.y
self.init_z = self.z
[docs] def translate(self, x, y, z):
"""Move atom.
x, y, z = distance in Angstroms in respective Cartesian directions to move atom."""
self.x += x
self.y += y
self.z += z
[docs] def map_grid_position(self, densMap):
"""Return the co-ordinates and density value of the grid point in a density map closest to this atom.
Return 0 if atom is outside of map."""
x_origin = densMap.x_origin
y_origin = densMap.y_origin
z_origin = densMap.z_origin
apix = densMap.apix
x_size = densMap.x_size
y_size = densMap.y_size
z_size = densMap.z_size
x_pos = int((self.getX()-x_origin)/apix)
y_pos = int((self.getY()-y_origin)/apix)
z_pos = int((self.getZ()-z_origin)/apix)
if((x_size > x_pos >= 0) and (y_size > y_pos >= 0) and (z_size > z_pos >= 0)):
return (x_pos, y_pos, z_pos, self.mass)
else:
return 0
[docs] def get_pos_vector(self):
"""Return a Vector instance of the position of the atom."""
return Vector(self.x, self.y, self.z)
[docs] def get_pos_mass(self):
return [self.x, self.y, self.z, self.mass]
[docs] def get_x(self):
"""Return x co-ordinate of atom."""
return float(self.x)
[docs] def get_y(self):
"""Return y co-ordinate of atom."""
return float(self.y)
[docs] def get_z(self):
"""Return z co-ordinate of atom."""
return float(self.z)
[docs] def set_x(self, mod):
"""Change x co-ordinate of atom."""
self.x = mod
[docs] def set_y(self, mod):
"""Change y co-ordinate of atom."""
self.y = mod
[docs] def set_z(self, mod):
"""Change z co-ordinate of atom."""
self.z = mod
[docs] def get_name(self):
"""Get string of atom name (ie. 'CA' or 'O')"""
return self.atom_name
[docs] def get_res(self):
"""Get string of residue type (ie 'ARG')"""
return self.res
[docs] def get_res_no(self):
"""Get string of residue number"""
return self.res_no
[docs] def get_id_no(self):
"""Get string of atom serial number"""
return self.serial
[docs] def writeTerm(self):
line = ''
line += 'TER'.ljust(6)
line += str(self.serial).rjust(5)+' '
line += ''.center(4)
line += self.alt_loc.ljust(1)
line += self.res.ljust(4)
line += self.chain.ljust(1)
line += str(self.res_no).rjust(4)
return line
[docs] def write_to_PDB(self):
"""Write atom attributes as a line in a PDB file."""
line = ''
line += self.record_name.ljust(6)
line += str(self.serial).rjust(5)+' '
line += self.atom_name.center(4)
line += self.alt_loc.ljust(1)
line += self.res.ljust(3)+' '
line += self.chain.ljust(1)
line += str(self.res_no).rjust(4)
line += str(self.icode).ljust(1)+' '
x = '%.3f' % self.x
y = '%.3f' % self.y
z = '%.3f' % self.z
line += x.rjust(8)
line += y.rjust(8)
line += z.rjust(8)
occ = '%.2f'% float(self.occ)
temp_fac = '%.2f'% float(self.temp_fac)
line += occ.rjust(6)
line += temp_fac.rjust(6)+' '
line += self.elem.strip().rjust(2)
line += self.charge.strip().ljust(2)
return line + '\n'
[docs]class BioPy_Residue:
""""
A class representing an Residues, use instead the residues option if Biopy
"""
#here to be consistent with the original parser of TEMPY
#the implemented use of BIOpython is more efficient and retrieve more informations
""""""
def __init__(self, res_no, atom_list):
self.res_no = res_no
self.atom_list = atom_list[:]
def _copy(self):
"""Return copy of Residues instance."""
newAtomList = []
for atom in self.atom_list:
newAtomList.append(atom.copy())
return Residue(self.res_no, newAtomList)
def _translate(self, x, y, z):
"""Translate residues in three Cartesian directions.
x, y, z = distance in Angstroms to move structure in respective direction"""
for atom in self.atom_list:
atom.translate(x,y,z)
[docs]class BioPy_Structure:
"""
A class representing an Structure, as read from a PDB file using Biopython.
"""
def __init__(self, atomList, filename='Unknown', header='', footer = '', surface=False):
"""
Initialise using a string of the relevant pdb file name or a numpy array of Atom objects.
Arguments:
*pdbFileOrList*
String of pdb file name or array of Atom objects
*surface*
Boolean representing whether this Structure object contains surface accessibility data.
"""
self.header = header
self.footer = footer
self.filename = filename
if type(atomList) == ndarray:
self.atomList = atomList[:]
if type(atomList) == list:
self.atomList = array(atomList)
#Centre of mass calculations
self.CoM = self.calculate_centre_of_mass()
self.initCoM = self.CoM.copy()
def __getitem__(self, index):
return self.atomList[index]
def __len__(self):
return len(self.atomList)
def __repr__(self):
s = 'Filename: ' + self.filename + '\n'
s += 'No Of Atoms: ' + str(len(self)) + '\n'
s += 'First Atom: ' + str(self.atomList[0]) + '\n'
s += 'Last Atom: ' + str(self.atomList[-1]) + '\n'
return s
[docs] def write_to_PDB(self, filename):
"""
Write Structure instance to PDB file.
Arguments:
*filename*
output filename.
"""
if filename[-4:] == '.pdb':
g = open(filename, 'w')
else:
g = open(filename+'.pdb', 'w')
header='''EXPDTA MODEL GENERATE WITH TEMPY
REMARK MODEL GENERATE WITH TEMPY
'''
g.write(header)
for x in self.atomList:
g.write(x.write_to_PDB())
if x.isTerm:
line = x.writeTerm()+'\n'
g.write(line)
g.write(self.footer)
g.close()
[docs] def copy(self):
"""
Return copy of Structure instance.
"""
newAtomList = []
for atom in self.atomList:
newAtomList.append(atom.copy())
return BioPy_Structure(newAtomList)
#===========================================================================
# def add_het_atoms(self, filename):
# """Add het atoms from filename to this Structure instance.
# #NB: DO NOT USE IT ATM
# """
#
# self.atomList[-1].isTerm = True
# HETATMList = []
# f = open(filename, 'r')
# for line in f.readlines():
# info = line.split()
# if(info[0][:6] == 'HETATM'):
# HETATMList.append(Atom(line, False))
# f.close()
# print len(HETATMList)
# self.atomList = append(self.atomList, HETATMList)
# self.renumber_atoms()
#===========================================================================
[docs] def calculate_centre_of_mass(self):
"""
Return centre of mass of structure as a Vector instance.
"""
x_momentTotal = 0.0
y_momentTotal = 0.0
z_momentTotal = 0.0
massTotal = 0.0
for atom in self.atomList:
x = atom.get_x()
y = atom.get_y()
z = atom.get_z()
m = atom.get_mass()
x_momentTotal += x*m
y_momentTotal += y*m
z_momentTotal += z*m
massTotal += m
x_CoM = x_momentTotal/massTotal
y_CoM = y_momentTotal/massTotal
z_CoM = z_momentTotal/massTotal
return Vector(x_CoM, y_CoM, z_CoM)
[docs] def translate(self, x, y, z):
"""
Translate structure in three Cartesian directions.
Arguments:
*x, y, z*
distance in Angstroms to move structure in respective direction.
"""
for atom in self.atomList:
atom.translate(x,y,z)
self.CoM = self.CoM.translate(x,y,z)
[docs] def rotate_by_axis_angle(self, x, y, z, turn, x_trans=0, y_trans=0, z_trans=0, rad=False, com=False):
"""
Rotate this Structure instance around its centre.
Arguments:
*turn*
angle (in radians if rad == True, else in degrees) to rotate map.
*x,y,z*
axis to rotate about, ie. x,y,z = 0,0,1 rotates the structure round the xy-plane.
*x_trans, y_trans, z_trans*
extra translational movement if required.
*com*
centre of mass around which to rotate the structure. If False, rotates around centre of mass of structure.
"""
mat = axis_angle_to_matrix(x, y, z, turn, rad)
if not com:
com = self.CoM.copy()
newcom = com.matrix_transform(mat)
offset = com-newcom
self.matrix_transform(mat)
self.translate(x_trans+offset.x, y_trans+offset.y, z_trans+offset.z)
[docs] def rotate_by_euler(self, x_turn, y_turn, z_turn, x_trans=0, y_trans=0, z_trans=0, rad=False, com=False):
"""
Rotate this Structure instance around its centre.
Arguments:
*x_turn,y_turn,z_turn*
Euler angles (in radians if rad == True, else in degrees) used to rotate structure, in order XYZ.
*x_trans, y_trans, z_trans*
extra translational movement if required.
*com*
centre of mass around which to rotate the structure. If False, rotates around centre of mass of structure.
"""
mat = euler_to_matrix(x_turn, y_turn, z_turn, rad)
if not com:
com = self.CoM.copy()
newcom = com.matrix_transform(mat)
offset = com-newcom
self.matrix_transform(mat)
self.translate(x_trans+offset.x, y_trans+offset.y, z_trans+offset.z)
[docs] def randomise_position(self, max_trans, max_rot, v_grain=30, rad=False, verbose=False):
"""
Randomise the position of this Structure instance.
Arguments:
*max_trans*
Maximum translation permitted
*max_rot*
Maximum rotation permitted (in degree if rad=False)
*v_grain*
Graning Level for the generation of random vetors (default=30)
"""
t_v = random_vector(-v_grain, v_grain).unit()
r_v = random_vector(-v_grain, v_grain).unit()
if max_trans <= 0:
t_dist = 0
else:
t_dist = randrange(max_trans)
if max_rot <= 0:
r_ang = 0
else:
r_ang = randrange(max_rot)
t_v = t_v.times(t_dist)
self.rotate_by_axis_angle(r_v.x, r_v.y, r_v.z, r_ang, t_v.x, t_v.y, t_v.z, rad=rad)
#self.translate(t_v.x, t_v.y, t_v.z)
if verbose:
print (r_v.x, r_v.y, r_v.z, r_ang, t_v.x, t_v.y, t_v.z)
return (r_v.x, r_v.y, r_v.z, r_ang, t_v.x, t_v.y, t_v.z)
[docs] def reorder_residues(self):
"""
Order residues in atom list by residue number.
(NOTE: Does not check for chain information - split by chain first).
"""
self.atomList = list(self.atomList)
self.atomList.sort(cmp=lambda x,y: int(x.res_no)-int(y.res_no))
self.atomList = array(self.atomList)
[docs] def renumber_residues(self, startRes=1, missingRes=[]):
"""
Renumber the structure starting from startRes.
Missing number list to add.
"""
resNo = startRes
currentRes = self.atomList[0].res_no
for x in self.atomList:
if x.res_no == currentRes:
x.res_no = resNo
else:
currentRes = x.res_no
resNo +=1
while resNo in missingRes:
resNo +=1
x.res_no = resNo
[docs] def renumber_atoms(self):
for x in range(len(self.atomList)):
if (x+1) < 99999:
self.atomList[x].serial = x+1
else:
self.atomList[x].serial = '*****'
[docs] def rename_chains(self, chain_list=False):
if not chain_list:
chain_list = alphabet
else:
noc = self.no_of_chains()
if len(chain_list) != self.no_of_chains():
print 'No. of chains in structure = '+str(noc)
print 'Length of chain list = '+str(len(chain_list))
print 'Chains not changed.'
return
ch = self.atomList[0].chain
renum = 0
for atom in self.atomList:
if atom.chain == ch:
atom.chain = chain_list[renum]
else:
renum += 1
ch = atom.chain[:]
atom.chain = chain_list[renum]
[docs] def split_into_chains(self):
structList = []
currentChain = self.atomList[0].chain
currentStruct = []
for x in self.atomList:
if x.chain == currentChain:
currentStruct.append(x.copy())
else:
currentChain = x.chain
structList.append(BioPy_Structure(currentStruct))
currentStruct = [x.copy()]
structList.append(BioPy_Structure(currentStruct))
return structList
[docs] def no_of_chains(self):
a = self.split_into_chains()
return len(a)
[docs] def build_C_symmetric_model_around_line(self, l, c, noOfUnits):
output = [self.copy()]
output[0].rename_chains()
angle = 360./noOfUnits
for x in range(1,noOfUnits):
self.rotate_by_axis_angle(l.x, l.y, l.z, angle*x, com=c)
next_unit = self.copy()
next_unit.change_init_position()
for atom in next_unit.atomList:
atom.chain = alphabet[x]
output.append(next_unit)
self.reset_position()
output = output[0].combine_structures(output[1:])
output.CoM = c.copy()
output.renumber_atoms()
return output
[docs] def build_C_symmetric_model(self, symm_axis, noOfUnits, x_point, y_point, z_point):
c = Vector(x_point, y_point, z_point)
if symm_axis == 'x':
l = Vector(1,0,0)
elif symm_axis == 'y':
l = Vector(0,1,0)
else:
l = Vector(0,0,1)
return self.build_C_symmetric_model_around_line(l, c, noOfUnits)
[docs] def build_C_symmetric_model_using_map(self, noOfUnits, symm_axis, densMap):
centre = densMap.centre()
return self.build_C_symmetric_model(symm_axis, noOfUnits, centre[0], centre[1], centre[2])
[docs] def reset_position(self):
"""
Move structure back into initial position.
"""
for x in self.atomList:
x.reset_position()
self.CoM = self.initCoM.copy()
[docs] def change_init_position(self):
"""
Change initial position of structure to current position.
"""
for atom in self.atomList:
atom.change_init_position()
self.init_CoM = self.CoM.copy()
[docs] def RMSD_from_init_position(self, CA=False):
"""
Return RMSD of structure from initial position after transltation.
Arguments:
*CA*
True if only CA atoms are considered
False when all atoms are considered.
"""
dists = []
for x in self.atomList:
if CA:
if x.atom_name == 'CA':
dists.append(x.distance_from_init_position())
else:
dists.append(x.distance_from_init_position())
dists = array(dists)
return dists.mean()
[docs] def RMSD_from_same_structure(self, otherStruct, CA=False):
"""
Return the RMSD between two structure instance.
Arguments:
*otherStruct*
Structure instance to compare, containing the same atoms as the target instance.
*CA*
True if only CA atoms are considered
False when all atoms are considered.
"""
dists = []
for a in range(len(self.atomList)):
if CA:
if self.atomList[a].atom_name == 'CA':
if otherStruct.atomList[a].atom_name == 'CA':
dists.append(self.atomList[a].dist(otherStruct.atomList[a]))
else:
print self.atomList[a].atom_name, otherStruct.atomList[a].atom_name,self.atomList[a].res_no, otherStruct.atomList[a].res_no
else:
dists.append(self.atomList[a].dist(otherStruct.atomList[a]))
dists = array(dists)
return dists.mean()
[docs] def get_vector_list(self):
"""
Return an array containing Vector instances of positions of all atoms.
"""
v = []
for atom in self.atomList:
v.append(atom.get_pos_vector())
return array(v)
[docs] def get_pos_mass_list(self):
"""
Return an array containing Vector instances of positions of all atoms and mass.
"""
v = []
for atom in self.atomList:
v.append(atom.get_pos_mass())
return array(v)
[docs] def get_extreme_values(self):
"""
Return a 6-ple containing the minimum and maximum x, y and z co-ordinates of the structure.
Given in order (min_x, max_x, min_y, max_y, min_z, max_z).
"""
min_x = self.atomList[0].get_x()
max_x = self.atomList[0].get_x()
min_y = self.atomList[0].get_y()
max_y = self.atomList[0].get_y()
min_z = self.atomList[0].get_z()
max_z = self.atomList[0].get_z()
for atom in self.atomList[1:]:
if atom.get_x() < min_x:
min_x = atom.get_x()
if atom.get_x() > max_x:
max_x = atom.get_x()
if atom.get_y() < min_y:
min_y = atom.get_y()
if atom.get_y() > max_y:
max_y = atom.get_y()
if atom.get_z() < min_z:
min_z = atom.get_z()
if atom.get_z() > max_z:
max_z = atom.get_z()
return (min_x, max_x, min_y, max_y, min_z, max_z)
[docs] def get_atom_list(self):
"""
Return an array containing Atom instances of positions of all atoms as:
[(RES 1 A: x,y,z), ... ,(RES2 1 A: x1,y1,z1)].
"""
alist = []
for x in self.atomList:
alist.append(x.copy())
return alist
[docs] def find_same_atom(self, atom_index, otherStruct):
"""
Return an Atom instances if exists in compared structure, based on *atom index*.
"""
atom = self.atomList[atom_index]
for x in otherStruct.atomList:
if x.res_no == atom.res_no and x.atom_name == atom.atom_name and atom.res == atom.res and x.chain == atom.chain:
#print x
return x
return "No match of atom index %s in structure %s"%(atom_index,otherStruct)
[docs] def get_chain_list(self):
"""
Return list of chain ID in Structure.
"""
chain_list=[]
for x in self.atomList:
if x.chain not in chain_list:
chain_list.append(x.chain)
return chain_list
[docs] def get_chain(self, chainID):
"""
Return new Structure instance with only the requested chain.
"""
newAtomList = []
for x in self.atomList:
if x.chain == chainID:
newAtomList.append(x.copy())
return BioPy_Structure(newAtomList)
[docs] def get_selection(self, startRes, finishRes):
"""
Return new Structure instance of the selected residues range without considering residues chain.
"""
newAtomList = []
for x in self.atomList:
if(x.get_res_no() >= int(startRes) and x.get_res_no() <= int(finishRes)):
newAtomList.append(x.copy())
return BioPy_Structure(newAtomList)
[docs] def break_into_segments(self, rigid_list):
"""
Return a list of Structure instance of the selected segment from the structure:
Arguments:
*rigid list*
list of rigid body defined as:
[[riA,rfA],..,[riB,rfB]]
where :
riA= starting residues of segment A
rfA=final residues of segment A.
"""
structList = []
for r in rigid_list:
fstStruct = self.get_selection(r[0], r[1])
nxtStructs = []
for x in range(2, len(r), 2):
nxtStructs.append(self.get_selection(r[x], r[x+1]))
if len(nxtStructs) != 0:
structList.append(fstStruct.combine_structures(nxtStructs))
else:
structList.append(fstStruct)
return structList
#add IF 19/2/2013 of residues number
[docs] def get_RB(self, rigid_list):
"""
Return a Structure instance of the selected rigid body of non consecutively segment from a Structure instance:
Arguments:
*rigid list*
list of rigid body defined as:
[riA,rfA,..,riB,rfB]
where :
riA= starting residues of segment A
rfA=final residues of segment A
so that Rigid body Structure is formed by non consecutively segment.
"""
structList = []
nxtStructs=[]
fstStruct = self.get_selection(rigid_list[0],rigid_list[1])
if len(rigid_list)>2:
for r in range(2, len(rigid_list), 2):
nxtStructs.append(self.get_selection(rigid_list[r], rigid_list[r+1]))
if len(nxtStructs) != 0:
structList.append(fstStruct.combine_structures(nxtStructs))
else:
structList.append(fstStruct)
#return the last structureList that contains only the atoms of the defined RB
return structList[-1]
[docs] def combine_structures(self, structList):
"""
Add a list of Structure instance to the structure.
"""
atomList = self.atomList.copy()
for s in structList:
atomList = append(atomList, s.atomList)
return BioPy_Structure(atomList)
[docs] def combine_SSE_structures(self, structList):
"""
Combine a list of Structure instance in a unique rigid body (as Structure instance).
"""
atomList =[]
for s in structList:
atomList = append(atomList, s.atomList)
return BioPy_Structure(atomList)
[docs] def get_selection_more_than(self, startRes):
"""
Return a Structure instance comprising all residues greater then startRes.
"""
newAtomList = []
for x in self.atomList:
if(x.get_res_no() >= int(startRes)):
newAtomList.append(x.copy())
return BioPy_Structure(newAtomList)
[docs] def get_selection_less_than(self, endRes):
"""
Return a Structure instance comprising all residues smaller then startRes.
"""
newAtomList = []
for x in self.atomList:
if(x.get_res_no() <= endRes):
newAtomList.append(x.copy())
return BioPy_Structure(newAtomList)
[docs] def get_residue(self, resNo):
"""
Return specific residue in Structure instance.
"""
return BioPy_Structure([x.copy() for x in self.atomList if x.get_res_no() == int(resNo)])
[docs] def get_atom(self, index):
"""
Return specific atom in Structure instance.
"""
return self.atomList[int(index)]
[docs] def get_backbone(self):
"""
Return Structure instance of the backbone atoms in structure.
"""
backboneList = []
#print self.atomList
for atom in self.atomList:#error again due to aold atom list
if(atom.get_name() == 'CA' or atom.get_name() == 'N' or atom.get_name() == 'C'):
backboneList.append(atom.copy())
return BioPy_Structure(backboneList[:])
[docs] def vectorise(self):
vectorList = []
vList = []
for x in self.atomList:
vectorList.append(x.get_pos_vector())
for y in range(len(vectorList)-1):
vList.append(vectorList[y]-(vectorList[y+1]))
return vList
[docs] def get_torsion_angles(self):
"""Return list of torsion angle in Structure instance"""
vectorList = self.vectorise()
angles = []
for v in range(len(vectorList)-2):
angles.append(altTorsion(vectorList[v], vectorList[v+1].reverse(), vectorList[v+2]))
return angles
[docs] def get_prot_mass_from_res(self,Termini=False):
# ADD by IF 22-4-2013
#from Harpal code calculation of mass from seq.
"""
Calculates Mass (kDa) of the Structure instance, from average mass
"""
#NOTE: problem with Residues class from Structure class need a more elegand way of doing it
#PROBLEM ONLY 1 CHAIN READ
#atm seq_list_resno to create the sequence from pdb
aa = {'ARG':'R','HIS':'H','LYS':'K','ASP':'D','GLU':'E','SER':'S','THR':'T','ASN':'N','GLN':'Q','CYS':'C','SEC':'U','GLY':'G','PRO':'P','ALA':'A','ILE':'I','LEU':'L','MET':'M','PHE':'F','TRP':'W','TYR':'Y','VAL':'V'}
#based on http://web.expasy.org/findmod/findmod_masses.html
mass_tot=0
str=self.copy()
seq_string=''
for chain in str.split_into_chains():
seq_list_resno=[]
seq_str_aa=[]
for x in chain.atomList:
if x.res in aa.keys():
if x.res_no not in seq_list_resno:
seq_list_resno.append(x.res_no)
if x.res not in aa.keys():
seq_string+="x"
res_singleletter=aa[x.res]
seq_string+="%s"%res_singleletter
mass_tot += aa_mass[res_singleletter]
else:
pass
if Termini:
mass_tot += 17.992
return float(mass_tot/1000)
[docs] def get_prot_mass_from_atoms(self):
"""
Calculates Mass (kDa) of the Structure instance, from average mass. Atoms based
use get_prot_mass_from_res is more accurate.
"""
# ADD by IF 22-4-2013
#problem with this are the PDBs not cleaned with ANISU or similar problems
mass_tot=0
for x in self.atomList:
mass_tot+=x.get_mass()
return float(mass_tot/1000)