| 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 | #
|
|---|
| 21 | def 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 | #
|
|---|
| 41 | def 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 | #
|
|---|
| 96 | from Midas import MidasError as err
|
|---|
| 97 | if not 'arguments' in globals() or len(arguments) != 1:
|
|---|
| 98 | raise err, 'Syntax: runscript placem.py <placement-file>'
|
|---|
| 99 |
|
|---|
| 100 | place_models(arguments[0])
|
|---|