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