def _button_factory(self, name, label=None, enabled=None, align=None, **kw): ''' ''' b = Item(name, show_label=False, **kw) if label is None: label = '{}_label'.format(name) if label is not None: b.editor = ButtonEditor(label_value=label) if enabled is not None: b.enabled_when = enabled if align is not None: if align == 'right': b = HGroup(spring, b) elif align == 'center': b = HGroup(spring, b, spring) else: b = HGroup(b, spring) return b
def _get_group(self): g = Group(Item('show_label', label='Display label')) return g
def _get_group(self): return Item('radius')
class MandelbrotView(ModelView): """ Traits UI and Chaco view of a Mandelbrot set. """ # The model part of this UI. model = Instance(MandelbrotParameters) # The Chaco plot. mandelbrot_plot = Instance(Plot) def _mandelbrot_plot_default(self): return self._create_mandelbrot_plot() # The Chaco data source for the Mandelbrot set. mandelbrot_plot_data = Instance(ArrayPlotData) def _mandelbrot_plot_data_default(self): plot_data = ArrayPlotData() self._set_plot_data(plot_data) return plot_data # The Chaco plot renderer. mandelbrot_renderer = Instance(AbstractPlotRenderer) # A button that resets the view to the default one. reset_view = Button def _reset_view_fired(self): self.model.set(xmin=-2, xmax=1, ymin=-1.5, ymax=1.5) # The colormap of the plot. colormap = Enum(dc.color_map_name_dict.keys()) @on_trait_change('colormap') def set_colormap(self): data_range = DataRange1D(low=-1.0, high=200) colormap = dc.color_map_name_dict[self.colormap](data_range) self.mandelbrot_renderer.color_mapper = colormap self.mandelbrot_renderer.invalidate_and_redraw() @on_trait_change('model:xmin,model:xmax,model:ymin,model:ymax') def _update_plot_data_and_bounds(self): """ Update the image data and the plot bounds when the bounds change. """ self._set_plot_data(self.mandelbrot_plot_data) self.mandelbrot_plot = self._create_mandelbrot_plot() def _create_mandelbrot_plot(self): plot = Plot(self.mandelbrot_plot_data) self.mandelbrot_renderer = plot.img_plot( 'mandelbrot', xbounds=self.model.x_coords, ybounds=self.model.y_coords, name='mandelbrot_plot')[0] plot.aspect_ratio = 1.0 plot.tools.append(MandelzoomTool(component=plot, params=self.model)) self.set_colormap() return plot def _set_plot_data(self, plot_data): mandelbrot = mandelbrot_grid( self.model.x_bounds, self.model.y_bounds, self.model.grid_size ) plot_data.set_data('mandelbrot', mandelbrot) # Traits UI definition of the UI. traits_view = View( VGroup( Item('mandelbrot_plot', editor=ComponentEditor(), show_label=False), HGroup( Item('colormap'), Item('reset_view', show_label=False) ), ), resizable=True, )
class Visualization(HasTraits): scene = Instance(MlabSceneModel, ()) lsto = ['TM Mode', 'Electric Field', 10.0, 0.05, 0.03, 6.0, 1.0, 1.0] #self.on_trait_change(self.update_plot, name='lsto') @on_trait_change('scene.activated') def update_plot(self): clf() lst = self.lsto lst[6] = int(lst[6]) lst[7] = int(lst[7]) if lst[4] >= lst[3]: tmp = lst[4] lst[4] = lst[3] lst[3] = tmp if 'TE Mode' == lst[0]: if lst[6] >= 1 and lst[7] >= 0: tmp = 100 else: popup = PopupClass() popup.show_popupTE() lst[6] = 1 lst[7] = 0 lst[5] = 1.0 field = RectTE(lst[3], lst[4], lst[2] * 1e+9, 8.85418782e-12 * (lst[5]**2), 1.25663706e-6, lst[6], lst[7]) if 'Electric Field' == lst[1]: func1 = np.vectorize(field.Ex) func2 = np.vectorize(field.Ey) func3 = np.vectorize(field.Ez) else: func1 = np.vectorize(field.Hx) func2 = np.vectorize(field.Hy) func3 = np.vectorize(field.Hz) else: if lst[6] >= 1 and lst[7] >= 1: tmp = 100 else: popup = PopupClass() popup.show_popupTM() lst[6] = 1 lst[7] = 1 lst[5] = 1.0 field = RectTM(lst[3], lst[4], lst[2] * 1e+9, 8.85418782e-12 * (lst[5]**2), 1.25663706e-6, lst[6], lst[7]) if 'Electric Field' == lst[1]: func1 = np.vectorize(field.Ex) func2 = np.vectorize(field.Ey) func3 = np.vectorize(field.Ez) else: func1 = np.vectorize(field.Hx) func2 = np.vectorize(field.Hy) func3 = np.vectorize(field.Hz) x_lim = lst[3] * 100. y_lim = lst[4] * 100. X, Y, Z = np.mgrid[0:x_lim:25j, 0:y_lim:25j, 0:5:20j] obj = quiver3d(X, Y, Z, func1(X, Y, Z, 1.), func2(X, Y, Z, 1.), func3(X, Y, Z, 1.)) colorbar() #outline() view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=250, width=300, show_label=False), resizable=True)
def traits_view(self): a = Group(Item('use_offline_database'), Item('database_path', editor=FileEditor()), label='Offline') return View(a)
def traits_view(self): v = View( VGroup(Item('name'), Item('host'), Item('username'), Item('password'))) return v
def traits_view(self): multicollect_grp = VGroup( Group( Item('multicollect_counts', label='Counts', tooltip='Number of data points to collect')), UItem('fit_block', editor=EnumEditor(name='fit_blocks')), UItem('fit_block', style='custom', editor=InstanceEditor()), # UItem('active_detectors', # style='custom', # editor=TableEditor( # sortable=False, # reorderable=False, # columns=[ # ObjectColumn(name='label', # editable=False, # label='Det.'), # CheckboxColumn(name='use', label='Use'), # ObjectColumn(name='isotope', # editor=EnumEditor(name='isotopes') # ), # ObjectColumn(name='fit', # editor=EnumEditor(values=[NULL_STR] + FIT_TYPES) # ), # ]) # ), label='Multicollect', show_border=True) baseline_grp = Group( Item('baseline_before', label='Baselines at Start'), Item('baseline_after', label='Baselines at End'), Item('baseline_counts', tooltip='Number of baseline data points to collect', label='Counts'), Item('baseline_detector', label='Detector'), Item( 'baseline_settling_time', label='Delay (s)', tooltip= 'Wait "Delay" seconds after setting magnet to baseline position' ), Item('baseline_mass', label='Mass'), label='Baseline', show_border=True) peak_center_grp = Group( Item('peak_center_before', label='Peak Center at Start'), Item('peak_center_after', label='Peak Center at End'), Item('peak_center_detector', label='Detector', enabled_when='peak_center_before or peak_center_after'), Item('peak_center_isotope', label='Isotope', enabled_when='peak_center_before or peak_center_after'), label='Peak Center', show_border=True) equilibration_grp = Group( Item('eq_time', label='Time (s)'), Item('eq_outlet', label='Ion Pump Valve'), Item( 'eq_delay', label='Delay (s)', tooltip='Wait "Delay" seconds before opening the Inlet Valve'), Item('eq_inlet', label='Inlet Valve'), label='Equilibration', show_border=True) peak_hop_group = VGroup( Group(Item('ncycles'), Item('baseline_ncycles')), HGroup(Spring(springy=False, width=28), Label('position'), Spring(springy=False, width=10), Label('Detectors'), Spring(springy=False, width=188), Label('counts'), spring), UItem('hops', editor=ListEditor(style='custom', editor=InstanceEditor())), label='Peak Hop', visible_when='use_peak_hop', show_border=True) action_editor = TableEditor( columns=[ CheckboxColumn(name='use', width=20), ObjectColumn(name='key', label='Key'), ObjectColumn(name='comparator', label='Comp.'), ObjectColumn(name='criterion', label='Crit.'), ObjectColumn(name='start_count', label='Start'), # ObjectColumn(name='frequency', # label='Freq.' # ), CheckboxColumn(name='resume', label='Resume'), ], deletable=True, row_factory=self._new_action) truncation_editor = TableEditor(columns=[ CheckboxColumn(name='use', width=20), ObjectColumn(name='key', label='Key'), ObjectColumn(name='comparator', label='Comp.'), ObjectColumn(name='criterion', label='Crit.'), ObjectColumn(name='start_count', label='Start'), ], deletable=True, row_factory=self._new_truncation) termination_editor = TableEditor(columns=[ CheckboxColumn(name='use', width=20), ObjectColumn(name='key', label='Key'), ObjectColumn(name='comparator', label='Comp.'), ObjectColumn(name='criterion', label='Crit.'), ObjectColumn(name='start_count', label='Start'), ], deletable=True, row_factory=self._new_termination) cond_grp = VGroup(Group(UItem('actions', editor=action_editor, style='custom'), label='Actions'), Group(UItem('truncations', editor=truncation_editor, style='custom'), label='Truncations'), Group(UItem('terminations', editor=termination_editor, style='custom'), label='Terminations'), label='Conditions') v = View( VGroup( Item('use_peak_hop'), peak_hop_group, Group(multicollect_grp, cond_grp, baseline_grp, peak_center_grp, equilibration_grp, layout='tabbed', visible_when='not use_peak_hop'), )) return v
def RFItem(name, **kw): return Item(make_rf_name(name), **kw)
def QFItem(name, **kw): return Item(make_qf_name(name), **kw)
def traits_view(self): v = View( UItem('analysis_type', style='readonly'), Item('isotopes', editor=TabularEditor(adapter=AnalysisHealthAdapter()))) return v
class Rabi(PulsedTau): """Defines a Rabi measurement.""" frequency = Range(low=1, high=20e9, value=2.8705e9, desc='microwave frequency', label='frequency [Hz]', mode='text', auto_set=False, enter_set=True, editor=TextEditor(auto_set=False, enter_set=True, evaluate=float, format_str='%e')) power = Range(low=-100., high=25., value=-20, desc='microwave power', label='power [dBm]', mode='text', auto_set=False, enter_set=True) switch = Enum('mw_x', 'mw_y', desc='switch to use for microwave pulses', label='switch', editor=EnumEditor(cols=3, values={ 'mw_x': '1:X', 'mw_y': '2:Y' })) laser = Range(low=1., high=100000., value=3000., desc='laser [ns]', label='laser [ns]', mode='text', auto_set=False, enter_set=True) decay_init = Range( low=0., high=10000., value=1000., desc='time to let the system decay after laser pulse [ns]', label='decay init [ns]', mode='text', auto_set=False, enter_set=True) decay_read = Range( low=0., high=10000., value=0., desc='time to let the system decay before laser pulse [ns]', label='decay read [ns]', mode='text', auto_set=False, enter_set=True) aom_delay = Range( low=0., high=1000., value=0., desc= 'If set to a value other than 0.0, the aom triggers are applied\nearlier by the specified value. Use with care!', label='aom delay [ns]', mode='text', auto_set=False, enter_set=True) def start_up(self): PulseGenerator().Night() Microwave().setOutput(self.power, self.frequency) def shut_down(self): PulseGenerator().Light() Microwave().setOutput(None, self.frequency) def generate_sequence(self): MW = self.switch tau = self.tau laser = self.laser decay_init = self.decay_init decay_read = self.decay_read aom_delay = self.aom_delay if aom_delay == 0.0: sequence = [(['aom'], laser)] for t in tau: sequence += [([], decay_init), ([MW], t), ([], decay_read), (['laser', 'aom'], laser)] sequence += [(['sequence'], 100)] sequence = sequence_remove_zeros(sequence) else: s1 = [(['aom'], laser)] s2 = [([], aom_delay + laser)] for t in tau: s1 += [([], decay_init + t + decay_read), (['aom'], laser)] s2 += [([], decay_init), ([MW], t), ([], decay_read), (['laser'], laser)] s2 += [(['sequence'], 100)] s1 = sequence_remove_zeros(s1) s2 = sequence_remove_zeros(s2) sequence = sequence_union(s1, s2) return sequence get_set_items = PulsedTau.get_set_items + [ 'frequency', 'power', 'switch', 'laser', 'decay_init', 'decay_read', 'aom_delay' ] traits_view = View( VGroup( HGroup( Item('submit_button', show_label=False), Item('remove_button', show_label=False), Item('resubmit_button', show_label=False), Item('priority'), Item('state', style='readonly'), Item('run_time', style='readonly'), Item('stop_time'), ), Tabbed( VGroup(HGroup( Item('frequency', width=-120, enabled_when='state != "run"'), Item('power', width=-60, enabled_when='state != "run"'), Item('switch', style='custom', enabled_when='state != "run"'), Item('aom_delay', width=-80, enabled_when='state != "run"'), ), HGroup( Item('laser', width=-80, enabled_when='state != "run"'), Item('decay_init', width=-80, enabled_when='state != "run"'), Item('decay_read', width=-80, enabled_when='state != "run"'), ), HGroup( Item('tau_begin', width=-80, enabled_when='state != "run"'), Item('tau_end', width=-80, enabled_when='state != "run"'), Item('tau_delta', width=-80, enabled_when='state != "run"'), ), label='manipulation'), VGroup(HGroup( Item('record_length', width=-80, enabled_when='state != "run"'), Item('bin_width', width=-80, enabled_when='state != "run"'), ), label='acquisition'), ), ), title='Rabi Measurement AOM Delay', )
class T1pi(Rabi): """T1 measurement with pi-pulse.""" t_pi = Range(low=0., high=100000., value=1000., desc='pi pulse length', label='pi [ns]', mode='text', auto_set=False, enter_set=True) def generate_sequence(self): MW = self.switch tau = self.tau laser = self.laser decay_init = self.decay_init decay_read = self.decay_read aom_delay = self.aom_delay t_pi = self.t_pi if aom_delay == 0.0: sequence = [(['aom'], laser)] for t in tau: sequence += [([], decay_init), ([MW], t_pi), ([], t + decay_read), (['laser', 'aom'], laser)] sequence += [(['sequence'], 100)] sequence = sequence_remove_zeros(sequence) else: s1 = [(['aom'], laser)] s2 = [([], aom_delay + laser)] for t in tau: s1 += [([], decay_init + t_pi + t + decay_read), (['aom', 'laser'], laser)] s2 += [([], decay_init), ([MW], t_pi), ([], t + decay_read + laser)] s2 += [(['sequence'], 100)] s1 = sequence_remove_zeros(s1) s2 = sequence_remove_zeros(s2) sequence = sequence_union(s1, s2) return sequence get_set_items = Rabi.get_set_items + ['t_pi'] traits_view = View( VGroup( HGroup( Item('submit_button', show_label=False), Item('remove_button', show_label=False), Item('resubmit_button', show_label=False), Item('priority', width=-60), Item('state', style='readonly'), Item('run_time', style='readonly'), Item('stop_time'), ), Tabbed( VGroup(HGroup( Item('frequency', width=-120, enabled_when='state != "run"'), Item('power', width=-60, enabled_when='state != "run"'), Item('switch', style='custom', enabled_when='state != "run"'), Item('aom_delay', width=-80, enabled_when='state != "run"'), ), HGroup( Item('laser', width=-80, enabled_when='state != "run"'), Item('decay_init', width=-80, enabled_when='state != "run"'), Item('t_pi', width=-80, enabled_when='state != "run"'), Item('decay_read', width=-80, enabled_when='state != "run"'), ), HGroup( Item('tau_begin', width=-80, enabled_when='state != "run"'), Item('tau_end', width=-80, enabled_when='state != "run"'), Item('tau_delta', width=-80, enabled_when='state != "run"'), ), label='manipulation'), VGroup(HGroup( Item('record_length', width=-80, enabled_when='state != "run"'), Item('bin_width', width=-80, enabled_when='state != "run"'), ), label='acquisition'), ), ), title='T1pi AOM Delay', )
def default_custom_view(): """ Default view of DateRangeEditor """ view = View( Item(name="date_range", style="custom", editor=DateRangeEditor()) ) return view
class ImagePlaneWidget(Module): # The version of this class. Used for persistence. __version__ = 0 ipw = Instance(tvtk.ImagePlaneWidget, allow_none=False, record=True) use_lookup_table = Bool(True, help='Use a lookup table to map input scalars to colors') input_info = PipelineInfo(datasets=['image_data'], attribute_types=['any'], attributes=['scalars']) view = View(Group(Item(name='ipw', style='custom', resizable=True), show_labels=False ), width=600, height=600, resizable=True, scrollable=True ) ###################################################################### # `Module` interface ###################################################################### def setup_pipeline(self): """Override this method so that it *creates* the tvtk pipeline. This method is invoked when the object is initialized via `__init__`. Note that at the time this method is called, the tvtk data pipeline will *not* yet be setup. So upstream data will not be available. The idea is that you simply create the basic objects and setup those parts of the pipeline not dependent on upstream sources and filters. You should also set the `actors` attribute up at this point. """ # Create the various objects for this module. self.ipw = tvtk.ImagePlaneWidget(display_text=1, key_press_activation=0, left_button_action=1, middle_button_action=0, user_controlled_lookup_table=True) self.setup_lut() def update_pipeline(self): """Override this method so that it *updates* the tvtk pipeline when data upstream is known to have changed. This method is invoked (automatically) when any of the inputs sends a `pipeline_changed` event. """ mod_mgr = self.module_manager if mod_mgr is None: return # Data is available, so set the input for the IPW. input = mod_mgr.source.outputs[0] dataset = mod_mgr.source.get_output_dataset() if not (dataset.is_a('vtkStructuredPoints') \ or dataset.is_a('vtkImageData')): msg = 'ImagePlaneWidget only supports structured points or '\ 'image data.' error(msg) raise TypeError(msg) self.configure_input(self.ipw, input) self.setup_lut() def update_data(self): """Override this method so that it flushes the vtk pipeline if that is necessary. This method is invoked (automatically) when any of the inputs sends a `data_changed` event. """ # Just set data_changed, the component should do the rest. self.data_changed = True @on_trait_change('use_lookup_table') def setup_lut(self): # Set the LUT for the IPW. if self.use_lookup_table: if self.module_manager is not None: self.ipw.lookup_table = \ self.module_manager.scalar_lut_manager.lut else: self.ipw.color_map.lookup_table = None self.render() ###################################################################### # Non-public methods. ###################################################################### def _ipw_changed(self, old, new): if old is not None: old.on_trait_change(self.render, remove=True) self.widgets.remove(old) new.on_trait_change(self.render) self.widgets.append(new) if old is not None: self.update_pipeline() self.pipeline_changed = True
class WriteWAV(TimeInOut): """ Saves time signal from one or more channels as mono/stereo/multi-channel `*.wav` file. """ #: Basename for cache, readonly. basename = Property(depends_on='digest') #: Channel(s) to save. List can only contain one or two channels. channels = List(desc="channel to save") # internal identifier digest = Property(depends_on=['source.digest', 'channels', '__class__']) traits_view = View([ Item('source', style='custom'), ['basename~{File name}', '|[Properties]'], '|' ], title='Write wav file', buttons=OKCancelButtons) @cached_property def _get_digest(self): return digest(self) @cached_property def _get_basename(self): obj = self.source # start with source try: while obj: if 'basename' in obj.all_trait_names(): # at original source? basename = obj.basename # get the name break else: obj = obj.source # traverse down until original data source else: basename = 'void' except AttributeError: basename = 'void' # if no file source is found return basename def save(self): """ Saves source output to one- or multiple-channel `*.wav` file. """ nc = len(self.channels) if nc == 0: raise ValueError("No channels given for output.") if nc > 2: warn( "More than two channels given for output, exported file will have %i channels" % nc) name = self.basename for nr in self.channels: name += '_%i' % nr name += '.wav' wf = wave.open(name, 'w') wf.setnchannels(nc) wf.setsampwidth(2) wf.setframerate(self.source.sample_freq) wf.setnframes(self.source.numsamples) mx = 0.0 ind = array(self.channels) for data in self.source.result(1024): mx = max(abs(data[:, ind]).max(), mx) scale = 0.9 * 2**15 / mx for data in self.source.result(1024): wf.writeframesraw( array(data[:, ind] * scale, dtype=int16).tostring()) wf.close()
def RTItem(name, **kw): return Item(make_rt_name(name), **kw)
def traits_view(self): v = View(Item('path')) return v
class SimPStudy(HasTraits): """ The main application window. """ def __init__(self, **kw): super(SimPStudy, self).__init__(**kw) # The initialization should not be considered dirty # therefore set the flag to indicate unsaved study to false # self.dirty = False sim_array = Instance(SimArray) def _sim_array_default(self): return SimArray() sim_model = Property() def _set_sim_model(self, value): self.sim_array.sim_model = value def __getitem__(self, factor_slices): '''Direct access to the sim_array. ''' return self.sim_array[factor_slices] #--------------------------------------------------------------- # PERSISTENCY #------------------------------------------------------------------- file_base_name = Property() def _get_file_base_name(self): return self.sim_model.__class__.__name__ file_path = Str('') dirty = False @on_trait_change('sim_array.changed') def _set_dirty(self): self.dirty = True def new(self): sim_model = self.sim_array.sim_model self.sim_array = SimArray(sim_model=sim_model) self.dirty = False def load(self, file_name): file = open(file_name, 'r') self.sim_array = pickle.load(file) file.close() self.dirty = False def save(self, file_name): file = open(file_name, 'w') pickle.dump(self.sim_array, file) file.close() self.dirty = False def clear_cache(self): self.sim_array.clear_cache() toolbar = ToolBar(Action(name="New Study", tooltip='Create a new study', image=ImageResource('New-32'), action="new_study"), Action(name="Open Study", tooltip='Open a study', image=ImageResource('fileopen-32'), action="open_study"), Action(name="Save Study", tooltip='Save study', image=ImageResource('save'), action="save_study"), Action(name="New View", tooltip='Create new view', image=ImageResource('new_view'), action="new_view"), Action(name="Clear Cache", tooltip='Reset cache', image=ImageResource('reset'), action="clear_cache"), image_size=(22, 22), show_tool_names=False, show_divider=True, name='study_toolbar') menubar = MenuBar( Menu(Action(name="&New", action="new_study"), Action(name="&Open", action="open_study"), Action(name="&Save", action="save_study"), Action(name="Save &As", action="save_study_as"), Action(name="&Exit", action="exit_study"), name="&File"), Menu(Action(name="&New View", action="new_view"), name="&View"), Menu(Action(name="&Clear Cache", action="clear_cache"), name="&Data"), Menu(Action(name="About PStudy", action="about_pstudy"), HelpAction, name="Help")) view = View( Item('sim_array@', show_label=False), id='simvisage.simiter.pstudy', dock='tab', menubar=menubar, toolbar=toolbar, resizable=True, width=0.8, height=0.8, title='SimVisage: Parametric Study', handler=SimPStudyController, )
class AFile ( HasTraits ): file = File view = View( Item( 'file', style = 'custom', show_label = False ) )
class PUFoamModel(BaseDataSourceModel): #: Name of experiment name = Str("experiment") #: Toggle between input of foam volume fraction or mass (g) use_mass = Bool(False) #: Whether to toggle initial conditions input as fixed or variable #: in the MCO as a parameter input_method = Enum(['Model', 'Parameter'], changes_slots=True) #: Initial volume fraction of PUFoam in domain if fixed foam_volume = Float(0.1) #: Initial mass of PUFoam in domain if fixed (g) foam_mass = Float(100) #: Length of simulation run time_steps = Int(100) #: File path containing the simulation data files simulation_directory = Str(desc="Path to the simulation folder") #: File path for the simulation output data output_file = Str(desc="File name to store simulation output data") #: This should allow the user to either choose the existing docker #: implementation of the PUFoam executable, or provide a custom #: command to run the simulation, i.e. with local PUFoam installation simulation_executable = Enum(["docker", "custom"]) #: Name of the docker image used to run the PUFoam simulation image_name = Str( "registry.gitlab.cc-asp.fraunhofer.de:4567/force/pufoam:latest") # Name of Docker container running PUFoam image container_name = Str('BDSS_PUFOAM') # Host of Docker container running PUFoam image host = Str('0.0.0.0') # Port used to connect to Docker container running PUFoam image port = Int(5000) traits_view = View( Group(Item('input_method'), Item("use_mass"), Item("foam_volume", editor=RangeEditor(low=0, high=1, is_float=True), visible_when="not use_mass and input_method=='Model'"), Item("foam_mass", visible_when="use_mass and input_method=='Model'"), label='Initial Conditions'), Group(Item("time_steps"), Item("simulation_directory"), Item("output_file"), Item("simulation_executable"), Item("image_name", visible_when="simulation_executable == 'docker'"), Item("container_name", visible_when="simulation_executable == 'docker'"), Item("host", visible_when="simulation_executable == 'docker'"), Item("port", visible_when="simulation_executable == 'docker'"), label='Simulation Parameters')) def verify(self): """Overloads parent method to include check for initial PUFoam volume fraction """ errors = super(PUFoamModel, self).verify() if self.foam_volume < 0 or self.foam_volume > 1: errors.append( VerifierError( subject=self, severity='warning', local_error="PuFoam initial volume is not a fraction", global_error=( "PUFoam initial volume must be between 0 - 1"), )) return errors
class AutoFocus( ManagedJob, GetSetItemsMixin ): # overwrite default priority from ManagedJob (default 0) priority = 10 confocal = Instance( Confocal ) odmr = Instance( ODMR ) #counter_trace = Instance ( CounterTrace ) size_xy = Range(low=0.5, high=10., value=0.8, desc='Size of XY Scan', label='Size XY [micron]', mode='slider', auto_set=False, enter_set=True) size_z = Range(low=0.5, high=10., value=1.5, desc='Size of Z Scan', label='Size Z [micron]', mode='slider', auto_set=False, enter_set=True) step_xy = Range(low=0.01, high=10., value=0.04, desc='Step of XY Scan', label='Step XY [micron]', mode='slider', auto_set=False, enter_set=True) step_z = Range(low=0.01, high=10., value=0.15, desc='Step of Z Scan', label='Step Z [micron]', mode='slider', auto_set=False, enter_set=True) seconds_per_point_xy = Range(low=1e-3, high=10, value=0.03, desc='Seconds per point for XY Scan', label='seconds per point XY [s]', mode='text', auto_set=False, enter_set=True) seconds_per_point_z = Range(low=1e-3, high=10, value=0.05, desc='Seconds per point for Z Scan', label='seconds per point Z [s]', mode='text', auto_set=False, enter_set=True) fit_method_xy = Enum('Maximum', 'Gaussian', desc='Fit Method for XY Scan', label='XY Fit Method') fit_method_z = Enum('Maximum', 'Gaussian', desc='Fit Method for Z Scan', label='Z Fit Method') X = Array(value=np.array((0.,1.)) ) Y = Array(value=np.array((0.,1.)) ) Z = Array(value=np.array((-1.,1.)) ) data_xy = Array( ) data_z = Array( value=np.array((0,0)) ) targets = Instance( {}.__class__, factory={}.__class__ ) # Dict traits are no good for pickling, therefore we have to do it with an ordinary dictionary and take care about the notification manually target_list = Instance( list, factory=list, args=([None],) ) # list of targets that are selectable in current_target editor current_target = Enum(values='target_list') drift = Array( value=np.array(((0,0,0,),)) ) drift_time = Array( value=np.array((0,)) ) current_drift = Array( value=np.array((0,0,0)) ) focus_interval = Range(low=1, high=6000, value=10, desc='Time interval between automatic focus events', label='Interval [m]', auto_set=False, enter_set=True) periodic_focus = Bool(False, label='Periodic focusing') periodic_freq_feedback = Bool(False, label='Periodic freq feedback') threshold = Range(low=1, high=6000, value=1000, desc='ignore oil junks', label='threshold kcs/s', auto_set=False, enter_set=True) target_name = Str(label='name', desc='name to use when adding or removing targets') add_target_button = Button(label='Add Target', desc='add target with given name') remove_current_target_button = Button(label='Remove Current', desc='remove current target') next_target_button = Button(label='Next Target', desc='switch to next available target') undo_button = Button(label='undo', desc='undo the movement of the stage') previous_state = Instance( () ) plot_data_image = Instance( ArrayPlotData ) plot_data_line = Instance( ArrayPlotData ) plot_data_drift = Instance( ArrayPlotData ) figure_image = Instance( HPlotContainer, editor=ComponentEditor() ) figure_line = Instance( Plot, editor=ComponentEditor() ) figure_drift = Instance( Plot, editor=ComponentEditor() ) image_plot = Instance( CMapImagePlot ) def __init__(self, confocal, odmr): super(AutoFocus, self).__init__() self.confocal = confocal self.odmr = odmr #self.counter_trace = counter_trace self.on_trait_change(self.update_plot_image, 'data_xy', dispatch='ui') self.on_trait_change(self.update_plot_line_value, 'data_z', dispatch='ui') self.on_trait_change(self.update_plot_line_index, 'Z', dispatch='ui') self.on_trait_change(self.update_plot_drift_value, 'drift', dispatch='ui') self.on_trait_change(self.update_plot_drift_index, 'drift_time', dispatch='ui') @on_trait_change('next_target_button') def next_target(self): """Convenience method to switch to the next available target.""" keys = self.targets.keys() key = self.current_target if len(keys) == 0: logging.getLogger().info('No target available. Add a target and try again!') elif not key in keys: self.current_target = keys[0] else: self.current_target = keys[(keys.index(self.current_target)+1)%len(keys)] def _targets_changed(self, name, old, new): l = new.keys() + [None] # rebuild target_list for Enum trait l.sort() self.target_list = l self._draw_targets() # redraw target labels def _current_target_changed(self): self._draw_targets() # redraw target labels def _draw_targets(self): c = self.confocal c.remove_all_labels() c.show_labels=True for key, coordinates in self.targets.iteritems(): if key == self.current_target: c.set_label(key, coordinates, marker_color='red') else: c.set_label(key, coordinates) def _periodic_focus_changed(self, new): if not new and hasattr(self, 'cron_event'): CronDaemon().remove(self.cron_event) if new: self.cron_event = CronEvent(self.submit, min=range(0,60,self.focus_interval)) CronDaemon().register(self.cron_event) def fit_xy(self): if self.fit_method_xy == 'Maximum': index = self.data_xy.argmax() xp = self.X[index%len(self.X)] yp = self.Y[index/len(self.X)] self.XYFitParameters = [xp, yp] self.xfit = xp self.yfit = yp return xp, yp else: print 'Not Implemented! Fix Me!' def fit_z(self): if self.fit_method_z == 'Maximum': zp = self.Z[self.data_z.argmax()] self.zfit = zp return zp else: print 'Not Implemented! Fix Me!' def add_target(self, key, coordinates=None): if coordinates is None: c = self.confocal coordinates = np.array((c.x,c.y,c.z)) if self.targets == {}: self.forget_drift() if self.targets.has_key(key): if warning('A target with this name already exists.\nOverwriting will move all targets.\nDo you want to continue?'): self.current_drift = coordinates - self.targets[key] self.forget_drift() else: return else: coordinates = coordinates - self.current_drift self.targets[key] = coordinates self.trait_property_changed('targets', self.targets) # trigger event such that Enum is updated and Labels are redrawn self.confocal.show_labels=True def remove_target(self, key): if not key in self.targets: logging.getLogger().info('Target cannot be removed. Target does not exist.') return self.targets.pop(key) # remove target from dictionary self.trait_property_changed('targets', self.targets) # trigger event such that Enum is updated and Labels are redrawn def remove_all_targets(self): self.targets = {} def forget_drift(self): targets = self.targets # reset coordinates of all targets according to current drift for key in targets: targets[key] += self.current_drift # trigger event such that target labels are redrawn self.trait_property_changed('targets', self.targets) # set current_drift to 0 and clear plot self.current_drift = np.array((0., 0., 0.)) self.drift_time = np.array((time.time(),)) self.drift = np.array(((0,0,0),)) def _add_target_button_fired(self): self.add_target( self.target_name ) def _remove_current_target_button_fired(self): self.remove_target( self.current_target ) def _run(self): logging.getLogger().debug("trying run.") try: self.state='run' #ha.PulseGenerator().Light() if self.current_target is None: self.focus() if np.amax(self.data_xy)<10: self._undo_button_fired() pg.Light() self.focus() # if self.periodic_freq_feedback: # self.odmr.submit() else: # focus target coordinates = self.targets[self.current_target] confocal = self.confocal confocal.x, confocal.y, confocal.z = coordinates + self.current_drift current_coordinates = self.focus() self.current_drift = current_coordinates - coordinates self.drift = np.append(self.drift, (self.current_drift,), axis=0) self.drift_time = np.append(self.drift_time, time.time()) logging.getLogger().debug('Drift: %.2f, %.2f, %.2f'%tuple(self.current_drift)) # if self.periodic_freq_feedback: # self.odmr.submit() finally: self.state = 'idle' def focus(self): """ Focuses around current position in x, y, and z-direction. """ xp = self.confocal.x yp = self.confocal.y zp = self.confocal.z self.previous_state = ((xp,yp,zp), self.current_target) ##+scanner.getXRange()[1] safety = 0 #distance to keep from the ends of scan range xmin = np.clip(xp-0.5*self.size_xy, scanner.getXRange()[0]+safety, scanner.getXRange()[1]-safety) xmax = np.clip(xp+0.5*self.size_xy, scanner.getXRange()[0]+safety, scanner.getXRange()[1]-safety) ymin = np.clip(yp-0.5*self.size_xy, scanner.getYRange()[0]+safety, scanner.getYRange()[1]-safety) ymax = np.clip(yp+0.5*self.size_xy, scanner.getYRange()[0]+safety, scanner.getYRange()[1]-safety) X = np.arange(xmin, xmax, self.step_xy) Y = np.arange(ymin, ymax, self.step_xy) self.X = X self.Y = Y XP = X[::-1] self.data_xy=np.zeros((len(Y),len(X))) #self.image_plot.index.set_data(X, Y) for i,y in enumerate(Y): if threading.current_thread().stop_request.isSet(): self.confocal.x = xp self.confocal.y = yp self.confocal.z = zp return xp, yp, zp if i%2 != 0: XL = XP else: XL = X YL = y * np.ones(X.shape) ZL = zp * np.ones(X.shape) Line = np.vstack( (XL, YL, ZL) ) c = scanner.scanLine(Line, self.seconds_per_point_xy)/1e3 if i%2 == 0: self.data_xy[i,:] = c[:] else: self.data_xy[i,:] = c[-1::-1] self.trait_property_changed('data_xy', self.data_xy) for i in range(self.data_xy.shape[0]): for j in range(self.data_xy.shape[1]): if self.data_xy[i][j]>self.threshold: self.data_xy[i][j]=0 xp, yp = self.fit_xy() self.confocal.x = xp self.confocal.y = yp Z = np.hstack( ( np.arange(zp, zp-0.5*self.size_z, -self.step_z), np.arange(zp-0.5*self.size_z, zp+0.5*self.size_z, self.step_z), np.arange(zp+0.5*self.size_z, zp, -self.step_z) ) ) Z = np.clip(Z, scanner.getZRange()[0]+safety, scanner.getZRange()[1]-safety) X = xp * np.ones(Z.shape) Y = yp * np.ones(Z.shape) if not threading.current_thread().stop_request.isSet(): Line = np.vstack( (X, Y, Z) ) data_z = scanner.scanLine(Line, self.seconds_per_point_z)/1e3 self.Z = Z self.data_z = data_z for i in range(self.data_z.shape[0]): if self.data_z[i]>self.threshold: self.data_z[i]=0 zp = self.fit_z() self.confocal.z = zp logging.getLogger().info('Focus: %.2f, %.2f, %.2f' %(xp, yp, zp)) return xp, yp, zp def undo(self): if self.previous_state is not None: coordinates, target = self.previous_state self.confocal.x, self.confocal.y, self.confocal.z = coordinates if target is not None: self.drift_time = np.delete(self.drift_time, -1) self.current_drift = self.drift[-2] self.drift = np.delete(self.drift, -1, axis=0) self.previous_state = None else: logging.getLogger().info('Can undo only once.') def _undo_button_fired(self): self.remove() self.undo() def _plot_data_image_default(self): return ArrayPlotData(image=np.zeros((2,2))) def _plot_data_line_default(self): return ArrayPlotData(x=self.Z, y=self.data_z) def _plot_data_drift_default(self): return ArrayPlotData(t=self.drift_time, x=self.drift[:,0], y=self.drift[:,1], z=self.drift[:,2]) def _figure_image_default(self): plot = Plot(self.plot_data_image, width=180, height=180, padding=3, padding_left=48, padding_bottom=32) plot.img_plot('image', colormap=jet, name='image') plot.aspect_ratio=1 #plot.value_mapper.domain_limits = (scanner.getYRange()[0],scanner.getYRange()[1]) #plot.index_mapper.domain_limits = (scanner.getXRange()[0],scanner.getXRange()[1]) plot.value_mapper.domain_limits = (0,self.size_xy) plot.index_mapper.domain_limits = (0,self.size_xy) container = HPlotContainer() image = plot.plots['image'][0] colormap = image.color_mapper colorbar = ColorBar(index_mapper=LinearMapper(range=colormap.range), color_mapper=colormap, plot=plot, orientation='v', resizable='v', width=20, height=200, padding=8, padding_left=20) container = HPlotContainer() container.add(plot) container.add(colorbar) return container def _figure_line_default(self): plot = Plot(self.plot_data_line, width=70, height=40, padding=8, padding_left=64, padding_bottom=32) plot.plot(('x','y'), color='blue') plot.index_axis.title = 'z [um]' plot.value_axis.title = 'Fluorescence [ k / s ]' return plot def _figure_drift_default(self): plot = Plot(self.plot_data_drift, width=70, height=40, padding=8, padding_left=64, padding_bottom=32) plot.plot(('t','x'), type='line', color='blue', name='x') plot.plot(('t','y'), type='line', color='red', name='y') plot.plot(('t','z'), type='line', color='green', name='z') bottom_axis = PlotAxis(plot, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) plot.index_axis=bottom_axis plot.index_axis.title = 'time' plot.value_axis.title = 'drift [um]' plot.legend.visible=True return plot def _image_plot_default(self): return self.figure_image.components[0].plots['image'][0] def update_plot_image(self): self.plot_data_image.set_data('image', self.data_xy) def update_plot_line_value(self): self.plot_data_line.set_data('y', self.data_z) def update_plot_line_index(self): self.plot_data_line.set_data('x', self.Z) def update_plot_drift_value(self): if len(self.drift) == 1: self.plot_data_drift.set_data('x', np.array(())) self.plot_data_drift.set_data('y', np.array(())) self.plot_data_drift.set_data('z', np.array(())) else: self.plot_data_drift.set_data('x', self.drift[:,0]) self.plot_data_drift.set_data('y', self.drift[:,1]) self.plot_data_drift.set_data('z', self.drift[:,2]) def update_plot_drift_index(self): if len(self.drift_time) == 0: self.plot_data_drift.set_data('t', np.array(())) else: self.plot_data_drift.set_data('t', self.drift_time - self.drift_time[0]) traits_view = View(VGroup(HGroup(Item('submit_button', show_label=False), Item('remove_button', show_label=False), Item('priority'), Item('state', style='readonly'), Item('undo_button', show_label=False), ), Group(VGroup(HGroup(Item('target_name'), Item('add_target_button', show_label=False), ), HGroup(Item('current_target'), Item('next_target_button', show_label=False), Item('remove_current_target_button', show_label=False), ), HGroup(Item('periodic_focus'), Item('focus_interval', enabled_when='not periodic_focus'), ), HGroup(Item('periodic_freq_feedback'), Item('threshold') ), label='tracking', ), VGroup(Item('size_xy'), Item('step_xy'), Item('size_z'), Item('step_z'), HGroup(Item('seconds_per_point_xy'), Item('seconds_per_point_z'), ), label='Settings', springy=True, ), layout='tabbed' ), VSplit(Item('figure_image', show_label=False, resizable=True)), HGroup(Item('figure_line', show_label=False, resizable=True), Item('figure_drift', show_label=False, resizable=True), ), ), menubar = MenuBar(Menu(Action(action='save', name='Save (.pyd or .pys)'), Action(action='load', name='Load'), Action(action='_on_close', name='Quit'), name='File'), Menu(Action(action='remove_all_targets', name='Remove All'), Action(action='forget_drift', name='Forget Drift'), name='Target'),), title='Auto Focus', width=500, height=700, buttons=[], resizable=True, handler=AutoFocusHandler) get_set_items=['confocal','targets','current_target','current_drift','drift','drift_time','periodic_focus', 'size_xy', 'size_z', 'step_xy', 'step_z', 'seconds_per_point_xy', 'seconds_per_point_z', 'data_xy', 'data_z', 'X', 'Y', 'Z', 'focus_interval', 'threshold' ] get_set_order=['confocal','targets']
class MATS1DElastic(MATS1DEval): ''' Elastic Model. ''' E = Float( 1., # 34e+3, label="E", desc="Young's Modulus", auto_set=False, enter_set=True) #------------------------------------------------------------------------- # Piece wise linear stress strain curve #------------------------------------------------------------------------- _stress_strain_curve = Instance(MFnLineArray) def __stress_strain_curve_default(self): return MFnLineArray(ydata=[0., self.E], xdata=[0., 1.]) @on_trait_change('E') def reset_stress_strain_curve(self): self._stress_strain_curve = MFnLineArray(ydata=[0., self.E], xdata=[0., 1.]) stress_strain_curve = Property def _get_stress_strain_curve(self): return self._stress_strain_curve def _set_stress_strain_curve(self, curve): self._stress_strain_curve = curve # This event can be used by the clients to trigger an action upon # the completed reconfiguration of the material model # changed = Event #------------------------------------------------------------------------- # View specification #------------------------------------------------------------------------- view_traits = View(Item('E'), ) #------------------------------------------------------------------------- # Private initialization methods #------------------------------------------------------------------------- def __init__(self, **kwtraits): ''' Subsidiary arrays required for the integration. they are set up only once prior to the computation ''' super(MATS1DElastic, self).__init__(**kwtraits) def new_cntl_var(self): return np.zeros(1, np.float_) def new_resp_var(self): return np.zeros(1, np.float_) #------------------------------------------------------------------------- # Evaluation - get the corrector and predictor #------------------------------------------------------------------------- def get_corr_pred(self, sctx, eps_app_eng, d_eps, tn, tn1, *args, **kw): ''' Corrector predictor computation. @param eps_app_eng input variable - engineering strain ''' eps_n1 = float(eps_app_eng) # E = self.E # D_el = array([[E]]) # sigma = dot( D_el, eps_app_eng ) D_el = np.array([[self.stress_strain_curve.diff(eps_n1)]]) sigma = np.array([self.stress_strain_curve(eps_n1)]) # You print the stress you just computed and the value of the apparent # E return sigma, D_el #------------------------------------------------------------------------- # Subsidiary methods realizing configurable features #------------------------------------------------------------------------- #------------------------------------------------------------------------- # Response trace evaluators #------------------------------------------------------------------------- # Declare and fill-in the rte_dict - it is used by the clients to # assemble all the available time-steppers. # rte_dict = Trait(Dict) def _rte_dict_default(self): return {'sig_app': self.get_sig_app, 'eps_app': self.get_eps_app} #------------------------------------------------------------------------- # List of response tracers to be constructed within the mats_explorer #------------------------------------------------------------------------- def _get_explorer_rtrace_list(self): '''Return the list of relevant tracers to be used in mats_explorer. ''' return [ RTDofGraph(name='strain - stress', var_x='eps_app', idx_x=0, var_y='sig_app', idx_y=0, record_on='update') ]
class BeadCalibrationHandler(OpHandler): add_channel = Event remove_channel = Event channels = Property(List(Str), observe='context.channels') beads_name_choices = Property beads_units = Property(observe='model.beads_name') operation_traits_view = \ View(VGroup( Item('beads_name', editor = EnumEditor(name = 'handler.beads_name_choices'), label = "Beads"), Item('beads_file', editor = FileEditor(dialog_style = 'open'))), VGroup(Item('units_list', editor = VerticalListEditor(editor = InstanceHandlerEditor(view = 'unit_view', handler_factory = UnitHandler), style = 'custom', mutable = False), style = 'custom'), Item('handler.add_channel', editor = ButtonEditor(value = True, label = "Add a channel")), Item('handler.remove_channel', editor = ButtonEditor(value = True, label = "Remove a channel")), label = "Controls", show_labels = False), Item('bead_peak_quantile', editor = TextEditor(auto_set = False, evaluate = int, format_func = lambda x: "" if x is None else str(x), placeholder = "None"), label = "Peak\nQuantile"), Item('bead_brightness_threshold', editor = TextEditor(auto_set = False, evaluate = float, format_func = lambda x: "" if x is None else str(x), placeholder = "None"), label = "Peak\nThreshold "), Item('bead_brightness_cutoff', editor = TextEditor(auto_set = False, evaluate = float, format_func = lambda x: "" if x is None else str(x), placeholder = "None"), label = "Peak\nCutoff"), Item('do_estimate', editor = ButtonEditor(value = True, label = "Estimate!"), show_label = False), shared_op_traits_view) # MAGIC: called when add_control is set def _add_channel_fired(self): self.model.units_list.append(BeadCalibrationUnit()) def _remove_channel_fired(self): if self.model.units_list: self.model.units_list.pop() def _get_channels(self): if self.context and self.context.channels: return natsorted(self.context.channels) else: return [] def _get_beads_name_choices(self): return list(self.model.BEADS.keys()) def _get_beads_units(self): if self.model.beads_name: return list(self.model.BEADS[self.model.beads_name].keys()) else: return []
class YeadonGUI(HasTraits): """A GUI for the yeadon module, implemented using the traits package.""" # Input. measurement_file_name = File() # Drawing options. show_mass_center = Bool(False) show_inertia_ellipsoid = Bool(False) # Configuration variables. opts = {'enter_set': True, 'auto_set': True, 'mode': 'slider'} for name, bounds in zip(Human.CFGnames, Human.CFGbounds): # TODO : Find a better way than using locals here, it may not be a good # idea, but I don't know the consequences. locals()[name] = Range(float(rad2deg(bounds[0])), float(rad2deg(bounds[1])), 0.0, **opts) reset_configuration = Button() # Display of Human object properties. Ixx = Property(Float, depends_on=sliders) Ixy = Property(Float, depends_on=sliders) Ixz = Property(Float, depends_on=sliders) Iyx = Property(Float, depends_on=sliders) Iyy = Property(Float, depends_on=sliders) Iyz = Property(Float, depends_on=sliders) Izx = Property(Float, depends_on=sliders) Izy = Property(Float, depends_on=sliders) Izz = Property(Float, depends_on=sliders) x = Property(Float, depends_on=sliders) y = Property(Float, depends_on=sliders) z = Property(Float, depends_on=sliders) scene = Instance(MlabSceneModel, args=()) input_group = Group(Item('measurement_file_name')) vis_group = Group(Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=580, width=430, show_label=False)) config_first_group = Group( Item('somersault'), Item('tilt'), Item('twist'), Item('PTsagittalFlexion', label='PT sagittal flexion'), Item('PTbending', label='PT bending'), Item('TCspinalTorsion', label='TC spinal torsion'), Item('TCsagittalSpinalFlexion', label='TC sagittal spinal flexion'), label='Whole-body, pelvis, torso', dock='tab', ) config_upper_group = Group( Item('CA1extension', label='CA1 extension'), Item('CA1adduction', label='CA1 adduction'), Item('CA1rotation', label='CA1 rotation'), Item('CB1extension', label='CB1 extension'), Item('CB1abduction', label='CB1 abduction'), Item('CB1rotation', label='CB1 rotation'), Item('A1A2extension', label='A1A2 extension'), Item('B1B2extension', label='B1B2 extension'), label='Upper limbs', dock='tab', ) config_lower_group = Group( Item('PJ1extension', label='PJ1 extension'), Item('PJ1adduction', label='PJ1 adduction'), Item('PK1extension', label='PK1 extension'), Item('PK1abduction', label='PK1 abduction'), Item('J1J2flexion', label='J1J2 flexion'), Item('K1K2flexion', label='K1K2 flexion'), label='Lower limbs', dock='tab', ) config_group = VGroup( Label('Configuration'), Group(config_first_group, config_upper_group, config_lower_group, layout='tabbed', ), Item('reset_configuration', show_label=False), Label('P: pelvis (red); T: thorax (orange); C: chest-head (yellow)'), Label('A1/A2: left upper arm/forearm-hand; B1/B2: right arm'), Label('J1/J2: left thigh/shank-foot; K1/K2: right leg'), show_border=True, ) inertia_prop = VGroup( Label('Mass center (from origin of coord. sys.) (m):'), HGroup( Item('x', style='readonly', format_func=format_func), Item('y', style='readonly', format_func=format_func), Item('z', style='readonly', format_func=format_func) ), Label('Inertia tensor (about origin, in basis shown) (kg-m^2):'), HSplit( # HSplit 2 Group( Item('Ixx', style='readonly', format_func=format_func), Item('Iyx', style='readonly', format_func=format_func), Item('Izx', style='readonly', format_func=format_func), ), Group( Item('Ixy', style='readonly', format_func=format_func), Item('Iyy', style='readonly', format_func=format_func), Item('Izy', style='readonly', format_func=format_func), ), Group( Item('Ixz', style='readonly', format_func=format_func), Item('Iyz', style='readonly', format_func=format_func), Item('Izz', style='readonly', format_func=format_func) ), ), # end HSplit 2 Label('X, Y, Z axes drawn as red, green, blue arrows, respectively.'), show_border=True, ) # end VGroup view = View( VSplit( input_group, HSplit(vis_group, VSplit( config_group, Item('show_mass_center'), Item('show_inertia_ellipsoid'), inertia_prop ) ), ), resizable=True, title='Yeadon human inertia model' ) # end View measPreload = { 'Ls5L' : 0.545, 'Lb2p' : 0.278, 'La5p' : 0.24, 'Ls4L' : 0.493, 'La5w' : 0.0975, 'Ls4w' : 0.343, 'La5L' : 0.049, 'Lb2L' : 0.2995, 'Ls4d' : 0.215, 'Lj2p' : 0.581, 'Lb5p' : 0.24, 'Lb5w' : 0.0975, 'Lk8p' : 0.245, 'Lk8w' : 0.1015, 'Lj5L' : 0.878, 'La6w' : 0.0975, 'Lk1L' : 0.062, 'La6p' : 0.2025, 'Lk1p' : 0.617, 'La6L' : 0.0805, 'Ls5p' : 0.375, 'Lj5p' : 0.2475, 'Lk8L' : 0.1535, 'Lb5L' : 0.049, 'La3p' : 0.283, 'Lj9w' : 0.0965, 'La4w' : 0.055, 'Ls6L' : 0.152, 'Lb0p' : 0.337, 'Lj8w' : 0.1015, 'Lk2p' : 0.581, 'Ls6p' : 0.53, 'Lj9L' : 0.218, 'La3L' : 0.35, 'Lj8p' : 0.245, 'Lj3L' : 0.449, 'La4p' : 0.1685, 'Lk3L' : 0.449, 'Lb3p' : 0.283, 'Ls7L' : 0.208, 'Ls7p' : 0.6, 'Lb3L' : 0.35, 'Lk3p' : 0.3915, 'La4L' : 0.564, 'Lj8L' : 0.1535, 'Lj3p' : 0.3915, 'Lk4L' : 0.559, 'La1p' : 0.2915, 'Lb6p' : 0.2025, 'Lj6L' : 0.05, 'Lb6w' : 0.0975, 'Lj6p' : 0.345, 'Lb6L' : 0.0805, 'Ls0p' : 0.97, 'Ls0w' : 0.347, 'Lj6d' : 0.122, 'Ls8L' : 0.308, 'Lk5L' : 0.878, 'La2p' : 0.278, 'Lj9p' : 0.215, 'Ls1L' : 0.176, 'Lj1L' : 0.062, 'Lb1p' : 0.2915, 'Lj1p' : 0.617, 'Ls1p' : 0.865, 'Ls1w' : 0.317, 'Lk4p' : 0.34, 'Lk5p' : 0.2475, 'La2L' : 0.2995, 'Lb4w' : 0.055, 'Lb4p' : 0.1685, 'Lk9p' : 0.215, 'Lk9w' : 0.0965, 'Ls2p' : 0.845, 'Lj4L' : 0.559, 'Ls2w' : 0.285, 'Lk6L' : 0.05, 'La7w' : 0.047, 'La7p' : 0.1205, 'La7L' : 0.1545, 'Lk6p' : 0.345, 'Ls2L' : 0.277, 'Lj4p' : 0.34, 'Lk6d' : 0.122, 'Lk9L' : 0.218, 'Lb4L' : 0.564, 'La0p' : 0.337, 'Ls3w' : 0.296, 'Ls3p' : 0.905, 'Lb7p' : 0.1205, 'Lb7w' : 0.047, 'Lj7p' : 0.252, 'Lb7L' : 0.1545, 'Ls3L' : 0.388, 'Lk7p' : 0.252 } def __init__(self, meas_in=None): HasTraits.__init__(self, trait_value=True) if meas_in: measurement_file_name = meas_in else: measurement_file_name = 'Path to measurement input text file.' self.H = Human(meas_in if meas_in else self.measPreload) self._init_draw_human() def _init_draw_human(self): self.H.draw(self.scene.mlab, True) if self.show_mass_center: self.H._draw_mayavi_mass_center_sphere(self.scene.mlab) if self.show_inertia_ellipsoid: self.H._draw_mayavi_inertia_ellipsoid(self.scene.mlab) @on_trait_change('scene.activated') def set_view(self): """Sets a reasonable camera angle for the intial view.""" self.scene.mlab.view(azimuth=90.0, elevation=-90.0) def _get_Ixx(self): return self.H.inertia[0, 0] def _get_Ixy(self): return self.H.inertia[0, 1] def _get_Ixz(self): return self.H.inertia[0, 2] def _get_Iyx(self): return self.H.inertia[1, 0] def _get_Iyy(self): return self.H.inertia[1, 1] def _get_Iyz(self): return self.H.inertia[1, 2] def _get_Izx(self): return self.H.inertia[2, 0] def _get_Izy(self): return self.H.inertia[2, 1] def _get_Izz(self): return self.H.inertia[2, 2] def _get_x(self): return self.H.center_of_mass[0, 0] def _get_y(self): return self.H.center_of_mass[1, 0] def _get_z(self): return self.H.center_of_mass[2, 0] @on_trait_change('measurement_file_name') def _update_measurement_file_name(self): # Must convert to str (from unicode), because Human parses it # differently depending on its type, and there's no consideration for # it being unicode. self.H = Human(str(self.measurement_file_name)) self.scene.mlab.clf() self._init_draw_human() @on_trait_change('show_inertia_ellipsoid') def _update_show_inertia_ellipsoid(self): if self.show_inertia_ellipsoid: self.H._draw_mayavi_inertia_ellipsoid(self.scene.mlab) else: self.H._ellipsoid_mesh.remove() def _maybe_update_inertia_ellipsoid(self): if self.show_inertia_ellipsoid: self.H._update_mayavi_inertia_ellipsoid() @on_trait_change('show_mass_center') def _update_show_mass_center(self): if self.show_mass_center: self.H._draw_mayavi_mass_center_sphere(self.scene.mlab) else: self.H._mass_center_sphere.remove() def _maybe_update_mass_center(self): if self.show_mass_center: self.H._update_mayavi_mass_center_sphere() @on_trait_change('reset_configuration') def _update_reset_configuration(self): # TODO: This is really slow because it sets every trait one by one. It # would be nice to set them all to zero and only call the redraw once. for cfg in sliders: setattr(self, cfg, self.trait(cfg).default_value()[1]) @on_trait_change('somersault') def _update_somersault(self): self.H.set_CFG('somersault', deg2rad(self.somersault)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('tilt') def _update_tilt(self): self.H.set_CFG('tilt', deg2rad(self.tilt)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('twist') def _update_twist(self): self.H.set_CFG('twist', deg2rad(self.twist)) self._update_mayavi(['P', 'T', 'C', 'A1', 'A2', 'B1', 'B2', 'J1', 'J2', 'K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PTsagittalFlexion') def _update_PTsagittalFlexion(self): self.H.set_CFG('PTsagittalFlexion', deg2rad(self.PTsagittalFlexion)) self._update_mayavi(['T', 'C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PTbending') def _update_PTFrontalFlexion(self): self.H.set_CFG('PTbending', deg2rad(self.PTbending)) self._update_mayavi(['T', 'C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('TCspinalTorsion') def _update_TCSpinalTorsion(self): self.H.set_CFG('TCspinalTorsion', deg2rad(self.TCspinalTorsion)) self._update_mayavi(['C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('TCsagittalSpinalFlexion') def _update_TCLateralSpinalFlexion(self): self.H.set_CFG('TCsagittalSpinalFlexion', deg2rad(self.TCsagittalSpinalFlexion)) self._update_mayavi(['C', 'A1', 'A2', 'B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1extension') def _update_CA1extension(self): self.H.set_CFG('CA1extension', deg2rad(self.CA1extension)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1adduction') def _update_CA1adduction(self): self.H.set_CFG('CA1adduction', deg2rad(self.CA1adduction)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CA1rotation') def _update_CA1rotation(self): self.H.set_CFG('CA1rotation', deg2rad(self.CA1rotation)) self._update_mayavi(['A1', 'A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1extension') def _update_CB1extension(self): self.H.set_CFG('CB1extension', deg2rad(self.CB1extension)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1abduction') def _update_CB1abduction(self): self.H.set_CFG('CB1abduction', deg2rad(self.CB1abduction)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('CB1rotation') def _update_CB1rotation(self): self.H.set_CFG('CB1rotation', deg2rad(self.CB1rotation)) self._update_mayavi(['B1', 'B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('A1A2extension') def _update_A1A2extension(self): self.H.set_CFG('A1A2extension', deg2rad(self.A1A2extension)) self._update_mayavi(['A2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('B1B2extension') def _update_B1B2extension(self): self.H.set_CFG('B1B2extension', deg2rad(self.B1B2extension)) self._update_mayavi(['B2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PJ1extension') def _update_PJ1extension(self): self.H.set_CFG('PJ1extension', deg2rad(self.PJ1extension)) self._update_mayavi(['J1', 'J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PJ1adduction') def _update_PJ1adduction(self): self.H.set_CFG('PJ1adduction', deg2rad(self.PJ1adduction)) self._update_mayavi(['J1', 'J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PK1extension') def _update_PK1extension(self): self.H.set_CFG('PK1extension', deg2rad(self.PK1extension)) self._update_mayavi(['K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('PK1abduction') def _update_PK1abduction(self): self.H.set_CFG('PK1abduction', deg2rad(self.PK1abduction)) self._update_mayavi(['K1', 'K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('J1J2flexion') def _update_J1J2flexion(self): self.H.set_CFG('J1J2flexion', deg2rad(self.J1J2flexion)) self._update_mayavi(['J2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() @on_trait_change('K1K2flexion') def _update_K1K2flexion(self): self.H.set_CFG('K1K2flexion', deg2rad(self.K1K2flexion)) self._update_mayavi(['K2']) self._maybe_update_mass_center() self._maybe_update_inertia_ellipsoid() def _update_mayavi(self, segments): """Updates all of the segments and solids.""" for affected in segments: seg = self.H.get_segment_by_name(affected) for solid in seg.solids: solid._mesh.scene.disable_render = True for affected in segments: self.H.get_segment_by_name(affected)._update_mayavi() for affected in segments: seg = self.H.get_segment_by_name(affected) for solid in seg.solids: solid._mesh.scene.disable_render = False
class ExecutionLayerTemplate(BaseTemplate): # ------------------ # Regular Attributes # ------------------ #: Template referring to the primary surfactant data primary_surfactant_template = Instance(IngredientTemplate) #: Template referring to the secondary surfactant data secondary_surfactant_template = Instance(IngredientTemplate) #: A list of possible surfactant ingredient to choose from surfactant_template_list = List(IngredientTemplate) #: An empty surfactant Template empty_surfactant_template = Instance(IngredientTemplate) #: Template referring to the chloride ion data salt_template = Instance(IngredientTemplate) #: Template referring to the solvent data solvent_template = Instance(IngredientTemplate) #: Internal database of available Ingredient objects _gromacs_database = Instance(GromacsDatabase) # ------------------ # Properties # ------------------ #: Factory ID for Workflow id = Property(Unicode, depends_on='plugin_id') #: List containing all fragment templates to be used in #: a generated Workflow ingredient_templates = Property(List(IngredientTemplate), depends_on='primary_surfactant_template,' 'secondary_surfactant_template') #: Number of Ingredients n_ingredients = Property(Int, depends_on='ingredient_templates[]') # ------------------ # Properties # ------------------ #: A list of possible secondary surfactant ingredient, including an #: empty ingredient option secondary_surfactant_list = Property(List(IngredientTemplate), depends_on='surfactant_template_list,' 'primary_surfactant_template') # ------------------ # View # ------------------ traits_view = View( HGroup( Group(Heading("Primary Surfactant"), Item("primary_surfactant_template", editor=InstanceEditor(name='surfactant_template_list'), style='custom'), show_labels=False), Group(Heading("Secondary Surfactant"), Item("secondary_surfactant_template", editor=InstanceEditor(name='secondary_surfactant_list'), style='custom'), show_labels=False))) # ------------------ # Defaults # ------------------ def _empty_surfactant_template_default(self): return IngredientTemplate(plugin_id=self.id) def __gromacs_database_default(self): return GromacsDatabase() def _surfactant_template_list_default(self): surfactants = self._gromacs_database.get_role('Surfactant') surfactant_templates = [ IngredientTemplate(plugin_id=self.id, ingredient=surfactant) for surfactant in surfactants ] return surfactant_templates def _primary_surfactant_template_default(self): return self.surfactant_template_list[0] def _secondary_surfactant_template_default(self): return self.empty_surfactant_template def _salt_template_default(self): salt = self._gromacs_database.get_ingredient('Sodium Chloride') return IngredientTemplate(plugin_id=self.id, ingredient=salt) def _solvent_template_default(self): water = self._gromacs_database.get_ingredient('Water') return IngredientTemplate(plugin_id=self.id, ingredient=water) # ------------------ # Listeners # ------------------ def _get_id(self): return '.'.join([self.plugin_id, "factory"]) @cached_property def _get_ingredient_templates(self): templates = [ self.primary_surfactant_template, self.salt_template, self.solvent_template ] if self.secondary_surfactant_template.ingredient: templates.insert(1, self.secondary_surfactant_template) return templates @cached_property def _get_n_ingredients(self): return len(self.ingredient_templates) @cached_property def _get_secondary_surfactant_list(self): secondary_list = [self.empty_surfactant_template] secondary_list += [ surfactant for surfactant in self.surfactant_template_list if surfactant != self.primary_surfactant_template ] return secondary_list @on_trait_change('primary_surfactant_template') def update_secondary_surfactant_template(self): if (self.primary_surfactant_template == self.secondary_surfactant_template): self.secondary_surfactant_template = ( self._secondary_surfactant_template_default()) @on_trait_change('plugin_id') def update_plugin_id(self): for surfactant_template in self.surfactant_template_list: surfactant_template.plugin_id = self.id self.empty_surfactant_template.plugin_id = self.id self.salt_template.plugin_id = self.id self.solvent_template.plugin_id = self.id # ------------------ # Public Methods # ------------------ def create_database_templates(self): templates = [] for ingredient_template in self.ingredient_templates: template = ingredient_template.create_template() templates.append(template) return templates def create_formulation_template(self): input_slot_info = [] for template in self.ingredient_templates: if template.ingredient.role != 'Solvent': input_slot_info.append( {"name": f"{template.variable_name}_ingredient"}) input_slot_info.append( {"name": f"{template.variable_name}_conc"}) else: input_slot_info.append( {"name": f"{template.variable_name}_ingredient"}) return { "id": f"{self.id}.formulation", "model_data": { "n_surfactants": self.n_ingredients - 2, "input_slot_info": input_slot_info, "output_slot_info": [{ "name": "formulation" }] } } def create_simulation_template(self): return { "id": f"{self.id}.simulation", "model_data": { "name": "surfactant_experiment", "size": 500, "dry_run": False, "input_slot_info": [{ "name": "formulation" }], "output_slot_info": [{ "name": "results" }] } } def create_micelle_template(self): surfactants = [ template.ingredient for template in self.ingredient_templates if template.ingredient.role == 'Surfactant' ] fragment_symbols = [ surfactant.fragments[0].symbol for surfactant in surfactants ] return { "id": f"{self.id}.micelle", "model_data": { "method": 'atomic', "fragment_symbols": fragment_symbols, "r_thresh": 0.98, "input_slot_info": [{ "name": "formulation" }, { "name": "results" }], "output_slot_info": [{ "name": "micelle" }] } } def create_viscosity_template(self): return { "id": f"{self.id}.viscosity", "model_data": { "input_slot_info": [{ "name": "results" }], "output_slot_info": [{ "name": "viscosity" }] } } def create_cost_template(self): return { "id": f"{self.id}.cost", "model_data": { "input_slot_info": [{ "name": "formulation" }], "output_slot_info": [{ "name": "cost" }] } } def create_template(self): return [{ 'data_sources': self.create_database_templates() }, { 'data_sources': [self.create_formulation_template()] }, { 'data_sources': [self.create_simulation_template()] }, { 'data_sources': [self.create_micelle_template(), self.create_cost_template()] }]
class Mixer(TimeInOut): """ Mixes the signals from several sources. """ #: Data source; :class:`~acoular.sources.SamplesGenerator` object. source = Trait(SamplesGenerator) #: List of additional :class:`~acoular.sources.SamplesGenerator` objects #: to be mixed. sources = List(Instance(SamplesGenerator, ())) #: Sampling frequency of the signal as given by :attr:`source`. sample_freq = Delegate('source') #: Number of channels in output as given by :attr:`source`. numchannels = Delegate('source') #: Number of samples in output as given by :attr:`source`. numsamples = Delegate('source') # internal identifier ldigest = Property(depends_on=[ 'sources.digest', ]) # internal identifier digest = Property(depends_on=['source.digest', 'ldigest', '__class__']) traits_view = View(Item('source', style='custom')) @cached_property def _get_ldigest(self): res = '' for s in self.sources: res += s.digest return res @cached_property def _get_digest(self): return digest(self) @on_trait_change('sources,source') def validate_sources(self): """ validates if sources fit together """ if self.source: for s in self.sources: if self.sample_freq != s.sample_freq: raise ValueError("Sample frequency of %s does not fit" % s) if self.numchannels != s.numchannels: raise ValueError("Channel count of %s does not fit" % s) def result(self, num): """ Python generator that yields the output block-wise. The output from the source and those in the list sources are being added. Parameters ---------- num : integer This parameter defines the size of the blocks to be yielded (i.e. the number of samples per block). Returns ------- Samples in blocks of shape (num, numchannels). The last block may be shorter than num. """ gens = [i.result(num) for i in self.sources] for temp in self.source.result(num): sh = temp.shape[0] for g in gens: temp1 = next(g) if temp.shape[0] > temp1.shape[0]: temp = temp[:temp1.shape[0]] temp += temp1[:temp.shape[0]] yield temp if sh > temp.shape[0]: break
def _get_group(self): g = Item('text', style='custom') return g
class FiltFiltOctave(TimeInOut): """ Octave or third-octave filter with zero phase delay. This filter can be applied on time signals. It requires large amounts of memory! """ #: Band center frequency; defaults to 1000. band = Float(1000.0, desc="band center frequency") #: Octave fraction: 'Octave' or 'Third octave'; defaults to 'Octave'. fraction = Trait('Octave', { 'Octave': 1, 'Third octave': 3 }, desc="fraction of octave") # internal identifier digest = Property( depends_on = ['source.digest', '__class__', \ 'band', 'fraction']) traits_view = View([ Item('source', style='custom'), 'band{Center frequency}', 'fraction{Bandwidth}', ['sample_freq~{Output sampling frequency}', '|[Properties]'], '|' ], title='Linear average', buttons=OKCancelButtons) @cached_property def _get_digest(self): return digest(self) def ba(self, order): """ Internal Butterworth filter design routine. Parameters ---------- order : integer The order of the filter. Returns ------- b, a : ndarray, ndarray Filter coefficients. """ # filter design fs = self.sample_freq # adjust filter edge frequencies beta = pi / (4 * order) alpha = pow(2.0, 1.0 / (2.0 * self.fraction_)) beta = 2 * beta / sin(beta) / (alpha - 1 / alpha) alpha = (1 + sqrt(1 + beta * beta)) / beta fr = 2 * self.band / fs if fr > 1 / sqrt(2): raise ValueError("band frequency too high:%f,%f" % (self.band, fs)) om1 = fr / alpha om2 = fr * alpha # print om1, om2 return butter(order, [om1, om2], 'bandpass') def result(self, num): """ Python generator that yields the output block-wise. Parameters ---------- num : integer This parameter defines the size of the blocks to be yielded (i.e. the number of samples per block). Returns ------- Samples in blocks of shape (num, numchannels). Delivers the zero-phase bandpass filtered output of source. The last block may be shorter than num. """ b, a = self.ba(3) # filter order = 3 data = empty((self.source.numsamples, self.source.numchannels)) j = 0 for block in self.source.result(num): ns, nc = block.shape data[j:j + ns] = block j += ns for j in range(self.source.numchannels): data[:, j] = filtfilt(b, a, data[:, j]) j = 0 ns = data.shape[0] while j < ns: yield data[j:j + num] j += num
class TimeCache(TimeInOut): """ Caches time signal in cache file. """ # basename for cache basename = Property(depends_on='digest') # hdf5 cache file h5f = Instance(tables.File, transient=True) # internal identifier digest = Property(depends_on=['source.digest', '__class__']) traits_view = View([ Item('source', style='custom'), ['basename~{Cache file name}', '|[Properties]'], '|' ], title='TimeCache', buttons=OKCancelButtons) @cached_property def _get_digest(self): return digest(self) @cached_property def _get_basename(self): obj = self.source # start with source basename = 'void' # if no file source is found while obj: if 'basename' in obj.all_trait_names(): # at original source? basename = obj.basename # get the name break else: try: obj = obj.source # traverse down until original data source except AttributeError: obj = None return basename # result generator: delivers input, possibly from cache def result(self, num): """ Python generator that yields the output from cache block-wise. Parameters ---------- num : integer This parameter defines the size of the blocks to be yielded (i.e. the number of samples per block). Returns ------- Samples in blocks of shape (num, numchannels). The last block may be shorter than num. Echos the source output, but reads it from cache when available and prevents unnecassary recalculation. """ name = 'tc_' + self.digest H5cache.get_cache(self, self.basename) if not name in self.h5f.root: ac = self.h5f.create_earray(self.h5f.root, name, \ tables.atom.Float32Atom(), \ (0, self.numchannels)) ac.set_attr('sample_freq', self.sample_freq) for data in self.source.result(num): ac.append(data) yield data else: ac = self.h5f.get_node('/', name) i = 0 while i < ac.shape[0]: yield ac[i:i + num] i += num
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 = BorderVGroup(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')), queue_factory_uitem('email', springy=True), label='Email') user_grp = BorderHGroup( UItem(queue_factory_name('username'), editor=ComboboxEditor(name=queue_factory_name('usernames'))), icon_button_editor(queue_factory_name('edit_user'), 'database_edit'), label='User') load_select = BorderHGroup( queue_factory_uitem('load_name', width=150), queue_factory_item( 'tray', editor=EnumEditor(name=queue_factory_name('trays'))), icon_button_editor( queue_factory_name('select_existing_load_name_button'), 'database_go', tooltip='Get Load from Database'), label='Load') generate_queue = BorderHGroup( 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'), label='Generate Queue') lgrp = VGroup(load_select, generate_queue) ms_ed_grp = BorderVGroup(HGroup( queue_factory_uitem( 'mass_spectrometer', editor=myEnumEditor( name=queue_factory_name('mass_spectrometers'))), queue_factory_uitem( 'extract_device', editor=myEnumEditor( name=queue_factory_name('extract_devices')))), lgrp, queue_factory_item('default_lighting'), label='Spectrometer/Extract Device') name = queue_factory_name('available_conditionals') queue_cond_grp = BorderHGroup(queue_factory_uitem( 'queue_conditionals_name', label='Queue Conditionals', editor=myEnumEditor(name=name)), label='Queue Conditionals') delay_grp = BorderVGroup( queue_factory_item('delay_before_analyses', label='Before Analyses (s)'), queue_factory_item('delay_between_analyses', label='Between Analyses (s)'), queue_factory_item('delay_after_blank', label='After Blank (s)'), queue_factory_item('delay_after_air', label='After Air (s)'), label='Delays') note_grp = BorderVGroup(queue_factory_uitem('note', style='custom', height=150), label='Note') queue_grp = VGroup(user_grp, email_grp, ms_ed_grp, queue_cond_grp, delay_grp, note_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, enabled_when='edit_enabled'), kind='live', width=225) return v