1
2
3
4
5
6 from Numeric import Float0, zeros
7
8 from Bio.SVDSuperimposer import SVDSuperimposer
9 from Bio.PDB.PDBExceptions import PDBException
10
11
12 __doc__="Superimpose two structures."
13
14
16 """
17 Rotate/translate one set of atoms on top of another,
18 thereby minimizing the RMSD.
19 """
21 self.rotran=None
22 self.rms=None
23
25 """
26 Put (translate/rotate) the atoms in fixed on the atoms in
27 moving, in such a way that the RMSD is minimized.
28
29 @param fixed: list of (fixed) atoms
30 @param moving: list of (moving) atoms
31 @type fixed,moving: [L{Atom}, L{Atom},...]
32 """
33 if not (len(fixed)==len(moving)):
34 raise PDBException, "Fixed and moving atom lists differ in size"
35 l=len(fixed)
36 fixed_coord=zeros((l, 3), 'd')
37 moving_coord=zeros((l, 3), 'd')
38 for i in range(0, len(fixed)):
39 fixed_coord[i]=fixed[i].get_coord()
40 moving_coord[i]=moving[i].get_coord()
41 sup=SVDSuperimposer()
42 sup.set(fixed_coord, moving_coord)
43 sup.run()
44 self.rms=sup.get_rms()
45 self.rotran=sup.get_rotran()
46
47 - def apply(self, atom_list):
48 """
49 Rotate/translate a list of atoms.
50 """
51 if self.rotran is None:
52 raise PDBException, "No transformation has been calculated yet"
53 rot, tran=self.rotran
54 rot=rot.astype(Float0)
55 tran=tran.astype(Float0)
56 for atom in atom_list:
57 atom.transform(rot, tran)
58
59
60 if __name__=="__main__":
61
62 import sys
63 from Numeric import *
64
65 from Bio.PDB import *
66
67 p=PDBParser()
68 s1=p.get_structure("FIXED", sys.argv[1])
69 fixed=Selection.unfold_entities(s1, "A")
70
71 s2=p.get_structure("MOVING", sys.argv[1])
72 moving=Selection.unfold_entities(s2, "A")
73
74 rot=identity(3).astype(Float0)
75 tran=array((1.0, 2.0, 3.0), Float0)
76
77 for atom in moving:
78 atom.transform(rot, tran)
79
80 sup=Superimposer()
81
82 sup.set_atoms(fixed, moving)
83
84 print sup.rotran
85 print sup.rms
86
87 sup.apply(moving)
88