Scripts: placem.py

File placem.py, 3.0 KB (added by goddard, 15 years ago)
Line 
1# -----------------------------------------------------------------------------
2# Read a file listing models and placements (x,y,z translation and optionally
3# quaternion for rotation) and open the models at the specified positions.
4# Run this script from the Chimera command-line (Favorites / Command Line).
5#
6# runscript /Users/smith/placem.py /mydata/placements.txt
7#
8# Example file placements.txt:
9#
10# map1.mrc 10.25 -15.44 24.5
11# map2.mrc 9.24 12.24 23.1
12# proteinX.pdb 3.24 43.243 11.11 .7071 0 0 .7071
13#
14# The final 4 fields specify a rotation as a quaternion:
15#
16# cos(a/2) vx*sin(a/2) vy*sin(a/2) vz*sin(a/2)
17#
18# where a is rotation angle and v = (vx,vy,vz) is normalized rotation axis.
19# If not specified, not rotation is applied.
20#
21def place_models(path):
22
23 from chimera import openModels, Xform, replyobj, viewer
24
25 # Make placecements relative to an already opened model.
26 mlist = openModels.list()
27 rel = mlist[0].openState.xform if mlist else Xform()
28
29 pxlist = read_placement_file(path)
30 for path, xform in pxlist:
31 xform.premultiply(rel)
32 for m in openModels.open(path):
33 m.openState.xform = xform
34
35 replyobj.status('placed %d models' % len(pxlist))
36
37 viewer.viewAll()
38
39# -----------------------------------------------------------------------------
40#
41def read_placement_file(path):
42
43 try:
44 f = open(path, 'r')
45 except IOError:
46 from Midas import MidasError as err
47 raise err, 'Could not open "%s"' % path
48 lines = f.readlines()
49 f.close()
50
51 pxlist = []
52 from os.path import exists, dirname, join
53 dir = dirname(path)
54 from chimera import Xform
55 warnings = []
56 for line in lines:
57 fields = line.split()
58 if line[0] == '#':
59 continue
60 mpath = join(dir, fields[0])
61 if not exists(mpath):
62 warnings.append('File does not exist "%s"' % mpath)
63 continue
64 if len(fields) != 4 and len(fields) != 8:
65 warnings.append('Line must have 4 or 8 fields "%s"' % line.strip())
66 continue
67 try:
68 x,y,z = [float(s) for s in fields[1:4]]
69 except ValueError:
70 warnings.append('Could not parse shift values "%s"' % line.strip())
71 continue
72 if len(fields) == 8:
73 try:
74 q = [float(s) for s in fields[4:]]
75 except ValueError:
76 warnings.append('Could not parse quaternion values "%s"' % line.strip())
77 continue
78 else:
79 q = (1,0,0,0) # Identity rotation
80
81 a,b,c,d = q
82 xf = Xform.xform(a*a+b*b-c*c-d*d, 2*b*c-2*a*d, 2*b*d+2*a*c, x,
83 2*b*c+2*a*d, a*a-b*b+c*c-d*d, 2*c*d-2*a*b, y,
84 2*b*d-2*a*c, 2*c*d+2*a*b, a*a-b*b-c*c+d*d, z,
85 orthogonalize = True)
86 pxlist.append((mpath, xf))
87
88 if warnings:
89 from chimera import replyobj
90 replyobj.warning('\n'.join(warnings))
91
92 return pxlist
93
94# -----------------------------------------------------------------------------
95#
96from Midas import MidasError as err
97if not 'arguments' in globals() or len(arguments) != 1:
98 raise err, 'Syntax: runscript placem.py <placement-file>'
99
100place_models(arguments[0])