Advertisement
Guest User

Untitled

a guest
Jan 20th, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.02 KB | None | 0 0
  1. import sys
  2. import numpy
  3.  
  4. import openbabel
  5.  
  6.  
  7. openbabel.obErrorLog.SetOutputLevel(-1)
  8.  
  9. def OBMolFromFilename(filename):
  10. obmol = openbabel.OBMol()
  11. obconv = openbabel.OBConversion()
  12. obconv.SetInFormat("pdb")
  13. obconv.ReadFile(obmol, filename)
  14. return obmol
  15.  
  16. def OBMolToFilename(filename, mol):
  17. obconv = openbabel.OBConversion()
  18. obconv.SetOutFormat("pdb")
  19. obconv.WriteFile(mol, filename)
  20.  
  21. def get_center_of_mass(mol):
  22. x = 0.0
  23. y = 0.0
  24. z = 0.0
  25. m = 0.0
  26.  
  27. for residue in openbabel.OBResidueIter(mol):
  28. for atom in openbabel.OBResidueAtomIter(residue):
  29. ms = atom.GetAtomicMass()
  30. x += atom.GetX()*ms
  31. y += atom.GetY()*ms
  32. z += atom.GetZ()*ms
  33. m += ms
  34.  
  35. x /= m
  36. y /= m
  37. z /= m
  38. return numpy.array([x,y,z])
  39.  
  40. def get_distances_to_cm(cm, mol):
  41. """This is per molecule (residue), not per atom
  42. and it is the minimum distance
  43. """
  44. Rs = []
  45. Is = []
  46. for residue in openbabel.OBResidueIter(mol):
  47. r = get_residue_distance_to_cm(cm, residue)
  48. Rs.append(r)
  49. Is.append(residue.GetNum())
  50.  
  51. Rs = numpy.array(Rs)
  52. Is = numpy.array(Is)
  53.  
  54. ind = numpy.argsort(Rs)
  55. Is = Is[ind]
  56. Rs = Rs[ind]
  57.  
  58. return (Rs, Is)
  59.  
  60. def get_residue_distance_to_cm(cm, residue):
  61. r = 30.0e8
  62. for atom in openbabel.OBResidueAtomIter(residue):
  63. d = get_atom_distance_to_cm(cm, atom)
  64. if d < r: r = d
  65. return r
  66.  
  67. def get_min_distances_from(idx, mol):
  68. Rs = [0.0]
  69. Is = [idx]
  70. res = None
  71. for ri in openbabel.OBResidueIter(mol):
  72. rii = ri.GetNum()
  73. if idx == rii: res = ri
  74.  
  75. #print idx, res
  76.  
  77. #for residue in openbabel.OBResidueIter(mol):
  78. # print residue.GetIdx(), idx
  79. # if residue.GetIdx()+1 == idx: res = residue
  80.  
  81. #print Rs, Is, res
  82. if res is None: exit("Error: something terrible went wrong. Aborting.")
  83. for residue in openbabel.OBResidueIter(mol):
  84. if residue.GetNum() == idx: continue
  85. r = get_residue_distance_to(res, residue)
  86. Rs.append(r)
  87. Is.append(residue.GetNum())
  88.  
  89. Rs = numpy.array(Rs)
  90. Is = numpy.array(Is)
  91. ind = numpy.argsort(Rs)
  92. Is = Is[ind]
  93. Rs = Rs[ind]
  94.  
  95. return (Rs, Is)
  96.  
  97. def get_residue_distance_to(r, residue):
  98. d = 30e8
  99. for atom_i in openbabel.OBResidueAtomIter(r):
  100. ic = numpy.array(get_atom_coords(atom_i))
  101. for atom_j in openbabel.OBResidueAtomIter(residue):
  102. r = get_atom_distance_to_cm(ic, atom_j)
  103. d = min(r,d)
  104. return d
  105.  
  106. def get_atom_distance_to_cm(cm, atom):
  107. x,y,z = get_atom_coords(atom)
  108. R = numpy.array([x,y,z])
  109. v = R - cm
  110. return numpy.sqrt(numpy.dot(v,v))
  111.  
  112. def get_atom_coords(atom):
  113. return atom.GetX(), atom.GetY(), atom.GetZ()
  114.  
  115. def get_residue_cm(idx, mol):
  116. for residue in openbabel.OBResidueIter(mol):
  117. if residue.GetNum() == idx:
  118. break
  119. xm,ym,zm,mm = 0.0, 0.0, 0.0, 0.0
  120. for atom in openbabel.OBResidueAtomIter(residue):
  121. m = atom.GetAtomicMass()
  122. x,y,z = get_atom_coords(atom)
  123. xm += x*m
  124. ym += y*m
  125. zm += z*m
  126. mm += m
  127.  
  128. xm /= mm
  129. ym /= mm
  130. zm /= mm
  131. return numpy.array([xm,ym,zm])
  132.  
  133. args = sys.argv[1:]
  134.  
  135. if len(args) == 0:
  136. print "usage: cm.py [options] filename"
  137. print
  138. print " : -d FLOAT print Res# for all atoms within d"
  139. print
  140. print " : -c cuts out all residues with a distance larger than d. Requires d."
  141. print
  142. print " : -m uses minimum distance instead of center of mass"
  143. print
  144. print " : -o specify output filename"
  145. sys.exit()
  146.  
  147. dist = -1.0
  148. cut = False
  149. min_distance = False
  150. verbose = False
  151. ofile = None
  152. while len(args) > 1:
  153. if args[0] == "-d":
  154. dist = float(args[1])
  155. args = args[2:]
  156.  
  157. if args[0] == "-c":
  158. cut = True
  159. args = args[1:]
  160.  
  161. if args[0] == "-m":
  162. min_distance = True
  163. args = args[1:]
  164.  
  165. if args[0] == "-v":
  166. verbose = True
  167. args = args[1:]
  168.  
  169. if args[0] == "-o":
  170. ofile = args[1]
  171. args = args[2:]
  172.  
  173. if dist < 0.0 and (cut or min_distance):
  174. print "Error: You forgot to specify distance using -d"
  175. sys.exit()
  176.  
  177. if verbose:
  178. print "Options:"
  179. print " dist: %6.2f" % dist
  180. if cut: print "will make cutout"
  181. if min_distance: print "using mininum interfragment distances"
  182.  
  183. filename = args[0]
  184. mol = OBMolFromFilename(filename)
  185.  
  186. cm = get_center_of_mass(mol)
  187. (R,I) = get_distances_to_cm(cm, mol)
  188.  
  189. if dist > 0.0:
  190. V = get_residue_cm(I[0], mol)
  191. if not min_distance:
  192. (Ri,Ii) = get_distances_to_cm(V, mol)
  193. else:
  194. (Ri,Ii) = get_min_distances_from(I[0], mol)
  195.  
  196. # print the indices of the
  197. if dist > 0.0 and not cut:
  198. idx = numpy.where(Ri<=dist)
  199. for val in Ii[idx]:
  200. print "%i" % (val),
  201.  
  202. # if the user requested to cut the cluster out
  203. # of some larger bulk
  204. if dist > 0.0 and cut:
  205. idx = numpy.where(Ri>dist)
  206. atoms_to_delete = []
  207. for residue in openbabel.OBResidueIter(mol):
  208. if residue.GetNum() in Ii[idx]:
  209. for atom in openbabel.OBResidueAtomIter(residue):
  210. atoms_to_delete.append(atom)
  211. if len(atoms_to_delete) == 0:
  212. print "Error: No atoms to remove"
  213. sys.exit()
  214.  
  215. for atom in atoms_to_delete:
  216. mol.DeleteAtom(atom)
  217.  
  218. # attempt to fix that damn naming scheme
  219. ff = filename[:-4].split(".")
  220. idx = int(ff[1])
  221. fname = "{0:s}_{1:04d}.pdb".format(ff[0], idx)
  222. if ofile is not None: fname = ofile
  223. OBMolToFilename(fname, mol)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement