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 Tristan Croll, 8 years ago

OK, yep - re-implementing Volume._update_drawings() in the subclass to check and re-zone after running super._update_drawings() gets things working for me again.

comment:2 by Tom Goddard, 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 Tom Goddard, 8 years ago

Resolution: fixed
Status: assignedclosed

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.

Note: See TracTickets for help on using tickets.