Opened 8 years ago
Closed 8 years ago
#962 closed defect (fixed)
Can't re-contour and re-zone Volume in same graphics update
Reported by: | Tristan Croll | Owned by: | Tom Goddard |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | Graphics | Version: | |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Notify when closed: | Platform: | all | |
Project: | ChimeraX |
Description
For example, my Mousemode method below acts on a Volume object (or subclass such as my Clipper Xmap). The adjust_threshold_level()
method calls set_parameters()
to set the new contours, then I check the Volume object for an added _surface_zone
property (which just contains the coordinate(s) and mask radius) and calls surface_zone()
if it finds it. If I understand correctly, the problem is that with the new VolumeUpdateManager implementation, the changes to the triangle mask get over-written at the next redraw, so the results of the surface_zone()
call are thrown away. This breaks things for me in a few different places - ISOLDE relies fairly heavily on the ability to change contours on masked maps.
Looks like I can work around it for my derived Volume classes by re-implementing _update_drawings()
, but an official solution would be nice.
def wheel(self, event): d = event.wheel_value() v = self.selector.picked_volume if v is not None: self.target_volume = v sd = v.mean_sd_rms()[1] step = d/30 * sd rep, levels = adjust_threshold_level(v, step, self.symmetrical) lsig = tuple(l/sd for l in levels) if rep != 'solid': lstr = ', '.join(format(l, '.3f') for l in levels) sstr = ', '.join(format(s, '.3f') for s in lsig) self.session.logger.status('Volume {} contour level(s): {} ({} sigma)'.format(v.name, lstr, sstr)) if hasattr(v, '_surface_zone'): sz = v._surface_zone coords = sz.all_coords distance = sz.distance if coords is not None: from chimerax.core.surface.zone import surface_zone surface_zone(v, coords, distance)
Change History (3)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
My change to Volume graphics updating a few days ago means that the contour surface is not updated until the volume is drawn. So when you set a new level then try to mask the surface using a zone before the next draw, the surface has not been updated, and when it gets updated the zone mask is cleared as you describe. I think the best way to handle this situation is that after you change the contour level with volume.set_parameters() then you call volume.update_drawings() before doing the surface zone. Before my changes a few days ago set_parameters() did this for you. But my change was to allow more control of when the surface gets recomputed which is important for optimizing performance -- the case I was handling was multi-channel microscopy data where the displayed volume bounds are changed and channels that are not displayed had to be recomputed with the older code but now will not be recomputed allowing for better performance.
Currently the Volume._update_drawings() method is private and I will remove the leading underscore and make it public. For today I suggest you call the private method. I am on vacation today and will not make this fix until next week.
comment:3 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I renamed Volume._update_drawings() to Volume.update_drawings() making it public, and calling that if you change surface level and then want to color the surface before it is drawn and calculated is the recommended solution.
OK, yep - re-implementing
Volume._update_drawings()
in the subclass to check and re-zone after runningsuper._update_drawings()
gets things working for me again.