class Plot2dPane(TraitsTaskPane): #### 'ITaskPane' interface ################################################ id = "example.attractors.plot_2d_pane" name = "Plot 2D Pane" #### 'Plot2dPane' interface ############################################### active_model = Instance(IPlottable2d) models = List(IPlottable2d) plot_type = Property(Str, depends_on="active_model.plot_type") title = Property(Str, depends_on="active_model.name") x_data = Property(depends_on="active_model.x_data") y_data = Property(depends_on="active_model.y_data") x_label = Property(Str, depends_on="active_model.x_label") y_label = Property(Str, depends_on="active_model.y_label") view = View( HGroup( Label("Model: "), Item("active_model", editor=EnumEditor(name="_enum_map")), show_labels=False, ), ChacoPlotItem( "x_data", "y_data", show_label=False, resizable=True, orientation="h", marker="pixel", marker_size=1, type_trait="plot_type", title="", x_label_trait="x_label", y_label_trait="y_label", color="blue", bgcolor="white", border_visible=False, border_width=1, ), resizable=True, ) #### Private traits ####################################################### _enum_map = Dict(IPlottable2d, Str) ########################################################################### # Protected interface. ########################################################################### #### Trait property getters/setters ####################################### def _get_plot_type(self): return self.active_model.plot_type if self.active_model else "line" def _get_title(self): return self.active_model.name if self.active_model else "" def _get_x_data(self): return self.active_model.x_data if self.active_model else [] def _get_y_data(self): return self.active_model.y_data if self.active_model else [] def _get_x_label(self): return self.active_model.x_label if self.active_model else "" def _get_y_label(self): return self.active_model.y_label if self.active_model else "" #### Trait change handlers ################################################ @on_trait_change("models[]") def _update_models(self): # Make sure that the active model is valid with the new model list. if self.active_model not in self.models: self.active_model = self.models[0] if self.models else None # Refresh the EnumEditor map. self._enum_map = dict((model, model.name) for model in self.models)
def channel_traits_view(self): return View(HGroup( Item('channel', editor=EnumEditor(name='handler.context.channels')), Item('scale')), handler=self)
def traits_view(self): v = View(Item('name', editor=EnumEditor(name='names'))) return v
def traits_view(self): pgrp = HGroup(UItem('stage_manager.calibrated_position_entry', tooltip='Enter a position e.g 1 for a hole, ' 'or 3,4 for X,Y'), Item('stage_manager.keep_images_open', enabled_when='stage_manager.autocenter_manager' '.use_autocenter', label='Keep Images Open', tooltip='If checked do not automatically close ' 'autocentering images when move finished'), label='Calibrated Position', show_border=True) hgrp = HGroup( UItem('stage_manager.stop_button'), UItem('stage_manager.home'), UItem('stage_manager.home_option', editor=EnumEditor(name='stage_manager.home_options'))) chgrp = VGroup( HGroup(Item('canvas.show_laser_position', label='Show Current'), UItem('canvas.crosshairs_color')), HGroup(Item('canvas.show_desired_position', label='Show Desired'), UItem('canvas.desired_position_color')), Item('canvas.crosshairs_kind', label='Kind'), Item('canvas.crosshairs_radius', label='Radius'), HGroup(Item('canvas.crosshairs_offsetx', label='Offset (mm)'), UItem('canvas.crosshairs_offsety')), Item('canvas.crosshairs_offset_color', label='Offset Color'), label='Crosshairs', show_border=True) cngrp = VGroup(Item('canvas.show_bounds_rect', label='Show Bounds Rectangle'), Item('canvas.show_grids', label='Show Grids'), chgrp, label='Canvas') mode = self.model.mode cagrp = VGroup(visible_when='use_video', label='Camera') if self.model.stage_manager.__class__.__name__ == 'VideoStageManager': mvgrp = VGroup( UItem('stage_manager.autocenter_manager', style='custom'), # UItem('stage_manager.autofocus_manager', style='custom'), UItem('stage_manager.zoom_calibration_manager', style='custom'), label='Machine Vision', show_border=True) recgrp = VGroup(HGroup( icon_button_editor('stage_manager.snapshot_button', 'camera', tooltip='Take a snapshot'), icon_button_editor('stage_manager.record', 'media-record', tooltip='Record video'), CustomLabel('stage_manager.record_label', color='red')), VGroup(Item('stage_manager.auto_save_snapshot'), Item('stage_manager.render_with_markup')), show_border=True, label='Recording') cfggrp = VGroup( Item('stage_manager.camera_zoom_coefficients', label='Zoom Coefficients')) cagrp.content.extend((cfggrp, recgrp, mvgrp)) cgrp = Group(UItem('stage_manager.stage_controller', style='custom', label='Axes'), cngrp, cagrp, layout='tabbed') if mode != 'client': pp_grp = UItem('stage_manager.points_programmer', label='Points', style='custom') cgrp.content.append(pp_grp) tc_grp = VGroup( UItem('tray_calibration.style', enabled_when='not tray_calibration.isCalibrating()'), HGroup( UItem('tray_calibration.calibrate', editor=ButtonEditor( label_value='tray_calibration.calibration_step'), width=-125), UItem('tray_calibration.add_holes_button', label='Add Holes'), UItem('tray_calibration.reset_holes_button', label='Reset Holes')), UItem('tray_calibration.holes_list', editor=ListStrEditor()), VGroup(HGroup( Item('tray_calibration.x', format_str='%0.3f', style='readonly'), Item('tray_calibration.y', format_str='%0.3f', style='readonly')), Item('tray_calibration.rotation', format_str='%0.3f', style='readonly'), Item('tray_calibration.scale', format_str='%0.4f', style='readonly'), Item('tray_calibration.error', format_str='%0.2f', style='readonly'), label='Results', show_border=True), # UItem('tray_calibration.calibrator', style='custom', # editor=InstanceEditor()), VGroup(CustomLabel('tray_calibration.calibration_help', color='green', height=75, width=300), label='Help', show_border=True), label='Calibration') cgrp.content.append(tc_grp) v = View(VGroup(hgrp, pgrp, cgrp)) return v
class PortChooser(HasTraits): port = Str(None) ports = List() mode = Enum(cnx_type_list) flow_control = Enum(flow_control_options_list) ip_port = Int(55555) ip_address = Str('192.168.0.222') choose_baud = Bool(True) baudrate = Int() refresh_ports_button = SVGButton(label='', tooltip='Refresh Port List', filename=resource_filename('console/images/fontawesome/refresh_blue.svg'), allow_clipping=False, width_padding=4, height_padding=4 ) traits_view = View( VGroup( Spring(height=8), HGroup( Spring(width=-2, springy=False), Item( 'mode', style='custom', editor=EnumEditor( values=cnx_type_list, cols=2, format_str='%s'), show_label=False)), HGroup( VGroup( Label('Serial Device:'), HGroup( Item('port', editor=EnumEditor(name='ports'), show_label=False, springy=True), Item('refresh_ports_button', show_label=False, padding=0, height=-20, width=-20), ), ), VGroup( Label('Baudrate:'), Item( 'baudrate', editor=EnumEditor(values=BAUD_LIST), show_label=False, visible_when='choose_baud'), Item( 'baudrate', show_label=False, visible_when='not choose_baud', style='readonly'), ), VGroup( Label('Flow Control:'), Item( 'flow_control', editor=EnumEditor( values=flow_control_options_list, format_str='%s'), show_label=False), ), visible_when="mode==\'Serial/USB\'"), HGroup( VGroup( Label('IP Address:'), Item( 'ip_address', label="IP Address", style='simple', show_label=False, height=-24), ), VGroup( Label('IP Port:'), Item( 'ip_port', label="IP Port", style='simple', show_label=False, height=-24), ), Spring(), visible_when="mode==\'TCP/IP\'"), ), buttons=['OK', 'Cancel'], default_button='OK', close_result=False, icon=icon, width=460, title='Swift Console v{0} - Select Interface'.format(CONSOLE_VERSION) ) def refresh_ports(self): """ This method refreshes the port list """ try: self.ports = [p for p, _, _ in s.get_ports()] except TypeError: pass def _refresh_ports_button_fired(self): self.refresh_ports() def __init__(self, baudrate=None): self.refresh_ports() # As default value, use the first city in the list: try: self.port = self.ports[0] except IndexError: pass if baudrate not in BAUD_LIST: self.choose_baud = False self.baudrate = baudrate
class IFSDesigner(HasTraits): color_maps = List current_map = Str("Greens") figure = Instance(Figure) # 控制绘图控件的Figure对象 ifs_triangle = Instance(IFSTriangles) add_button = Button(u"添加三角形") del_button = Button(u"删除三角形") settings = Instance(SettingManager) clear = Bool(True) view = View(VGroup( HGroup(Item("add_button"), Item("del_button"), Item("settings", style="custom"), Item("current_map", editor=EnumEditor(name="color_maps")), show_labels=False), Item("figure", editor=MPLFigureEditor(toolbar=False), show_label=False), ), resizable=True, height=450, width=800, title=u"迭代函数系统设计器", handler=IFSHandler()) def _settings_default(self): settings = SettingManager(target=self) return settings def _color_maps_default(self): return sorted(cm.cmap_d.keys()) def load_settings(self, setting): self.ifs_triangle.set_points(np.array(setting["points"])) self.current_map = setting["cmap"] def get_settings(self): return dict(points=self.ifs_triangle.points.tolist(), cmap=self.current_map) def _add_button_fired(self): """ 添加三角形按钮事件处理 """ self.ifs_triangle.add_triangle() def _del_button_fired(self): self.ifs_triangle.del_triangle() def ifs_calculate(self): if self.clear == True: self.clear = False self.initpos = [0, 0] p = self.ifs_triangle.get_areas() eqs = self.ifs_triangle.get_eqs() self.ifs = IFS(p, eqs, 100000, size=600) self.ax2.clear() self.img = self.ax2.imshow(np.ones((10, 10)), norm=LogNorm(), cmap=self.current_map, origin="lower") self.ax2.set_aspect("equal") self.ax2.axis("off") try: count = self.ifs.update() except ZeroDivisionError: count = None if count is None: return self.img.set_data(count) self.img.norm.autoscale(count) self.img.set_cmap(self.current_map) h, w = count.shape self.img.set_extent([0, w, 0, h]) self.ax2.set_xlim(0, w) self.ax2.set_ylim(0, h) self.figure.canvas.draw() @on_trait_change("ifs_triangle.version") def on_ifs_version_changed(self): """ 当三角形更新时,重新绘制所有的迭代点 """ self.clear = True def _figure_default(self): """ figure属性的缺省值,直接创建一个Figure对象 """ figure = Figure(figsize=(8, 4), dpi=100) self.ax = figure.add_subplot(121) self.ax2 = figure.add_subplot(122) self.ax.set_axis_off() figure.subplots_adjust(left=0, right=1, bottom=0, top=1, wspace=0, hspace=0) figure.patch.set_facecolor("w") return figure def init_gui_component(self): self.ifs_triangle = IFSTriangles(self.ax) self.figure.canvas.draw() self.settings.select_last() self.timer = Timer(10, self.ifs_calculate)
class PortChooser(HasTraits): ports = List() port = Str(None) mode = Enum(['Serial/USB', 'TCP/IP']) flow_control = Enum(['None', 'Hardware RTS/CTS']) ip_port = Int(55555) ip_address = Str('192.168.0.222') choose_baud = Bool(True) baudrate = Int() traits_view = View( VGroup( Spring(height=8), HGroup( Spring(width=-2, springy=False), Item('mode', style='custom', editor=EnumEditor(values=['Serial/USB', 'TCP/IP'], cols=2, format_str='%s'), show_label=False)), HGroup( VGroup( Label('Serial Device:'), Item('port', editor=EnumEditor(name='ports'), show_label=False), ), VGroup( Label('Baudrate:'), Item('baudrate', editor=EnumEditor(values=BAUD_LIST), show_label=False, visible_when='choose_baud'), Item('baudrate', show_label=False, visible_when='not choose_baud', style='readonly'), ), VGroup( Label('Flow Control:'), Item('flow_control', editor=EnumEditor(values=['None', 'Hardware RTS/CTS'], format_str='%s'), show_label=False), ), visible_when="mode==\'Serial/USB\'"), HGroup(VGroup( Label('IP Address:'), Item('ip_address', label="IP Address", style='simple', show_label=False, height=-24), ), VGroup( Label('IP Port:'), Item('ip_port', label="IP Port", style='simple', show_label=False, height=-24), ), Spring(), visible_when="mode==\'TCP/IP\'"), ), buttons=['OK', 'Cancel'], close_result=False, icon=icon, width=400, title='Swift Console - Select Piksi Interface', ) def __init__(self, baudrate=None): try: self.ports = [p for p, _, _ in s.get_ports()] if baudrate not in BAUD_LIST: self.choose_baud = False self.baudrate = baudrate except TypeError: pass
class WeightsVisualization(HasTraits): scene = Instance(MlabSceneModel, (), kw=dict(background=(1, 1, 1))) weight_index = Range(value=0, low='_min_weight', high='_max_weight') display_all = Bool(True) display_labels = Bool(True) _min_weight = Int(0) _max_weight = Int() selected_mesh = String() _names = List(String) save_all = Button() def __init__(self, meshes, center=True, vmin=None, vmax=None, offset_axis=0, offset_spacing=0.2, contours=None, colormap='RdBu', show_labels=False, actor_options=dict(), offset_axis2=1, offset_spacing2=0.5, label_offset_axis=None, label_offset=1.1, num_columns=None, **kwargs): HasTraits.__init__(self) if type(meshes) is dict: names, verts, tris, weights = list( zip(*[(n, v, t, w) for n, (v, t, w) in meshes.items()])) elif type(meshes) in [list, tuple]: names, verts, tris, weights = [], [], [], [] for i, mesh in enumerate(meshes): # (verts, tris, weights, name) verts.append(mesh[0]) tris.append(mesh[1]) weights.append(mesh[2]) if len(mesh) < 4: names.append(str(i)) else: names.append(mesh[3]) else: raise ValueError('illegal value for parameter "meshes"') ## single arrays given? #share_verts, share_tris = False, False #if type(weights) is np.ndarray and weights.ndim == 2: # weights = [weights] #if type(verts) is np.ndarray and verts.ndim == 2: # verts = cycle([verts]) # share_verts = True #if type(tris) is np.ndarray and tris.ndim == 2: # tris = cycle([tris]) # share_tris = True #else: # if not share_tris and len(tris) != len(weights): # raise ValueError, "need the same number of weight and triangle arrays" # if not share_verts and len(verts) != len(weights): # raise ValueError, "need the same number of weight and vertex arrays" # if names is not None and len(names) != len(weights): # raise ValueError, "need the same number of weight arrays and names" if names is not None: assert len(set(names)) == len(names) self._weights = list(map(_centered, weights)) if center else weights self._verts = verts self._tris = tris valid_weights = [ w.shape[-1] - 1 for w in self._weights if w is not None ] self._max_weight = max(valid_weights) if len(valid_weights) > 0 else 0 self._names = names #self._names = map(str, range(len(self._weights))) if names is None else names #if len(weights) == 2: # self.display_all = True # visualize each mesh self._trimeshes = [] self._texts = [] self._offsets = [] offset = np.zeros(3) for i, (verts_i, tris_i, weights_i, name_i) in enumerate(zip(verts, tris, weights, names)): if i > 0: offset[offset_axis] += verts_i[:, offset_axis].ptp() * ( 1 + offset_spacing) if num_columns is not None and i % num_columns == 0: offset[offset_axis2] += verts_i[:, offset_axis2].ptp() * ( 1 + offset_spacing2) offset[offset_axis] = 0 if center: vmin, vmax = 0, 1 else: vmin, vmax = vmin, vmax # draw mesh tm = mlab.triangular_mesh( verts_i[:, 0], verts_i[:, 1], verts_i[:, 2], tris_i, scalars=weights_i[..., 0] if weights_i is not None and not weights_i.dtype == np.uint8 else None, colormap=colormap, vmin=vmin, vmax=vmax, figure=self.scene.mayavi_scene) if weights_i is None: tm.actor.mapper.scalar_visibility = False # disable normal splitting tm.parent.parent.filter.splitting = False if contours is not None and weights_i is not None: from mayavi.modules.surface import Surface engine = tm.scene.engine tm_contour = Surface() engine.add_filter(tm_contour, tm.module_manager) tm_contour.enable_contours = True tm_contour.contour.number_of_contours = contours tm_contour.actor.mapper.scalar_visibility = False tm_contour.actor.property.set(color=(0.0, 0.0, 0.0), line_width=4) self._trimeshes.append([tm, tm_contour]) else: self._trimeshes.append([tm]) if show_labels: txt = mlab.text(0, 0, str(name_i), z=0, color=(0, 0, 0), width=0.12) txt.actor.text_scale_mode = 'none' txt.property.set(font_size=11, justification='centered') self._texts.append(txt) #tm.actor.actor.property.edit_traits() # for the next mesh, add the extent of the current mesh (plus spacing) to the offset self._offsets.append(offset.copy()) tm.actor.property.set(**actor_options) #if handle_points is not None: # h = verts2.ptp() # mlab.points3d(handle_points[:,0], handle_points[:,1], handle_points[:,2], scale_factor=h / 20) #actor_prop.edit_traits() self.selected_mesh = self._names[0] self._label_offset_axis = label_offset_axis self._label_offset = label_offset if self._label_offset_axis is None: self._label_offset_axis = (np.abs(self._offsets[-1]).argmax() + 1) % 3 self._update_view() self._reposition_meshes() @on_trait_change('weight_index') def _update_view(self): for tms, w in zip(self._trimeshes, self._weights): tm = tms[0] if w is None: continue try: wi = w[..., self.weight_index] if wi.dtype == np.uint8: tm.actor.mapper.input.point_data.scalars = wi self.scene.render() else: tm.mlab_source.set(scalars=wi) except IndexError: logging.warn("coult not reference index %d" % self.weight_index) @on_trait_change('display_all') def _reposition_meshes(self): self.scene.disable_render = True if self.display_all: for tms, offset in zip(self._trimeshes, self._offsets): for tm in tms: tm.actor.actor.position = offset for txt, v, offset in zip(self._texts, self._verts, self._offsets): ax = np.zeros(3) ax[self._label_offset_axis] = self._label_offset txt.x_position, txt.y_position, txt.z_position = ( v.mean(axis=0) + v.ptp(axis=0) * ax) + offset else: for tms in self._trimeshes: for tm in tms: tm.actor.actor.position = (0, 0, 0) self.scene.disable_render = False @on_trait_change('display_all, selected_mesh, display_labels') def _update_mesh_visibilities(self): self.scene.disable_render = True for name, tms in zip(self._names, self._trimeshes): for tm in tms: tm.visible = self.display_all or name == self.selected_mesh for txt in self._texts: txt.visible = self.display_all and self.display_labels self.scene.disable_render = False def _save_all_fired(self): file_dialog = DirectoryDialog(action='open', title='Select Directory') if file_dialog.open() == OK: out_path = file_dialog.path if self.display_all: items = [(None, k) for k in range(self._max_weight + 1)] else: items = product(self._names, range(self._max_weight + 1)) for name, k in items: if name is not None: self.selected_mesh = name self.weight_index = k mlab.savefig(path.join(out_path, "%s_%03d.png" % (name, k))) view = View( Group( HGroup( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=600, width=800, show_label=False), ), HGroup( Item('weight_index', label='idx'), Item('display_all', label='all'), Item( 'display_labels', label='labels', visible_when='len(object._texts) > 0 and object.display_all' ), Item( 'selected_mesh', label='which', visible_when= "len(object._names) > 1 and not object.display_all", editor=EnumEditor(name='object._names'), ), Item('save_all'), ), ), resizable=True, title="Mesh Weights", )
class nidaq_import(time_data_import): """ This class provides an interface to import of measurement data using NI-DAQmx. """ #: Name of the NI task to use taskname = Str(desc="name of the NI task to use for the measurement") #: Sampling frequency, defaults to 48000. sample_freq = Float(48000.0, desc="sampling frequency") #: Number of time data samples, defaults to 48000. numsamples = Long(48000, desc="number of samples") #: Number of channels; is set automatically. numchannels = Long(0, desc="number of channels in the task") #: Number of devices; is set automatically. numdevices = Long(0, desc="number of devices in the task") #: Name of channels; is set automatically. namechannels = List(desc="names of channels in the task") #: Name of devices; is set automatically. namedevices = List(desc="names of devices in the task") #: Name of available and valid tasks. tasknames = List traits_view = View([ Item('taskname{Task name}', editor=EnumEditor(name='tasknames')), ['sample_freq', 'numsamples', '-'], [ [ 'numdevices~{count}', Item('namedevices~{names}', height=3), '-[Devices]' ], [ 'numchannels~{count}', Item('namechannels~{names}', height=3), '-[Channels]' ], ], '|[Task]' ], title='NI-DAQmx data aquisition', buttons=OKCancelButtons) def __init__(self, **traits): time_data_import.__init__(self, **traits) taskHandle = TaskHandle(0) buf_size = 1024 # buf = ctypes.create_string_buffer('\000' * buf_size) buf = ctypes.create_string_buffer(b'\000' * buf_size) DAQmxGetSysTasks(ctypes.byref(buf), buf_size) # tasknamelist = buf.value.split(', ') tasknamelist = buf.value.split(b', ') self.tasknames = [] for taskname in tasknamelist: # is task valid ?? try to load try: DAQmxLoadTask(taskname, ctypes.byref(taskHandle)) except RuntimeError: continue self.tasknames.append(taskname) DAQmxClearTask(taskHandle) def _taskname_changed(self): taskHandle = TaskHandle(0) buf_size = 1024 * 4 # buf = ctypes.create_string_buffer('\000' * buf_size) buf = ctypes.create_string_buffer(b'\000' * buf_size) num = uInt32() fnum = float64() lnum = uInt64() try: DAQmxLoadTask(str.encode(self.taskname), ctypes.byref(taskHandle)) except RuntimeError: return DAQmxGetTaskNumChans(taskHandle, ctypes.byref(num)) self.numchannels = num.value # commented for compatibility with older NIDAQmx #~ DAQmxGetTaskNumDevices(taskHandle,ctypes.byref(num)) #~ self.numdevices = num.value DAQmxGetTaskChannels(taskHandle, ctypes.byref(buf), buf_size) self.namechannels = buf.value.decode().split(', ') DAQmxGetTaskDevices(taskHandle, ctypes.byref(buf), buf_size) self.namedevices = buf.value.decode().split(', ') self.numdevices = len(self.namedevices) DAQmxGetSampClkRate(taskHandle, ctypes.byref(fnum)) self.sample_freq = fnum.value DAQmxGetSampQuantSampMode(taskHandle, ctypes.byref(num)) if num.value == DAQmx_Val_FiniteSamps: DAQmxGetSampQuantSampPerChan(taskHandle, ctypes.byref(lnum)) self.numsamples = lnum.value DAQmxClearTask(taskHandle) def _sample_freq_changed(self, dispatch='ui'): taskHandle = TaskHandle(0) fnum = float64() try: DAQmxLoadTask(str.encode(self.taskname), ctypes.byref(taskHandle)) except RuntimeError: return try: DAQmxSetSampClkRate(taskHandle, float64(self.sample_freq)) except RuntimeError: pass DAQmxGetSampClkRate(taskHandle, ctypes.byref(fnum)) self.sample_freq = fnum.value DAQmxClearTask(taskHandle) print(self.sample_freq) def get_data(self, td): """ Main work is done here: loads data from buffer into :class:`~acoular.sources.TimeSamples` object `td` and saves also a '*.h5' file. """ taskHandle = TaskHandle(0) read = uInt32() fnum = float64() lnum = uInt64() try: DAQmxLoadTask(str.encode(self.taskname), ctypes.byref(taskHandle)) if self.numchannels < 1: raise RuntimeError DAQmxSetSampClkRate(taskHandle, float64(self.sample_freq)) except RuntimeError: # no valid task time_data_import.get_data(self, td) return #import data name = td.name if name == '': name = datetime.now().isoformat('_').replace(':', '-').replace( '.', '_') name = path.join(td_dir, name + '.h5') f5h = tables.open_file(name, mode='w') ac = f5h.create_earray(f5h.root, 'time_data', tables.atom.Float32Atom(), (0, self.numchannels)) ac.set_attr('sample_freq', self.sample_freq) DAQmxSetSampQuantSampPerChan(taskHandle, uInt64(100000)) DAQmxGetSampQuantSampPerChan(taskHandle, ctypes.byref(lnum)) max_num_samples = lnum.value print("Puffergroesse: %i" % max_num_samples) data = numpy.empty((max_num_samples, self.numchannels), dtype=numpy.float64) DAQmxStartTask(taskHandle) count = 0 numsamples = self.numsamples while count < numsamples: #~ DAQmxReadAnalogF64(taskHandle,-1,float64(10.0), #~ DAQmx_Val_GroupByScanNumber,data.ctypes.data, #~ data.size,ctypes.byref(read),None) DAQmxReadAnalogF64(taskHandle, 1024, float64(10.0), DAQmx_Val_GroupByScanNumber, data.ctypes.data, data.size, ctypes.byref(read), None) ac.append( numpy.array(data[:min(read.value, numsamples - count)], dtype=numpy.float32)) count += read.value #~ if read.value>200: #~ print count, read.value DAQmxStopTask(taskHandle) DAQmxClearTask(taskHandle) f5h.close() td.name = name td.load_data() def get_single(self): """ Gets one block of data """ taskHandle = TaskHandle(0) read = uInt32() fnum = float64() lnum = uInt64() try: DAQmxLoadTask(str.encode(self.taskname), ctypes.byref(taskHandle)) if self.numchannels < 1: raise RuntimeError except RuntimeError: # no valid task time_data_import.get_data(self, td) return #import data ac = numpy.empty((self.numsamples, self.numchannels), numpy.float32) DAQmxGetSampQuantSampPerChan(taskHandle, ctypes.byref(lnum)) max_num_samples = lnum.value data = numpy.empty((max_num_samples, self.numchannels), dtype=numpy.float64) DAQmxStartTask(taskHandle) count = 0 numsamples = self.numsamples while count < numsamples: DAQmxReadAnalogF64(taskHandle, -1, float64(10.0), DAQmx_Val_GroupByScanNumber, data.ctypes.data, data.size, ctypes.byref(read), None) anz = min(read.value, numsamples - count) ac[count:count + anz] = numpy.array(data[:anz], dtype=numpy.float32) count += read.value DAQmxStopTask(taskHandle) DAQmxClearTask(taskHandle) return ac
class testVI(HasTraits): renderAll = Button() renderImagePlane = Button() renderData = Button() imageList0 = 'None' imageList = List([]) imagePlane = Enum(('x_axes', 'y_axes', 'z_axes')) imageVisible = Bool(False) dataList0 = 'None' dataList = List([]) dataVisible = Bool(True) dataUpdate = Button() saveImageFilename = Str('screenshot.jpeg') saveImageWidth = Str('2000') saveImageLength = Str('1500') saveImage = Button() scene = Instance(MlabSceneModel, ()) t = Int(3) plot = Instance(PipelineBase) colours = {'bone': (0.84705882, 0.8, 0.49803922)} defaultColor = colours['bone'] # bone #~ defaultColor = (0.5,0.5,0.5) # bone view = View( HSplit( Tabbed( VGroup( Item('renderAll', show_label=False, label='render all objects', springy=True), #~ Item('renderImagePlane', show_label=False, label='render image plane', springy=True), Item('renderData', show_label=False, label='render data clouds', springy=True), VGroup( Item('imageList0', show_label=True, label='images', editor=EnumEditor(name='imageList')), HGroup( Item('imageVisible', show_label=True, label='visible', springy=True), Item('imagePlane', show_label=True, label='image plane', springy=True), )), VGroup( Item('dataList0', show_label=True, label='Dataclouds', editor=EnumEditor(name='dataList')), HGroup( Item('dataVisible', show_label=True, label='visible', springy=True), Item('dataUpdate', show_label=False, label='update', springy=True))), VGroup( Item('saveImageFilename', show_label=True, label='filename', editor=TextEditor()), HGroup( Item('saveImageWidth', show_label=True, label='W', editor=TextEditor()), Item('saveImageLength', show_label=True, label='L', editor=TextEditor()), ), Item('saveImage', show_label=False, label='saveImage', springy=True), ), label='Render'), springy=False), Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=600, width=800, show_label=False), ), resizable=True, ) #@on_trait_change('t') #def _drawData( self, name ): # self.scene.disable_render = True # d = self.data[name] # s = self.dataScalar.get(name) # renderArgs = self.dataRenderArgs[name] # if s!=None: #~ self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0], d[:,1], d[:,2], s, #~ mode='point', scale_factor=0.5, #~ scale_mode='none', #~ name=name ) # self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0,self.t], d[:,1,self.t], d[:,2,self.t], s, **renderArgs) # else: #~ self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0], d[:,1], d[:,2], #~ mode='point', scale_factor=0.5, #~ color=(0.0,1.0,0.0), #~ name=name ) # self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0,self.t], d[:,1,self.t], d[:,2,self.t], **renderArgs ) # self.scene.disable_render = False def __init__(self): HasTraits.__init__(self) self.I = None self.images = {} self.imageCounter = 0 self.sceneObjectImages = {} self.imageRenderArgs = {} self.data = {} self.dataScalar = {} self.dataCounter = 0 self.sceneObjectData = {} self.dataRenderArgs = {} self.sceneObjectImageVolume = None self.modeVectorFlip = 1.0 self.view = None self.roll = None self.onCloseCallback = None # image plane widget attributes self._ipw_picked_obj = None self._ipw_picked_points = [] def addOnCloseCallback(self, callback): self.onCloseCallback = callback def closed(self, info, is_ok): if self.onCloseCallback != None: self.onCloseCallback() def addData(self, name, d, scalar=None, renderArgs=None): if name not in self.data.keys(): self.dataCounter += 1 self.dataList.append(name) self.data[name] = d if renderArgs == None: self.dataRenderArgs[name] = {} else: self.dataRenderArgs[name] = renderArgs if scalar is not None: self.dataScalar[name] = scalar else: self.dataScalar[name] = None self.dataList0 = name def _drawData(self, name): self.scene.disable_render = True d = self.data[name] s = self.dataScalar.get(name) t = self.t renderArgs = self.dataRenderArgs[name] if s != None: #~ self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0], d[:,1], d[:,2], s, #~ mode='point', scale_factor=0.5, #~ scale_mode='none', #~ name=name ) self.sceneObjectData[name] = self.scene.mlab.points3d( d[:, 0], d[:, 1], d[:, 2], s, **renderArgs) else: #~ self.sceneObjectData[name] = self.scene.mlab.points3d( d[:,0], d[:,1], d[:,2], #~ mode='point', scale_factor=0.5, #~ color=(0.0,1.0,0.0), #~ name=name ) self.sceneObjectData[name] = self.scene.mlab.points3d( d[:, 0], d[:, 1], d[:, 2], **renderArgs) self.scene.disable_render = False def _dataVisible_changed(self): try: self.sceneObjectData[self.dataList0].visible = self.dataVisible except KeyError: if self.dataVisible: self._drawData(self.dataList0) def _dataUpdate_fired(self): self.updateData(self.dataList0) def updateData(self, name, coords=None): if coords is None: d = self.data[name] else: d = coords s = self.dataScalar.get(name) renderArgs = self.dataRenderArgs[name] t = self.t try: if s is not None: self.sceneObjectData[ name].actor.mapper.scalar_visibility = True self.sceneObjectData[name].mlab_source.reset(x=d[:, 0], y=d[:, 1], z=d[:, 2], s=s) else: if 'color' not in renderArgs: color = self.defaultColor else: color = renderArgs['color'] self.sceneObjectData[ name].actor.mapper.scalar_visibility = False self.sceneObjectData[ name].actor.property.specular_color = color self.sceneObjectData[name].actor.property.diffuse_color = color self.sceneObjectData[name].actor.property.ambient_color = color self.sceneObjectData[name].actor.property.color = color self.sceneObjectData[name].mlab_source.reset(x=d[:, 0], y=d[:, 1], z=d[:, 2]) except KeyError: self._drawData(name) #def _renderData_fired( self ): """ redraw all data clouds
from pychron.entry.providers.macrostrat import get_lithology_values from pychron.envisage.icon_button_editor import icon_button_editor from pychron.processing.analyses.analysis_group import InterpretedAgeGroup from pychron.processing.analyses.preferred import preferred_item class BaseColumn(ObjectColumn): text_font = 'arial 10' class UObjectColumn(BaseColumn): editable = False lithology_grp = VGroup(Item('lithology', editor=EnumEditor(name='lithologies')), Item('lithology_class', label='Class', editor=EnumEditor(name='lithology_classes')), Item('lithology_group', label='Group', editor=EnumEditor(name='lithology_groups')), Item('lithology_type', label='Type', editor=EnumEditor(name='lithology_types')), show_border=True, label='Lithology') metadata_grp = VGroup( HGroup(Item('sample'), Item('igsn')), HGroup(Item('material'), UItem('grainsize',
def build_plot_list_editor(self): """ Build a table editor for the model's list of PlotDescriptors. """ num_containers = self.model.canvas_manager.num_container_managers container_idx_vals = list( range(num_containers)) + [CONTAINER_IDX_REMOVAL] name_to_col = { "id": ObjectColumn(name='id', style="readonly", cell_color="lightgrey"), "plot_title": ObjectColumn(name="plot_title"), # The format_func is called with an argument, the object to # display, therefore the x argument placeholder: 'edit_plot_style': ObjectColumn(name='edit_plot_style', label="Edit Style", format_func=lambda x: "Edit"), "visible": CheckboxColumn(name='visible'), "frozen": CheckboxColumn(name='frozen', tooltip="Freeze the plot and skip updates when " "source data changes"), "plot_type": ObjectColumn(name='plot_type', style="readonly", cell_color="lightgrey"), "x_col_name": ObjectColumn(name='x_col_name', style="readonly", cell_color="lightgrey", label="X column"), 'x_axis_title': ObjectColumn(name='x_axis_title'), "y_col_name": ObjectColumn(name='y_col_name', style="readonly", cell_color="lightgrey", label="Y column"), 'y_axis_title': ObjectColumn(name='y_axis_title'), 'secondary_y_axis_title': ObjectColumn(name='secondary_y_axis_title', label="Second. Y title"), "z_col_name": ObjectColumn(name='z_col_name', style="readonly", cell_color="lightgrey", label="Z column (color)"), 'z_axis_title': ObjectColumn(name='z_axis_title'), "data_filter": ObjectColumn(name='data_filter', label="Analyzer data filter", style="readonly"), 'container_idx': ObjectColumn(name='container_idx', editor=EnumEditor(values=container_idx_vals), label="Move/Delete") } columns = [name_to_col[col] for col in self.plot_control_cols] plot_list_editor = TableEditor(columns=columns, auto_size=True, sortable=True, h_size_policy="expanding", editable=True, edit_on_first_click=False, reorderable=False, row_factory=None, deletable=False) return plot_list_editor
def control_traits_view(self): return View(HGroup(Item('channel', editor = EnumEditor(name = 'handler.wi.previous.channels')), Item('file', show_label = False)), handler = self)
def _new_load_view(self): v = okcancel_view(Item('new_load_name', label='Name'), Item('tray', editor=EnumEditor(name='trays')), title='New Load Name', width=300) return v
def trait_view(self, name=None, view_element=None): var_editor_vals = sorted([v.name for v in self.vars]) var_editor_vals.insert(0, '') var_col = [ ObjectColumn(name='name', label='Variable', editable=True, editor=EnumEditor(values=var_editor_vals), width=.5), ObjectColumn(name='type', label='Interactor Type', width=.5, editable=True) ] plot_editor_vals = sorted([ value.name for value in self.vars if isinstance(value.value, ndarray) and ( len(value.value.shape) == 1 or len(value.value.shape) == 2) ]) plot_editor = EnumEditor(values=plot_editor_vals) plot_col = [ ObjectColumn(name='number', label='Number', editable=True, width=.1), ObjectColumn(name='x', label='X Axis', editable=True, editor=plot_editor, width=.25), ObjectColumn(name='y', label='Y Axis', editable=True, editor=plot_editor, width=.25), # FIXME: This needs to be re-enabled and tested #ObjectColumn(name='color', label='Color', editable=True, # editor=plot_editor, width=.25), ObjectColumn(name='type', label='Type', editable=True, width=.15) ] return View( Label('Set up interactors:'), Item( 'var_configs', editor=TableEditor( columns=var_col, editable=True, deletable=False, configurable=False, sortable=False, sort_model=True, auto_add=True, menu=new_delete_menu, row_factory=VariableConfig, selection_bg_color=None, label_bg_color=WindowColor, cell_bg_color=0xFFFFFF, ), show_label=False, ), Label('Set up plots:'), Item( 'plot_configs', editor=TableEditor( columns=plot_col, editable=True, deletable=False, configurable=False, sortable=False, auto_add=True, menu=new_delete_menu, row_factory=PlotConfig, selection_bg_color=None, label_bg_color=WindowColor, cell_bg_color=0xFFFFFF, ), show_label=False, ), id="interactor.InteractorConfig", title="Configure Interactor", buttons=OKCancelButtons, handler=InteractorConfigHandler(), close_result=False, resizable=True, )
def _get_info_group(self): grp = Group(HGroup(run_factory_item('selected_irradiation', show_label=False, editor=EnumEditor(name=run_factory_name('irradiations'))), run_factory_item('selected_level', show_label=False, editor=EnumEditor(name=run_factory_name('levels')))), HGroup(run_factory_item('special_labnumber', show_label=False, editor=EnumEditor(values=SPECIAL_NAMES)), run_factory_item('run_block', show_label=False, editor=EnumEditor(name=run_factory_name('run_blocks'))), icon_button_editor(run_factory_name('edit_run_blocks'), 'cog'), run_factory_item('frequency_model.frequency_int', width=50), icon_button_editor(run_factory_name('edit_frequency_button'), 'cog'), # run_factory_item('freq_before', label='Before'), # run_factory_item('freq_after', label='After'), spring), # HGroup(run_factory_item('labnumber', # tooltip='Enter a Labnumber', # width=100, ), # run_factory_item('_labnumber', show_label=False, # editor=CheckListEditor(name=run_factory_name('labnumbers')), # width=-20), # run_factory_item('aliquot', # width=50), # spring), HGroup(run_factory_item('labnumber', tooltip='Enter a Labnumber', width=100, enabled_when='object.run_factory.special_labnumber == "Special Labnumber"', editor=ComboboxEditor(name=run_factory_name('labnumbers'))), run_factory_item('aliquot', width=50), spring), HGroup(run_factory_item('repository_identifier', label='Repository ID', editor=EnumEditor(name=run_factory_name('repository_identifiers'))), icon_button_editor(run_factory_name('add_repository_identifier'), 'add', tooltip='Add a new repository'), icon_button_editor(run_factory_name('set_repository_identifier_button'), 'arrow_left', tooltip='Set select runs repository_identifier to current value')), HGroup(run_factory_item('weight', label='Weight (mg)', tooltip='(Optional) Enter the weight of the sample in mg. ' 'Will be saved in Database with analysis'), run_factory_item('comment', tooltip='(Optional) Enter a comment for this sample. ' 'Will be saved in Database with analysis'), run_factory_item('auto_fill_comment', show_label=False, tooltip='Auto fill "Comment" with IrradiationLevel:Hole, e.g A:9'), # run_factory_item('comment_template', # editor=EnumEditor(name=run_factory_name('comment_templates')), # show_label=False), icon_button_editor(run_factory_name('edit_comment_template'), 'cog', tooltip='Edit comment template')), HGroup(run_factory_item('flux'), Label(u'\u00b1'), run_factory_item('flux_error', show_label=False), icon_button_editor(run_factory_name('save_flux_button'), 'database_save', tooltip='Save flux to database'), enabled_when=run_factory_name('labnumber')), show_border=True, label='Sample Info') return grp
def kind_select_view(self): v = okcancel_view(UItem('kind', editor=EnumEditor(name='kinds')), title='Select Pyscript kind') return v
def traits_view(self): add_button = icon_button_editor('add_button', 'add', # enabled_when='ok_add', tooltip='Add run') save_button = icon_button_editor('save_button', 'disk', tooltip='Save queue to file') edit_button = icon_button_editor('edit_mode_button', 'table_edit', enabled_when='edit_enabled', tooltip='Toggle edit mode') clear_button = icon_button_editor('clear_button', 'table_row_delete', tooltip='Clear all runs added using "frequency"') email_grp = VGroup(HGroup(queue_factory_item('use_email', label='Use Email', tooltip='Send email notifications'), queue_factory_item('use_group_email', tooltip='Email a group of users', label='Email Group'), icon_button_editor(queue_factory_name('edit_emails'), 'cog', tooltip='Edit user group')), Item(queue_factory_name('email')), show_border=True, label='Email') user_grp = HGroup(UItem(queue_factory_name('username'), show_label=False, editor=ComboboxEditor(name=queue_factory_name('usernames'))), icon_button_editor(queue_factory_name('edit_user'), 'database_edit'), show_border=True, label='User') lgrp = HGroup(queue_factory_item('load_name', width=150, label='Load', editor=ComboboxEditor(name=queue_factory_name('load_names'))), icon_button_editor('generate_queue_button', 'brick-go', tooltip='Generate a experiment queue from the selected load', enabled_when='load_name'), icon_button_editor('edit_queue_config_button', 'cog', tooltip='Configure experiment queue generation')) ms_ed_grp = VGroup(HGroup(queue_factory_item('mass_spectrometer', show_label=False, editor=EnumEditor(name=queue_factory_name('mass_spectrometers'))), queue_factory_item('extract_device', show_label=False, editor=EnumEditor(name=queue_factory_name('extract_devices')))), lgrp, HGroup(queue_factory_item('queue_conditionals_name', label='Queue Conditionals', editor=EnumEditor( name=queue_factory_name('available_conditionals')))), label='Spectrometer/Extract Device', show_border=True) delay_grp = VGroup(queue_factory_item('delay_before_analyses'), queue_factory_item('delay_between_analyses'), show_border=True, label='Delays') queue_grp = VGroup(user_grp, email_grp, ms_ed_grp, delay_grp, label='Queue') button_bar = HGroup(save_button, add_button, clear_button, edit_button, CustomLabel(run_factory_name('edit_mode_label'), color='red', width=40), spring) button_bar2 = HGroup(Item('auto_increment_id', label='Auto Increment L#'), Item('auto_increment_position', label='Position'), ) edit_grp = VFold(queue_grp, VGroup(self._get_info_group(), self._get_extract_group(), enabled_when=queue_factory_name('ok_make'), label='General'), self._get_script_group(), self._get_truncate_group()) v = View(VGroup(button_bar, button_bar2, UItem('pane.info_label', style='readonly'), edit_grp, style_sheet=load_stylesheet('experiment_factory')), kind='live', width=225) return v
def traits_view(self): v = View( VGroup(Item('irradiation', editor=EnumEditor(name='irradiations')), Item('level', editor=EnumEditor(name='levels')))) return v
class FieldViewer(HasTraits): # 三个轴的取值范围 x0, x1 = Float(-5), Float(5) y0, y1 = Float(-5), Float(5) z0, z1 = Float(-5), Float(5) points = Int(50) # 分割点数 autocontour = Bool(True) # 是否自动计算等值面 v0, v1 = Float(0.0), Float(1.0) # 等值面的取值范围 contour = Range("v0", "v1", 0.5) # 等值面的值 function = Str("x*x*0.5 + y*y + z*z*2.0") # 标量场函数 function_list = [ "x*x*0.5 + y*y + z*z*2.0", "x*y*0.5 + np.sin(2*x)*y +y*z*2.0", "x*y*z", "np.sin((x*x+y*y)/z)" ] plotbutton = Button(u"描画") scene = Instance(MlabSceneModel, ()) #❶ view = View( HSplit( VGroup( "x0", "x1", "y0", "y1", "z0", "z1", Item('points', label=u"点数"), Item('autocontour', label=u"自动等值"), Item('plotbutton', show_label=False), ), VGroup( Item( 'scene', editor=SceneEditor(scene_class=MayaviScene), #❷ resizable=True, height=300, width=350), Item('function', editor=EnumEditor(name='function_list', evaluate=lambda x: x)), Item('contour', editor=RangeEditor(format="%1.2f", low_name="v0", high_name="v1")), show_labels=False)), width=500, resizable=True, title=u"三维标量场观察器") def _plotbutton_fired(self): self.plot() def plot(self): # 产生三维网格 x, y, z = np.mgrid[ #❸ self.x0:self.x1:1j * self.points, self.y0:self.y1:1j * self.points, self.z0:self.z1:1j * self.points] # 根据函数计算标量场的值 scalars = eval(self.function) #❹ self.scene.mlab.clf() # 清空当前场景 # 绘制等值平面 g = self.scene.mlab.contour3d(x, y, z, scalars, contours=8, transparent=True) #❺ g.contour.auto_contours = self.autocontour self.scene.mlab.axes(figure=self.scene.mayavi_scene) # 添加坐标轴 # 添加一个X-Y的切面 s = self.scene.mlab.pipeline.scalar_cut_plane(g) cutpoint = (self.x0 + self.x1) / 2, (self.y0 + self.y1) / 2, ( self.z0 + self.z1) / 2 s.implicit_plane.normal = (0, 0, 1) # x cut s.implicit_plane.origin = cutpoint self.g = g #❻ self.scalars = scalars # 计算标量场的值的范围 self.v0 = np.min(scalars) self.v1 = np.max(scalars) def _contour_changed(self): #❼ if hasattr(self, "g"): if not self.g.contour.auto_contours: self.g.contour.contours = [self.contour] def _autocontour_changed(self): #❽ if hasattr(self, "g"): self.g.contour.auto_contours = self.autocontour if not self.autocontour: self._contour_changed()
def make_editor(trait=None): return EnumEditor(name=trait.values_name)
class InterpolatorView(HasTraits): # The bounds on which to interpolate. bounds = Array(cols=3, dtype=float, desc='spatial bounds for the interpolation ' '(xmin, xmax, ymin, ymax, zmin, zmax)') # The number of points to interpolate onto. num_points = Int(100000, enter_set=True, auto_set=False, desc='number of points on which to interpolate') # The particle arrays to interpolate from. particle_arrays = List # The scalar to interpolate. scalar = Str('rho', desc='name of the active scalar to view') # Sync'd trait with the scalar lut manager. show_legend = Bool(False, desc='if the scalar legend is to be displayed') # Enable/disable the interpolation visible = Bool(False, desc='if the interpolation is to be displayed') # A button to use the set bounds. set_bounds = Button('Set Bounds') # A button to recompute the bounds. recompute_bounds = Button('Recompute Bounds') # Private traits. ###################################################### # The interpolator we are a view for. interpolator = Instance(Interpolator) # The mlab plot for this particle array. plot = Instance(PipelineBase) scalar_list = List scene = Instance(MlabSceneModel) source = Instance(PipelineBase) _arrays_changed = Bool(False) # View definition ###################################################### view = View( Item(name='visible'), Item(name='scalar', editor=EnumEditor(name='scalar_list')), Item(name='num_points'), Item(name='bounds'), Item(name='set_bounds', show_label=False), Item(name='recompute_bounds', show_label=False), Item(name='show_legend'), ) # Private protocol ################################################### def _change_bounds(self): interp = self.interpolator if interp is not None: interp.set_domain(self.bounds, self.interpolator.shape) self._update_plot() def _setup_interpolator(self): if self.interpolator is None: interpolator = Interpolator(self.particle_arrays, num_points=self.num_points) self.bounds = interpolator.bounds self.interpolator = interpolator else: if self._arrays_changed: self.interpolator.update_particle_arrays(self.particle_arrays) self._arrays_changed = False # Trait handlers ##################################################### def _particle_arrays_changed(self, pas): if len(pas) > 0: all_props = reduce(set.union, [set(x.properties.keys()) for x in pas]) else: all_props = set() self.scalar_list = list(all_props) self._arrays_changed = True self._update_plot() def _num_points_changed(self, value): interp = self.interpolator if interp is not None: bounds = self.interpolator.bounds shape = get_nx_ny_nz(value, bounds) interp.set_domain(bounds, shape) self._update_plot() def _recompute_bounds_fired(self): bounds = get_bounding_box(self.particle_arrays) self.bounds = bounds self._change_bounds() def _set_bounds_fired(self): self._change_bounds() def _bounds_default(self): return [0, 1, 0, 1, 0, 1] @on_trait_change('scalar, visible') def _update_plot(self): if self.visible: mlab = self.scene.mlab self._setup_interpolator() interp = self.interpolator prop = interp.interpolate(self.scalar) if self.source is None: src = mlab.pipeline.scalar_field(interp.x, interp.y, interp.z, prop) self.source = src else: self.source.mlab_source.reset(x=interp.x, y=interp.y, z=interp.z, scalars=prop) src = self.source if self.plot is None: if interp.dim == 3: plot = mlab.pipeline.scalar_cut_plane(src) else: plot = mlab.pipeline.surface(src) self.plot = plot scm = plot.module_manager.scalar_lut_manager scm.set(show_legend=self.show_legend, use_default_name=False, data_name=self.scalar) self.sync_trait('show_legend', scm, mutual=True) else: self.plot.visible = True scm = self.plot.module_manager.scalar_lut_manager scm.data_name = self.scalar else: if self.plot is not None: self.plot.visible = False
class ChannelHandler(Controller): channel_view = View( HGroup( Item('channel', editor=EnumEditor(name='context_handler.channels')), Item('scale')))
class ParticleArrayHelper(HasTraits): """ This class manages a particle array and sets up the necessary plotting related information for it. """ # The particle array we manage. particle_array = Instance(ParticleArray) # The name of the particle array. name = Str # Current time. time = Float(0.0) # The active scalar to view. scalar = Str('rho', desc='name of the active scalar to view') # The mlab scalar plot for this particle array. plot = Instance(PipelineBase) # The mlab vectors plot for this particle array. plot_vectors = Instance(PipelineBase) # List of available scalars in the particle array. scalar_list = List(Str) scene = Instance(MlabSceneModel) # Sync'd trait with the scalar lut manager. show_legend = Bool(False, desc='if the scalar legend is to be displayed') # Show all scalars. list_all_scalars = Bool(False, desc='if all scalars should be listed') # Sync'd trait with the dataset to turn on/off visibility. visible = Bool(True, desc='if the particle array is to be displayed') # Show the time of the simulation on screen. show_time = Bool(False, desc='if the current time is displayed') # Edit the scalars. edit_scalars = Button('More options ...') # Show vectors. show_vectors = Bool(False, desc='if vectors should be displayed') vectors = Str('u, v, w', enter_set=True, auto_set=False, desc='the vectors to display') mask_on_ratio = Int(3, desc='mask one in specified points') scale_factor = Float(1.0, desc='scale factor for vectors', enter_set=True, auto_set=False) edit_vectors = Button('More options ...') # Private attribute to store the Text module. _text = Instance(PipelineBase) # Extra scalars to show. These will be added and saved to the data if # needed. extra_scalars = List(Str) # Set to True when the particle array is updated with a new property say. updated = Event # Private attribute to store old value of visibility in case of empty # arrays. _old_visible = Bool(True) ######################################## # View related code. view = View( Item(name='name', show_label=False, editor=TitleEditor()), Group(Group( Group( Item(name='visible'), Item(name='show_legend'), Item(name='scalar', editor=EnumEditor(name='scalar_list')), Item(name='list_all_scalars'), Item(name='show_time'), columns=2, ), Item(name='edit_scalars', show_label=False), label='Scalars', ), Group( Item(name='show_vectors'), Item(name='vectors'), Item(name='mask_on_ratio'), Item(name='scale_factor'), Item(name='edit_vectors', show_label=False), label='Vectors', ), layout='tabbed')) # Private protocol ############################################ def _add_vmag(self, pa): if 'vmag' not in pa.properties: if 'vmag2' in pa.output_property_arrays: vmag = numpy.sqrt(pa.vmag2) else: vmag = numpy.sqrt(pa.u**2 + pa.v**2 + pa.w**2) pa.add_property(name='vmag', data=vmag) if len(pa.output_property_arrays) > 0: # We do not call add_output_arrays when the default is empty # as if it is empty, all arrays are saved anyway. However, # adding just vmag in this case will mean that when the # particle array is saved it will only save vmag! This is # not what we want, hence we add vmag *only* if the # output_property_arrays is non-zero length. pa.add_output_arrays(['vmag']) self.updated = True def _get_scalar(self, pa, scalar): """Return the requested scalar from the given particle array. """ if scalar in self.extra_scalars: method_name = '_add_' + scalar method = getattr(self, method_name) method(pa) return getattr(pa, scalar) # Traits handlers ############################################# def _edit_scalars_fired(self): self.plot.edit_traits() def _edit_vectors_fired(self): self.plot_vectors.edit_traits() def _particle_array_changed(self, old, pa): self.name = pa.name self._list_all_scalars_changed(self.list_all_scalars) # Update the plot. x, y, z = pa.x, pa.y, pa.z s = self._get_scalar(pa, self.scalar) p = self.plot mlab = self.scene.mlab empty = len(x) == 0 old_empty = len(old.x) == 0 if old is not None else True if p is None and not empty: src = mlab.pipeline.scalar_scatter(x, y, z, s) p = mlab.pipeline.glyph(src, mode='point', scale_mode='none') p.actor.property.point_size = 3 scm = p.module_manager.scalar_lut_manager scm.set(show_legend=self.show_legend, use_default_name=False, data_name=self.scalar) self.sync_trait('visible', p, mutual=True) self.sync_trait('show_legend', scm, mutual=True) # set_arrays(p.mlab_source.m_data, pa) self.plot = p elif not empty: if len(x) == len(p.mlab_source.x): p.mlab_source.set(x=x, y=y, z=z, scalars=s) if self.plot_vectors: self._vectors_changed(self.vectors) else: if self.plot_vectors: u, v, w = self._get_vectors_for_plot(self.vectors) p.mlab_source.reset(x=x, y=y, z=z, scalars=s, u=u, v=v, w=w) else: p.mlab_source.reset(x=x, y=y, z=z, scalars=s) p.mlab_source.update() if empty and not old_empty: if p is not None: src = p.parent.parent self._old_visible = src.visible src.visible = False if old_empty and not empty: if p is not None: p.parent.parent.visible = self._old_visible self._show_vectors_changed(self.show_vectors) # Setup the time. self._show_time_changed(self.show_time) def _scalar_changed(self, value): p = self.plot if p is not None: p.mlab_source.scalars = self._get_scalar(self.particle_array, value) p.module_manager.scalar_lut_manager.data_name = value def _list_all_scalars_changed(self, list_all_scalars): pa = self.particle_array if list_all_scalars: sc_list = pa.properties.keys() self.scalar_list = sorted(set(sc_list + self.extra_scalars)) else: if len(pa.output_property_arrays) > 0: self.scalar_list = sorted( set(pa.output_property_arrays + self.extra_scalars)) else: sc_list = pa.properties.keys() self.scalar_list = sorted(set(sc_list + self.extra_scalars)) def _show_time_changed(self, value): txt = self._text mlab = self.scene.mlab if value: if txt is not None: txt.visible = True elif self.plot is not None: mlab.get_engine().current_object = self.plot txt = mlab.text(0.01, 0.01, 'Time = 0.0', width=0.35) self._text = txt self._time_changed(self.time) else: if txt is not None: txt.visible = False def _get_vectors_for_plot(self, vectors): pa = self.particle_array comps = [x.strip() for x in vectors.split(',')] if len(comps) == 3: try: vec = tuple(getattr(pa, x) for x in comps) except AttributeError: return None else: return vec def _vectors_changed(self, value): vec = self._get_vectors_for_plot(value) if vec is not None: self.plot.mlab_source.set(vectors=numpy.c_[vec[0], vec[1], vec[2]]) def _show_vectors_changed(self, value): pv = self.plot_vectors if pv is not None: pv.visible = value elif self.plot is not None and value: self._vectors_changed(self.vectors) pv = self.scene.mlab.pipeline.vectors( self.plot.mlab_source.m_data, mask_points=self.mask_on_ratio, scale_factor=self.scale_factor) self.plot_vectors = pv def _mask_on_ratio_changed(self, value): pv = self.plot_vectors if pv is not None: pv.glyph.mask_points.on_ratio = value def _scale_factor_changed(self, value): pv = self.plot_vectors if pv is not None: pv.glyph.glyph.scale_factor = value def _time_changed(self, value): txt = self._text if txt is not None: txt.text = 'Time = %.3e' % (value) def _extra_scalars_default(self): return ['vmag']
class DataSourceWizardView(DataSourceWizard): #---------------------------------------------------------------------- # Private traits #---------------------------------------------------------------------- _top_label = Str('Describe your data') _info_text = Str('Array size do not match') _array_label = Str('Available arrays') _data_type_text = Str("What does your data represents?") _lines_text = Str("Connect the points with lines") _scalar_data_text = Str("Array giving the value of the scalars") _optional_scalar_data_text = Str("Associate scalars with the data points") _connectivity_text = Str("Array giving the triangles") _vector_data_text = Str("Associate vector components") _position_text = Property(depends_on="position_type_") _position_text_dict = { 'explicit': 'Coordinnates of the data points:', 'orthogonal grid': 'Position of the layers along each axis:', } def _get__position_text(self): return self._position_text_dict.get(self.position_type_, "") _shown_help_text = Str _data_sources_wrappers = Property(depends_on='data_sources') def _get__data_sources_wrappers(self): return [ ArrayColumnWrapper(name=name, shape=repr(self.data_sources[name].shape)) for name in self._data_sources_names ] # A traits pointing to the object, to play well with traitsUI _self = Instance(DataSourceWizard) _suitable_traits_view = Property(depends_on="data_type_") def _get__suitable_traits_view(self): return "_%s_data_view" % self.data_type_ ui = Any(False) _preview_button = Button(label='Preview structure') def __preview_button_fired(self): if self.ui: self.build_data_source() self.preview() _ok_button = Button(label='OK') def __ok_button_fired(self): if self.ui: self.ui.dispose() self.build_data_source() _cancel_button = Button(label='Cancel') def __cancel_button_fired(self): if self.ui: self.ui.dispose() _is_ok = Bool _is_not_ok = Bool def _anytrait_changed(self): """ Validates if the OK button is enabled. """ if self.ui: self._is_ok = self.check_arrays() self._is_not_ok = not self._is_ok _preview_window = Instance(PreviewWindow, ()) _info_image = Instance(ImageResource, ImageLibrary.image_resource('@std:alert16', )) #---------------------------------------------------------------------- # TraitsUI views #---------------------------------------------------------------------- _coordinates_group = \ HGroup( Item('position_x', label='x', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('position_y', label='y', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('position_z', label='z', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), ) _position_group = \ Group( Item('position_type'), Group( Item('_position_text', style='readonly', resizable=False, show_label=False), _coordinates_group, visible_when='not position_type_=="image data"', ), Group( Item('grid_shape_source_', label='Grid shape', editor=EnumEditor( name='_grid_shape_source_labels', invalid='_is_not_ok')), HGroup( spring, Item('grid_shape', style='custom', editor=ArrayEditor(width=-60), show_label=False), enabled_when='grid_shape_source==""', ), visible_when='position_type_=="image data"', ), label='Position of the data points', show_border=True, show_labels=False, ), _connectivity_group = \ Group( HGroup( Item('_connectivity_text', style='readonly', resizable=False), spring, Item('connectivity_triangles', editor=EnumEditor(name='_data_sources_names'), show_label=False, ), show_labels=False, ), label='Connectivity information', show_border=True, show_labels=False, enabled_when='position_type_=="explicit"', ), _scalar_data_group = \ Group( Item('_scalar_data_text', style='readonly', resizable=False, show_label=False), HGroup( spring, Item('scalar_data', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), show_labels=False, ), label='Scalar value', show_border=True, show_labels=False, ) _optional_scalar_data_group = \ Group( HGroup( 'has_scalar_data', Item('_optional_scalar_data_text', resizable=False, style='readonly'), show_labels=False, ), Item('_scalar_data_text', style='readonly', resizable=False, enabled_when='has_scalar_data', show_label=False), HGroup( spring, Item('scalar_data', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok'), enabled_when='has_scalar_data'), show_labels=False, ), label='Scalar data', show_border=True, show_labels=False, ), _vector_data_group = \ VGroup( HGroup( Item('vector_u', label='u', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_v', label='v', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_w', label='w', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), ), label='Vector data', show_border=True, ), _optional_vector_data_group = \ VGroup( HGroup( Item('has_vector_data', show_label=False), Item('_vector_data_text', style='readonly', resizable=False, show_label=False), ), HGroup( Item('vector_u', label='u', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_v', label='v', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_w', label='w', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), enabled_when='has_vector_data', ), label='Vector data', show_border=True, ), _array_view = \ View( Item('_array_label', editor=TitleEditor(), show_label=False), Group( Item('_data_sources_wrappers', editor=TabularEditor( adapter = ArrayColumnAdapter(), ), ), show_border=True, show_labels=False )) _questions_view = View( Item('_top_label', editor=TitleEditor(), show_label=False), HGroup( Item('_data_type_text', style='readonly', resizable=False), spring, 'data_type', spring, show_border=True, show_labels=False, ), HGroup( Item( '_self', style='custom', editor=InstanceEditor(view_name='_suitable_traits_view'), ), Group( # FIXME: Giving up on context sensitive help # because of lack of time. #Group( # Item('_shown_help_text', editor=HTMLEditor(), # width=300, # label='Help', # ), # show_labels=False, # label='Help', #), #Group( Item('_preview_button', enabled_when='_is_ok'), Item('_preview_window', style='custom', label='Preview structure'), show_labels=False, #label='Preview structure', #), #layout='tabbed', #dock='tab', ), show_labels=False, show_border=True, ), ) _point_data_view = \ View(Group( Group(_coordinates_group, label='Position of the data points', show_border=True, ), HGroup( 'lines', Item('_lines_text', style='readonly', resizable=False), label='Lines', show_labels=False, show_border=True, ), _optional_scalar_data_group, _optional_vector_data_group, # XXX: hack to have more vertical space Label('\n'), Label('\n'), Label('\n'), )) _surface_data_view = \ View(Group( _position_group, _connectivity_group, _optional_scalar_data_group, _optional_vector_data_group, )) _vector_data_view = \ View(Group( _vector_data_group, _position_group, _optional_scalar_data_group, )) _volumetric_data_view = \ View(Group( _scalar_data_group, _position_group, _optional_vector_data_group, )) _wizard_view = View( Group( HGroup( Item( '_self', style='custom', show_label=False, editor=InstanceEditor(view='_array_view'), width=0.17, ), '_', Item( '_self', style='custom', show_label=False, editor=InstanceEditor(view='_questions_view'), ), ), HGroup( Item('_info_image', editor=ImageEditor(), visible_when="_is_not_ok"), Item('_info_text', style='readonly', resizable=False, visible_when="_is_not_ok"), spring, '_cancel_button', Item('_ok_button', enabled_when='_is_ok'), show_labels=False, ), ), title='Import arrays', resizable=True, ) #---------------------------------------------------------------------- # Public interface #---------------------------------------------------------------------- def __init__(self, **traits): DataSourceFactory.__init__(self, **traits) self._self = self def view_wizard(self): """ Pops up the view of the wizard, and keeps the reference it to be able to close it. """ # FIXME: Workaround for traits bug in enabled_when self.position_type_ self.data_type_ self._suitable_traits_view self.grid_shape_source self._is_ok self.ui = self.edit_traits(view='_wizard_view') def preview(self): """ Display a preview of the data structure in the preview window. """ self._preview_window.clear() self._preview_window.add_source(self.data_source) data = lambda name: self.data_sources[name] g = Glyph() g.glyph.glyph_source.glyph_source = \ g.glyph.glyph_source.glyph_list[0] g.glyph.scale_mode = 'data_scaling_off' if not (self.has_vector_data or self.data_type_ == 'vector'): g.glyph.glyph_source.glyph_source.glyph_type = 'cross' g.actor.property.representation = 'points' g.actor.property.point_size = 3. self._preview_window.add_module(g) if not self.data_type_ in ('point', 'vector') or self.lines: s = Surface() s.actor.property.opacity = 0.3 self._preview_window.add_module(s) if not self.data_type_ == 'point': self._preview_window.add_filter(ExtractEdges()) s = Surface() s.actor.property.opacity = 0.2 self._preview_window.add_module(s)
class Kit2FiffPanel(HasPrivateTraits): """Control panel for kit2fiff conversion""" model = Instance(Kit2FiffModel) # model copies for view use_mrk = DelegatesTo('model') sqd_file = DelegatesTo('model') hsp_file = DelegatesTo('model') fid_file = DelegatesTo('model') stim_chs = DelegatesTo('model') stim_chs_manual = DelegatesTo('model') stim_slope = DelegatesTo('model') # info can_save = DelegatesTo('model') sqd_fname = DelegatesTo('model') hsp_fname = DelegatesTo('model') fid_fname = DelegatesTo('model') # Source Files reset_dig = Button # Visualization scene = Instance(MlabSceneModel) fid_obj = Instance(PointObject) elp_obj = Instance(PointObject) hsp_obj = Instance(PointObject) # Output save_as = Button(label='Save FIFF...') clear_all = Button(label='Clear All') queue = Instance(queue.Queue, ()) queue_feedback = Str('') queue_current = Str('') queue_len = Int(0) queue_len_str = Property(Str, depends_on=['queue_len']) error = Str('') view = View( VGroup( VGroup(Item('sqd_file', label="Data"), Item('sqd_fname', show_label=False, style='readonly'), Item('hsp_file', label='Dig Head Shape'), Item('hsp_fname', show_label=False, style='readonly'), Item('fid_file', label='Dig Points'), Item('fid_fname', show_label=False, style='readonly'), Item('reset_dig', label='Clear Digitizer Files', show_label=False), Item('use_mrk', editor=use_editor, style='custom'), label="Sources", show_border=True), VGroup(Item('stim_slope', label="Event Onset", style='custom', editor=EnumEditor(values={ '+': '2:Peak (0 to 5 V)', '-': '1:Trough (5 to 0 V)' }, cols=2), help="Whether events are marked by a decrease " "(trough) or an increase (peak) in trigger " "channel values"), Item('stim_chs', label="Binary Coding", style='custom', editor=EnumEditor(values={ '>': '1:1 ... 128', '<': '3:128 ... 1', 'man': '2:Manual' }, cols=2), help="Specifies the bit order in event " "channels. Assign the first bit (1) to the " "first or the last trigger channel."), Item('stim_chs_manual', label='Stim Channels', style='custom', visible_when="stim_chs == 'man'"), label='Events', show_border=True), HGroup(Item('save_as', enabled_when='can_save'), spring, 'clear_all', show_labels=False), Item('queue_feedback', show_label=False, style='readonly'), Item('queue_current', show_label=False, style='readonly'), Item('queue_len_str', show_label=False, style='readonly'), )) def __init__(self, *args, **kwargs): super(Kit2FiffPanel, self).__init__(*args, **kwargs) # setup save worker def worker(): while True: raw, fname = self.queue.get() basename = os.path.basename(fname) self.queue_len -= 1 self.queue_current = 'Processing: %s' % basename # task try: raw.save(fname, overwrite=True) except Exception as err: self.error = str(err) res = "Error saving: %s" else: res = "Saved: %s" # finalize self.queue_current = '' self.queue_feedback = res % basename self.queue.task_done() t = Thread(target=worker) t.daemon = True t.start() # setup mayavi visualization m = self.model self.fid_obj = PointObject(scene=self.scene, color=(25, 225, 25), point_scale=5e-3) m.sync_trait('fid', self.fid_obj, 'points', mutual=False) m.sync_trait('head_dev_trans', self.fid_obj, 'trans', mutual=False) self.elp_obj = PointObject(scene=self.scene, color=(50, 50, 220), point_scale=1e-2, opacity=.2) m.sync_trait('elp', self.elp_obj, 'points', mutual=False) m.sync_trait('head_dev_trans', self.elp_obj, 'trans', mutual=False) self.hsp_obj = PointObject(scene=self.scene, color=(200, 200, 200), point_scale=2e-3) m.sync_trait('hsp', self.hsp_obj, 'points', mutual=False) m.sync_trait('head_dev_trans', self.hsp_obj, 'trans', mutual=False) self.scene.camera.parallel_scale = 0.15 self.scene.mlab.view(0, 0, .15) def _clear_all_fired(self): self.model.clear_all() @cached_property def _get_queue_len_str(self): if self.queue_len: return "Queue length: %i" % self.queue_len else: return '' def _reset_dig_fired(self): self.reset_traits(['hsp_file', 'fid_file']) def _save_as_fired(self): # create raw try: raw = self.model.get_raw() except Exception as err: error(None, str(err), "Error Creating KIT Raw") raise # find default path stem, _ = os.path.splitext(self.sqd_file) if not stem.endswith('raw'): stem += '-raw' default_path = stem + '.fif' # save as dialog dlg = FileDialog(action="save as", wildcard="fiff raw file (*.fif)|*.fif", default_path=default_path) dlg.open() if dlg.return_code != OK: return fname = dlg.path if not fname.endswith('.fif'): fname += '.fif' if os.path.exists(fname): answer = confirm( None, "The file %r already exists. Should it " "be replaced?", "Overwrite File?") if answer != YES: return self.queue.put((raw, fname)) self.queue_len += 1
def traits_view(self): #======================================================================= # convienience functions #======================================================================= def make_sm_name(name): return 'object.stage_manager.{}'.format(name) def SItem(name, **kw): return Item( make_sm_name(name), # defined_when='mode!="client"', **kw) def CItem(name, **kw): return Item( 'object.stage_manager.canvas.{}'.format(name), # defined_when='mode!="client"', **kw) def CUItem(name, **kw): return UItem( 'object.stage_manager.canvas.{}'.format(name), # defined_when='mode!="client"', **kw) #======================================================================= # #======================================================================= # agrp = SUItem('stage_controller', style='custom') pgrp = Group(SUItem( 'calibrated_position_entry', tooltip='Enter a positon e.g 1 for a hole, or 3,4 for X,Y'), label='Calibrated Position', show_border=True) hgrp = HGroup( SUItem('stop_button'), SUItem('home'), SUItem( 'home_option', editor=EnumEditor(name='object.stage_manager.home_options'))) cngrp = VGroup( CItem('show_bounds_rect'), # Item('render_map'), CItem('show_grids'), HGroup( CItem('show_laser_position'), CUItem( 'crosshairs_color', # editor=ColorEditor(), # springy=True, # show_label=False )), CItem('crosshairs_kind'), CItem('crosshairs_radius'), HGroup(CItem('crosshairs_offsetx', label='Offset'), CUItem('crosshairs_offsety')), CItem('crosshairs_offset_color'), HGroup( CItem('show_desired_position'), CUItem('desired_position_color', # springy=True )), label='Canvas') # if self.model.mode != 'client': mode = self.model.mode # mvgrp = None # recgrp = None cagrp = VGroup(visible_when='use_video', label='Camera') if self.model.stage_manager.__class__.__name__ == 'VideoStageManager': mvgrp = VGroup( # HGroup(SItem('use_autocenter', label='Enabled'), # SUItem('autocenter_button', # enabled_when='use_autocenter'), # SUItem('configure_autocenter_button') # ), SUItem('autocenter_manager', style='custom'), SUItem('autofocus_manager', style='custom'), label='Machine Vision', show_border=True, ) recgrp = VGroup( HGroup( SItem('snapshot_button', show_label=False), VGroup(SItem('auto_save_snapshot'), SItem('render_with_markup'))), SUItem('record', editor=ButtonEditor( label_value=make_sm_name('record_label'))), show_border=True, label='Recording') cfggrp = VGroup( SItem('camera_zoom_coefficients', label='Zoom Coefficients')) cagrp.content.extend((cfggrp, recgrp, mvgrp)) # else: # recgrp = Group() # cagrp = VGroup( # recgrp, # # label='Machine Vision', show_border=True) # visible_when='use_video', # label='Camera' # ) # if mode != 'client' and mvgrp: # cagrp.content.insert(0, co) # cagrp.content.append(mvgrp) cgrp = Group(SUItem('stage_controller', style='custom', label='Axes'), cngrp, cagrp, layout='tabbed') if mode != 'client': grps = (SUItem('points_programmer', label='Points', defined_when='mode!="client"', style='custom'), SUItem( 'tray_calibration_manager', label='Calibration', style='custom', defined_when='mode!="client"', )) cgrp.content.extend(grps) v = View( # VFold(agrp, VGroup(hgrp, pgrp, cgrp) # ) ) # else: # v = View() return v
class TableFilterEditor(HasTraits): """ An editor that manages table filters. """ # ------------------------------------------------------------------------- # Trait definitions: # ------------------------------------------------------------------------- #: TableEditor this editor is associated with editor = Instance(TableEditor) #: The list of filters filters = List(TableFilter) #: The list of available templates from which filters can be created templates = Property(List(TableFilter), observe="filters") #: The currently selected filter template selected_template = Instance(TableFilter) #: The currently selected filter selected_filter = Instance(TableFilter, allow_none=True) #: The view to use for the current filter selected_filter_view = Property(observe="selected_filter") #: Buttons for add/removing filters add_button = Button("New") remove_button = Button("Delete") # The default view for this editor view = View( Group( Group( Group( Item("add_button", enabled_when="selected_template"), Item( "remove_button", enabled_when="len(templates) > 1 and " "selected_filter is not None", ), orientation="horizontal", show_labels=False, ), Label("Base filter for new filters:"), Item("selected_template", editor=EnumEditor(name="templates")), Item( "selected_filter", style="custom", editor=EnumEditor(name="filters", mode="list"), ), show_labels=False, ), Item( "selected_filter", width=0.75, style="custom", editor=InstanceEditor(view_name="selected_filter_view"), ), id="TableFilterEditorSplit", show_labels=False, layout="split", orientation="horizontal", ), id="traitsui.qt4.table_editor.TableFilterEditor", buttons=["OK", "Cancel"], kind="livemodal", resizable=True, width=800, height=400, title="Customize filters", ) # ------------------------------------------------------------------------- # Private methods: # ------------------------------------------------------------------------- # -- Trait Property getter/setters ---------------------------------------- @cached_property def _get_selected_filter_view(self): view = None if self.selected_filter: model = self.editor.model index = model.mapToSource(model.index(0, 0)) if index.isValid(): obj = self.editor.items()[index.row()] else: obj = None view = self.selected_filter.edit_view(obj) return view @cached_property def _get_templates(self): templates = [f for f in self.editor.factory.filters if f.template] templates.extend(self.filters) return templates # -- Trait Change Handlers ------------------------------------------------ def _editor_changed(self): self.filters = [ f.clone_traits() for f in self.editor.factory.filters if not f.template ] self.selected_template = self.templates[0] def _add_button_fired(self): """ Create a new filter based on the selected template and select it. """ new_filter = self.selected_template.clone_traits() new_filter.template = False new_filter.name = new_filter._name = "New filter" self.filters.append(new_filter) self.selected_filter = new_filter def _remove_button_fired(self): """ Delete the currently selected filter. """ if self.selected_template == self.selected_filter: self.selected_template = self.templates[0] index = self.filters.index(self.selected_filter) del self.filters[index] if index < len(self.filters): self.selected_filter = self.filters[index] else: self.selected_filter = None @observe("selected_filter:name") def _update_filter_list(self, event): """ A hack to make the EnumEditor watching the list of filters refresh their text when the name of the selected filter changes. """ filters = self.filters self.filters = [] self.filters = filters
class TableFilterEditor(HasTraits): """ An editor that manages table filters. """ #------------------------------------------------------------------------- # Trait definitions: #------------------------------------------------------------------------- # TableEditor this editor is associated with editor = Instance(TableEditor) # The list of filters filters = List(TableFilter) # The list of available templates from which filters can be created templates = Property(List(TableFilter), depends_on='filters') # The currently selected filter template selected_template = Instance(TableFilter) # The currently selected filter selected_filter = Instance(TableFilter, allow_none=True) # The view to use for the current filter selected_filter_view = Property(depends_on='selected_filter') # Buttons for add/removing filters add_button = Button('New') remove_button = Button('Delete') # The default view for this editor view = View(Group( Group(Group(Item('add_button', enabled_when='selected_template'), Item('remove_button', enabled_when='len(templates) > 1 and ' 'selected_filter is not None'), orientation='horizontal', show_labels=False), Label('Base filter for new filters:'), Item('selected_template', editor=EnumEditor(name='templates')), Item('selected_filter', style='custom', editor=EnumEditor(name='filters', mode='list')), show_labels=False), Item('selected_filter', width=0.75, style='custom', editor=InstanceEditor(view_name='selected_filter_view')), id='TableFilterEditorSplit', show_labels=False, layout='split', orientation='horizontal'), id='traitsui.qt4.table_editor.TableFilterEditor', buttons=['OK', 'Cancel'], kind='livemodal', resizable=True, width=800, height=400, title='Customize filters') #------------------------------------------------------------------------- # Private methods: #------------------------------------------------------------------------- #-- Trait Property getter/setters ---------------------------------------- @cached_property def _get_selected_filter_view(self): view = None if self.selected_filter: model = self.editor.model index = model.mapToSource(model.index(0, 0)) if index.isValid(): obj = list(self.editor.items())[index.row()] else: obj = None view = self.selected_filter.edit_view(obj) return view @cached_property def _get_templates(self): templates = [f for f in self.editor.factory.filters if f.template] templates.extend(self.filters) return templates #-- Trait Change Handlers ------------------------------------------------ def _editor_changed(self): self.filters = [ f.clone_traits() for f in self.editor.factory.filters if not f.template ] self.selected_template = self.templates[0] def _add_button_fired(self): """ Create a new filter based on the selected template and select it. """ new_filter = self.selected_template.clone_traits() new_filter.template = False new_filter.name = new_filter._name = 'New filter' self.filters.append(new_filter) self.selected_filter = new_filter def _remove_button_fired(self): """ Delete the currently selected filter. """ if self.selected_template == self.selected_filter: self.selected_template = self.templates[0] index = self.filters.index(self.selected_filter) del self.filters[index] if index < len(self.filters): self.selected_filter = self.filters[index] else: self.selected_filter = None @on_trait_change('selected_filter:name') def _update_filter_list(self): """ A hack to make the EnumEditor watching the list of filters refresh their text when the name of the selected filter changes. """ filters = self.filters self.filters = [] self.filters = filters
# ----------------------------------------------------------------------------- # LineStyle trait # ----------------------------------------------------------------------------- # Privates used for specification of line style trait. _line_style_trait_values = { "solid": None, "dot dash": array([3.0, 5.0, 9.0, 5.0]), "dash": array([6.0, 6.0]), "dot": array([2.0, 2.0]), "long dash": array([9.0, 5.0]), } # An editor preset for line styles. LineStyleEditor = EnumEditor(values=list(_line_style_trait_values)) # A mapped trait for use in specification of line style attributes. LineStyle = Map( _line_style_trait_values, default_value='solid', editor=LineStyleEditor, ) # ----------------------------------------------------------------------------- # Trait definitions: # ----------------------------------------------------------------------------- # Font trait: font_trait = KivaFont(default_font_name)