| 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 | #
|
|---|
| 17 | def 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 |
|
|---|
| 43 | def 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 |
|
|---|
| 60 | if 'arguments' in globals() and len(arguments) == 2:
|
|---|
| 61 | blend(*arguments)
|
|---|
| 62 | else:
|
|---|
| 63 | from chimera import replyobj
|
|---|
| 64 | replyobj.status('Need two arguments: runscript blend.py #1-3 #5')
|
|---|