1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
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
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
77 self.history = ComplexList()
78
79 if com_0 != None:
80 self.history.append( com_0 )
81
82
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
88 """
89 Version of class.
90
91 @return: version of class
92 @rtype: str
93 """
94 return 'ComplexEvolving $Revision: 2.10 $'
95
96
98 """
99 __iter__() <==> for k in self
100 """
101 return iter( self.history + [self] )
102
103
105 """
106 length of self
107 """
108 return len( self.history ) + 1
109
110
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
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
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
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
182 if old_model.equals( new_model ) == [1,1]:
183
184
185 r = old_model.__class__( source=old_model )
186
187 r.setXyz( new_model.getXyz() )
188
189
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
212 """
213 @return: all historic complexes plus current one as Complex
214 @rtype: ComplexList
215 """
216 return self.history + [ self.toComplex() ]
217
218
220 """
221 @return: all historic complexes plus current one as Complex
222 @rtype: [Complex]
223 """
224 return self.history.toList() + [ self.toComplex() ]
225
226
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
263
264 import Biskit.test as BT
265
266 -class Test(BT.BiskitTest):
267 """Test case"""
268
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