class DateEditor(EditorFactory): """ Editor factory for date/time editors. """ # ------------------------------------------------------------------------- # Trait definitions: # ------------------------------------------------------------------------- # -- ReadonlyEditor traits ------------------------------------------------ #: Message to show when Date is None. message = Str("Undefined") #: The string representation of the date to show. Uses time.strftime #: format. strftime = Str("%B %d %Y (%a)") #: An optional view to display when a read-only text editor is clicked: view = AView # -- CustomEditor traits -------------------------------------------------- #: Should users be able to pick future dates when using the CustomEditor? allow_future = Bool(True) #: How many months to show at a time. months = Int(3) #: True: Must be a List of Dates. False: Must be a Date instance. multi_select = Bool(False) #: When a user multi-selects entries and some of those entries are already #: selected and some are not, what should be the behavior for the seletion? #: #: Options: #: #: - 'toggle': Toggle each day to the opposite of the current state. #: - 'on': Always turn them on. #: - 'off': Always turn them off. #: - 'max_change': Change all to same state, with most days changing. #: For example 1 selected and 9 not, then they would all get selected. #: - 'min_change': Change all to same state, with min days changing. #: For example 1 selected and 9 not, then they would all get unselected. on_mixed_select = Enum("toggle", "on", "off", "max_change", "min_change") #: How much space to put between the individual months. padding = Int(5) #: Does the user have to hold down Shift for the left-click multiselect? shift_to_select = Bool(False) #: Style used when a date is selected. selected_style = Instance( CellFormat, kw={ "bold": True, "fgcolor": (255, 255, 255), "bgcolor": (0, 128, 0) }, )
class VisibleWhenProblem(HasTraits): which = Enum("one", "two") on = Bool() txt = Str() onoff_group = HGroup( VGroup( Item("on", resizable=False, width=-100, height=-70), show_left=False, show_border=True, visible_when='which == "one"', ) ) text_group = VGroup( Item("txt", width=-_TEXT_WIDTH, height=-_TEXT_HEIGHT), visible_when='which == "two"', show_border=True, ) traits_view = View( Item("which"), VGroup(Include("onoff_group"), Include("text_group")), resizable=True, buttons=["OK", "Cancel"], )
class Node(pynetsym.Node): state = Enum('S', 'I', 'R') recovery_rate = Float(1.0) infection_rate = Float(1.0) spread_out = False def initialize(self, state): self.state = state if state == 'I': self.send(Activator.name, 'infected', node=self.id) def infect(self): if self.state == 'S': self.state = 'I' self.send(Activator.name, 'infected', node=self.id) def activate(self): if self.state == 'I': if not self.spread_out or self.infection_rate < 1.0: for node in self.neighbors(): if random.random() < self.infection_rate: self.send(node, 'infect') self.spread_out = True if random.random() < self.recovery_rate: self.state = 'R' self.send(Activator.name, 'not_infected', node=self.id)
class Node(pynetsym.Node): state = Enum('S', 'I', 'R') recovery_rate = Float(1.0) infection_rate = Float(1.0) infected_fraction = Float def initialize(self, state): self.state = state if state == 'I': self.send(Activator.name, 'infected', node=self.id) def infect(self): if self.state == 'S': self.state = 'I' self.send(Activator.name, 'infected', node=self.id) def activate(self): if self.state == 'I': for node in self.neighbors(): if random.random() < self.infection_rate: self.send(node, 'infect') if random.random() < self.recovery_rate: self.state = 'R' self.send(Activator.name, 'not_infected', node=self.id) elif self.state in ('R', 'S'): pass else: self.send_log('I should not get here.')
def _pin_changed(self): self.initmode = True self.name = self.pin.name self.mode = ['INPUT', 'OUTPUT'][self.pin.read_mode()] if self.mode == 'OUTPUT': # TODO: self.digital_output = bool(self.pin.read_digital_value()) self.function = self.pin.programming_function if hasattr(self.pin, 'is_usb_plus'): self.usb = ['', '+', '-'][self.pin.is_usb_plus + 2 * self.pin.is_usb_minus] else: self.usb = '' if self.pin.pwm.available: ls = [ int(x) for x in self.pin.pwm.frequencies_available if x is not None ] if not ls: ls = [-1] self.add_trait('pwm_frequency', Enum(ls)) self.pwm_frequency = int( self.pin.pwm.frequency if self.pin.pwm.frequency else -1) self.timer = self.pin.pwm.timer_register_name_b self.avr_pin = self.pin.avr_pin self.initmode = False
class VisibleWhenProblem(HasTraits): which = Enum('one', 'two') on = Bool txt = Str onoff_group = HGroup( VGroup(Item('on', resizable=False, width=-100, height=-70), show_left=False, show_border=True, visible_when='which == "one"'), ) text_group = VGroup( Item('txt', width=-_TEXT_WIDTH, height=-_TEXT_HEIGHT), visible_when='which == "two"', show_border=True, ) traits_view = View(Item('which'), VGroup( Include('onoff_group'), Include('text_group'), ), resizable=True, buttons=['OK', 'Cancel'])
def PinTrait(typ='all'): analog = ['A%s' % x for x in range(6)] digital = ['D%s' % x for x in range(14)] # if typ == 'analog': # return Enum(analog) # if typ == 'digital': # return Enum(digital) return Enum(['GND'] + digital + analog)
class FlipBvecInputSpec(BaseInterfaceInputSpec): bvecs = File(exists=True, desc="Input diffusion gradient bvec file") flipping_axis = List(desc="List of axis to be flipped") delimiter = Str(desc="Delimiter used in the table") header_lines = Int(0, desc="Line number of table header") orientation = Enum(['v', 'h'], desc="Orientation of the table")
class CodeView(ModelView): model = Instance(CodeModel) show_line_numbers = Bool(True) style = Enum('simple', 'readonly') def default_traits_view(self): traits_view = View( Item('model.code', editor=CodeEditor(show_line_numbers=self.show_line_numbers), style=self.style)) return traits_view
class ApplymultipleXfmInputSpec(BaseInterfaceInputSpec): in_files = InputMultiPath(File(mandatory=True, exists=True), desc="Files to be registered") xfm_file = File(desc="Transform file", mandatory=True, exists=True) reference = File(desc="Reference image used for target space", mandatory=True, exists=True) interp = Enum('nearestneighbour', 'spline', desc='Interpolation used')
class BoardWrapper(HasTraits): port = Enum(ports) def _port_changed(self): if self.serialobj: self.serialobj.close() self.serialobj = None try: self.serialobj = serial.Serial(self.port) except serial.serialutil.SerialException, e: print '%s %s' % (self.port, e)
class DateEditor(EditorFactory): """ Editor factory for date/time editors. """ #------------------------------------------------------------------------- # Trait definitions: #------------------------------------------------------------------------- #-- ReadonlyEditor traits ------------------------------------------------ # Message to show when Date is None. message = Str('Undefined') # The string representation of the date to show. Uses time.strftime # format. strftime = Str('%B %d %Y (%a)') # An optional view to display when a read-only text editor is clicked: view = AView #-- CustomEditor traits -------------------------------------------------- # Should users be able to pick future dates when using the CustomEditor? allow_future = Bool(True) # How many months to show at a time. months = Int(3) # True: Must be a List of Dates. False: Must be a Date instance. multi_select = Bool(False) # When a user multi-selects entries and some of those entries are already # selected and some are not, what should be the behavior for the seletion? # Options:: # # 'toggle' -- Toggle each day to the opposite of the current state. # 'on' -- Always turn them on. # 'off' -- Always turn them off. # 'max_change' -- Change all to same state, with most days changing. # For example 1 selected and 9 not, then they would # all get selected. # 'min_change' -- Change all to same state, with min days changing. # For example 1 selected and 9 not, then they would # all get unselected. on_mixed_select = Enum('toggle', 'on', 'off', 'max_change', 'min_change') # How much space to put between the individual months. padding = Int(5) # Does the user have to hold down Shift for the left-click multiselect? shift_to_select = Bool(False)
class Specimen(Node): state = Enum('S', 'I', 'R') remaining_infection_time = Int(-1) infection_probability = Float average_infection_length = Int std_infection_length = Int(3) infected_fraction = Float # DEBUG_SEND = True def infection_time(self): value = int( random.gauss(self.average_infection_length, self.std_infection_length)) tmp_solution.tduration[self.id] = value return value def initialize(self, state): self.state = state if state == 'I': self.remaining_infection_time = self.infection_time() self.send(Activator.name, 'infected', node=self.id) def infect(self): if self.state == 'S': self.state = 'I' self.remaining_infection_time = self.infection_time() self.send(Activator.name, 'infected', node=self.id) def activate(self): if (self.state == 'I' and self.remaining_infection_time > 0): for node in self.neighbors(): if random.random() < self.infection_probability: self.send(node, 'infect') self.remaining_infection_time -= 1 elif (self.state == 'I' and self.remaining_infection_time == 0): self.remaining_infection_time -= 1 self.state = 'R' self.send(Activator.name, 'not_infected', node=self.id) elif self.state in ('R', 'S'): pass else: self.send_log('I should not get here.')
class FluxTool(HasTraits): calculate_button = Button('Calculate') monitor_age = Property(depends_on='monitor') color_map_name = Str('jet') levels = Int(10, auto_set=False, enter_set=True) model_kind = Str('Plane') data_source = Str('database') # plot_kind = Str('Contour') plot_kind=Enum('Contour','Hole vs J') # def _plot_kind_default(self,): monitor=Any monitors=List group_positions=Bool(False) def _monitor_default(self): return DummyFluxMonitor() def _get_monitor_age(self): ma = 28.02e6 if self.monitor: ma=self.monitor.age return ma def traits_view(self): contour_grp = VGroup(Item('color_map_name', label='Color Map', editor=EnumEditor(values=sorted(color_map_name_dict.keys()))), Item('levels'), visible_when='plot_kind=="Contour"') monitor_grp=Item('monitor', editor=EnumEditor(name='monitors')) v = View( VGroup(HGroup(UItem('calculate_button'), UItem('data_source', editor=EnumEditor(values=['database', 'file'])), monitor_grp), HGroup(Item('group_positions'), Item('object.monitor.sample', style='readonly',label='Sample')), HGroup(UItem('plot_kind'), Item('model_kind', label='Fit Model', editor=EnumEditor(values=['Bowl', 'Plane']))), # UItem('plot_kind', editor=EnumEditor(values=['Contour', 'Hole vs J']))), contour_grp)) return v
class ContextPlotEditor(BasicEditorFactory): plot_items = List() view_shadows = Bool(True) show_all = Bool(False) plot_configs = List() #(PlotConfig) klass = _ContextPlotEditor orientation = Enum('v', 'h') def simple_editor(self, ui, object, name, description, parent): return self.klass( parent, factory=self, ui=ui, object=object, name=name, description=description, plot_items=self.plot_items, view_shadows=self.view_shadows, plot_configs=self.plot_configs, orientation=self.orientation, show_all=self.show_all, )
class FluxTool(HasTraits): calculate_button = Button('Calculate') monitor_age = Property(depends_on='monitor') color_map_name = Str('jet') marker_size = Int(5) levels = Int(50, auto_set=False, enter_set=True) model_kind = Str('Plane') data_source = Str('database') # plot_kind = Str('Contour') plot_kind = Enum('Contour', 'Hole vs J') # def _plot_kind_default(self,): monitor = Any monitors = List group_positions = Bool(False) show_labels = Bool(True) mean_j_error_type = Enum(*ERROR_TYPES) predicted_j_error_type = Enum(*ERROR_TYPES) _prev_predicted_j_error_type = Str use_weighted_fit = Bool(False) use_monte_carlo = Bool(False) monte_carlo_ntrials =Int(10000) save_mean_j = Bool(False) auto_clear_cache = Bool(False) def _monitor_default(self): return DummyFluxMonitor() def _get_monitor_age(self): ma = 28.02e6 if self.monitor: ma = self.monitor.age return ma def _use_weighted_fit_changed(self, new): if new: self._prev_predicted_j_error_type = self.predicted_j_error_type self.predicted_j_error_type = 'SD' else: self.predicted_j_error_type = self._prev_predicted_j_error_type def traits_view(self): contour_grp = HGroup(Item('color_map_name', label='Color Map', editor=EnumEditor(values=sorted(color_map_name_dict.keys()))), Item('levels'), Item('marker_size'), visible_when='plot_kind=="Contour"') monitor_grp = Item('monitor', editor=EnumEditor(name='monitors')) v = View( VGroup(HGroup(UItem('calculate_button'), UItem('data_source', editor=EnumEditor(values=['database', 'file'])), monitor_grp), HGroup(Item('save_mean_j', label='Save Mean J'), Item('auto_clear_cache', label='Auto Clear Cache')), Item('mean_j_error_type', label='Mean J Error'), HGroup(Item('use_weighted_fit'), Item('use_monte_carlo'), Item('monte_carlo_ntrials', enabled_when='object.use_monte_carlo')), Item('predicted_j_error_type', label='Predicted J Error', enabled_when='not (object.use_weighted_fit or object.use_monte_carlo)'), HGroup(Item('group_positions'), Item('object.monitor.sample', style='readonly', label='Sample')), Item('show_labels', label='Display Labels', tooltip='Display hole labels on plot'), HGroup(UItem('plot_kind'), Item('model_kind', label='Fit Model', editor=EnumEditor(values=['Bowl', 'Plane']))), # UItem('plot_kind', editor=EnumEditor(values=['Contour', 'Hole vs J']))), contour_grp)) return v
class AnnotationsStatisticsView(HasTraits): statistics_name = Enum(ALL_STATS_NAMES) annotations = Array nclasses = Int info_button = Button("Info...") stats_view = Instance(HasTraits) def _info_button_fired(self): """Open dialog with description of statistics.""" if self.statistics_name in GLOBAL_STATS: stat_func = GLOBAL_STATS[self.statistics_name] else: stat_func = PAIRWISE_STATS[self.statistics_name] message(message=stat_func.__doc__, title='Statistics info') @on_trait_change('statistics_name') def _update_stats_view(self): if self.statistics_name in GLOBAL_STATS: stat_func = GLOBAL_STATS[self.statistics_name] try: res = stat_func(self.annotations, nclasses=self.nclasses) except PyannoValueError as e: logger.info(e) res = np.nan self.stats_view = _SingleStatView(value=res, name=self.statistics_name) else: stat_func = PAIRWISE_STATS[self.statistics_name] try: res = measures.pairwise_matrix(stat_func, self.annotations, nclasses=self.nclasses) except PyannoValueError as e: logger.info(e) nannotators = self.annotations.shape[1] res = np.empty((nannotators, nannotators)) res.fill(np.nan) self.stats_view = MatrixPlot(matrix=res, colormap_low=-1.0, colormap_high=1.0, title=self.statistics_name) def traits_view(self): self.statistics_name = "Cohen's Kappa" traits_view = View(VGroup( HGroup(Item("statistics_name", show_label=False), Item("info_button", show_label=False)), Spring(), HGroup( Spring(), Item("stats_view", style="custom", show_label=False, width=300, resizable=False), Spring()), ), width=400, resizable=True) return traits_view
class ModelBView(PyannoModelView): """ Traits UI Model/View for 'ModelB' objects. """ # name of the model (inherited from PyannoModelView) model_name = MODEL_B_NAME # dialog to instantiated when creating a new model new_model_dialog_class = NewModelBDialog @classmethod def _create_model_from_dialog(cls, dialog): # create prior alpha from user choice # prior strength multiplies the dirichlet parameters alpha alpha = (np.array(ALPHA_DEFAULT) - 1.) * dialog.prior_strength + 1. alpha = create_band_matrix(dialog.nclasses, alpha) model = ModelB.create_initial_state(dialog.nclasses, dialog.nannotators, alpha=alpha) return model @on_trait_change('model,model_updated') def update_from_model(self): """Update view parameters to the ones in the model.""" self.pi_hinton_diagram = HintonDiagramPlot( data = self.model.pi.tolist(), title = 'Pi parameters, P(label=k)') self.theta_matrix_plot = ModelB_MatrixThetaView(theta=self.model.theta) self.theta_line_plot = ModelB_LineThetaView(theta=self.model.theta) self.accuracy_plot = ThetaDistrPlot( theta=self.model.annotator_accuracy()) self._theta_view_update() def plot_theta_samples(self, samples): theta_samples, pi_samples, _ = samples self.theta_line_plot = ModelB_LineThetaView( theta = self.model.theta, theta_samples = theta_samples ) self.accuracy_plot = ThetaDistrPlot( theta = self.model.annotator_accuracy(), theta_samples = self.model.annotator_accuracy_samples( theta_samples, pi_samples), ) self._theta_view_update() #### UI traits pi_hinton_diagram = Instance(HintonDiagramPlot) theta_matrix_plot = Instance(ModelB_MatrixThetaView) theta_line_plot = Instance(ModelB_LineThetaView) accuracy_plot = Instance(ThetaDistrPlot) theta_views = Enum('Line plot', 'Matrix plot (does not support samples)', 'Accuracy plot, P(annotator j is correct)') theta_view = Instance(HasTraits) def _theta_view_default(self): return self.theta_line_plot @on_trait_change('theta_views') def _theta_view_update(self): if self.theta_views.startswith('Line'): self.theta_view = self.theta_line_plot elif self.theta_views.startswith('Matrix'): self.theta_view = self.theta_matrix_plot else: self.theta_view = self.accuracy_plot #### Actions view_pi = Button(label='View Pi...') view_theta = Button(label='View Theta...') edit_prior = Button(label='Edit priors (Alpha, Beta)...') def _view_pi_fired(self): """Create viewer for parameters pi.""" pi_view = ParametersTabularView( title = 'Model B, parameters Pi', data = [self.model.pi.tolist()] ) pi_view.edit_traits() def _view_theta_fired(self): """Create viewer for parameters theta.""" ModelB_TabularThetaView.show(self.model.theta) def _edit_prior_fired(self): """Create editor for prior parameters.""" beta, alpha = ModelB_PriorView.show(beta=self.model.beta, alpha=self.model.alpha) if beta is not None: # user pressed 'OK' self.model.beta = beta self.model.alpha = alpha self.model_updated = True #### Traits UI view ######### def traits_view(self): if is_display_small(): w_view = 400 else: w_view = 510 parameters_group = VGroup( Item('_'), HGroup( Item('handler.edit_prior', show_label=False, width=100), Spring(), ), Item('_'), HGroup( VGroup( Spring(), Item('handler.pi_hinton_diagram', style='custom', resizable=False, show_label=False, width=w_view), Spring(), ), Spring(), VGroup( Spring(), Item('handler.view_pi', show_label=False), Spring() ), ), Item('_'), HGroup( VGroup( Item('handler.theta_views', show_label=False), Item('handler.theta_view', style='custom', resizable=False, show_label=False, width = w_view), Spring() ), VGroup( Spring(), Item('handler.view_theta', show_label=False), Spring() ) ), ) body = VGroup( Include('info_group'), parameters_group ) traits_view = View(body, buttons=[OKButton], resizable=True) return traits_view
def __init__(self, visualisation_model, decision_threshold, start_day=3, num_of_shown_days="30 days", precompute_cache=False): ''' :param visualisation_model: an instance of EventDataModel :param decision_threshold: a float larger or equal to 0.0 that is used for deciding when an anomaly score is significantly anomalous :param start_day: an integer >= or an instance of datetime.date or an string, like "2014-10-11" or a tuple, like (2014, 10, 11) :param num_of_shown_days: an integer > 1 that specifies the number of days back in time from start_day that will be shown. :param precompute_cache: boolean that indates whether all anomaly scores should be computed at once or when asked for. :return: ''' assert isinstance(visualisation_model, EventDataModel) assert isinstance( start_day, int) or isinstance(start_day, str) or isinstance( start_day, datetime.date) or (isinstance(start_day, tuple) and len(start_day) == 3) HasTraits.__init__(self) self.used_cache_size = 0 # must be initialized self._data = visualisation_model._event_data_object self.num_of_shown_days = num_of_shown_days # Updates self.used_cache_size self._vis_model = visualisation_model self._anomaly_detector = visualisation_model._anomaly_detector self.anomaly_detection_threshold = decision_threshold dates = visualisation_model._event_data_object.dates_ self._data_times = array([datetools.to_datetime(d) for d in dates]) self.source_names = list( unique(visualisation_model._event_data_object.sources_)) self._data_sources = array([ self.source_names.index(source) for source in visualisation_model._event_data_object.sources_ ]) self._num_of_sources = len(unique( self.source_names)) # number of sources self.barcharts = [] self.barchart_actors = [] self.time_text3ds = [] self.source_text3ds = [] self.xy_positions = [] self._high_start_day_number = int( (self._data_times.max() - self._data_times.min()).days) self.scene.anti_aliasing_frames = 8 # add traits dynamically self.add_trait("Relative_Start_Day", Range(0, self._high_start_day_number)) self.add_trait("_selected_source_name", Enum(None, [None] + self.source_names)) self.configure_traits() self.scene.background = self.background # add the mouse pick handler self.picker = self.scene.mayavi_scene.on_mouse_pick( self.vis_picker, 'cell') self.picker.tolerance = 0.01 #cmap = matplotlib.cm.get_cmap('Reds') #self.severity_color = [cmap(x)[:-1] for x in linspace(0.75, 0.95, self._vis_model.num_of_severity_levels_)] if self._vis_model.num_of_severity_levels_ > 1: self.severity_color = self.severity_color = [ (1, x / 100.0, x / 100.0) for x in range(70, 30, -40 / self._vis_model.num_of_severity_levels_) ] else: self.severity_color = [(255.0 / 255, 51 / 255.0, 51 / 255.0)] # This used for a fix to manage a bug in Mayavi library, an invisible default object self._obj = self.scene.mlab.points3d(0, 0, 0, opacity=0.0) # Cache all anomaly calculations for all data values if precompute_cache: self.used_cache_size = len(self._data) for data_index in xrange(len(self._data)): self._populate_cache(data_index) self.start_day = start_day self.update()
class PlotWnd(FigureWnd): dummy = Any def _dummy_default(self): self._project_changed() configfile = ConfigFile() # conf = None project = Enum(projects) def mfullpath(self, m): return self.project.result_dir / m def _project_default(self): x = Project.find(self.configfile.get('project')) if x: return x else: return projects[-1] plot_type = Any def _plot_type_default(self): x = self.project.plot(self.configfile.get('plot_type')) if x: return x else: if len(self.available_plots): return self.available_plots[-1] available_plots = List() def _available_plots_default(self): return self.project.allplots() measurement = Any available_measurements = List() def _available_measurements_default(self): return self.project.allmeasurements() # @traced def _measurement_changed(self): self.update_figure() self.result = '' self.result = self.project.analyse_str(self.mfullpath( self.measurement)) def _plot_type_changed(self): self.update_figure() if self.plot_type: self.configfile.set('plot_type', self.plot_type.name) def _available_plots_changed(self): if len(self.available_plots): self.plot_type = self.available_plots[0] # @traced def update_available_measurements(self): def fnames(ls): return [x.name for x in ls] self.available_measurements = fnames(self.project.allmeasurements()) if len(self.available_measurements): self.measurement = self.available_measurements[-1] else: self.measurement = None # self.measurement = None def _project_changed(self): self.configfile.set('project', self.project.name) # self.plot_type = None # self.available_plots = [] # self.measurement = None # self.available_measurements = [] self.update_available_measurements() self.available_plots = self.project.allplots() # if len(self.available_plots): # self.plot_type = self.available_plots[0] def create_plot(self, fig): # dw = DataWrapper(zipfile=self.measurement) try: assert self.measurement self.plot_type.create(fig, self.mfullpath(self.measurement)) except Exception as e: traceback.print_exc() # def measure(self, conf, stop_condition): # self.project.measure() reload = Button() def _reload_fired(self): self.update_available_measurements() show = Button() def _show_fired(self): assert self.measurement # dw = DataWrapper(zipfile=self.mfullpath(self.measurement)) # file_out = tempfile.NamedTemporaryFile( # prefix='measurement_', suffix='.json', delete=0) # file_out.close() # self.project.save(file_out.name, as_zip=0) d = tmpdir() z = ZipFile(self.mfullpath(self.measurement)) z.extractall(d) for f in d.walkfiles(): print f open_text_file_in_editor(f) rename = Button() def _rename_fired(self): assert self.measurement newname = inputbox(message='new name:', default=self.measurement) if newname: (self.project.result_dir / self.measurement).rename( self.project.result_dir / newname) self.update_available_measurements() delete = Button() def _delete_fired(self): assert self.measurement res = message('Delete "%s" ?' % self.measurement, buttons=['OK', 'Cancel']) if res: # path (self.project.result_dir / self.measurement).remove() self.update_available_measurements() directory = Button() def _directory_fired(self): open_text_file_in_editor(self.project.result_dir) analyse = Button() def _analyse_fired(self): assert self.measurement s = self.project.analyse_str(self.mfullpath(self.measurement)) print(s) textbox(s) open = Button() def _open_fired(self): # print self.measurement assert self.measurement # show.show(self.project.name, self.plot_type.name, self.measurement, # block=False) self.plot_type.display(self.mfullpath(self.measurement), block=False) config = Button() def _config_fired(self): open_text_file_in_editor(self.project.default_config_path) schematic_template = Button() def _schematic_template_fired(self): open_text_file_in_editor(self.project.schematic.template_path) schematic = Button() def _schematic_fired(self): open_string_in_editor(self.project.schematic.text) measure = Button() def _measure_fired(self): # print self.project.schematic.text # print self.project.default_config self.project.measure() self.update_available_measurements() # print self.available_plots # data = analyse(data) # IV_curve_plot(data, fig) # def measure(self, conf, stop_condition): # data = measure(self.conf) # return data result = Str() view = View( Group( Item(name='dummy', defined_when='0'), HGroup( 'project', button('config'), button('schematic_template'), button('schematic'), button('measure'), ), HGroup( Item( name='measurement', editor=EnumEditor(name='available_measurements'), # style='custom', ), button('reload'), button('show'), button('directory'), button('analyse'), button('rename'), button('delete'), ), HGroup( Item( name='plot_type', editor=EnumEditor(name='available_plots'), # style='custom', ), button('open'), ), # 'start', # 'stop', # 'auto_update', # readonly('alive', checkbox=True), ), '_', Tabbed( Item('figure', editor=MPLFigureEditor(), show_label=False), Item( name='result', show_label=False, style='readonly', editor=CodeEditor(), ), ), width=900, height=600, resizable=True)
class _ContextPlotEditor(Editor): scrollable = True plot = Instance(PlotComponent) view_shadows = Bool(True) plot_items = List() show_all = Bool(False) plot_configs = List() #(PlotConfig) orientation = Enum('v', 'h') def init(self, parent): self.create_plot() self._window = Window(parent, component=self.plot, bgcolor=(236 / 255.0, 233 / 255.0, 216 / 255.0)) self.control = self._window.control self.value.on_trait_change(self._context_items_changed, 'items_modified') return def _shadow_changed(self, event): self._context_items_changed(event) def _context_items_changed(self, event): if len(event.added) > 0 or len(event.removed) > 0: self.update_editor() def update_editor(self): self.create_plot() self._window.component = self.plot self.plot.request_redraw() return def create_plot(self): if hasattr(self.value, 'shadows'): color_gen = color_generator() shadowcolors = {} for shadow in self.value.shadows: shadowcolors[shadow] = color_gen.next() container_class = { 'h': HPlotContainer, 'v': VPlotContainer }[self.orientation] container = container_class(spacing=15, padding=15, bgcolor='transparent') container.fill_padding = True container.bgcolor = (236 / 255.0, 233 / 255.0, 216 / 255.0) if self.show_all: self.plot_items = self.value.keys() if len(self.plot_items) > 0: plot_configs = [] for (plot_num, var_name) in enumerate(self.plot_items): if not (isinstance(self.value[var_name], ndarray) and \ len(self.value[var_name].shape) == 1): continue plot_configs.append( PlotConfig(x=var_name + '_index', y=var_name, type='Line', number=plot_num)) self.plot_configs = plot_configs if len(self.plot_configs) > 0: number_to_plots = {} for plot_config in self.plot_configs: plotlist = number_to_plots.get(plot_config.number, []) plotlist.append(plot_config) number_to_plots[plot_config.number] = plotlist keys = number_to_plots.keys() keys.sort() container_list = [number_to_plots[number] for number in keys] for plot_group in container_list: context_adapter = PlotDataContextAdapter(context=self.value) plot = Plot(context_adapter) plot.padding = 15 plot.padding_left = 35 plot.padding_bottom = 30 plot.spacing = 15 plot.border_visible = True for plot_item in plot_group: if len(self.value[plot_item.y].shape) == 2: color_range = DataRange1D( low=min(self.value[plot_item.y]), high=max(self.value[plot_item.y])) plot.img_plot(plot_item.y, colormap=gray(color_range), name=plot_item.y) else: plot_type = { 'Line': 'line', 'Scatter': 'scatter' }[plot_item.type] plot.plot( (plot_item.x, plot_item.y), name=plot_item.x + " , " + plot_item.y, color=(.7, .7, .7), type=plot_type, ) if plot.index_axis.title != '': plot.index_axis.title = plot.index_axis.title + ', ' + plot_item.x else: plot.index_axis.title = plot_item.x if plot.value_axis.title != '': plot.value_axis.title = plot.value_axis.title + ', ' + plot_item.y else: plot.value_axis.title = plot_item.y if self.view_shadows and hasattr( self.value, 'shadows'): self.generate_shadow_plots(plot, shadowcolors, plot_item, plot_type) plot.tools.append(PanTool(plot)) container.add(plot) self.plot = container def generate_shadow_plots(self, plot, shadowcolors, plot_item, plot_type): shadow_num = 0 shadow = None for shadow_num, shadow in enumerate(self.value.shadows): show_shadow = False x_value = plot_item.x y_value = plot_item.y color_value = plot_item.color if plot_item.x in shadow.keys(): show_shadow = True x_value = 'shadow_' + str(shadow_num) + '_' + plot_item.x if plot_item.y in shadow.keys(): show_shadow = True y_value = 'shadow_' + str(shadow_num) + '_' + plot_item.y if plot_item.color is not None and plot_item.color in shadow.keys( ): color_value = 'shadow_' + str(shadow_num) + '_' + plot_item.y if show_shadow: if color_value is not None and color_value != '': plot.plot((x_value, y_value, color_value), type='cmap_scatter', name='shadow: ' + x_value + ' ' + y_value, bgcolor='transparent', color_mapper=hsv) else: plot.plot( (x_value, y_value), type=plot_type, name='shadow: ' + x_value + ' ' + y_value, color=shadowcolors[shadow], bgcolor='transparent', ) return
class ModelBtLoopDesignView(PyannoModelView): """ Traits UI Model/View for 'ModelBtLoopDesign' objects. """ model_name = Str(MODEL_BT_NAME) new_model_dialog_class = NewModelBtLoopDesignDialog @classmethod def _create_model_from_dialog(cls, dialog): return ModelBtLoopDesign.create_initial_state(dialog.nclasses) #### Model properties gamma = List(CFloat) @on_trait_change('model,model_updated') def update_from_model(self): """Update view parameters to the ones in the model.""" self.gamma = self.model.gamma.tolist() self.theta_distribution_plot = ThetaDistrPlot(theta=self.model.theta) self.theta_scatter_plot = ThetaScatterPlot(model=self.model) self._theta_view_update() def _gamma_default(self): return self.model.gamma.tolist() @on_trait_change('gamma[]', post_init=True) def _update_gamma(self): self.model.gamma = np.asarray(self.gamma) self.gamma_hinton.data = self.gamma #### UI-related traits gamma_hinton = Instance(HintonDiagramPlot) theta_scatter_plot = Instance(ThetaScatterPlot) theta_distribution_plot = Instance(ThetaDistrPlot) theta_views = Enum('Distribution plot', 'Scatter plot') theta_view = Instance(PyannoPlotContainer) def _gamma_hinton_default(self): return HintonDiagramPlot(data = self.gamma, title='Gamma parameters, P(label=k)') def _theta_view_default(self): return self.theta_distribution_plot @on_trait_change('theta_views') def _theta_view_update(self): if self.theta_views.startswith('Distr'): self.theta_view = self.theta_distribution_plot else: self.theta_view = self.theta_scatter_plot def plot_theta_samples(self, theta_samples): self.theta_distribution_plot = ThetaDistrPlot( theta = self.model.theta, theta_samples = theta_samples ) self.theta_scatter_plot = ThetaScatterPlot(model = self.model) self.theta_scatter_plot.theta_samples = theta_samples self.theta_scatter_plot.theta_samples_valid = True self._theta_view_update() #### Actions view_gamma = Button(label='View Gamma...') view_theta = Button(label='View Theta...') def _view_gamma_fired(self): """Create viewer for gamma parameters.""" gamma_view = ParametersTabularView( title = 'Model B-with-Theta, parameters Gamma', data=[self.gamma] ) gamma_view.edit_traits() def _view_theta_fired(self): """Create viewer for theta parameters.""" theta_view = ParametersTabularView( title = 'Model B-with-Theta, parameters Theta', data=[self.model.theta.tolist()] ) theta_view.edit_traits() #### Traits UI view ######### def traits_view(self): if is_display_small(): w_view = 350 else: w_view = 480 parameters_group = VGroup( Item('_'), HGroup( VGroup( Spring(), Item('handler.gamma_hinton', style='custom', resizable=False, show_label=False, width=w_view ), Spring() ), Spring(), VGroup( Spring(), Item('handler.view_gamma', show_label=False), Spring() ) ), Spring(), Item('_'), Spring(), HGroup( VGroup( UItem('handler.theta_views'), UItem('handler.theta_view', style='custom', resizable=False, width=w_view ), Spring() ), Spring(), VGroup( Spring(), UItem('handler.view_theta'), Spring() ) ) ) body = VGroup( Include('info_group'), parameters_group, ) traits_view = View(body, buttons=[OKButton], resizable=True) return traits_view
class BoardWrapper(HasTraits): pins = List(PinWrapper) digital_pins = List(PinWrapper) analog_pins = List(PinWrapper) defines = List(GuiDefine) port_type = Enum('serial', [ 'none', 'serial', ] ) serial_device = Enum(_auto_detect_serial_unix()) baudrate = Int(115200) sleep_after_connect = Int(2) timeout = Int(1) uptime = Float() tree = None vcc = Float() avr_name = Str() arduino_version = Str() firmware_build_time = Str() gcc_version = Str() libc_version = Str() libc_date = Str() connected = Bool(False) connect = Button() disconnect = Button() def _connect_fired(self): try: connection = SerialManager(device=self.serial_device, baudrate=self.baudrate, sleep_after_connect=self.sleep_after_connect, timeout=self.timeout) connection.open() print ArduinoApi(connection=connection).millis() except Exception as e: traceback.print_exc() message(traceback.format_exc(), buttons=['OK']) return a = self.tree = ArduinoTree(connection=connection) d = a.define.as_dict s = [GuiDefine(name=k, value=str(v)) for k, v in d.items()] s.sort(key=lambda x: x.name) self.defines = s self.digital_pins = [PinWrapper(pin=a.pin.get(x)) for x in a.pin.names_digital] self.analog_pins = [PinWrapper(pin=a.pin.get(x)) for x in a.pin.names_analog] self.pins = self.digital_pins + self.analog_pins fw = a.firmware_info self.arduino_version = fw.get('arduino_version') self.firmware_build_time = str(fw.get('compile_datetime')) self.avr_name = fw.get('avr_name') self.gcc_version = fw.get('gcc_version') self.libc_version = fw.get('libc_version') self.libc_date = str(fw.get('libc_date')) self.connected = True def _disconnect_fired(self): self.digital_pins = [] self.analog_pins = [] self.pins = [] self.defines = [] self.avr_name = '' self.arduino_version = '' self.firmware_build_time = '' self.gcc_version = '' self.libc_version = '' self.libc_date = '' self.tree.connection.close() del self.tree self.tree = None self.connected = False update_interval = Int(1000, desc='interval in msec') update_enable = Bool(True) def update(self): if self.update_enable and self.connected and self.tree: for x in self.pins: x.update() self.uptime = self.tree.api.millis() / 1000.0 self.vcc = self.tree.vcc.read() if self.tree.vcc else -1 time.sleep(self.update_interval / 1000.0) traits_view = View( Tabbed( Group( HGroup( Group( button('connect', enabled_when='not connected'), button('disconnect', enabled_when='connected'), Item( 'port_type', enabled_when='not connected', width=300, ), Group( 'serial_device', 'baudrate', 'sleep_after_connect', 'timeout', visible_when='port_type=="serial"', enabled_when='not connected', ), ), Group( 'avr_name', 'arduino_version', 'firmware_build_time', 'gcc_version', 'libc_version', 'libc_date', # 'baudrate', # 'sleep_after_connect', # visible_when='port_type=="serial"', springy=True, ), ), label='connection', ), Group( 'uptime', 'vcc', label='misc', ), Item(name='digital_pins', editor=ListEditor( style='custom', ), style='readonly', show_label=False, ), Item(name='analog_pins', editor=ListEditor( style='custom', ), style='readonly', show_label=False, ), Group( 'update_enable', Item(name='update_interval', editor=RangeEditor( mode='slider', low=1, high=1000, ), style='custom', ), label='settings', ), Item('defines', show_label=False, editor=ListEditor( # auto_size=False, # editable=False, # configurable=False, style='custom', ), style='readonly', ) ), width=800, height=600, buttons=['Undo', 'Revert', 'OK', 'Cancel'], kind='live', resizable=True, handler=Handler(), )
class ModelDataView(ModelView): #### Information about available models model_name = Enum( 'Model B-with-theta', 'Model B-with-theta (loop design)', 'Model B', 'Model A (loop design)', ) _model_name_to_class = { 'Model B-with-theta': ModelBt, 'Model B-with-theta (loop design)': ModelBtLoopDesign, 'Model B': ModelB, 'Model A (loop design)': ModelA } _model_class_to_view = { ModelBt: ModelBtView, ModelBtLoopDesign: ModelBtLoopDesignView, ModelB: ModelBView, ModelA: ModelAView } #### Application-related traits # reference to pyanno application application = Any #### Model-related traits # the annotations model model = Any # Traits UI view of the model model_view = Instance(ModelView) # fired when the model is updates model_updated = Event # parameters view should not update when this trait is False model_update_suspended = Bool(False) #### Annotation-related traits # File trait to load a new annotations file annotations_file = File # True then annotations are loaded correctly annotations_are_defined = Bool(False) # fired when annotations are updated annotations_updated = Event # Traits UI view of the annotations annotations_view = Instance(AnnotationsView) # Traits UI view of the annotations' statistics annotations_stats_view = Instance(AnnotationsStatisticsView) # shortcut to the annotations annotations = Property def _get_annotations(self): return self.annotations_view.annotations_container.annotations # property that combines information from the model and the annotations # to give a consistent number of classes nclasses = Property def _get_nclasses(self): return max(self.model.nclasses, self.annotations.max() + 1) # info string -- currently not used info_string = Str # used to display the current log likelihood log_likelihood = Float def _annotations_view_default(self): anno = AnnotationsContainer.from_array([[0]], name='<undefined>') return AnnotationsView(annotations_container=anno, nclasses=self.model.nclasses, application=self.application, model=HasTraits()) @on_trait_change('annotations_file') def _update_annotations_file(self): logger.info('Load file {}'.format(self.annotations_file)) anno = AnnotationsContainer.from_file(self.annotations_file) self.set_annotations(anno) @on_trait_change('annotations_updated,model_updated') def _update_log_likelihood(self): if self.annotations_are_defined: if not self.model.are_annotations_compatible(self.annotations): self.log_likelihood = np.nan else: self.log_likelihood = self.model.log_likelihood( self.annotations) @on_trait_change('model.nclasses') def _update_nclasses(self): self.annotations_view.nclasses = self.model.nclasses self.annotations_view.annotations_updated = True @on_trait_change('model,model:theta,model:gamma') def _fire_model_updated(self): if not self.model_update_suspended: self.model_updated = True if self.model_view is not None: self.model_view.model_updated = True ### Control content ####################################################### def set_model(self, model): """Update window with a new model. """ self.model = model model_view_class = self._model_class_to_view[model.__class__] self.model_view = model_view_class(model=model) self.model_updated = True def set_annotations(self, annotations_container): """Update window with a new set of annotations.""" self.annotations_view = AnnotationsView( annotations_container=annotations_container, nclasses=self.model.nclasses, application=self.application, model=HasTraits()) self.annotations_stats_view = AnnotationsStatisticsView( annotations=self.annotations, nclasses=self.nclasses) self.annotations_are_defined = True self.annotations_updated = True def set_from_database_record(self, record): """Set main window model and annotations from a database record.""" self.set_model(record.model) self.set_annotations(record.anno_container) ### Actions ############################################################## #### Model creation actions # create a new model new_model = Button(label='Create...') # show informations about the selected model get_info_on_model = Button(label='Info...') #### Annotation creation actions # create new annotations new_annotations = Button(label='Create...') #### Model <-> data computations # execute Maximum Likelihood estimation of parameters ml_estimate = Button(label='ML estimate...', desc=('Maximum Likelihood estimate of model ' 'parameters')) # execute MAP estimation of parameters map_estimate = Button(label='MAP estimate...') # draw samples from the posterior over accuracy sample_posterior_over_accuracy = Button(label='Sample parameters...') # compute posterior over label classes estimate_labels = Button(label='Estimate labels...') #### Database actions # open database window open_database = Button(label="Open database") # add current results to database add_to_database = Button(label="Add to database") def _new_model_fired(self): """Create new model.""" # delegate creation to associated model_view model_name = self.model_name model_class = self._model_name_to_class[model_name] responsible_view = self._model_class_to_view[model_class] # if annotations are loaded, set default values for number of # annotations and annotators to the ones in the data set kwargs = {} if self.annotations_are_defined: anno = self.annotations_view.annotations_container kwargs['nclasses'] = anno.nclasses kwargs['nannotators'] = anno.nannotators # model == None if the user cancelled the action model = responsible_view.create_model_dialog(self.info.ui.control, **kwargs) if model is not None: self.set_model(model) def _new_annotations_fired(self): """Create an empty annotations set.""" annotations = CreateNewAnnotationsDialog.create_annotations_dialog() if annotations is not None: name = self.application.database.get_available_id() anno_cont = AnnotationsContainer.from_array(annotations, name=name) self.set_annotations(anno_cont) def _open_database_fired(self): """Open database window.""" if self.application is not None: self.application.open_database_window() def _get_info_on_model_fired(self): """Open dialog with model description.""" model_class = self._model_name_to_class[self.model_name] message(message=model_class.__doc__, title='Model info') def _add_to_database_fired(self): """Add current results to database.""" if self.application is not None: self.application.add_current_state_to_database() def _action_finally(self): """Operations that need to be executed both in case of a success and a failure of the long-running action. """ self.model_update_suspended = False def _action_success(self, result): self._action_finally() self._fire_model_updated() def _action_failure(self, err): self._action_finally() if isinstance(err, PyannoValueError): errmsg = err.args[0] if 'Annotations' in errmsg: # raised when annotations are incompatible with the model error('Error: ' + errmsg) else: # re-raise exception if it has not been handled raise err def _action_on_model(self, message, method, args=None, kwargs=None, on_success=None, on_failure=None): """Call long running method on model. While the call is running, a window with a pulse progress bar is displayed. An error message is displayed if the call raises a PyannoValueError (raised when annotations are incompatible with the current model). """ if args is None: args = [] if kwargs is None: kwargs = {} if on_success is None: on_success = self._action_success if on_failure is None: on_failure = self._action_failure self.model_update_suspended = True call = LongRunningCall( parent=None, title='Calculating...', message=message, callable=method, args=args, kw=kwargs, on_success=on_success, on_failure=on_failure, ) call() def _ml_estimate_fired(self): """Run ML estimation of parameters.""" message = 'Computing maximum likelihood estimate' self._action_on_model(message, self.model.mle, args=[self.annotations]) def _map_estimate_fired(self): """Run ML estimation of parameters.""" message = 'Computing maximum a posteriori estimate' self._action_on_model(message, self.model.map, args=[self.annotations]) def _sample_posterior_success(self, samples): if (samples is not None and hasattr(self.model_view, 'plot_theta_samples')): self.model_view.plot_theta_samples(samples) self._action_finally() def _sample_posterior_over_accuracy_fired(self): """Sample the posterior of the parameters `theta`.""" message = 'Sampling from the posterior over accuracy' # open dialog asking for number of samples params = _SamplingParamsDialog() dialog_ui = params.edit_traits(kind='modal') if not dialog_ui.result: # user pressed "Cancel" return nsamples = params.nsamples self._action_on_model(message, self.model.sample_posterior_over_accuracy, args=[self.annotations, nsamples], kwargs={ 'burn_in_samples': params.burn_in_samples, 'thin_samples': params.thin_samples }, on_success=self._sample_posterior_success) def _estimate_labels_success(self, posterior): if posterior is not None: post_plot = PosteriorPlot(posterior=posterior, title='Posterior over classes') post_view = PosteriorView(posterior_plot=post_plot, annotations=self.annotations) post_view.edit_traits() self._action_finally() def _estimate_labels_fired(self): """Compute the posterior over annotations and show it in a new window""" message = 'Computing the posterior over classes' self._action_on_model(message, self.model.infer_labels, args=[self.annotations], on_success=self._estimate_labels_success) ### Views ################################################################ def traits_view(self): ## Model view # adjust sizes to display size if is_display_small(): # full view size w_view, h_view = 1024, 768 w_data_create_group = 350 w_data_info_group = 500 h_annotations_stats = 270 else: w_view, h_view = 1300, 850 w_data_create_group = 400 w_data_info_group = 700 h_annotations_stats = 330 model_create_group = (VGroup(HGroup( UItem(name='model_name', width=200), UItem(name='new_model', width=100), UItem(name='get_info_on_model', width=100, height=25), ), label='Create new model')) model_group = (VGroup( model_create_group, VGroup( Item('model_view', style='custom', show_label=False, width=400), label='Model view', ), ), ) ## Data view data_create_group = VGroup( #Label('Open annotation file:', width=800), HGroup( Item('annotations_file', style='simple', label='Open file:', width=w_data_create_group, height=25), UItem('new_annotations', height=25)), label='Load/create annotations', show_border=False, ) data_info_group = VGroup( Item( 'annotations_view', style='custom', show_label=False, visible_when='annotations_are_defined', width=w_data_info_group, ), Item('annotations_stats_view', style='custom', show_label=False, visible_when='annotations_are_defined', height=h_annotations_stats), label='Data view', ) data_group = (VGroup( data_create_group, data_info_group, ), ) ## (Model,Data) view model_data_group = ( VGroup( #Item('info_string', show_label=False, style='readonly'), Item('log_likelihood', label='Log likelihood', style='readonly'), HGroup( Item('ml_estimate', enabled_when='annotations_are_defined'), Item('map_estimate', enabled_when='annotations_are_defined'), Item('sample_posterior_over_accuracy', enabled_when='annotations_are_defined'), Item('estimate_labels', enabled_when='annotations_are_defined'), Spring(), Item('add_to_database', enabled_when='annotations_are_defined'), Item('open_database'), show_labels=False, ), label='Model-data view', )) ## Full view full_view = View( VGroup( HGroup(model_group, data_group), model_data_group, ), title='PyAnno - Models of data annotations by multiple curators', width=w_view, height=h_view, resizable=False) return full_view
class EventVisualization(HasTraits): background = (0, 0, 0) normal_barcolor = (153.0 / 255, 204.0 / 255, 255.0 / 255) textcolor = normal_barcolor scene = Instance(MlabSceneModel, ()) def default_traits_view(self): view = View( Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=600, width=600, show_label=False), HGroup( Item("current_time", label="Date"), Item(" "), Item("num_of_shown_days", label="Show"), Item("_home_button", show_label=False), Item("_selected_source_name", show_label=False), Item("_selected_event_name", editor=CheckListEditor(name='_selected_events_list'), show_label=False), Item("_back1", show_label=False), Item( "Relative_Start_Day", show_label=False, editor=RangeEditor(mode="slider", low_name="_low_start_day_number", high_name="_high_start_day_number"), tooltip= "Shows total number of days in data set and the currently selected day", springy=True, full_size=True), Item("_forward1", show_label=False), Item("move_step", show_label=False), Item("play_button", label='Play')), title="Visualization of Events", resizable=True) view.resizable = True return view # Index to the currently selected source. None if no source is selected. selected_source = Trait(None, None, Int) _selected_source_name = Enum(None, [None]) # index to a selected event. None if not selected. selected_event = None _selected_event_name = List _selected_events_list = List(['None', 'None']) # Current (most recent) time, can also be set usinh start day, but then relative to the total number of days. current_time = Date start_day = Trait(None, int, tuple, String, Date) _low_start_day_number = Int(0) # minimum start day = 0 _high_start_day_number = Int( 100) # maximum start day = total number of days # Configures the shown number of days in the visualization. num_of_shown_days = Trait( "30 days", Enum([ "7 days", "14 days", "30 days", "60 days", "90 days", "120 days", "180 days", "365 days" ])) ## Buttons for controlling the visualization _home_button = Button("Unselect>>", width_padding=0, height_padding=0) _back1 = Button("<", width_padding=0, height_padding=0) _forward1 = Button(">", width_padding=0, height_padding=0) # Play button sets the visualization on stepping in the last selected direction, back or forth. play_button = Bool # Configure the number of days the visualization can step. move_step = Trait("1 day", Enum(["1 day", "2 days", "3 days", "7 days"])) # Home button, unselects any selection def __home_button_changed(self): self.selected_source = None _last_clicked_direction = None def move_backward(self): ''' Moves the shown area backward 1 step. :return: ''' if self.Relative_Start_Day >= (self._low_start_day_number + int(self.move_step[0])): self.Relative_Start_Day -= int(self.move_step[0]) def move_forward(self): ''' Moves the shown area forward 1 step. :return: ''' if self.Relative_Start_Day <= (self._high_start_day_number - int(self.move_step[0])): self.Relative_Start_Day += int(self.move_step[0]) def __back1_changed(self): ''' Triggered when back button is pressed :return: ''' self.move_backward() self._last_clicked_direction = self.move_backward def __forward1_changed(self): ''' Triggered when forward button is pressed :return: ''' self.move_forward() self._last_clicked_direction = self.move_forward _play_thread = False def _play_button_changed(self, play_pressed): ''' Triggered when play button is selected :param play_pressed: :return: ''' if play_pressed: if not self._play_thread: self._play_thread = True GUI.invoke_after(1, self._play_func) else: self._play_thread = False def _play_func(self): ''' Called while play button is selected :return: ''' if self._play_thread: if self._last_clicked_direction is not None: self._last_clicked_direction() else: self.move_forward() GUI.invoke_after(1000, self._play_func) @on_trait_change("Relative_Start_Day") def _relative_start_day_changed(self, new_value): self.start_day = new_value def _start_day_changed(self, new_time): if isinstance(new_time, int): self.current_time = datetools.to_datetime(self._data_times.min() + datetools.Day(new_time)) elif isinstance(new_time, str): self.current_time = datetools.to_datetime(new_time) elif isinstance(new_time, datetime.date): self.current_time = datetools.to_datetime(new_time) else: print "Unsupported start day ", new_time return def _selected_source_changed(self, old_source, new_source): #print "Source changed", old_source, new_source if old_source is not new_source: if new_source is not None: self._selected_source_name = self._get_source_name(new_source) self._update_selected_event(None) self._update_selected_event( self._vis_model.get_num_of_selected_events() - 1) else: self._selected_source_name = None self._update_selected_event(None) def __selected_source_name_changed(self, old_source, new_source): if new_source in self.source_names: source_index = self.source_names.index(new_source) else: source_index = -1 if self.selected_source != source_index: if source_index == -1: self.selected_source = None else: self.selected_source = source_index def _current_time_changed(self, old_time, new_time): num_of_days = int( (datetools.to_datetime(new_time) - self._data_times.min()).days) if self.Relative_Start_Day != num_of_days: self.Relative_Start_Day = num_of_days elif old_time != new_time: self.current_time = datetools.to_datetime(self.current_time) self.update() _old_event_name = -1 def _update_selected_event(self, event_index): if event_index > -1: event = self._vis_model.get_selected_event(event_index) else: event = None # if self._old_event_name == event or event is not None and self._old_event_name == event.name: # return # Do nothing self._old_event_name = None if event is None else event.name if event_index > -1: selected_event = self._vis_model.expand_events( event.parent if self.selected_event > -1 and event_index >= self.selected_event else self._vis_model. get_selected_event(event_index)) else: selected_event = self._vis_model.expand_events(None) self.selected_event = selected_event if event is not None: sevents = self._vis_model.get_selected_events_name() names = list( sorted([ pyisc._get_string_value(sevents, i) for i in range( self._vis_model.get_num_of_selected_events()) ])) if event.name in names: self._selected_events_list = names self._selected_event_name = [event.name] else: self._selected_events_list = ['None'] self._selected_event_name = ['None'] self.update() def __selected_event_name_changed(self, oldvalue, newvalue): if self._old_event_name is None or len( self._selected_event_name ) == 1 and self._old_event_name != self._selected_event_name[0]: if len(oldvalue) != len(newvalue) or len( newvalue) == 1 and oldvalue[0] != newvalue[0]: if len(self._selected_event_name ) == 1 and self._selected_event_name[0] != 'None': event_index = self._vis_model.get_event_index( self._selected_event_name[0]) self._update_selected_event(event_index) else: self._update_selected_event(None) def _num_of_shown_days_changed(self): self.used_cache_size = self._num_of_shown_days_to_int( ) * self._num_of_sources self.update() # Used for caching anomaly calculations _cache = dict() # Used for scaling visualizatuion in the z direction _scale_z = Trait(0.1, Range(0.0, 1.0)) # Used for setting a good default view in 3D _last_view = None def __init__(self, visualisation_model, decision_threshold, start_day=3, num_of_shown_days="30 days", precompute_cache=False): ''' :param visualisation_model: an instance of EventDataModel :param decision_threshold: a float larger or equal to 0.0 that is used for deciding when an anomaly score is significantly anomalous :param start_day: an integer >= or an instance of datetime.date or an string, like "2014-10-11" or a tuple, like (2014, 10, 11) :param num_of_shown_days: an integer > 1 that specifies the number of days back in time from start_day that will be shown. :param precompute_cache: boolean that indates whether all anomaly scores should be computed at once or when asked for. :return: ''' assert isinstance(visualisation_model, EventDataModel) assert isinstance( start_day, int) or isinstance(start_day, str) or isinstance( start_day, datetime.date) or (isinstance(start_day, tuple) and len(start_day) == 3) HasTraits.__init__(self) self.used_cache_size = 0 # must be initialized self._data = visualisation_model._event_data_object self.num_of_shown_days = num_of_shown_days # Updates self.used_cache_size self._vis_model = visualisation_model self._anomaly_detector = visualisation_model._anomaly_detector self.anomaly_detection_threshold = decision_threshold dates = visualisation_model._event_data_object.dates_ self._data_times = array([datetools.to_datetime(d) for d in dates]) self.source_names = list( unique(visualisation_model._event_data_object.sources_)) self._data_sources = array([ self.source_names.index(source) for source in visualisation_model._event_data_object.sources_ ]) self._num_of_sources = len(unique( self.source_names)) # number of sources self.barcharts = [] self.barchart_actors = [] self.time_text3ds = [] self.source_text3ds = [] self.xy_positions = [] self._high_start_day_number = int( (self._data_times.max() - self._data_times.min()).days) self.scene.anti_aliasing_frames = 8 # add traits dynamically self.add_trait("Relative_Start_Day", Range(0, self._high_start_day_number)) self.add_trait("_selected_source_name", Enum(None, [None] + self.source_names)) self.configure_traits() self.scene.background = self.background # add the mouse pick handler self.picker = self.scene.mayavi_scene.on_mouse_pick( self.vis_picker, 'cell') self.picker.tolerance = 0.01 #cmap = matplotlib.cm.get_cmap('Reds') #self.severity_color = [cmap(x)[:-1] for x in linspace(0.75, 0.95, self._vis_model.num_of_severity_levels_)] if self._vis_model.num_of_severity_levels_ > 1: self.severity_color = self.severity_color = [ (1, x / 100.0, x / 100.0) for x in range(70, 30, -40 / self._vis_model.num_of_severity_levels_) ] else: self.severity_color = [(255.0 / 255, 51 / 255.0, 51 / 255.0)] # This used for a fix to manage a bug in Mayavi library, an invisible default object self._obj = self.scene.mlab.points3d(0, 0, 0, opacity=0.0) # Cache all anomaly calculations for all data values if precompute_cache: self.used_cache_size = len(self._data) for data_index in xrange(len(self._data)): self._populate_cache(data_index) self.start_day = start_day self.update() def _create_barcharts(self, severities, x, y, z): ''' Creates and shows the 3D bars :param severities: :param x: :param y: :param z: :return: ''' #self.scene.disable_render = True x = array(x) y = array(y) z = array(z) severities = array(severities) for s in set(severities): s_index = (severities == s) color = self.normal_barcolor if s == -1 else self.background if s == -2 else self.severity_color[ s] x0 = x[s_index] y0 = y[s_index] z0 = z[s_index] barchart = self.scene.mlab.barchart(x0, y0, z0, color=color, auto_scale=False, reset_zoom=False) self.barcharts.append(barchart) self.barchart_actors.append(barchart.actor.actors[0]) self.xy_positions.append((x0, y0, z0)) for actor in self.barchart_actors: actor.scale = array([1.0, 1.0, self._scale_z]) #self.scene.disable_render = False def clear_figure(self): ''' Removes the objects from the scene. :return: ''' self.scene.remove_actors(self.barchart_actors) # A bug fix, when there are no objects left in the scene it stops working unless you set a default current_object # It is an invisibale point outside the 3D bar plot region. self.scene.mlab.get_engine().current_object = self._obj self.barchart_actors = [] self.xy_positions = [] def _trim_cache(self, data_index, used_cache_size): ''' Keeps the cache to the defined size. :param data_index: :param used_cache_size: :return: ''' if len(self._cache) > used_cache_size: max_index = max(self._cache.keys()) min_index = min(self._cache.keys()) if data_index > max_index: del self._cache[min_index] elif data_index < min_index: del self._cache[max_index] else: # Remove the one farest away median_index = median(self._cache.keys()) triple_indexes = array([min_index, median_index, max_index]) diffs = abs(data_index - triple_indexes) diff_max_index = diffs.argmax() del self._cache[triple_indexes[diff_max_index]] def update(self): ''' Plots the 3D bars and axis. :return: ''' is_first_update = False if self._last_view is None: self._last_view = (38, 8, 205, array([8, 17.5, 49.25])) self.scene.mlab.view(*self._last_view) is_first_update = True else: self._last_view = self.scene.mlab.view() self.scene.disable_render = True self.clear_figure() #print "Day: %s" % time.ctime(self.current_time) max_z = 0 time_index = ( (self._data_times <= datetools.to_datetime(self.current_time)) & (self._data_times >= (datetools.to_datetime(self.current_time) - self._num_of_shown_days_to_timedelta()))) if self.selected_source is None: # Plot all sources x = [] y = [] z = [] severities = [] for source in range(self._num_of_sources): for data_index in array(range(len(self._data)))[time_index][ self._data_sources[time_index] == source]: if self.used_cache_size > 0 and self._cache.has_key( data_index): devsptr, sevs, expectptr, min2, max2, count = self._cache[ data_index] else: devs, sevs, expect, min2, max2 = self._vis_model.calc_one( data_index) devsptr = pyisc._to_cpp_array(devs) expectptr = pyisc._to_cpp_array(expect) count = None if count is None: self._trim_cache(data_index, self.used_cache_size) vec = self._data._get_intfloat(data_index) count = sum([ pyisc._get_intfloat_value( vec, self._vis_model.get_event_hierarchy(). get_index_value(l)) for l in range( self._vis_model.num_of_severity_levels_) if self._vis_model.get_event_hierarchy(). get_index_value(l) != -1 ]) self._cache[data_index] = (devsptr, sevs, expectptr, min2, max2, count) ztime = self._num_of_shown_days_to_int() - ( self.current_time - self._data_times[data_index]).days x.append(source) y.append(ztime) z.append(count) sev_max = argmax(sevs) sev = (-1 if sevs[sev_max] < self.anomaly_detection_threshold else sev_max) severities.append(sev) self._create_barcharts(severities, x, y, z) max_z = max([max_z] + z) else: # Plot for selected source source_index = self._data_sources[ time_index] == self.selected_source data_indexes = array(range(len( self._data)))[time_index][source_index] x = [] y = [] z = [] severities = [] # Plot selected events for data_index in data_indexes: if self.used_cache_size > 0 and self._cache.has_key( data_index): devsptr, sevs, expectptr, min2, max2, _ = self._cache[ data_index] else: devs, sevs, expect, min2, max2 = self._vis_model.calc_one( data_index) devsptr = pyisc._to_cpp_array(devs) expectptr = pyisc._to_cpp_array(expect) self._trim_cache(data_index, self.used_cache_size) self._cache[data_index] = (devsptr, sevs, expectptr, min2, max2, None) ztime = self._num_of_shown_days_to_int() - ( datetools.to_datetime(self.current_time) - self._data_times[data_index]).days if self._vis_model.get_num_of_selected_events() > 0: for element in range( self._vis_model.get_num_of_selected_events()): x.append(element) y.append(ztime) (dev, sev, count, mexp, maxind) = self._vis_model.summarize_event_children( self._vis_model.get_selected_event(element), devsptr, expectptr, self._data._get_intfloat(data_index), 1 if element >= self.selected_event else 0) z.append(count) if dev < self.anomaly_detection_threshold: severities.append(-1) else: severities.append(sev) self._create_barcharts(severities, x, y, z) max_z = max([max_z] + z) self.scene.disable_render = True datetime.date curr_t = self.current_time time_strs = [ str(t.date()) for t in date_range( curr_t - self._num_of_shown_days_to_timedelta(), curr_t) ] time_max_len = min([len(t) for t in time_strs]) max_x = (self._num_of_sources if self.selected_source is None else self._vis_model.get_num_of_selected_events()) max_y = self._num_of_shown_days_to_int() if len(self.time_text3ds) != len(time_strs): self.scene.remove_actors( [t.actor.actors[0] for t in self.time_text3ds]) self.time_text3ds = [] for slot in range(len(time_strs)): name = time_strs[slot] pos = (max_x + time_max_len / 2 - 1, slot, 0) self.time_text3ds.append( self.scene.mlab.text3d(*pos, text=name, scale=0.5, color=self.textcolor, orient_to_camera=False, orientation=(180, 180, 0))) else: for slot in range(len(time_strs)): name = time_strs[slot] pos = (max_x + time_max_len / 2 - 1, slot, 0) self.time_text3ds[slot].position = pos self.time_text3ds[slot].text = name if self.selected_source is None: source_strs = [ self._get_source_name(source) for source in range(self._num_of_sources) ] num_of_sources = self._num_of_sources else: source_strs = [ self._get_event_name(element) for element in range( self._vis_model.get_num_of_selected_events()) ] num_of_sources = self._vis_model.get_num_of_selected_events() if len(self.source_text3ds ) != num_of_sources or self.selected_source is None: self.scene.remove_actors( [t.actor.actors[0] for t in self.source_text3ds]) self.source_text3ds = [] for source in range(num_of_sources): name = source_strs[source] if self.selected_source is None: self.source_text3ds.append( self.scene.mlab.text3d(source, max_y + 0.5, 0, name, scale=0.6, color=self.textcolor, orient_to_camera=False, orientation=(0, 0, 90))) else: self.source_text3ds.append( self.scene.mlab.text3d( source, max_y + 0.5, 0, name, color=self.textcolor if source < self.selected_event else (192.0 / 255, 192.0 / 255, 192.0 / 255) if source > self.selected_event else (1.0, 1.0, 1.0), scale=0.5, orient_to_camera=False, orientation=(0, 0, 90))) else: for source in range(num_of_sources): name = source_strs[source] self.source_text3ds[source].text = name self.source_text3ds[source].position = (source, max_y + 0.5, 0) if is_first_update: self.scene.reset_zoom() self.scene.disable_render = False return last_picker = None def vis_picker(self, picker): ''' Called when the user clicks in the scene in order to find the object that was selected. :param picker: :return: ''' self.last_picker = picker _source = None if picker.actor is not None: if picker.actor in self.barchart_actors: actor_index = self.barchart_actors.index(picker.actor) _sources, _time_slots, _ = self.xy_positions[actor_index] _source = _sources[picker.point_id / 24] _time_slot = _time_slots[picker.point_id / 24] else: actors = [t.actor.actors[0] for t in self.source_text3ds] if picker.actor in actors: actor_index = actors.index(picker.actor) _source = actor_index if _source is not None: if self.selected_source is None: if _source >= 0 and _source < self._num_of_sources: self.selected_source = _source elif _source >= 0 and _source < self._vis_model.get_num_of_selected_events( ): self._update_selected_event(_source) def _num_of_shown_days_to_timedelta(self): return datetools.to_offset( str(self.num_of_shown_days).split(' ')[0] + "d") def _num_of_shown_days_to_int(self): return int(str(self.num_of_shown_days).split(' ')[0]) def _get_source_name(self, source): return self.source_names[source] def _get_event_name(self, element): return self._vis_model.get_selected_event(element).name def _populate_cache(self, data_index): devs, sevs, expect, min2, max2 = self._vis_model.calc_one(data_index) devsptr = pyisc._to_cpp_array(devs) expectptr = pyisc._to_cpp_array(expect) vec = self._data._get_intfloat(data_index) count = sum([ pyisc._get_intfloat_value( vec, self._vis_model.get_event_hierarchy().get_index_value(l)) for l in xrange(self._vis_model.num_of_severity_levels_) if self._vis_model.get_event_hierarchy().get_index_value(l) != -1 ]) self._cache[data_index] = (devsptr, sevs, expectptr, min2, max2, count)
class ModelAView(PyannoModelView): """ Traits UI Model/View for 'ModelA' objects. """ # name of the model (inherited from PyannoModelView) model_name = MODEL_A_NAME # dialog to instantiated when creating a new model new_model_dialog_class = NewModelADialog @classmethod def _create_model_from_dialog(cls, dialog): return ModelA.create_initial_state(dialog.nclasses) @on_trait_change('model,model_updated') def update_from_model(self): """Recreate plots.""" self.omega_hinton_diagram = HintonDiagramPlot( data=self.model.omega.tolist(), title='Omega parameters, P(label = k)') self.theta_distribution_plot = ThetaDistrPlot(theta=self.model.theta) self.theta_scatter_plot = ThetaScatterPlot(model=self.model) self._theta_view_update() def _theta_view_default(self): return self.theta_distribution_plot @on_trait_change('theta_views') def _theta_view_update(self): if self.theta_views.startswith('Distr'): self.theta_view = self.theta_distribution_plot else: self.theta_view = self.theta_scatter_plot def plot_theta_samples(self, theta_samples): self.theta_distribution_plot = ThetaDistrPlot( theta=self.model.theta, theta_samples=theta_samples) self.theta_scatter_plot = ThetaScatterPlot(model=self.model) self.theta_scatter_plot.theta_samples = theta_samples self.theta_scatter_plot.theta_samples_valid = True self._theta_view_update() #### UI traits omega_hinton_diagram = Instance(HintonDiagramPlot) theta_scatter_plot = Instance(ThetaScatterPlot) theta_distribution_plot = Instance(ThetaDistrPlot) theta_views = Enum('Distribution plot', 'Scatter plot') theta_view = Instance(PyannoPlotContainer) #### Actions view_omega = Button(label='View Omega...') view_theta = Button(label='View Theta...') def _view_theta_fired(self): """Create viewer for theta parameters.""" theta_view = ParametersTabularView(title='Model A, parameters Theta', data=[self.model.theta.tolist()]) theta_view.edit_traits() def _view_omega_fired(self): """Create viewer for parameters omega.""" omega_view = ParametersTabularView(title='Model A, parameters Omega', data=[self.model.omega.tolist()]) omega_view.edit_traits() #### Traits UI view ######### def traits_view(self): w_view = 350 if is_display_small() else 480 parameters_group = VGroup( Item('_'), HGroup( VGroup( Spring(), Item('handler.omega_hinton_diagram', style='custom', resizable=False, show_label=False, width=w_view), Spring()), Spring(), VGroup(Spring(), Item('handler.view_omega', show_label=False), Spring())), Spring(), Item('_'), Spring(), HGroup( VGroup( UItem('handler.theta_views'), UItem('handler.theta_view', style='custom', resizable=False, width=w_view), Spring()), Spring(), VGroup(Spring(), UItem('handler.view_theta'), Spring()))) body = VGroup(Include('info_group'), parameters_group) traits_view = View(body, buttons=[OKButton], resizable=True) return traits_view
class ProjectInfoUI(cmp.project.ProjectInfo): """Class that extends the :class:`ProjectInfo` with graphical components. It supports graphically the setting of all processing properties / attributes of an :class:`ProjectInfo` instance. Attributes ----------- creation_mode : traits.Enum Mode for loading the dataset. Valid values are 'Load BIDS dataset', 'Install Datalad BIDS dataset' install_datalad_dataset_via_ssh : traits.Bool If set to True install the datalad dataset from a remote server via ssh.(True by default) ssh_user : traits.Str Remote server username. (Required if ``install_datalad_dataset_via_ssh`` is True) ssh_pwd <traits.Password> Remote server password. (Required if ``install_datalad_dataset_via_ssh`` is True) ssh_remote : traits.Str Remote server IP or URL. (Required if ``install_datalad_dataset_via_ssh`` is True) datalad_dataset_path : traits.Directory Path to the datalad dataset on the remote server. (Required if ``install_datalad_dataset_via_ssh`` is True) summary_view_button : traits.ui.Button Button that shows the pipeline processing summary table pipeline_processing_summary_view : traits.ui.VGroup TraitsUI VGroup that contains ``Item('pipeline_processing_summary')`` dataset_view : traits.ui.View TraitsUI View that shows a summary of project settings and modality available for a given subject traits_view : QtView TraitsUI QtView that includes the View 'dataset_view' create_view : traits.ui.View Dialog view to create a BIDS Dataset subject_view : traits.ui.View Dialog view to select of subject subject_session_view : traits.ui.View Dialog view to select the subject session dmri_bids_acq_view : traits.ui.View Dialog view to select the diffusion acquisition model anat_warning_view : traits.ui.View View that displays a warning message regarding the anatomical T1w data anat_config_error_view : traits.ui.View Error view that displays an error message regarding the configuration of the anatomical pipeline dmri_warning_view : traits.ui.View View that displays a warning message regarding the diffusion MRI data dmri_config_error_view : traits.ui.View View that displays an error message regarding the configuration of the diffusion pipeline fmri_warning_view : traits.ui.View View that displays a warning message regarding the functional MRI data fmri_config_error_view : traits.ui.View View that displays an error message regarding the configuration of the fMRI pipeline open_view : traits.ui.View Dialog view to load a BIDS Dataset anat_select_config_to_load : traits.ui.View Dialog view to load the configuration file of the anatomical pipeline diffusion_imaging_model_select_view : traits.ui.View Dialog view to select the diffusion acquisition model dmri_select_config_to_load : traits.ui.View Dialog view to load the configuration file of the diffusion MRI pipeline fmri_select_config_to_load : traits.ui.View Dialog view to load the configuration file of the fMRI pipeline """ creation_mode = Enum("Load BIDS dataset", "Install Datalad BIDS dataset") install_datalad_dataset_via_ssh = Bool(True) ssh_user = String("remote_username") ssh_pwd = Password("") ssh_remote = String("IP address/ Machine name") datalad_dataset_path = Directory( "/shared/path/to/existing/datalad/dataset") anat_runs = List() anat_run = Enum(values="anat_runs") dmri_runs = List() dmri_run = Enum(values="dmri_runs") fmri_runs = List() fmri_run = Enum(values="fmri_runs") summary_view_button = Button("Pipeline processing summary") pipeline_processing_summary_view = VGroup( Item("pipeline_processing_summary")) dataset_view = VGroup( VGroup( HGroup( Item( "base_directory", width=-0.3, style="readonly", label="", resizable=True, ), Item( "number_of_subjects", width=-0.3, style="readonly", label="Number of participants", resizable=True, ), "summary_view_button", ), label="BIDS Dataset", ), spring, HGroup( Group( Item("subject", style="simple", show_label=True, resizable=True)), Group( Item("subject_session", style="simple", label="Session", resizable=True), visible_when='subject_session!=""', ), springy=True, ), spring, Group( Item("t1_available", style="readonly", label="T1", resizable=True), HGroup( Item( "dmri_available", style="readonly", label="Diffusion", resizable=True, ), Item( "diffusion_imaging_model", label="Model", resizable=True, enabled_when="dmri_available", ), ), Item("fmri_available", style="readonly", label="BOLD", resizable=True), label="Modalities", ), spring, Group( Item( "anat_last_date_processed", label="Anatomical pipeline", style="readonly", resizable=True, enabled_when="t1_available", ), Item( "dmri_last_date_processed", label="Diffusion pipeline", style="readonly", resizable=True, enabled_when="dmri_available", ), Item( "fmri_last_date_processed", label="fMRI pipeline", style="readonly", resizable=True, enabled_when="fmri_available", ), label="Last date processed", ), spring, Group(Item("number_of_cores", resizable=True), label="Processing configuration"), "550", spring, springy=True, ) traits_view = QtView(Include("dataset_view")) create_view = View( Item("creation_mode", style="custom"), Group( Group( Item("base_directory", label="BIDS Dataset"), visible_when='creation_mode=="Load BIDS dataset"', ), Group( Item("install_datalad_dataset_via_ssh"), visible_when='creation_mode=="Install Datalad/BIDS dataset"', ), Group( Item( "ssh_remote", label="Remote ssh server", visible_when="install_datalad_dataset_via_ssh", ), Item( "ssh_user", label="Remote username", visible_when="install_datalad_dataset_via_ssh", ), Item( "ssh_pwd", label="Remote password", visible_when="install_datalad_dataset_via_ssh", ), Item( "datalad_dataset_path", label="Datalad/BIDS Dataset Path/URL to be installed", ), Item("base_directory", label="Installation directory"), visible_when='creation_mode=="Install Datalad/BIDS dataset"', ), ), kind="livemodal", title="Data creation: BIDS dataset selection", # style_sheet=style_sheet, width=modal_width, buttons=["OK", "Cancel"], ) subject_view = View( Group(Item("subject", label="Selected Subject")), kind="modal", title="Subject and session selection", # style_sheet=style_sheet, width=modal_width, buttons=["OK", "Cancel"], ) subject_session_view = View( Group( Item("subject", style="readonly", label="Selected Subject"), Item("subject_session", label="Selected Session"), ), kind="modal", title="Session selection", # style_sheet=style_sheet, width=modal_width, buttons=["OK", "Cancel"], ) dmri_bids_acq_view = View( Group(Item("dmri_bids_acq", label="Selected model"), ), kind="modal", title="Selection of diffusion acquisition model", # style_sheet=style_sheet, width=modal_width, buttons=["OK", "Cancel"], ) anat_warning_view = View( Group(Item("anat_warning_msg", style="readonly", show_label=False), ), title="Warning : Anatomical T1w data", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) anat_config_error_view = View( Group( Item("anat_config_error_msg", style="readonly", show_label=False), ), title="Error", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) dmri_warning_view = View( Group(Item("dmri_warning_msg", style="readonly", show_label=False), ), title="Warning : Diffusion MRI data", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) dmri_config_error_view = View( Group( Item("dmri_config_error_msg", style="readonly", show_label=False), ), title="Error", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) fmri_warning_view = View( Group(Item("fmri_warning_msg", style="readonly", show_label=False), ), title="Warning : fMRI data", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) fmri_config_error_view = View( Group( Item("fmri_config_error_msg", style="readonly", show_label=False), ), title="Error", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) open_view = View( Item("creation_mode", label="Mode"), Group( Item("install_datalad_dataset_via_ssh"), Item( "ssh_remote", label="Remote ssh server", visible_when="install_datalad_dataset_via_ssh", ), Item( "ssh_user", label="Remote username", visible_when="install_datalad_dataset_via_ssh", ), Item( "ssh_pwd", label="Remote password", visible_when="install_datalad_dataset_via_ssh", ), Item( "datalad_dataset_path", label="Datalad/BIDS Dataset Path/URL to be installed", ), Item("base_directory", label="Installation directory"), visible_when='creation_mode=="Install Datalad BIDS dataset"', ), Group( Item("base_directory", label="BIDS Dataset"), visible_when='creation_mode=="Load BIDS dataset"', ), kind="livemodal", title="BIDS Dataset Creation/Loading", # style_sheet=style_sheet, width=600, height=250, buttons=["OK", "Cancel"], ) anat_select_config_to_load = View( Group( Item("anat_config_to_load_msg", style="readonly", show_label=False), Item( "anat_config_to_load", style="custom", editor=EnumEditor(name="anat_available_config"), show_label=False, ), ), title="Select configuration for anatomical pipeline", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) anat_custom_map_view = View( Group( Item( "anat_custom_last_stage", editor=EnumEditor(name="anat_stage_names"), style="custom", show_label=False, ), ), title="Select until which stage to process the anatomical pipeline.", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) diffusion_imaging_model_select_view = View( Group(Item("diffusion_imaging_model", label="Diffusion MRI modality"), ), title="Please select diffusion MRI modality", kind="modal", width=modal_width, buttons=["OK", "Cancel"], ) dmri_select_config_to_load = View( Group( Item("dmri_config_to_load_msg", style="readonly", show_label=False), ), Item( "dmri_config_to_load", style="custom", editor=EnumEditor(name="dmri_available_config"), show_label=False, ), title="Select configuration for diffusion pipeline", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) dmri_custom_map_view = View( Group( Item( "dmri_custom_last_stage", editor=EnumEditor(name="dmri_stage_names"), style="custom", show_label=False, ), ), title="Select until which stage to process the diffusion pipeline.", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) fmri_select_config_to_load = View( Group( Item("fmri_config_to_load_msg", style="readonly", show_label=False), ), Item( "fmri_config_to_load", style="custom", editor=EnumEditor(name="fmri_available_config"), show_label=False, ), title="Select configuration for fMRI pipeline", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) fmri_custom_map_view = View( Group( Item( "fmri_custom_last_stage", editor=EnumEditor(name="fmri_stage_names"), style="custom", show_label=False, ), ), title="Select until which stage to process the fMRI pipeline.", kind="modal", width=modal_width, # style_sheet=style_sheet, buttons=["OK", "Cancel"], ) def _summary_view_button_fired(self): self.configure_traits(view="pipeline_processing_summary_view")
class PinWrapper(HasTraits): pin = Any() function = Any() usb = Any() timer = Any() initmode = False avr_pin = Any() def _pin_changed(self): self.initmode = True self.name = self.pin.name self.mode = ['INPUT', 'OUTPUT'][self.pin.read_mode()] if self.mode == 'OUTPUT': # TODO: self.digital_output = bool(self.pin.read_digital_value()) self.function = self.pin.programming_function if hasattr(self.pin, 'is_usb_plus'): self.usb = ['', '+', '-'][self.pin.is_usb_plus + 2 * self.pin.is_usb_minus] else: self.usb = '' if self.pin.pwm.available: ls = [ int(x) for x in self.pin.pwm.frequencies_available if x is not None ] if not ls: ls = [-1] self.add_trait('pwm_frequency', Enum(ls)) self.pwm_frequency = int( self.pin.pwm.frequency if self.pin.pwm.frequency else -1) self.timer = self.pin.pwm.timer_register_name_b self.avr_pin = self.pin.avr_pin self.initmode = False def _pwm_frequency_changed(self): self.pin.pwm.frequency = self.pwm_frequency pwm_output = Range(0, 255) def _pwm_output_changed(self): self.pin.pwm.write_value(self.pwm_output) pwm = Bool() def _pwm_changed(self): if self.pwm: self._pwm_output_changed() else: self._digital_output_changed() name = Str() mode = Enum(['INPUT', 'OUTPUT']) def _mode_changed(self): if not self.initmode: self.pin.write_mode(OUTPUT if (self.mode == 'OUTPUT') else INPUT) pullup = Bool() def _pullup_changed(self): self.pin.write_pullup(self.pullup) digital_input = Bool() digital_output = Bool() def _digital_output_changed(self): if not self.initmode: # TODO: self.pin.write_digital_value(self.digital_output) analog_input = Any() # voltage = Any() def update(self): '' if self.mode == 'INPUT': self.analog_input = self.pin.analog_value # self.voltage = an.voltage self.digital_input = bool(self.pin.read_digital_value()) traits_view = View( HGroup( Item( 'name', show_label=False, style='readonly', ), Item( 'avr_pin', show_label=False, style='readonly', format_func=lambda x: '(%s)' % (x), ), 'mode', Item( 'pwm', visible_when='mode=="OUTPUT"', defined_when='pin.pwm.available', ), HGroup( Item( 'digital_input', defined_when='pin.is_digital', enabled_when='0', ), Item( 'analog_input', defined_when='pin.is_analog', style='readonly', ), # Item('voltage', # defined_when='pin.is_analog', # style='readonly', # ), Item('pullup', ), visible_when='mode=="INPUT"', ), Item( 'digital_output', visible_when='mode=="OUTPUT" and not pwm', ), HGroup( Item('pwm_frequency', ), Item( name='pwm_output', editor=RangeEditor( mode='slider', low=0, high=255, ), style='custom', ), visible_when='mode=="OUTPUT" and pwm', defined_when='pin.pwm.available', ), Item( 'timer', defined_when='timer', style='readonly', ), Item( 'function', defined_when='function', style='readonly', ), Item( 'usb', defined_when='usb', style='readonly', ), ), )