PageRenderTime 261ms CodeModel.GetById 42ms RepoModel.GetById 12ms app.codeStats 0ms

/Tailor/Description.py

https://github.com/gilleain/tailor
Python | 355 lines | 313 code | 34 blank | 8 comment | 28 complexity | 785aad287bdddfba98d89e57553f5acd MD5 | raw file
  1. from copy import copy
  2. from Condition import PropertyCondition, TorsionBoundCondition, HBondCondition
  3. from Measure import HBondMeasure, TorsionMeasure
  4. def constructSelection(chainID=None, chainType=None, residuePosition=None, atomName=None):
  5. """ Make a selection-Description for use in Measures.
  6. """
  7. if chainID != None or chainType != None:
  8. #selection = ChainDescription({"chainID" : chainID, "chainType" : chainType})
  9. selection = ChainDescription({"chainType" : chainType})
  10. selection.addResidue(ResidueDescription({"position" : residuePosition}))
  11. selection.children[0].addAtom(atomName)
  12. else:
  13. selection = ResidueDescription({"position" : residuePosition})
  14. selection.addAtom(atomName)
  15. return selection
  16. class Description(object):
  17. def __init__(self, propertyConditions):
  18. self.children = []
  19. self.conditions = []
  20. self.addPropertyConditions(propertyConditions)
  21. def addPropertyConditions(self, propertyConditions):
  22. for conditionKey, conditionValue in propertyConditions.iteritems():
  23. self.addPropertyCondition(conditionKey, conditionValue)
  24. def addPropertyCondition(self, propertyName, propertyValue):
  25. self.__dict__[propertyName] = propertyValue
  26. self.conditions.append(PropertyCondition(propertyName, propertyValue))
  27. def addCondition(self, condition):
  28. self.conditions.append(condition)
  29. def describes(self, feature):
  30. for condition in self.conditions:
  31. if condition.satisfiedBy(feature):
  32. continue
  33. else:
  34. return False
  35. return self.matchesSubFeatures(feature)
  36. def matchesSubFeatures(self, feature):
  37. for subDescription in self:
  38. matchingSubFeature = None
  39. for subFeature in feature:
  40. #print "trying", subDescription, "against", subFeature
  41. if subDescription.describes(subFeature):
  42. matchingSubFeature = subFeature
  43. else:
  44. continue
  45. if matchingSubFeature is None:
  46. #print subDescription, "had no match"
  47. return False
  48. else:
  49. #print subDescription, "matched", matchingSubFeature
  50. continue
  51. return True
  52. def addSubDescription(self, subDescription):
  53. self.children.append(subDescription)
  54. def hasSubDescriptions(self):
  55. return len(self) > 0
  56. def __getattr__(self, key):
  57. for condition in self.conditions:
  58. if type(condition) == PropertyCondition and condition.propertyKey == key:
  59. return condition.propertyValue
  60. raise AttributeError, "No attribute or PropertyCondition found with key %s" % key
  61. def hasattr(self, key):
  62. for condition in self.conditions:
  63. if type(condition) == PropertyCondition and condition.propertyKey == key:
  64. return True
  65. return False
  66. def __len__(self):
  67. return len(self.children)
  68. def __iter__(self):
  69. return iter(self.children)
  70. def to_str(self):
  71. return "%s %s" % (self, self.children)
  72. class StructureDescription(Description):
  73. def __init__(self, propertyConditions, name=None):
  74. super(type(self), self).__init__(propertyConditions)
  75. self.name = name
  76. self.levelCode = "S"
  77. def addChain(self, chainDescription):
  78. self.children.append(chainDescription)
  79. def selectChain(self, chainID):
  80. for chainDescription in self:
  81. if chainDescription.chainID == chainID:
  82. return copy(chainDescription)
  83. return None
  84. def selectChainType(self, chainType):
  85. for chainDescription in self:
  86. if chainDescription.chainType == chainType:
  87. return copy(chainDescription)
  88. return None
  89. def __repr__(self):
  90. try:
  91. return "%s" % self.name
  92. except AttributeError:
  93. return "?"
  94. class ChainDescription(Description):
  95. def __init__(self, propertyConditions):
  96. super(type(self), self).__init__(propertyConditions)
  97. self.levelCode = "C"
  98. def createResidues(self, n):
  99. self.createResidueFromToInclusive(1, n)
  100. def createResidueFromToInclusive(self, i, j):
  101. for x in range(i - 1, j):
  102. self.createResidueWithBackbone(x)
  103. def createResidueWithBackbone(self, i):
  104. residue = ResidueDescription({"position" : i + 1})
  105. for atomName in ["N", "CA", "C", "O", "H"]:
  106. #for atomName in ["N", "CA", "C", "O"]:
  107. residue.addAtom(atomName)
  108. self.addResidue(residue)
  109. def addResidue(self, residue):
  110. self.children.append(residue)
  111. def getResidue(self, i):
  112. return self.children[i - 1]
  113. def selectResidue(self, i):
  114. return copy(self.children[i - 1])
  115. def getName(self):
  116. return self.chainID
  117. def createBackboneHBondConditions(self, donorAcceptorResidueNumbers, maxHO, minHOC, minNHO):
  118. conditions = []
  119. for donorResidueNumber, acceptorResidueNumber in donorAcceptorResidueNumbers:
  120. conditions.append(self.createBackboneHBondCondition(donorResidueNumber, acceptorResidueNumber, maxHO, minHOC, minNHO))
  121. return conditions
  122. def createBackboneHBondCondition(self, donorResidueNumber, acceptorResidueNumber, maxHO, minHOC, minNHO):
  123. """
  124. N = self.selectResidue(donorResidueNumber).selectAtom("N")
  125. H = self.selectResidue(donorResidueNumber).selectAtom("H")
  126. C = self.selectResidue(acceptorResidueNumber).selectAtom("C")
  127. O = self.selectResidue(acceptorResidueNumber).selectAtom("O")
  128. """
  129. N = constructSelection(chainType="Protein", residuePosition=donorResidueNumber, atomName="N")
  130. H = constructSelection(chainType="Protein", residuePosition=donorResidueNumber, atomName="H")
  131. C = constructSelection(chainType="Protein", residuePosition=acceptorResidueNumber, atomName="C")
  132. O = constructSelection(chainType="Protein", residuePosition=acceptorResidueNumber, atomName="O")
  133. name = "NH(%i)->CO(%i)" % (donorResidueNumber, acceptorResidueNumber)
  134. # note the dha/haa swap - would be nice to fix this!
  135. bond = HBondCondition(N, H, O, C, maxHO, minNHO, minHOC, name=name)
  136. self.addCondition(bond)
  137. return bond
  138. def createBackboneHBondMeasures(self, donorAcceptorResidueNumbers):
  139. measures = []
  140. for donorResidueNumber, acceptorResidueNumber in donorAcceptorResidueNumbers:
  141. measures.append(self.createBackboneHBondMeasure(donorResidueNumber, acceptorResidueNumber))
  142. return measures
  143. def createBackboneHBondMeasure(self, donorResidueNumber, acceptorResidueNumber):
  144. """
  145. N = self.selectResidue(donorResidueNumber).selectAtom("N")
  146. H = self.selectResidue(donorResidueNumber).selectAtom("H")
  147. C = self.selectResidue(acceptorResidueNumber).selectAtom("C")
  148. O = self.selectResidue(acceptorResidueNumber).selectAtom("O")
  149. """
  150. N = constructSelection(chainType="Protein", residuePosition=donorResidueNumber, atomName="N")
  151. H = constructSelection(chainType="Protein", residuePosition=donorResidueNumber, atomName="H")
  152. C = constructSelection(chainType="Protein", residuePosition=acceptorResidueNumber, atomName="C")
  153. O = constructSelection(chainType="Protein", residuePosition=acceptorResidueNumber, atomName="O")
  154. bond = HBondMeasure(N, H, O, C)
  155. bond.setName("NH(%i)->CO(%i)" % (donorResidueNumber, acceptorResidueNumber))
  156. return bond
  157. def createPhiPsiMeasures(self, residueNumbers):
  158. measures = []
  159. for residueNumber in residueNumbers:
  160. measures.extend(self.createPhiPsiMeasure(residueNumber))
  161. return measures
  162. def createPhiPsiMeasure(self, residueNumber):
  163. return self.createPhiMeasure(residueNumber), self.createPsiMeasure(residueNumber)
  164. def createPhiMeasure(self, residueNumber):
  165. i = residueNumber
  166. phi = self.createTorsionMeasure(i - 1, "C", i, "N", i, "CA", i, "C")
  167. phi.setName("phi%i" % residueNumber)
  168. return phi
  169. def createPsiMeasure(self, residueNumber):
  170. i = residueNumber
  171. psi = self.createTorsionMeasure(i, "N", i, "CA", i, "C", i + 1, "N")
  172. psi.setName("psi%i" % residueNumber)
  173. return psi
  174. def createPhiBoundCondition(self, residueNumber, center, range):
  175. i = residueNumber
  176. condition = self.createTorsionBoundCondition(i - 1, "C", i, "N", i, "CA", i, "C", center, range, "phi%s" % i)
  177. self.addCondition(condition)
  178. return condition
  179. def createPsiBoundCondition(self, residueNumber, center, range):
  180. i = residueNumber
  181. condition = self.createTorsionBoundCondition(i, "N", i, "CA", i, "C", i + 1, "N", center, range, "psi%s" % i)
  182. self.addCondition(condition)
  183. return condition
  184. def createTorsionBoundCondition(self, firstR, firstA, secondR, secondA, thirdR, thirdA, fourthR, fourthA, center, range, name=None):
  185. """
  186. a = self.selectResidue(firstR).selectAtom(firstA)
  187. b = self.selectResidue(secondR).selectAtom(secondA)
  188. c = self.selectResidue(thirdR).selectAtom(thirdA)
  189. d = self.selectResidue(fourthR).selectAtom(fourthA)
  190. """
  191. a = constructSelection(chainType="Protein", residuePosition=firstR, atomName=firstA)
  192. b = constructSelection(chainType="Protein", residuePosition=secondR, atomName=secondA)
  193. c = constructSelection(chainType="Protein", residuePosition=thirdR, atomName=thirdA)
  194. d = constructSelection(chainType="Protein", residuePosition=fourthR, atomName=fourthA)
  195. if name is None:
  196. return TorsionBoundCondition(a, b, c, d, center, range)
  197. else:
  198. return TorsionBoundCondition(a, b, c, d, center, range, name)
  199. def createTorsionMeasure(self, firstR, firstA, secondR, secondA, thirdR, thirdA, fourthR, fourthA):
  200. """
  201. a = self.selectResidue(firstR).selectAtom(firstA)
  202. b = self.selectResidue(secondR).selectAtom(secondA)
  203. c = self.selectResidue(thirdR).selectAtom(thirdA)
  204. d = self.selectResidue(fourthR).selectAtom(fourthA)
  205. """
  206. a = constructSelection(chainType="Protein", residuePosition=firstR, atomName=firstA)
  207. b = constructSelection(chainType="Protein", residuePosition=secondR, atomName=secondA)
  208. c = constructSelection(chainType="Protein", residuePosition=thirdR, atomName=thirdA)
  209. d = constructSelection(chainType="Protein", residuePosition=fourthR, atomName=fourthA)
  210. return TorsionMeasure(a, b, c, d)
  211. def __repr__(self):
  212. try:
  213. return "%s" % self.chainID
  214. except AttributeError:
  215. try :
  216. return "%s" % self.chainType
  217. except AttributeError:
  218. return "?"
  219. class ResidueDescription(Description):
  220. def __init__(self, propertyConditions):
  221. super(type(self), self).__init__(propertyConditions)
  222. self.levelCode = "R"
  223. def addAtom(self, atomName):
  224. self.addSubDescription(AtomDescription({"name" : atomName}))
  225. def getAtom(self, atomName):
  226. for atomDescription in self.children:
  227. for condition in atomDescription.conditions:
  228. if condition.satisfiedBy(atomName):
  229. return atomDescription
  230. return None
  231. def selectAtom(self, atomName):
  232. self.children = []
  233. self.addAtom(atomName)
  234. return self
  235. def getResname(self):
  236. try:
  237. return self.name
  238. except AttributeError:
  239. return "Any"
  240. def getPosition(self):
  241. p = self.position
  242. if p < 1:
  243. return "i - %i" % abs((p - 1))
  244. elif p == 1:
  245. return "i"
  246. elif p > 1:
  247. return "i + %i" % (p - 1)
  248. def __repr__(self):
  249. return "%s %s" % (self.getPosition(), self.children)
  250. class AtomDescription(Description):
  251. def __init__(self, propertyConditions):
  252. super(type(self), self).__init__(propertyConditions)
  253. self.levelCode = "A"
  254. def __repr__(self):
  255. return "%s" % self.name
  256. """
  257. The following utility functions generate descriptions from dictionaries or lists of values.
  258. """
  259. predefined_bounds = {
  260. "AR" : ((-90, 30), ( 0, 30)),
  261. "AL" : (( 90, 30), ( 0, 30)),
  262. "BR" : ((-90, 30), (150, 30)),
  263. }
  264. predefined_values = {
  265. "RLnest" : ("AR", "AL"),
  266. "LRNest" : ("AL", "AR"),
  267. "RCatmat3" : ("AR", "BR"),
  268. "RCatmat4" : ("AR", "AR", "BR")
  269. }
  270. def generateBackboneDescription(name, bounds):
  271. chain = ChainDescription({"chainID" : name})
  272. chain.createResidues(len(bounds) + 2)
  273. for i in range(len(bounds)):
  274. r = i + 2
  275. phiBound, psiBound = bounds[i]
  276. phiCenter, phiRange = phiBound
  277. psiCenter, psiRange = psiBound
  278. chain.createPhiBoundCondition(r, phiCenter, phiRange)
  279. chain.createPsiBoundCondition(r, psiCenter, psiRange)
  280. return chain
  281. def generatePredefined(name, boundNames):
  282. return (name, generateBackboneDescription(name, [predefined_bounds[b] for b in boundNames]))
  283. def generatePredefinedFromDictionary(valueDict):
  284. return dict([generatePredefined(name, bounds) for name, bounds in valueDict.iteritems()])
  285. predefined_descriptions = generatePredefinedFromDictionary(predefined_values)