Réimplémentation du programme DSSP en Python

structure.py 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import math
  2. class Structure:
  3. def __init__(self, res):
  4. self.res = res
  5. class Turn(Structure):
  6. def __init__(self, turn_type, res):
  7. self.turn_type = turn_type
  8. Structure.res = res
  9. class Bridge(Structure):
  10. def __init__(self, bridge_type, res_num):
  11. self.bridge_type = bridge_type
  12. self.res_num = res_num
  13. Structure.res = res_num
  14. class Helix(Structure):
  15. def __init__(self, residues, res_num):
  16. self.residues = residues
  17. self.res_num = res_num
  18. Structure.res = res_num
  19. def get_turns(residues):
  20. turns = {}
  21. for i,res in enumerate(residues):
  22. for j in range(3,6):
  23. if(i+j<len(residues)):
  24. if(res.h_bond(residues[i+j])<-0.5):
  25. print("TURN", i+1, i+j+1)
  26. turns[i] = Turn(j,i)
  27. return(turns)
  28. def get_bridges(residues):
  29. bridges = []
  30. bridge = {}
  31. strongest_bridge = {}
  32. for i in range(1,len(residues)-4):
  33. E_min = 0
  34. for j in range(i+2,len(residues)-1):
  35. # select triplet with the minimal energy
  36. if(residues[i-1].h_bond(residues[j])<-0.5
  37. and residues[j].h_bond(residues[i+1])<-0.5):
  38. bridge = {'res1':residues[i-1].h_bond(residues[j]),
  39. 'res2':residues[j].h_bond(residues[i+1]),
  40. 'ipos':i,
  41. 'jpos':j,
  42. 'btype':"para"}
  43. # if(residues[i-1].h_bond(residues[j])+
  44. # residues[j].h_bond(residues[i+1]))<E_min:
  45. # E_min = residues[i-1].h_bond(residues[j])
  46. # +residues[j].h_bond(residues[i+1])
  47. # bridge_type = "para"
  48. if(residues[j-1].h_bond(residues[i])<-0.5
  49. and residues[i].h_bond(residues[j+1])<-0.5):
  50. bridge = {'res1':residues[j-1].h_bond(residues[i]),
  51. 'res2':residues[i].h_bond(residues[j+1]),
  52. 'ipos':i,
  53. 'jpos':j,
  54. 'btype':"para"}
  55. # if(residues[j-1].h_bond(residues[i])+
  56. # residues[i].h_bond(residues[j+1]))<E_min:
  57. # E_min = residues[j-1].h_bond(residues[i])
  58. # +residues[i].h_bond(residues[j+1])
  59. # bridge_type = "para"
  60. if(residues[i].h_bond(residues[j])<-0.5
  61. and residues[j].h_bond(residues[i])<-0.5):
  62. bridge = {'res1':residues[i].h_bond(residues[j]),
  63. 'res2':residues[j].h_bond(residues[i]),
  64. 'ipos':i,
  65. 'jpos':j,
  66. 'btype':"anti"}
  67. # if(residues[i].h_bond(residues[j])+
  68. # residues[j].h_bond(residues[i]))<E_min:
  69. # E_min = residues[i].h_bond(residues[j])
  70. # +residues[j].h_bond(residues[i])
  71. # bridge_type = "anti"
  72. if(residues[i-1].h_bond(residues[j+1])<-0.5
  73. and residues[j-1].h_bond(residues[i+1])<-0.5):
  74. bridge = {'res1':residues[i-1].h_bond(residues[j+1]),
  75. 'res2':residues[j-1].h_bond(residues[i+1]),
  76. 'ipos':i,
  77. 'jpos':j,
  78. 'btype':"anti"}
  79. # if(residues[i-1].h_bond(residues[j+1])+
  80. # residues[j-1].h_bond(residues[i+1]))<E_min:
  81. # E_min = residues[i-1].h_bond(residues[j+1])
  82. # +residues[j-1].h_bond(residues[i+1])
  83. # bridge_type = "anti"
  84. if(bridge):
  85. if(bridge['res1']+bridge['res2']<E_min):
  86. E_min = bridge['res1']+bridge['res2']
  87. strongest_bridge = bridge
  88. bridge = {}
  89. # finally add the strongest bridge at i and j pos
  90. if(strongest_bridge):
  91. bridges.append(Bridge(strongest_bridge['btype'],
  92. strongest_bridge['ipos']))
  93. bridges.append(Bridge(strongest_bridge['btype'],
  94. strongest_bridge['jpos']))
  95. if(len(bridges)>0):
  96. return(bridges)
  97. else:
  98. return(False)
  99. def get_helix(residues, turns):
  100. i = 1
  101. helix = []
  102. while i <= len(residues):
  103. if(i in turns.keys() and i-1 in turns.keys()):
  104. k = 0
  105. temp_res = []
  106. while(i+k in turns):
  107. k+=1
  108. temp_res.append(residues[i])
  109. if(k>2):
  110. print(k,"- HELIX at", residues[i].resid)
  111. helix.append(Helix(temp_res,residues[i].resid))
  112. i = i+k
  113. else:
  114. i+=1
  115. return(helix)
  116. def get_bends(residues):
  117. bends = {}
  118. for i in range(2,len(residues)-2):
  119. # print("angle",i,calculer_angles(residues[i-2].atoms["CA"].coords,
  120. # residues[i].atoms["CA"].coords,
  121. # residues[i+2].atoms["CA"].coords))
  122. angle = vector_angles(vectors_substr(position_vector(residues[i].atoms["CA"].coords),
  123. position_vector(residues[i-2].atoms["CA"].coords)),
  124. vectors_substr(position_vector(residues[i+2].atoms["CA"].coords),
  125. position_vector(residues[i].atoms["CA"].coords)))
  126. if(angle>70):
  127. print("angle", residues[i].resid, angle)
  128. return(bends)
  129. def vecteur_deux_points (a, b):
  130. xAB = b[0]-a[0]
  131. yAB = b[1]-a[1]
  132. zAB = b[2]-a[2]
  133. coord_AB = [xAB,yAB,zAB]
  134. return coord_AB
  135. def produit_scalaire (a, b, c):
  136. coord_BA = vecteur_deux_points(b, a)
  137. coord_BC = vecteur_deux_points(b, c)
  138. dot_product = coord_BA[0]*coord_BC[0] + coord_BA[1]*coord_BC[1] + coord_BA[2]*coord_BC[2]
  139. return dot_product
  140. def norme_vecteur (a,b):
  141. vecteur = vecteur_deux_points(a,b)
  142. norme = math.sqrt(vecteur[0]**2 + vecteur[1]**2 + vecteur[2]**2)
  143. return norme
  144. def vector_norm(v):
  145. norm = math.sqrt(v[0]**2 + v[1]**2 + v[2]**2)
  146. return norm
  147. def dot_product(v1,v2):
  148. dot_product = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]
  149. return(dot_product)
  150. def position_vector(c):
  151. vector = vecteur_deux_points([0,0,0],c)
  152. return vector
  153. def vectors_substr(v1, v2):
  154. return ([v1[0]-v2[0],
  155. v1[1]-v2[1],
  156. v1[2]-v2[2]])
  157. def vector_angles(v1,v2):
  158. dot_prod = dot_product(v1,v2)
  159. norm_v1 = vector_norm(v1)
  160. norm_v2 = vector_norm(v2)
  161. term = dot_prod/(abs(norm_v1)*abs(norm_v2))
  162. rad_angle = math.acos(term)
  163. deg_angle = rad_angle*(180/math.pi)
  164. return deg_angle
  165. def calculer_angles (a,b,c):
  166. dot_product_ABC = produit_scalaire(a,b,c)
  167. norme_BA = norme_vecteur (b,a)
  168. norme_BC = norme_vecteur (b,c)
  169. terme = dot_product_ABC/(abs(norme_BA)*abs(norme_BC))
  170. angle_radian = math.acos(terme)
  171. angle_degre = angle_radian*(180/math.pi)
  172. return angle_degre