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