class FrameInfo(HasTraits): """This holds information about each frame. This is to be used in :class:`Video` """ #: frame index index = Range(low='_low', high='_high') #: frame time time = Property(depends_on='index,fps', editor=RangeEditor(is_float=True, low_name='object._low_', high_name='duration')) #: duration of the movie duration = Float(1.) #: frame rate fps = Float(1.) #: number of frames n_frames = Long(1) view = View('index', 'time') _low = Int(0) _high = Property(depends_on='n_frames') _low_ = Float(0) def _get_time(self): return self.index / self.fps def _set_time(self, value): value = int(round(self.fps * value + 0.5)) if value > self.n_frames - 1: value = self.n_frames - 1 self.index = value def _get__high(self): return self.n_frames - 1
class MappingMarchingCubes(TVTKMapperWidget): operator = Instance(tvtk.MarchingCubes) mapper = Instance(tvtk.HierarchicalPolyDataMapper) vmin = Float vmax = Float auto_set = Bool(False) _val_redit = RangeEditor(format="%0.2f", low_name='vmin', high_name='vmax', auto_set=False, enter_set=True) traits_view = View( Item('value', editor=_val_redit), Item('auto_set'), Item('alpha', editor=RangeEditor( low=0.0, high=1.0, enter_set=True, auto_set=False, )), Item('lut_manager', show_label=False, editor=InstanceEditor(), style='custom')) def __init__(self, vmin, vmax, vdefault, **traits): HasTraits.__init__(self, **traits) self.vmin = vmin self.vmax = vmax trait = Range(float(vmin), float(vmax), value=vdefault) self.add_trait("value", trait) self.value = vdefault def _auto_set_changed(self, old, new): if new is True: self._val_redit.auto_set = True self._val_redit.enter_set = False else: self._val_redit.auto_set = False self._val_redit.enter_set = True def _value_changed(self, old, new): self.operator.set_value(0, new) self.post_call()
class MappingPlane(TVTKMapperWidget): plane = Instance(tvtk.Plane) _coord_redit = editor = RangeEditor(format="%0.2e", low_name='vmin', high_name='vmax', auto_set=False, enter_set=True) auto_set = Bool(False) traits_view = View( Item('coord', editor=_coord_redit), Item('auto_set'), Item('alpha', editor=RangeEditor(low=0.0, high=1.0, enter_set=True, auto_set=False)), Item('lut_manager', show_label=False, editor=InstanceEditor(), style='custom')) vmin = Float vmax = Float def _auto_set_changed(self, old, new): if new is True: self._coord_redit.auto_set = True self._coord_redit.enter_set = False else: self._coord_redit.auto_set = False self._coord_redit.enter_set = True def __init__(self, vmin, vmax, vdefault, **traits): HasTraits.__init__(self, **traits) self.vmin = vmin self.vmax = vmax trait = Range(float(vmin), float(vmax), value=vdefault) self.add_trait("coord", trait) self.coord = vdefault def _coord_changed(self, old, new): orig = self.plane.origin[:] orig[self.axis] = new self.plane.origin = orig self.post_call()
class HierarchyImporter(HasTraits): pf = Any min_grid_level = Int(0) max_level = Int(1) number_of_levels = Range(0, 13) max_import_levels = Property(depends_on='min_grid_level') field = Str("Density") field_list = List center_on_max = Bool(True) center = CArray(shape=(3, ), dtype='float64') cache = Bool(True) smoothed = Bool(True) show_grids = Bool(True) def _field_list_default(self): fl = self.pf.h.field_list df = self.pf.h.derived_field_list fl.sort() df.sort() return fl + df default_view = View( Item('min_grid_level', editor=RangeEditor(low=0, high_name='max_level')), Item('number_of_levels', editor=RangeEditor(low=1, high_name='max_import_levels')), Item('field', editor=EnumEditor(name='field_list')), Item('center_on_max'), Item('center', enabled_when='not object.center_on_max'), Item('smoothed'), Item('cache', label='Pre-load data'), Item('show_grids'), buttons=OKCancelButtons) def _center_default(self): return [0.5, 0.5, 0.5] @cached_property def _get_max_import_levels(self): return min(13, self.pf.h.max_level - self.min_grid_level + 1)
class OutputSystemViewer(HasTraits): num_outputs = Property(Int(1), depends_on='runoutput.eigenmodes') @cached_property def _get_num_outputs(self): ret = len(self.runoutput.eigenmodes) #print 'num_outputs', ret return ret run_number = Int(1) #Range(low=1, high='num_outputs') runoutput = Instance(RunOutput) modes = Property(List(EigenMode), depends_on='runoutput.eigenmodes,run_number') @cached_property def _get_modes(self): return self.runoutput.eigenmodes[self.run_number - 1] modes_array = Property(Array(numpy.complex), depends_on='modes') @cached_property def _get_modes_array(self): ret = numpy.empty((len(self.modes), 13), dtype='complex') for i, mode in enumerate(self.modes): ret[i, 0] = mode.eigenvalue #.real #ret[i,1] = mode.eigenvalue.imag ret[i, 1:] = mode.eigenvector #print mode.eigenvector return ret matrix = Property(Instance(EigenMatrix), depends_on='runoutput.eigenmatrix,run_number') @cached_property def _get_matrix(self): #print len(self.runoutput.eigenmatrix) return self.runoutput.eigenmatrix[self.run_number - 1] view = View(Item('run_number', editor=RangeEditor(mode='spinner')), Group( Item('modes_array', editor=TabularEditor(adapter=ModesAdapter(), operations=[], editable=False), show_label=False), Item('object.matrix.matrix', editor=TabularEditor(adapter=EigenMatrixAdapter(), operations=[], editable=False), show_label=False)), resizable=True)
class TestRangeEditor(HasTraits): x = Float low = Float(123.123) high = Float(1123.123) list = List( Float(editor=RangeEditor( low_name='low', high_name='high', # These force the large range # slider to be used. low=100.0, high=10000.123))) view = View( Item( name='x', editor=RangeEditor( low_name='low', high_name='high', # These force the large range # slider to be used. low=100.0, high=10000.123)), Item('list'), resizable=True)
class SettableCachedProperty(HasTraits): a = Range(1, 10) b = Range(1, 10) c = Property(Int) d = Property view = View(Item('a'), Item('b'), '_', Item('c', editor=RangeEditor(low=1, high=100, mode='slider')), Item('c'), '_', Item('d', editor=RangeEditor(low=1, high=400, mode='slider')), Item('d'), width=0.3) @property_depends_on('a,b', settable=True) def _get_c(self): return (self.a * self.b) @property_depends_on('c') def _get_d(self): return (self.c + self.c)
class ImageTimeseriesViewer(BaseDataViewer): plots = Dict plotdata = Instance(ArrayPlotData) image = Any time_index = Int time_points = Int time = Any traits_view = View( Tabbed( HSplit( VGroup( Item('plot', editor=ComponentEditor(), show_label=False, resizable=True, label='View'), Item("time_index", style='custom', editor=RangeEditor(low=0, high_name='time_points')), Item("time", style='readonly'), ), Item('tasks', style='custom', show_label=False, label='Tasks'), ), Item('results', style='custom', show_label=False, label='Results'), ), ) def _time_points_default(self): return self.data.shape[0] - 1 def _time_index_default(self): return 0 def _time_default(self): return self.get_data_time(0, 0) def _plotdata_default(self): data = self.get_data_slice(0, 0) plotdata = ArrayPlotData() plotdata.set_data('xy', data) return plotdata def _time_index_changed(self): self.select_xy_slice(self.time_index) def select_xy_slice(self, t): data = self.get_data_slice(t, 0) self.time = self.get_data_time(t, 0) self.plotdata.set_data('xy', data) self.image.invalidate_and_redraw() def reset(self): pass def redraw(self): self.image.invalidate_and_redraw() def get_plot(self): pixel_sizes = self.data_source.pixel_sizes shape = self.data.shape[1:] m = min(pixel_sizes) s = [int(d * sz / m) for d, sz in zip(shape, pixel_sizes)] plot_sizes = dict(xy=(s[1], s[0])) plot = Plot( self.plotdata, padding=30, fixed_preferred_size=plot_sizes['xy'], ) image = plot.img_plot('xy', colormap=bone)[0] image.overlays.append(ZoomTool(image)) image.tools.append(PanTool(image, drag_button='right')) imgtool = ImageInspectorTool(image) image.tools.append(imgtool) overlay = ImageInspectorOverlay(component=image, bgcolor='white', image_inspector=imgtool) image.overlays.append(overlay) self.image = image self.plots = dict(xy=image) return plot
# -*- coding: utf-8 -*-
class MultiSelections(HasTraits): """ Object used to store analysis objects in List of points """ selections = List(RectangleSelection) selection = Instance(RectangleSelection, transient=True) #: default filename for points load, save filename = File() add_point = Button() load = Button() save = Button() index_high = Property(Int, depends_on='selections', transient=True) index = Property(Int, depends_on='selection,index_high', transient=True) updated = Event() _update = Bool(True) view = View(Item('index', editor=RangeEditor(low=0, high_name='index_high', is_float=False, mode='spinner')), HGroup( Item('add_point', show_label=False, springy=True), Item('load', show_label=False, springy=True), Item('save', show_label=False, springy=True), ), '_', VGroup( Item('selections@', id='notebook', show_label=False, editor=ListEditor(use_notebook=True, deletable=True, selected='selection', export='DockWindowShell', page_name='.name')), ), id='enthought.traits.ui.demo.Traits UI Demo.Advanced.' 'List_editor_notebook_selection_demo', dock='horizontal', resizable=True, height=-0.5) def _load_fired(self): f = FileDialog(action='open', title='Load points', default_path=self.filename, wildcard='*.points') if f.open() == OK: self.filename = f.path self.from_file() def _save_fired(self): f = FileDialog(action='save as', title='Save points', default_path=self.filename, wildcard='*.points') if f.open() == OK: self.filename = f.path self.to_file() def _selection_default(self): return self.selections[0] def _get_index_high(self): return len(self.selections) - 1 def _add_point_fired(self): self._update = False point = (self.selections[self.index]).clone_traits() point.name = 'point ' + str(len(self.selections)) self.selections.append(point) self.selection = self.selections[-1] self._update = True self.update() def _selections_default(self): return POINTS @on_trait_change('selections[]') def _update_names(self): #update point names for i, point in enumerate(self.selections): point.name = 'point ' + str(i) def _get_index(self): try: return self.selections.index(self.selection) except: return self.index_high self.update() def _set_index(self, value): self.selection = self.selections[value] def from_file(self): """Reads selections from file """ with open(self.filename, 'rb') as f: self._update = False self.selections = pickle.load(f) self.index = 0 self._update = True self.update() def to_file(self): """Stores selections to file """ with open(self.filename, 'wb') as f: pickle.dump(self.selections, f) @on_trait_change('selection.updated') def update(self): """ Notify update """ if self._update: self.updated = True
class DataSetBrowser(HasTraits): """ A class that allows browsing of a DataSet object with sliders to navigate through plates, images within plates, and objects within images. """ view = View(VGroup( HGroup( Item('image_plots', editor=ComponentEditor(size=(50, 50)), show_label=False), ), HGroup( Item('plots', editor=ComponentEditor(size=(250, 300)), show_label=False), ), Group( Item('object_index', editor=RangeEditor(low=1, high_name='num_objects', mode='slider')), Item('image_index', editor=RangeEditor(low=1, high_name='num_images', mode='slider')), Item('plate_index', editor=RangeEditor(low=1, high_name='num_plates', mode='slider')), ), HGroup( Item('num_internal_knots', label='Number of internal spline knots'), Item('smoothing', label='Amount of smoothing applied'))), height=700, width=800, resizable=True) # Chaco plot gfp_plot = Instance(Plot) sil_plot = Instance(Plot) image_plots = Instance(HPlotContainer) rotated_plot = Instance(Plot) plots = Instance(GridPlotContainer) #legends = Instance(VPlotContainer) # DataSet being viewed dataset = Instance(DataSet) # Plate object currently being examined current_plate = Instance(Plate) # ImageSilhouette object currently being examined current_image = Instance(ImageSilhouette) # ObjectSilhouette object currently being examined current_object = Instance(ObjectSilhouette) # Index traits that control the selected plate/image/object plate_index = Int(1) image_index = Int(1) object_index = Int(1) # Number of plates, images, and objects in the current context num_plates = Property(Int, depends_on='dataset') num_images = Property(Int, depends_on='current_plate') num_objects = Property(Int, depends_on='current_image') num_internal_knots = Range(1, 20, 3) smoothing = Range(0.0, 2.0, 0) def __init__(self, *args, **kwargs): """Construct a DataSetBrowser from the specified DataSet object.""" super(DataSetBrowser, self).__init__(*args, **kwargs) self.current_plate = self.dataset[self.plate_index - 1] self.current_image = self.current_plate[self.image_index - 1] self.current_object = self.current_image[self.object_index - 1] self.sil_plot = Plot() self._object_index_changed() ######################### Private interface ########################## def _plate_index_changed(self): """Handle the plate index changing.""" try: self.current_plate = self.dataset[self.plate_index - 1] except IndexError: self.current_plate = None self.image_index = 1 self._image_index_changed() def _image_index_changed(self): """Handle the image index slider changing.""" try: self.current_image = self.current_plate[self.image_index - 1] except IndexError: self.current_image = None self.object_index = 1 self._object_index_changed() def _object_index_changed(self): """Handle object index slider changing.""" try: self.current_object = self.current_image[self.object_index - 1] # Display sil = self.current_object.image self._update_img_plot('sil_plot', sil, 'Extracted mask') # .T to get major axis horizontal rotated = self.current_object.aligned_version.image.T self._update_img_plot('rotated_plot', rotated, 'Aligned mask') self.image_plots = HPlotContainer(self.sil_plot, self.rotated_plot, valign="top", bgcolor="transparent") self._update_spline_plot() except IndexError: self.current_object = None def _get_num_plates(self): """Return the number of plates in the currently viewed dataset.""" return len(self.dataset) def _get_num_images(self): """Return the number of images in the currently viewed plate.""" return len(self.current_plate) def _get_num_objects(self): """Return the number of objects in the currently viewed image.""" return len(self.current_image) def _update_img_plot(self, plot_name, image, title): """Update an image plot.""" plotdata = ArrayPlotData(imagedata=image) xbounds = (0, image.shape[1] - 1) ybounds = (0, image.shape[0] - 1) plot = Plot(plotdata) plot.aspect_ratio = float(xbounds[1]) / float(ybounds[1]) plot.img_plot("imagedata", colormap=bone, xbounds=xbounds, ybounds=ybounds) plot.title = title setattr(self, plot_name, plot) getattr(self, plot_name).request_redraw() def _update_spline_plot(self): """Update the spline plot.""" knots = np.mgrid[0:1:((self.num_internal_knots + 2) * 1j)][1:-1] medial_repr = self.current_object.aligned_version.medial_repr dependent_variable = np.mgrid[0:1:(medial_repr.length * 1j)] laplacian = ndimage.gaussian_laplace(medial_repr.width_curve, self.smoothing, mode='constant', cval=np.nan) m_spline = LSQUnivariateSpline(dependent_variable, medial_repr.medial_axis, knots) w_spline = LSQUnivariateSpline(dependent_variable, medial_repr.width_curve, knots) # sample at double the frequency spl_dep_var = np.mgrid[0:1:(medial_repr.length * 2j)] plots = self.plots if plots is None: # Render the plot for the first time. plotdata = ArrayPlotData( medial_x=dependent_variable, medial_y=medial_repr.medial_axis, width_x=dependent_variable, width_y=medial_repr.width_curve, medial_spline_x=spl_dep_var, medial_spline_y=m_spline(spl_dep_var), width_spline_x=spl_dep_var, width_spline_y=w_spline(spl_dep_var), laplacian_y=laplacian, ) plot = Plot(plotdata) # Width data self._width_data_renderer, = plot.plot( ("width_x", "width_y"), type="line", color="blue", name="Original width curve data") filterdata = ArrayPlotData(x=dependent_variable, laplacian=laplacian) filterplot = Plot(filterdata) self._laplacian_renderer, = filterplot.plot( ("x", "laplacian"), type="line", color="black", name="Laplacian-of-Gaussian") # Titles for plot & axes plot.title = "Width curves" plot.x_axis.title = "Normalized position on medial axis" plot.y_axis.title = "Fraction of medial axis width" # Legend mangling stuff legend = plot.legend plot.legend = None legend.set(component=None, visible=True, resizable="", auto_size=True, bounds=[250, 70], padding_top=plot.padding_top) filterlegend = filterplot.legend filterplot.legend = None filterlegend.set(component=None, visible=True, resizable="", auto_size=True, bounds=[250, 50], padding_top=filterplot.padding_top) self.plots = GridPlotContainer(plot, legend, filterplot, filterlegend, shape=(2, 2), valign="top", bgcolor="transparent") else: # Update the real width curve self._width_data_renderer.index.set_data(dependent_variable) self._width_data_renderer.value.set_data(medial_repr.width_curve) # Render the Laplacian self._laplacian_renderer.index.set_data(dependent_variable) self._laplacian_renderer.value.set_data(laplacian) def _num_internal_knots_changed(self): """Hook to update the plot when we change the number of knots.""" self._update_spline_plot() def _smoothing_changed(self): """Hook to update the plot when we change the smoothing parameter.""" self._update_spline_plot()
class TFGaussian(HasTraits): center = Range(low = 'left_edge', high = 'right_edge') left_edge = DelegatesTo('tf') right_edge = DelegatesTo('tf') tf = Any width = Property rwidth = Range(0.0, 0.5, 0.05) red = Range(0.0, 1.0, 0.5) green = Range(0.0, 1.0, 0.5) blue = Range(0.0, 1.0, 0.5) alpha = Range(0.0, 1.0, 1.0) traits_view = View(VGroup( HGroup( Item('center', editor=RangeEditor(format='%0.4f')), Item('rwidth', label='Width', editor=RangeEditor(format='%0.4f')), ), HGroup( Item('red', editor=RangeEditor(format='%0.4f')), Item('green', editor=RangeEditor(format='%0.4f')), Item('blue', editor=RangeEditor(format='%0.4f')), Item('alpha', editor=RangeEditor(format='%0.4f')) ), show_border=True,), ) def _get_width(self): width = self.rwidth * (self.tf.right_edge - self.tf.left_edge) return width def _center_default(self): return (self.left_edge + self.right_edge)/2.0 def _width_default(self): return (self.right_edge - self.left_edge)/20.0 def _red_changed(self): self.tf._redraw() def _green_changed(self): self.tf._redraw() def _blue_changed(self): self.tf._redraw() def _alpha_changed(self): self.tf._redraw() def _center_changed(self): self.tf._redraw() def _height_changed(self): self.tf._redraw() def _rwidth_changed(self): self.tf._redraw()
class DynamicRangeEditor(HasPrivateTraits): """ Defines an editor for dynamic ranges (i.e. ranges whose bounds can be changed at run time). """ # The value with the dynamic range: value = Float # This determines the low end of the range: low = Range(0.0, 10.0, 0.0) # This determines the high end of the range: high = Range(20.0, 100.0, 20.0) # An integer value: int_value = Int # This determines the low end of the integer range: int_low = Range(0, 10, 0) # This determines the high end of the range: int_high = Range(20, 100, 20) # Traits view definitions: view = View( # Dynamic simple slider demo: Group(Item('value', editor=RangeEditor(low_name='low', high_name='high', format='%.1f', label_width=28, mode='auto')), '_', Item('low'), Item('high'), '_', Label('Move the Low and High sliders to change the range of ' 'Value.'), label='Simple Slider'), # Dynamic large range slider demo: Group(Item('value', editor=RangeEditor(low_name='low', high_name='high', format='%.1f', label_width=28, mode='xslider')), '_', Item('low'), Item('high'), '_', Label('Move the Low and High sliders to change the range of ' 'Value.'), label='Large Range Slider'), # Dynamic spinner demo: Group(Item('int_value', editor=RangeEditor(low=0, high=20, low_name='int_low', high_name='int_high', format='%d', is_float=False, label_width=28, mode='spinner')), '_', Item('int_low'), Item('int_high'), '_', Label('Move the Low and High sliders to change the range of ' 'Value.'), label='Spinner'), title='Dynamic Range Editor Demonstration', buttons=['OK'], resizable=True)
class LineSelectorTask(BaseViewerTask): min_x = min_y = Int(0) max_x = Int max_y = Int corner_xll = Int(editor=RangeEditor( low_name='min_x', high_name='corner_xur', is_float=False)) corner_yll = Int(editor=RangeEditor( low_name='min_y', high_name='corner_yur', is_float=False)) corner_xur = Int(editor=RangeEditor( low_name='corner_xll', high_name='max_x', is_float=False)) corner_yur = Int(editor=RangeEditor( low_name='corner_yll', high_name='max_y', is_float=False)) cursor_xyll = Instance(BaseCursorTool) cursor_xyur = Instance(BaseCursorTool) have_cursors = Bool(False) visible = Bool(True) traits_view = View( VGroup( Item('visible', label='Visible'), Item('corner_xll', label='Xll'), Item('corner_yll', label='Yll'), Item('corner_xur', label='Xur'), Item('corner_yur', label='Yur'), #Item('create_button', show_label = False), #Item('message', show_label=False, style='readonly'), )) def startup(self): self._create_cursors() def _visible_changed(self): if self.have_cursors: b = self.visible self.cursor_xyll.visible = b self.cursor_xyur.visible = b self.viewer.redraw() def _max_x_default(self): return self.viewer.data.shape[2] def _max_y_default(self): return self.viewer.data.shape[1] @property def corner_ll(self): return self.corner_xll, self.corner_yll @property def corner_ur(self): return self.corner_xur, self.corner_yur def _corner_xll_changed(self): if self.have_cursors: self.cursor_xyll.current_position = (self.corner_xll, self.corner_yll) def _corner_yll_changed(self): if self.have_cursors: self.cursor_xyll.current_position = (self.corner_xll, self.corner_yll) def _corner_xur_changed(self): if self.have_cursors: self.cursor_xyur.current_position = (self.corner_xur, self.corner_yur) def _corner_yur_changed(self): if self.have_cursors: self.cursor_xyur.current_position = (self.corner_xur, self.corner_yur) @on_trait_change('cursor_xyll.current_position') def _on_cursor_xyll_change(self): self.corner_xll, self.corner_yll = self.cursor_xyll.current_position @on_trait_change('cursor_xyur.current_position') def _on_cursor_xyur_change(self): self.corner_xur, self.corner_yur = self.cursor_xyur.current_position def _create_cursors(self): plot_name = 'xy' plot = self.viewer.plots[plot_name] a, b = plot_name cursor = CursorTool(plot, color='green', marker=LowerLeftMarker(), marker_size=5, threshold=5) plot.overlays.append(cursor) cursor.current_position = eval('self.corner_%sll, self.corner_%sll' % (a, b)) setattr(self, 'cursor_%sll' % (plot_name), cursor) cursor = CursorTool(plot, color='green', marker=UpperRightMarker(), marker_size=5, threshold=5) plot.overlays.append(cursor) cursor.current_position = eval('self.corner_%sur, self.corner_%sur' % (a, b)) setattr(self, 'cursor_%sur' % (plot_name), cursor) self.have_cursors = True
class VMPlotTab(PlotFrameTab): pf = Instance(EnzoStaticOutput) figure = Instance(Figure, args=()) field = DelegatesTo('plot_spec') field_list = DelegatesTo('plot_spec') plot = Instance(VMPlot) axes = Instance(Axes) disp_width = Float(1.0) unit = Str('unitary') min_width = Property(Float, depends_on=['pf', 'unit']) max_width = Property(Float, depends_on=['pf', 'unit']) unit_list = Property(depends_on='pf') smallest_dx = Property(depends_on='pf') traits_view = View(VGroup( HGroup(Item('figure', editor=MPLVMPlotEditor(), show_label=False)), HGroup( Item('disp_width', editor=RangeEditor(format="%0.2e", low_name='min_width', high_name='max_width', mode='logslider', enter_set=True), show_label=False, width=400.0), Item('unit', editor=EnumEditor(name='unit_list')), ), HGroup(Item('field', editor=EnumEditor(name='field_list')), )), resizable=True) def __init__(self, **traits): super(VMPlotTab, self).__init__(**traits) self.axes = self.figure.add_subplot(111, aspect='equal') def _field_changed(self, old, new): self.plot.switch_z(new) self._redraw() @cached_property def _get_min_width(self): return 50.0 * self.smallest_dx * self.pf[self.unit] @cached_property def _get_max_width(self): return self.pf['unitary'] * self.pf[self.unit] @cached_property def _get_smallest_dx(self): return self.pf.h.get_smallest_dx() @cached_property def _get_unit_list(self): return self.pf.units.keys() def _unit_changed(self, old, new): self.disp_width = self.disp_width * self.pf[new] / self.pf[old] def _disp_width_changed(self, old, new): self.plot.set_width(new, self.unit) self._redraw() def _redraw(self): self.figure.canvas.draw() def recenter(self, event): xp, yp = event.xdata, event.ydata dx = abs(self.plot.xlim[0] - self.plot.xlim[1]) / self.plot.pix[0] dy = abs(self.plot.ylim[0] - self.plot.ylim[1]) / self.plot.pix[1] x = (dx * xp) + self.plot.xlim[0] y = (dy * yp) + self.plot.ylim[0] xi = lagos.x_dict[self.axis] yi = lagos.y_dict[self.axis] cc = self.center[:] cc[xi] = x cc[yi] = y self.plot.data.center = cc[:] self.plot.data.set_field_parameter('center', cc.copy()) self.center = cc
class BoxSelectorTask(BaseViewerTask): # corners of a volume slice min_x = min_y = min_z = Int(0) max_x = Int max_y = Int max_z = Int corner_xll = Int(editor=RangeEditor( low_name='min_x', high_name='corner_xur', is_float=False)) corner_yll = Int(editor=RangeEditor( low_name='min_y', high_name='corner_yur', is_float=False)) corner_zll = Int(editor=RangeEditor( low_name='min_z', high_name='corner_zur', is_float=False)) corner_xur = Int(editor=RangeEditor( low_name='corner_xll', high_name='max_x', is_float=False)) corner_yur = Int(editor=RangeEditor( low_name='corner_yll', high_name='max_y', is_float=False)) corner_zur = Int(editor=RangeEditor( low_name='corner_zll', high_name='max_z', is_float=False)) # cursors for volume slice cursor_xyll = Instance(BaseCursorTool) cursor_xyur = Instance(BaseCursorTool) cursor_xzll = Instance(BaseCursorTool) cursor_xzur = Instance(BaseCursorTool) cursor_zyll = Instance(BaseCursorTool) cursor_zyur = Instance(BaseCursorTool) have_cursors = Bool(False) visible = Bool(True) create_button = Button('Create new view with selected box') message = Str traits_view = View( VGroup(Item('visible', label='Visible'), Item('corner_xll', label='Xll'), Item('corner_yll', label='Yll'), Item('corner_zll', label='Zll'), Item('corner_xur', label='Xur'), Item('corner_yur', label='Yur'), Item('corner_zur', label='Zur'), Item('create_button', show_label=False), Item('message', show_label=False, style='readonly'))) def startup(self): self._create_cursors() def _visible_changed(self): if self.have_cursors: b = self.visible self.cursor_xyll.visible = b self.cursor_xzll.visible = b self.cursor_zyll.visible = b self.cursor_xyur.visible = b self.cursor_xzur.visible = b self.cursor_zyur.visible = b self.viewer.redraw() def _max_x_default(self): return self.viewer.data.shape[2] def _max_y_default(self): return self.viewer.data.shape[1] def _max_z_default(self): return self.viewer.data.shape[0] def _corner_xur_default(self): return self.max_x def _corner_yur_default(self): return self.max_y def _corner_zur_default(self): return self.max_z @property def corner_ll(self): return self.corner_xll, self.corner_yll, self.corner_zll @property def corner_ur(self): return self.corner_xur, self.corner_yur, self.corner_zur def _corner_xll_changed(self): if self.have_cursors: if self.cursor_xyll is not None: self.cursor_xyll.current_position = (self.corner_xll, self.corner_yll) if self.cursor_xzll is not None: self.cursor_xzll.current_position = (self.corner_xll, self.corner_zll) def _corner_yll_changed(self): if self.have_cursors: if self.cursor_xyll is not None: self.cursor_xyll.current_position = (self.corner_xll, self.corner_yll) if self.cursor_zyll is not None: self.cursor_zyll.current_position = (self.corner_zll, self.corner_yll) def _corner_zll_changed(self): if self.have_cursors: if self.cursor_xzll is not None: self.cursor_xzll.current_position = (self.corner_xll, self.corner_zll) if self.cursor_zyll is not None: self.cursor_zyll.current_position = (self.corner_zll, self.corner_yll) def _corner_xur_changed(self): if self.have_cursors: if self.cursor_xyur is not None: self.cursor_xyur.current_position = (self.corner_xur, self.corner_yur) if self.cursor_xzur is not None: self.cursor_xzur.current_position = (self.corner_xur, self.corner_zur) def _corner_yur_changed(self): if self.have_cursors: if self.cursor_xyur is not None: self.cursor_xyur.current_position = (self.corner_xur, self.corner_yur) if self.cursor_zyur is not None: self.cursor_zyur.current_position = (self.corner_zur, self.corner_yur) def _corner_zur_changed(self): if self.have_cursors: if self.cursor_xzur is not None: self.cursor_xzur.current_position = (self.corner_xur, self.corner_zur) if self.cursor_zyur is not None: self.cursor_zyur.current_position = (self.corner_zur, self.corner_yur) @on_trait_change('cursor_xyll.current_position') def _on_cursor_xyll_change(self): self.corner_xll, self.corner_yll = self.cursor_xyll.current_position @on_trait_change('cursor_xzll.current_position') def _on_cursor_xzll_change(self): self.corner_xll, self.corner_zll = self.cursor_xzll.current_position @on_trait_change('cursor_zyll.current_position') def _on_cursor_zyll_change(self): self.corner_zll, self.corner_yll = self.cursor_zyll.current_position @on_trait_change('cursor_xyur.current_position') def _on_cursor_xyur_change(self): self.corner_xur, self.corner_yur = self.cursor_xyur.current_position @on_trait_change('cursor_xzur.current_position') def _on_cursor_xzur_change(self): self.corner_xur, self.corner_zur = self.cursor_xzur.current_position @on_trait_change('cursor_zyur.current_position') def _on_cursor_zyur_change(self): self.corner_zur, self.corner_yur = self.cursor_zyur.current_position def _create_cursors(self): for plot_name, plot in self.viewer.plots.items(): if plot_name not in ['xy', 'xz', 'zy']: continue a, b = plot_name cursor = CursorTool(plot, color='green', marker=LowerLeftMarker(), marker_size=5, threshold=5) plot.overlays.append(cursor) cursor.current_position = eval( 'self.corner_%sll, self.corner_%sll' % (a, b)) setattr(self, 'cursor_%sll' % (plot_name), cursor) cursor = CursorTool(plot, color='green', marker=UpperRightMarker(), marker_size=5, threshold=5) plot.overlays.append(cursor) cursor.current_position = eval( 'self.corner_%sur, self.corner_%sur' % (a, b)) setattr(self, 'cursor_%sur' % (plot_name), cursor) self.have_cursors = True def _create_button_fired(self): ll, ur = self.corner_ll, self.corner_ur data_source = ArrayDataSource(original_source=self.viewer.data_source, kind=self.viewer.data_source.kind, data=self.viewer.data[ll[2]:ur[2], ll[1]:ur[1], ll[0]:ur[0]]) viewer = self.viewer.__class__(data_source=data_source) self.viewer.add_result(viewer) viewer.copy_tasks(self.viewer) self.message = 'Last box selection is in Results/%s tab.' % ( viewer.name)
class RectangleSelections(HasTraits): """ Object used to store analysis objects in List of points """ selections = List(RectangleSelection) selection = Instance(RectangleSelection,transient = True) #: default filename for points load, save filename = File() add_point = Button() load = Button() save = Button() index_high = Property(Int,depends_on = 'selections',transient = True) index = Property(Int, depends_on = 'selection,index_high',transient = True) updated = Event() _update = Bool(True) view = View( Item('index' , editor = RangeEditor( low = 0, high_name = 'index_high', is_float = False, mode = 'spinner' )), HGroup( Item('add_point', show_label = False, springy = True), Item('load', show_label = False, springy = True), Item('save', show_label = False, springy = True), ), '_', VGroup( Item( 'selections@', id = 'notebook', show_label = False, editor = ListEditor( use_notebook = True, deletable = True, selected = 'selection', export = 'DockWindowShell', page_name = '.name' ) ), ), dock = 'horizontal' , resizable = True, height = -0.5) def _load_fired(self): f = FileDialog(action = 'open', title = 'Load points', default_path = self.filename, wildcard = '*.points') if f.open() == OK: self.filename = f.path self.from_file(f.path) def _save_fired(self): f = FileDialog(action = 'save as', title = 'Save points', default_path = self.filename, wildcard = '*.points') if f.open() == OK: self.filename = f.path self.to_file(f.path, self.selections) def _selection_default(self): return self.selections[0] def _get_index_high(self): return len(self.selections)-1 def _add_point_fired(self): self._update = False point = (self.selections[self.index]).clone_traits() point.name = 'point ' + str(len(self.selections)) self.selections.append(point) self.selection = self.selections[-1] self._update = True self.update() def _selections_default(self): return POINTS # @on_trait_change('selections[]') # def _update_names(self): # #update point names # for i, point in enumerate(self.selections): # point.name = 'point ' + str(i) def _get_index(self): try: return self.selections.index(self.selection) except: return self.index_high self.update() def _set_index(self, value): self.selection = self.selections[value] def from_file(self, filename): """Reads selections from file """ selections = [] with open(filename, 'rb') as f: for line in f: selections.append(RectangleSelection(**safe_eval(line))) self.selections = selections self._update = True self.update() return selections def to_file(self, filename, selections): """Stores selections to file """ with open(filename, 'wb') as f: for s in selections: kw = s.get('width', 'height', 'name') kw['center'] = tuple(s.center) f.write(str(kw)) f.write('\n') @on_trait_change('selection.updated') def update(self): """ Notify update """ if self._update: self.updated = True