Package Biskit :: Package Dock :: Module ComplexEvolving
[hide private]
[frames] | no frames]

Source Code for Module Biskit.Dock.ComplexEvolving

  1  ## 
  2  ## Biskit, a toolkit for the manipulation of macromolecular structures 
  3  ## Copyright (C) 2004-2006 Raik Gruenberg & Johan Leckner 
  4  ## 
  5  ## This program is free software; you can redistribute it and/or 
  6  ## modify it under the terms of the GNU General Public License as 
  7  ## published by the Free Software Foundation; either version 2 of the 
  8  ## License, or any later version. 
  9  ## 
 10  ## This program is distributed in the hope that it will be useful, 
 11  ## but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  ## General Public License for more details. 
 14  ## 
 15  ## You find a copy of the GNU General Public License in the file 
 16  ## license.txt along with this program; if not, write to the Free 
 17  ## Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 18  ## 
 19  ## 
 20  ## $Revision: 2.10 $ 
 21  ## last $Author: graik $ 
 22  ## last $Date: 2007/04/06 10:16:08 $ 
 23   
 24  """ 
 25  Complex that keeps track of its previous versions (conformations). 
 26  """ 
 27   
 28  import Biskit.tools as t 
 29  import Biskit.mathUtils as MU 
 30  from Biskit import EHandler 
 31  from Complex import Complex as ProtComplex 
 32  from ComplexList import ComplexList 
 33   
 34   
35 -class ComplexEvolving( ProtComplex ):
36 """ 37 Complex that keeps track of its previous versions. The object behaves 38 like a normal L{Biskit.Dock.Complex} but encapsulates a 39 L{Biskit.Dock.ComplexList} with older versions/conformations of 40 this Complex. 41 42 - com[0] gives the very first version, com[1] the second, etc. 43 - com[-1] gives the current version (but as normal Complex, not 44 ComplexEvolving). 45 - e.g. com[0, 'fnac'] gives the according info value of the first version 46 - e.g. com['fnac'] gives the current info value (as for Dock.Complex) 47 """ 48
49 - def __init__(self, rec_model, lig_model, com_0=None, 50 ligMatrix=None, info={} ):
51 """ 52 Create a new ComplexEvolving from a previous Complex or ComplexEvolving 53 and a new set of receptor, ligand conformation and transformation. 54 55 @param rec_model: PDBModel/PCRModel, receptor conformation 56 @type rec_model: PDBModel 57 @param lig_model: PDBModel/PCRModel, ligand conformation 58 @type lig_model: PDBModel 59 @param com_0: Complex /ComplexEvolving, previous version(s) of this com 60 @type com_0: Complex OR ComplexEvolving 61 @param ligMatrix: transformation matrix of ligand versus receptor 62 @type ligMatrix: 4x4 array 63 @param info: info dictionary {'info_key': value, ..}, additional infos 64 @type info: dict 65 """ 66 ProtComplex.__init__(self, rec_model, lig_model, ligMatrix, info ) 67 68 if isinstance( com_0, ComplexEvolving ): 69 ## get history from mother complex ... 70 self.history = com_0.history 71 72 com_0 = ProtComplex( com_0.rec_model, com_0.lig_model, 73 com_0.ligandMatrix, com_0.info ) 74 75 else: 76 ## ... or create a new history 77 self.history = ComplexList() 78 79 if com_0 != None: 80 self.history.append( com_0 ) 81 82 ## save only differences between old and new conformations 83 self.rec_model = self.__syncModel( self.rec_model, com_0.rec_model) 84 self.lig_model = self.__syncModel( self.lig_model, com_0.lig_model)
85 86
87 - def version( self ):
88 """ 89 Version of class. 90 91 @return: version of class 92 @rtype: str 93 """ 94 return 'ComplexEvolving $Revision: 2.10 $'
95 96
97 - def __iter__(self):
98 """ 99 __iter__() <==> for k in self 100 """ 101 return iter( self.history + [self] )
102 103
104 - def __len__( self ):
105 """ 106 length of self 107 """ 108 return len( self.history ) + 1
109 110
111 - def getComplex( self, i, copy=0 ):
112 """ 113 Return one version as Complex. -1 returns a copy of the latest 114 version. By default the info dictionary remains connected but 115 other fields don't. I.e. replacing rec_model in the copy does 116 not affect the original complex. 117 118 @param i: index in complex history, -1 returns toComplex() 119 @type i: int 120 @param copy: copy info dictionary in case of i==-1 (changes in 121 c.getComplex( -1 ).info will not appear in c.info [0] 122 @type copy: 1|0 123 124 @return: complex 125 @rtype: Dock.Complex 126 """ 127 if i == -1: 128 return self.toComplex( copy=copy ) 129 130 if i >= 0 and i < len( self.history ): 131 return self.history[ i ] 132 133 return self.toSimpleList()[i]
134 135
136 - def __getitem__( self, k ):
137 """ 138 Get a Complex OR a info key value for a Complex specified Complex 139 OR info dic value. 140 141 @param k: tuple OR int OR str 142 @type k: any OR Complex 143 """ 144 if type(k) == tuple: 145 146 i, key = k[0], k[1] 147 148 if i == len( self.history ): 149 return self.info[key] 150 151 return self.getComplex(i).info[key] 152 153 if isinstance(k, int): 154 155 return self.getComplex( k ) 156 157 return self.info[k]
158 159
160 - def __syncModel( self, new_model, old_model ):
161 """ 162 Connect new rec or lig model to old one, to minimize storage. 163 164 @param new_model: PDBModel / PCRModel 165 @type new_model: PDBModel 166 @param old_model: PDBModel / PCRModel 167 @type old_model: PDBModel 168 169 @return: PDBModel / PCRModel, new model that only keeps 170 changes relative to old, the old model becomes the 171 source of the new, if possible 172 @rtype: PDBModel 173 """ 174 ## try to fix atom order of new_model so that it is identical to old 175 if old_model.equals( new_model ) != [1,1]: 176 i_new, i_old = new_model.compareAtoms( old_model ) 177 178 if len( i_new ) == len( new_model ): 179 new_model.keep( i_new ) 180 181 ## create result model that only keeps difference of new and old 182 if old_model.equals( new_model ) == [1,1]: 183 184 ## stays compatible with PCRModel.__init__ and PDBModel.__init 185 r = old_model.__class__( source=old_model ) 186 187 r.setXyz( new_model.getXyz() ) 188 189 ## check for profiles identical to source and adapt 'changed' 190 r.update() 191 192 if not MU.arrayEqual( r.xyz, old_model.xyz ): 193 r.removeProfile( 'relASA', 'ASA_sc', 'ASA_total', 'ASA_bb' ) 194 195 return r 196 197 EHandler.warning( 198 'ComplexEvolving: Cannot connect new to old PDBModel.') 199 200 new_model.disconnect() 201 return new_model
202 203
204 - def sortHistory( self ):
205 """ 206 Sort by date 207 """ 208 self.history = self.history.sortBy( 'date' )
209 210
211 - def toList( self ):
212 """ 213 @return: all historic complexes plus current one as Complex 214 @rtype: ComplexList 215 """ 216 return self.history + [ self.toComplex() ]
217 218
219 - def toSimpleList( self ):
220 """ 221 @return: all historic complexes plus current one as Complex 222 @rtype: [Complex] 223 """ 224 return self.history.toList() + [ self.toComplex() ]
225 226
227 - def toComplex( self, copy=0 ):
228 """ 229 Copy of latest version as a normal Complex. 230 231 @param copy: also disconnect info dict (default: 0) 232 @type copy: 1|0 233 234 @return: Complex 235 @rtype: Complex 236 """ 237 r = ProtComplex( self.rec_model, self.lig_model, 238 self.ligandMatrix, self.info ) 239 if not copy: 240 r.info = self.info 241 242 return r
243 244
245 - def valuesOf( self, infoKey, default=None ):
246 """ 247 Get info values from all versions of this complex (oldest first). 248 249 @param infoKey: info dic key 250 @type infoKey: str 251 @param default: default value, if key is not present 252 @type default: any 253 254 @return: list of values 255 @rtype: [any] 256 """ 257 return [ c.get( infoKey, default ) for c in self ]
258 259 260 261 ############# 262 ## TESTING 263 ############# 264 import Biskit.test as BT 265
266 -class Test(BT.BiskitTest):
267 """Test case""" 268
269 - def test_ComplexEvolving(self):
270 """Dock.ComplexEvolving test""" 271 import time 272 273 from Biskit.Dock import ComplexEvolving 274 275 c = t.Load( t.testRoot() + '/com/ref.complex' ) 276 277 self.ce= ComplexEvolving( c.rec_model, c.lig(), c, 278 info={'comment':'test'} ) 279 280 time.sleep( 2 ) 281 282 lig = self.ce.lig().transform( MU.randomRotation(), [0,0,0] ) 283 self.ce2 = ComplexEvolving( self.ce.rec_model, lig, self.ce, 284 info={'comment':'test2'}) 285 286 if self.local: 287 print '\nGenerations: ' 288 for x in self.ce2: 289 print x['date'] 290 291 print 'Comments: ', self.ce2.valuesOf('comment') 292 293 self.assertEqual( self.ce2.valuesOf('comment'), 294 [None, 'test', 'test2'])
295 296 297 if __name__ == '__main__': 298 299 BT.localTest() 300