Scripts: blend.py

File blend.py, 2.3 KB (added by goddard, 12 years ago)
Line 
1#
2# Blend two or more solid volume renderings creating a new volumetric model.
3#
4# runscript blend.py #1-3 #5
5#
6# Maps must be shown in solid style and be the same size, and the color red, green and blue components
7# and opacity values are added, not averaged. The first argument lists the maps to blend, and the second
8# argument is the id number of the resulting model. The result is not a map. The result will not update
9# if the map display is changed. To update, redisplay the maps as desired then rerun this script.
10#
11# Script made for James Fraser to blend two x-ray maps in complementary green/magenta colors
12# so that overlap regions appear gray, and differences appear green or magenta.
13# An example is figure 6 in this article
14#
15# http://www.sciencedirect.com/science/article/pii/S1047847704001236
16#
17def blend_maps(vlist, vresult):
18
19 # Position result to map first blended map.
20 s0 = vlist[0].solid
21 vresult.set_array_coordinates(s0.transform)
22
23 # Get color plane callbacks.
24 planes = []
25 for v in vlist:
26 s = v.solid
27 s.color_mode = s.c_mode = 'rgba8'
28 cmap, cmap_range = s.colormap()
29 planes.append(lambda axis, plane, s=s, cmap=cmap, cmap_range=cmap_range:
30 s.color_values(axis, plane, cmap, cmap_range))
31
32 def get_color_plane(axis, plane, planes = planes):
33 p = None
34 for pfunc in planes:
35 vp = pfunc(axis, plane)
36 if p is None:
37 p = vp.copy()
38 else:
39 p += vp
40 return p
41 vresult.set_color_plane_callback(s0.size, get_color_plane)
42
43def blend(vspec, rspec):
44 from chimera.specifier import evalSpec
45 vlist = evalSpec(vspec).models()
46 from VolumeViewer import Volume
47 vlist = [v for v in vlist if isinstance(v,Volume)]
48 res = evalSpec(rspec).models()
49 from _volume import Volume_Model
50 res = [v for v in res if isinstance(v,Volume_Model)]
51 if len(res) == 0:
52 res = Volume_Model()
53 res.name = 'blend'
54 from chimera import openModels
55 openModels.add([res], baseId = int(rspec.lstrip('#')))
56 else:
57 res = res[0]
58 blend_maps(vlist, res)
59
60if 'arguments' in globals() and len(arguments) == 2:
61 blend(*arguments)
62else:
63 from chimera import replyobj
64 replyobj.status('Need two arguments: runscript blend.py #1-3 #5')