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

Source Code for Module Biskit.Dock.ComplexTraj

  1  ## Automatically adapted for numpy.oldnumeric Mar 26, 2007 by alter_code1.py 
  2   
  3  ## 
  4  ## Biskit, a toolkit for the manipulation of macromolecular structures 
  5  ## Copyright (C) 2004-2006 Raik Gruenberg & Johan Leckner 
  6  ## 
  7  ## This program is free software; you can redistribute it and/or 
  8  ## modify it under the terms of the GNU General Public License as 
  9  ## published by the Free Software Foundation; either version 2 of the 
 10  ## License, or any later version. 
 11  ## 
 12  ## This program is distributed in the hope that it will be useful, 
 13  ## but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 15  ## General Public License for more details. 
 16  ## 
 17  ## You find a copy of the GNU General Public License in the file 
 18  ## license.txt along with this program; if not, write to the Free 
 19  ## Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 20  ## 
 21  ## 
 22  ## last $Author: graik $ 
 23  ## last $Date: 2007/04/06 10:16:09 $ 
 24  ## $Revision: 2.11 $ 
 25  """ 
 26  Trajectory of two proteins. 
 27  """ 
 28   
 29  from Biskit import Trajectory, TrajError, EnsembleTraj, hist 
 30  from Complex import Complex as ProteinComplex 
 31   
 32  import numpy.oldnumeric as N 
 33   
 34  import Biskit.gnuplot as gnuplot 
 35   
 36   
37 -class ComplexTrajError( TrajError ):
38 pass
39
40 -class ComplexTraj( EnsembleTraj ):
41 """ 42 Multi-copy trajectory of a protein-protein complex. 43 Quite basic. 44 45 ComplexTraj keeps the reference PDBModel of the normal Trajectory 46 but, additionally, knows which chains in the reference belong to the 47 receptor and which chains belong to the ligand. It tries to keep the 48 2 lists of chain indices ( cr and cl ) up-to-date, even if chains are 49 removed or re-ordered. 50 51 Appending of atoms/chains (e.g. with concatAtoms) is currently not 52 considered and will most likely leed to additional chains that are 53 ignored by the complex-specific functions. 54 """ 55
56 - def __init__(self, traj=None, recChains=[0], n_members=10, rec=None):
57 """ 58 Use:: 59 ComplexTraj( traj, recChains=[0], n_members=10 ) 60 61 @param traj: Trajectory (default: 0) 62 @type traj: Trajectory 63 @param recChains: list of chain indices defining receptor 64 (default: [0]) 65 @type recChains: [int] 66 @param n_members: number of ensemble members (for multi-copy MD) 67 (default: 10) 68 @type n_members: int 69 @param rec: instead of using recChains, autodetect rec chains 70 by comparing traj.ref with the model given as rec 71 (default: None) 72 @type rec: PDBModel 73 """ 74 EnsembleTraj.__init__( self ) 75 76 if traj: 77 self.__dict__.update( traj.__dict__ ) 78 79 if rec: 80 self.cr = self.ref.compareChains( rec )[0] 81 else: 82 self.cr = N.sort( recChains ).tolist() 83 84 self.cl = range( 0, self.getRef().lenChains() ) 85 for c in self.cr: 86 self.cl.remove(c) 87 88 else: 89 self.cr = self.cl = None
90 91
92 - def version( self ):
93 """ 94 Version of Dock.Complex 95 96 @return: version of class 97 @rtype: str 98 """ 99 return EnsembleTraj.version(self) + '; ComplexTraj $Revision: 2.11 $'
100 101
102 - def ligTraj( self ):
103 """ 104 @return: ligand part of this Trajectory (copy) 105 @rtype: EnsembleTraj 106 """ 107 return self.takeChains( self.cl, EnsembleTraj )
108 109
110 - def recTraj( self ):
111 """ 112 @return: receptor part of this Trajectory (copy) 113 @rtype: EnsembleTraj 114 """ 115 return self.takeChains( self.cr, EnsembleTraj )
116 117
118 - def refRec( self ):
119 """ 120 @return: copy of the receptor part of the reference model 121 @rtype: PDBModel 122 """ 123 return self.getRef().takeChains( self.cr )
124 125
126 - def refLig( self ):
127 """ 128 @return: copy of the ligand part of the reference model 129 @rtype: PDBModel 130 """ 131 return self.getRef().takeChains( self.cl )
132 133
134 - def refCom( self ):
135 """ 136 @return: Complex 137 @rtype: 138 """ 139 return ProteinComplex( self.refRec(), self.refLig() )
140 141
142 - def __getitem__( self, i ):
143 return self.getComplex( i )
144 145
146 - def getComplex( self, index ):
147 """ 148 Use:: 149 getComplex( frame_index ) -> Complex 150 151 @param index: frame index 152 @type index: int 153 154 @return: Complex 155 @rtype: Complex 156 """ 157 m = self.getPDBModel( index ) 158 return ProteinComplex( m.takeChains(self.cr), m.takeChains(self.cl) )
159 160
161 - def replaceContent( self, traj ):
162 """ 163 Replace content of this trajectory by content of given traj. 164 No deep-copying, only references are taken. 165 166 @param traj: Trajectory 167 @type traj: Trajectory 168 169 @raise ComplexTrajError: if given traj is no ComplexTraj. 170 """ 171 if not isinstance( traj, ComplexTraj ): 172 raise ComplexTrajError( 173 "Cannot replace ComplexTraj by normal Trajectory.") 174 175 Trajectory.replaceContent( self, traj ) 176 self.cr = traj.cr 177 self.cl = traj.cl
178 179
180 - def __translateChainIndices( self, atomIndices, newChainMap ):
181 """ 182 Translate current chain indices into what they would look like in 183 a PDBModel containing only the given atoms in the given order. 184 185 @param atomIndices: indices of atoms 186 @type atomIndices: [int] 187 @param newChainMap: chain map [0000011133333..] 188 @type newChainMap: [int] 189 190 @return: { int:int, .. } map current chain indices to new ones 191 @rtype: {int:int} 192 193 @raise ComplexTrajError: if (parts of) chains are inserted into 194 each other 195 """ 196 ## todo: looks not very elegant 197 198 oldChainMap = N.take( self.ref.chainMap(), atomIndices ) 199 200 r = {} 201 for i in range( len( oldChainMap ) ): 202 old, new = oldChainMap[i], newChainMap[i] 203 if old in r: 204 if r[old] != new: 205 raise ComplexTrajError( 206 "Can't insert different chains into each other.") 207 else: 208 r[old] = new 209 210 return r
211 212
213 - def takeAtoms( self, indices, returnClass=None ):
214 """ 215 takeAtoms( indices, [returnClass] ) -> ComplexTraj 216 217 @param indices: atoms to extract 218 @type indices: [int] 219 @param returnClass: return type (default: current class) 220 @type returnClass: class 221 222 @return: ComplexTraj 223 @rtype: ComplexTraj 224 225 @raise ComplexTrajError: if (parts of) chains are inserted into 226 each other 227 """ 228 r = Trajectory.takeAtoms( self, indices, returnClass ) 229 230 oldToNew = self.__translateChainIndices( indices, r.ref.chainMap() ) 231 232 r.cr = [ oldToNew[ c ] for c in self.cr if c in oldToNew ] 233 r.cl = [ oldToNew[ c ] for c in self.cl if c in oldToNew ] 234 235 return r
236 237 238 ## NOT TESTED!!
239 - def concatAtoms( self, recChains, *traj ):
240 """ 241 Concatenate 2 trajectories of same (frame) length 'horizontally', i.e. 242 for each frame the coordinates of one are appended to the coordinates 243 of the other. The ref model of the new trajectory is a 'semi-deep' copy 244 of this trajectory's model (see L{Biskit.PDBModel.take()} ).:: 245 concatAtoms( recChains, traj1 [traj2, traj3..]) -> ComplexTraj 246 247 248 @param recChains: chain indices into traj that will be assigned to the 249 receptor; all remaining chains (if any) go to the 250 ligand 251 @type recChains: [int] 252 @param traj: trajectories to concatenate 253 @type traj: Trajectory 254 255 @return: ComplexTraj 256 @rtype: ComplexTraj 257 258 @warning: NOT TESTED!! 259 """ 260 currentLen = self.ref.lenChains() 261 262 recChains.sort() 263 cl = [c for c in range(0, traj.ref.lenChains() ) if not c in recChains] 264 265 recChains = [ c + currentLen for c in recChains ] 266 cl = [ c + currentLen for c in cl ] 267 268 r = EnsembleTraj.concatAtoms( self, *traj ) 269 r.cr = self.cr + recChains 270 r.cl = self.cl + cl 271 272 return r
273 274
275 - def atomContacts( self, index, cutoff=4.5, rec_mask=None, lig_mask=None ):
276 """ 277 Use:: 278 atomContacts( frame_index ) -> array len_rec x len_lig of 0||1 279 280 @param index: frame index 281 @type index: [int] 282 @param cutoff: contact cutoff in Angstrom (default: 4.5) 283 @type cutoff: float 284 @param rec_mask: atom mask 285 @type rec_mask: [int] 286 @param lig_mask: atom mask 287 @type lig_mask: [int] 288 289 @return: contact matrix 290 @rtype: matrix 291 """ 292 return self[ index ].atomContacts( cutoff, rec_mask, lig_mask )
293 294
295 - def averageContacts( self, step=10, cutoff=4.5 ):
296 """ 297 Use:: 298 averageContacts( step=1, cutoff=4.5 ) 299 300 @param step: take only each |step|th frame (default: 10) 301 @type step: int 302 @param cutoff: distance cutoff in Angstrom (default: 4.5) 303 @type cutoff: float 304 305 @return: contact matrix with frequency of each contact in 306 (thinned) traj. 307 @rtype: matrix 308 """ 309 r = [ self.atomContacts( i, cutoff=cutoff ) 310 for i in range(0, len(self), step ) ] 311 return N.sum( N.array( r ) ) / ( 1. * len(r) )
312 313
314 - def plotContactDensity( self, step=1, cutoff=4.5 ):
315 """ 316 Example. plot histogramm of contact density. Somehing wrong?? 317 318 @raise ComplexTrajError: if gnuplot program is not installed 319 """ 320 if not gnuplot.installed: 321 raise ComplexTrajError, 'gnuplot program is not installed' 322 r = self.averageContacts( step, cutoff ) 323 r = N.ravel( r ) 324 r = N.compress( r, r ) 325 gnuplot.plot( hist.density( r, 10 ) )
326 327 328 329 ############# 330 ## TESTING 331 ############# 332 import Biskit.test as BT 333
334 -class Test(BT.BiskitTest):
335 """Test case""" 336 337 TAGS = [ BT.LONG ] 338
339 - def test_ComplexTraj(self):
340 """Dock.ComplexTraj test""" 341 342 import Biskit.tools as T 343 344 ## there is no complex trajectory in the test folder so will have 345 ## to create a fake trajectory with a complex 346 f = [ T.testRoot()+ '/com/1BGS.pdb' ] * 5 347 t = Trajectory( f, verbose=self.local ) 348 349 t = ComplexTraj( t, recChains=[0] ) 350 351 #if self.local: 352 #print 'plotting contact density...' 353 #t.plotContactDensity( step=2 ) 354 355 ## create a fake second chain in the ligand 356 for i in range( 1093+98, 1968 ): 357 t.ref.aProfiles['chain_id'][i] = 'B' 358 359 t.ref.chainIndex( force=1, cache=1 ) 360 t.cl = [1,2] 361 362 r = N.concatenate((range(1093,1191), range(0,1093), range(1191,1968))) 363 364 tt = t.takeAtoms( r ) 365 366 contactMat = tt.atomContacts( 1 ) 367 368 if self.local: 369 print 'Receptor chains: %s Ligand chains: %s'%(t.cr, t.cl) 370 371 self.assertEqual( N.sum(N.ravel(contactMat)), 308 )
372 373 if __name__ == '__main__': 374 375 #import Biskit.tools as T 376 377 ### there is no complex trajectory in the test folder so will have 378 ### to create a fake trajectory with a complex 379 #f = [ T.testRoot()+ '/com/1BGS.pdb' ] * 5 380 #t = Trajectory( f, verbose=1 ) 381 382 #t = ComplexTraj( t, recChains=[0] ) 383 384 ##if self.local: 385 ##print 'plotting contact density...' 386 ##t.plotContactDensity( step=2 ) 387 388 ##for i in range( 1093+98, 1968 ): 389 #t.ref.aProfiles['chain_id'][1093+98:1968] = 'B' 390 #t.ref.chainIndex( force=1, cache=1 ) 391 #t.cl = [1,2] 392 393 #r = N.concatenate((range(1093,1191), range(0,1093), range(1191,1968))) 394 395 #tt = t.takeAtoms( r ) 396 397 #contactMat = tt.atomContacts( 1 ) 398 BT.localTest() 399