1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from mglutil.math.rotax import rotax
17 from mglutil.math.transformation import Transformation
18 import Numeric, math, string
19
20
22 """ vector: list of floats [x, y, z]
23 point: list of floats [x, y, z]
24 symmetry int, >= 1
25 identity: int, 0 or 1
26 """
27
28 - def __init__(self, vector, point, symmetry, identity):
29 self.set(vector, point, symmetry, identity)
30
31
33 angle=360.0/self.symmetry
34 m=[]
35 t=Numeric.array(self.point)*-1
36
37 if self.identity == 1:
38 mat = Numeric.identity(4).astype('f')
39 m.append(mat)
40
41 T = Transformation(trans=t)
42 T1 = T.inverse()
43 for i in range(self.symmetry-1):
44 newList=[]
45 newList.extend(list(self.vector))
46 newList.append(angle)
47
48 R = Transformation(quaternion=newList)
49
50 mt = T1 * R * T
51
52 newmat = mt.getDejaVuMatrix()
53 m.append(newmat)
54 angle=angle+360.0/self.symmetry
55
56 return m
57
58
59 - def set(self, vector=None, point=None, symmetry=None, identity=None):
60 if vector:
61 assert len(vector)==3
62 self.vector = Numeric.array(vector).astype('f')
63 if point:
64 assert len(point)==3
65 self.point = Numeric.array(point).astype('f')
66 if symmetry:
67 assert symmetry >= 1
68 self.symmetry = symmetry
69 if identity is not None:
70 assert identity in (0,1)
71 self.identity = identity
72
73
74 - def __call__(self, inMatrices, applyIndex=None):
75 """outMatrices <- SymNFold(inMatrices, applyIndex=None)
76 inMatrices: list of 4x4 matrices
77 outMatrices: list of 4x4 matrices
78 if applyIndex is given it should be a list of 0-based indices of
79 matrices to which this operator's transformation will be applied.
80 """
81
82 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
83 matrices = Numeric.array(inMatrices)
84 assert len(matrices.shape)==3
85 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
86 ownmat = self.getMatrices()
87 out = []
88 for m in ownmat:
89 for im in matrices:
90 out.append( Numeric.matrixmultiply(m, im) )
91 return out
92
93
95
96 - def __init__(self, vector=(1.0, 0.0, 0.0), length=0.0, identity=0):
97 self.vector = vector
98 self.length = length
99 self.identity = identity
100
101
103 m=[]
104 mat=Numeric.identity(4).astype('f')
105
106 if self.length is None or self.length == 0:
107 m.append( Numeric.identity(4).astype('f') )
108 return m
109
110 if self.identity == 1:
111 m.append( Numeric.identity(4).astype('f') )
112
113 mat[:3, 3] = (self.vector*self.length).astype('f')
114 m.append(mat)
115 return m
116
117
118 - def set(self, vector=None, identity=None, length=None):
119 if vector:
120 assert len(vector)==3
121 self.vector = Numeric.array(vector).astype('f')
122 if identity is not None:
123 assert identity in (0,1)
124 self.identity = identity
125 if length is not None:
126 self.length = float(length)
127
128
129 - def __call__(self, inMatrices, applyIndex=None):
130 """outMatrices <- SymTrans(inMatrices, applyIndex=None)
131 inMatrices: list of 4x4 matrices
132 outMatrices: list of 4x4 matrices
133 """
134
135 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
136 matrices = Numeric.array(inMatrices)
137 assert len(matrices.shape)==3
138 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
139 ownmat = self.getMatrices()
140 out = []
141 for m in ownmat:
142 for im in matrices:
143 out.append( Numeric.matrixmultiply(m, im) )
144 return out
145
146
147
149
151 self.set(data, identity)
152
153 - def set(self, data=None, identity=None):
154 if data:
155 assert len(data)==6
156 self.vector1 = Numeric.array(data[3]).astype('f')*float(data[0])
157 self.vector2 = Numeric.array(data[4]).astype('f')*float(data[1])
158 self.vector3 = Numeric.array(data[5]).astype('f')*float(data[2])
159 if identity is not None:
160 assert identity in (0,1)
161 self.identity = identity
162
163
165 m=[]
166 t1=Numeric.array(self.vector1)
167 t2=Numeric.array(self.vector2)
168 t3=Numeric.array(self.vector3)
169
170 if self.identity == 1:
171 mat = Numeric.identity(4).astype('f')
172 m.append(mat)
173
174
175 T1 = Transformation(trans=t1)
176 T2 = Transformation(trans=t2)
177 T3 = Transformation(trans=t3)
178
179 mt = T1*T2*T3
180 newmat = mt.getMatrix()
181 m.append(newmat)
182
183 return m
184
185
186 - def __call__(self, inMatrices, applyIndex=None):
187 """outMatrices <- SymRot(inMatrices, applyIndex=None)
188 inMatrices: list of 4x4 matrices
189 outMatrices: list of 4x4 matrices
190 """
191
192 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
193 matrices = Numeric.array(inMatrices)
194 assert len(matrices.shape)==3
195 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
196 ownmat = self.getMatrices()
197 out = []
198 for m in ownmat:
199 for im in matrices:
200 out.append( Numeric.matrixmultiply(m, im) )
201 return out
202
203
204
206
207 - def __init__(self, vector, point, angle, identity):
208 self.set(vector, point, angle, identity)
209
210
212 m=[]
213 t=Numeric.array(self.point)*-1
214
215 if self.identity == 1:
216 mat = Numeric.identity(4).astype('f')
217 m.append(mat)
218
219 newList=[]
220 newList.extend(list(self.vector))
221 newList.append(self.angle)
222
223 T = Transformation(trans=t)
224 R = Transformation(quaternion=newList)
225
226 mt = T.inverse() * R * T
227 newmat = mt.getMatrix()
228 m.append(newmat)
229
230 return m
231
232
233 - def set(self, vector=None, point=None, angle=None, identity=None):
234 if vector:
235 assert len(vector)==3
236 self.vector = Numeric.array(vector).astype('f')
237 if point:
238 assert len(point)==3
239 self.point = Numeric.array(point).astype('f')
240 if angle is None: self.angle = 0.0
241 elif angle is not None:
242 self.angle = angle
243 if identity is not None:
244 assert identity in (0,1)
245 self.identity = identity
246
247
248 - def __call__(self, inMatrices, applyIndex=None):
249 """outMatrices <- SymRot(inMatrices, applyIndex=None)
250 inMatrices: list of 4x4 matrices
251 outMatrices: list of 4x4 matrices
252 """
253
254 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
255 matrices = Numeric.array(inMatrices)
256 assert len(matrices.shape)==3
257 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
258 ownmat = self.getMatrices()
259 out = []
260 for m in ownmat:
261 for im in matrices:
262 out.append( Numeric.matrixmultiply(m, im) )
263 return out
264
265
267
268 - def getMatrices(self, scaleFactor, selection=[1, 1, 1]):
269 mat = Numeric.identity(4).astype('f')
270
271
272 if selection[0] not in [0, False]:
273 mat[0][0] = scaleFactor
274 else:
275 mat[0][0] = 1.0
276
277 if selection[1] not in [0, False]:
278 mat[1][1] = scaleFactor
279 else:
280 mat[1][1] = 1.0
281
282 if selection[2] not in [0, False]:
283 mat[2][2] = scaleFactor
284 else:
285 mat[2][2] = 1.0
286
287 return mat
288
289
290 - def __call__(self, inMatrices, scaleFactor, applyIndex=None, selection=[True,True,True]):
291 """outMatrices <- SymScale(inMatrices, applyIndex=None, selection=[1,1,1])
292 inMatrices: list of 4x4 matrices
293 outMatrices: list of 4x4 matrices
294 (selection: scale x,y, and/or z) can be 1,True or 0,False)
295 """
296
297 if not inMatrices:
298 inMatrices = [Numeric.identity(4).astype('f')]
299
300 matrices = Numeric.array(inMatrices)
301 assert len(matrices.shape)==3
302 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
303 ownmat = self.getMatrices(scaleFactor, selection)
304 out = []
305 for im in matrices:
306 out.append( Numeric.matrixmultiply(im, ownmat) )
307 return out
308
309
311 """
312 Operator to build a stream of transforamtion matrices describing a helical
313 arrangment.
314
315 arguments:
316 vector: the 3-D vector defining the oriention of the helical axis
317 point: a 3-D point defining the location in space of the helical axis
318 angle: angular value in degrees between 2 consecutive copies
319 hrise: displacement along the helical axis between 2 consecutive copies
320 copies: number of transformations
321 """
322 - def __init__(self, vector, point, angle, hrise, copies):
323 self.copies = 1
324 self.hrise = 0
325 self.angle = 0
326 self.point = (0.,0.,0.)
327 self.vector = (0.,1.,0.)
328 self.set(vector, point, angle, hrise, copies)
329
330
332 nv = float(math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]))
333 return (v[0]/nv, v[1]/nv, v[2]/nv)
334
335
336 - def set(self, vector=None, point=None, angle=None, hrise=None,
337 copies=None):
338
339 if vector is not None:
340 assert len(vector)==3
341 self.vector = self.normalize(vector)
342
343 if point is not None:
344 assert len(vector)==3
345 self.point = point
346
347 if angle is not None:
348 self.angle = angle*math.pi/180.
349
350 if hrise is not None:
351 self.hrise = hrise
352
353 if copies is not None:
354 assert copies >= 1
355 self.copies=copies
356
357
359 matrices = []
360 r = self.hrise
361 v = self.vector
362 p = self.point
363 rv = (r*v[0], r*v[1], r*v[2])
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 R = rotax( p, [p[0]+v[0], p[1]+v[1], p[2]+v[2]],
381 self.angle, False)
382 riseMat = Numeric.identity(4).astype('f')
383 riseMat[:3, 3] = rv
384 transform = Numeric.matrixmultiply(riseMat, R)
385 N = Numeric
386
387 matrices.append( N.identity(4).astype('f'))
388 for i in range(1,self.copies):
389 mat = matrices[i-1]
390 mat = Numeric.matrixmultiply(mat, transform)
391 matrices.append(mat)
392
393 return matrices
394
395
396 - def __call__(self, inMatrices, applyIndex=None):
397 """outMatrices <- SymHelix(inMatrices, applyIndex=None)
398 inMatrices: list of 4x4 matrices
399 outMatrices: list of 4x4 matrices
400 """
401
402 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
403 matrices = Numeric.array(inMatrices)
404 assert len(matrices.shape)==3
405 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
406 ownmat = self.getMatrices()
407 out = []
408 for m in ownmat:
409 for im in matrices:
410 out.append( Numeric.matrixmultiply(m, im) )
411 return out
412
413
415
417 pass
418
420 pass
421
423 pass
424
425 - def __call__(self, inMatrices, applyIndex=None):
426 """outMatrices <- SymMerge(inMatrices, applyIndex=None)
427 inMatrices: list of 4x4 matrices
428 outMatrices: list of 4x4 matrices
429 """
430
431 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
432 return inMatrices
433
434
436 """ SymMultiply multiplies incoming matrices and ouputs them.
437 - 1 parent is multiplied with itself
438 - 2 parents: two valid options: either one of the parents has
439 lenght 1 (1 matrix) which is then multiplied to all other matrices
440 of the second parent or both parents have the same amount of
441 matrices. """
442
443
445 pass
446
447
449
450 matInA, matInB = self.set(matA, matB)
451
452
453 assert len(matInA) == 1 or len(matInB) == 1 or \
454 len(matInA) == len(matInB)
455
456 matrixOut = []
457
458
459 if len(matInA) == 1:
460 for i in range(len(matInB)):
461 matrixOut.append(Numeric.matrixmultiply(matInA[0],
462 matInB[i]))
463
464 elif len(matInB) == 1:
465 for i in range(len(matInA)):
466 matrixOut.append(Numeric.matrixmultiply(matInA[i],
467 matInB[0]))
468
469
470 else:
471 for i in range(len(matInA)):
472 matrixOut.append(Numeric.matrixmultiply(matInA[i],
473 matInB[i]))
474
475 return matrixOut
476
477
478 - def set(self, inA=None, inB=None):
479
480 if inA is None and inB is not None:
481 matInA = matInB = inB
482 elif inA is not None and inB is None:
483 matInA = matInB = inA
484 elif inA is not None and inB is not None:
485 matInA = inA
486 matInB = inB
487 elif inA is None and inB is None:
488 matInA = matInB = Numeric.identity(4).astype('f')
489
490 return matInA, matInB
491
492
493 - def __call__(self, matA=None, matB=None):
494 """outMatrices <- SymMerge(matA, matB)
495 matA: list of 4x4 matrices
496 matB: list of 4x4 matrices
497 outMatrices: list of 4x4 matrices
498 """
499
500 out = self.getMatrices(matA, matB)
501 return out
502
503
504
506 """unselected matrices of the incomming stream are sent to
507 output port 0, selected matrices are sent to additional output ports which get
508 created on selection.
509 selection is done by specifying matrices comma separated indices in the
510 incomming stream. Ranges can be specified using the ':' or '-' character.
511 additional ports are created by using the ';' character.
512 """
513
514
516 self.set(matrices, chars)
517
518
519 - def set(self, matrices=None, chars=None):
520 self.inMatrices = matrices
521 self.indices = self.processString(chars)
522
523
525 split1=[]
526 split2=[]
527 l=[]
528 ll=[]
529 newList=[]
530 split1=string.split(entry,';')
531 i=0
532 for i in range(len(split1)):
533 l=string.split(split1[i],',')
534 for item in l:
535 try:
536 val=int(item)
537 ll.append(val)
538 except:
539 for c in item:
540 if c == '-' or c == ':':
541 s=string.split(item,c)
542 newList=range(int(s[0]),int(s[1])+1)
543 for i in range(len(newList)):
544 ll.append(newList[i])
545
546 split2.append(ll)
547 ll=[]
548 return split2
549
550
552 outMatrices=[]
553 indicesComp = range(len(self.inMatrices))
554 if self.indices[0] == []:
555 self.indices[0] = indicesComp
556 fullList = []
557 else:
558 fullList = Numeric.concatenate(self.indices)
559 map( indicesComp.remove, fullList )
560 self.indices.insert(0,indicesComp)
561
562 for i in range(len(self.indices)):
563 outMatrices.append(Numeric.take(self.inMatrices, self.indices[i]))
564 return outMatrices
565
566
567 - def __call__(self, inMatrices, applyIndex=None):
568 """outMatrices <- SymSplit(inMatrices, applyIndex=None)
569 inMatrices: list of 4x4 matrices
570 outMatrices: list of 4x4 matrices
571 """
572 if not inMatrices:
573 outMatrices = [Numeric.identity(4).astype('f')]
574 else:
575 outMatrices = self.getMatrices()
576 return outMatrices
577
578
580 """ imputs xyz coords, outputs center of gravity """
581
582
585
586
587 - def set(self, coords=None):
588 self.coords = coords
589
590
592 if self.coords is None:
593 return [0., 0., 0.]
594 else:
595 self.coords=list(Numeric.sum(self.coords)/len(self.coords))
596 return self.coords
597
598
601
602
604 """ rotation around center of gravity """
605
606 - def __init__(self, vector, angle, center, identity):
607 self.set(vector, angle, center, identity)
608
609
611 m=[]
612 newList=[]
613 mat = Numeric.identity(4).astype('f')
614 if self.identity == 1:
615 m.append(mat)
616
617 newList.extend(list(self.vector))
618 newList.append(self.angle)
619 t=Numeric.array(self.center)*-1
620
621 T = Transformation(trans=t)
622 R = Transformation(quaternion=newList)
623
624 mt = T.inverse() * R * T
625 newmat = mt.getMatrix()
626
627 m.append(newmat)
628 return m
629
630
631 - def set(self, vector=None, angle=None, center=None, identity=None):
632 if vector:
633 assert len(vector)==3
634 self.vector = vector
635
636 if angle is None: self.angle = 0.0
637 elif angle is not None:
638 self.angle=angle
639
640 if center is None:
641 center=[0.,0,0]
642 self.center=center
643
644 if identity is not None:
645 assert identity in (0,1)
646 self.identity = identity
647
648
649 - def __call__(self, inMatrices, applyIndex=None):
650 """outMatrices <- SymOrient(inMatrices, applyIndex=None)
651 inMatrices: list of 4x4 matrices
652 outMatrices: list of 4x4 matrices
653 """
654
655 if not inMatrices: inMatrices = [Numeric.identity(4).astype('f')]
656 matrices = Numeric.array(inMatrices)
657 assert len(matrices.shape)==3
658 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
659 ownmat = self.getMatrices()
660 out = []
661 for m in ownmat:
662 for im in matrices:
663 out.append( Numeric.matrixmultiply(m, im) )
664 return out
665
666
667
668
670 """ applies matrices to coords and outputs transformed coords """
671
673 pass
674
676 pass
677
678 - def set(self, coords=None, matrices=None):
679 if coords is None: return
680 else: self.coords = Numeric.array(coords).astype('f')
681 if matrices is None:
682 self.matrices = [Numeric.identity(4).astype('f')]
683 else:
684
685 self.matrices = matrices
686
687
689 newCoords=[]
690 if self.coords is not None:
691 one = Numeric.ones( (self.coords.shape[0], 1), \
692 self.coords.typecode() )
693 c = Numeric.concatenate( (self.coords, one), 1 )
694
695
696 for m in range(len(self.matrices)):
697 newCoords.append(Numeric.matrixmultiply(c, \
698 Numeric.transpose(self.matrices[m]))[:, :3])
699 return Numeric.concatenate(newCoords)
700
701
704
705
706
708 """ inputs PDB file, parses MTRIXn records and returns a list of (4x4)
709 matrices. MTRIXn is the default PDB standard, however not everybody seems
710 to follow the standard, thus an optional keyword can be passed that
711 describes the matrix records in this non-standard PDB file."""
712
714 pass
715
716
718 if mol is None:
719 return
720
721 matrices = []
722 next = 0
723
724 lines = mol.data[0].parser.allLines
725 arr = Numeric.identity(4).astype('f')
726
727 for l in lines:
728
729 spl = string.split(l)
730 if spl[0][:-1] != keyword: continue
731 index = int(spl[0][-1:])-1
732
733 arr[index][0] = float(spl[2])
734 arr[index][1] = float(spl[3])
735 arr[index][2] = float(spl[4])
736
737 if index == 2:
738 matrices.append(arr)
739 arr = Numeric.identity(4).astype('f')
740
741 return matrices
742
743
744
746
747 """ SymTranspose transposes all incomming matrices. """
748
749
750 - def __call__(self, inMatrices=None, applyIndex=None):
751 """outMatrices <- SymTranspose(inMatrices, applyIndex=None)
752 inMatrices: list of 4x4 matrices
753 outMatrices: list of 4x4 matrices
754 """
755
756 if not inMatrices:
757 inMatrices = [Numeric.identity(4).astype('f')]
758
759 matrices = Numeric.array(inMatrices)
760 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
761
762 out = []
763 for im in matrices:
764 out.append( Numeric.transpose(im) )
765 return out
766
768
769 """ SymInverse inverse all incomming matrices. """
770
771
772 - def __call__(self, inMatrices=None, applyIndex=None):
773 """outMatrices <- SymInverse(inMatrices, applyIndex=None)
774 inMatrices: list of 4x4 matrices
775 outMatrices: list of 4x4 matrices
776 """
777
778 import LinearAlgebra
779
780 if not inMatrices:
781 inMatrices = [Numeric.identity(4).astype('f')]
782
783 matrices = Numeric.array(inMatrices)
784 assert matrices.shape[-2] == 4 and matrices.shape[-1] == 4
785
786 out = []
787 for im in matrices:
788 out.append( LinearAlgebra.inverse(im) )
789 return out
790
791
793
794 """Compute the distance between two (x,y,z) points"""
795
796
798 """point1, point2
799 both must be (x,y,z) coordinates"""
800
801 x1, y1, z1 = point1
802 x2, y2, z2 = point2
803 dist = math.sqrt( math.pow((x2-x1),2) + math.pow((y2-y1),2) + \
804 math.pow((z2-z1),2) )
805 return dist
806