def default_traits_view(self): return View( VGroup(Item('controls_list', editor=VerticalListEditor(editor=InstanceEditor( view=self.control_traits_view()), style='custom', mutable=False), style='custom'), Item('handler.add_control', editor=ButtonEditor(value=True, label="Add a control")), Item('handler.remove_control', editor=ButtonEditor(value=True, label="Remove a control")), label="Controls", show_labels=False), VGroup(Item( 'subset_list', show_label=False, editor=SubsetListEditor( conditions="handler.context.previous_wi.conditions", metadata="handler.context.previous_wi.metadata", when="'experiment' not in vars() or not experiment")), label="Subset", show_border=False, show_labels=False), Heading("WARNING: Very slow!"), Heading("Give it a few minutes..."), Item('do_estimate', editor=ButtonEditor(value=True, label="Estimate!"), show_label=False), shared_op_traits)
def traits_view(self): v = View(VGroup(VGroup(HGroup(Heading('Lower Bound'), UItem('use_low_post')), UItem('low_post', style='custom', enabled_when='use_low_post')), VGroup(HGroup(Heading('Upper Bound'), UItem('use_high_post')), UItem('high_post', style='custom', enabled_when='use_high_post')), VGroup(HGroup(Heading('Named Range'), UItem('use_named_date_range')), UItem('named_date_range', enabled_when='use_named_date_range'))), buttons=['OK', 'Cancel'], resizable=True, kind='livemodal') return v
def _workflow_group_default(self): workflow_group = Group( Heading("Chemical Ingredient Settings", springy=True), Group(Item('execution_layers_template', editor=InstanceEditor(), style='custom'), show_labels=False), Heading("Concentration Settings", springy=True), Group(Item('mco_template', editor=InstanceEditor(), style='custom'), show_labels=False)) return workflow_group
def default_traits_view(self): return View( Item("channels", editor=CheckListEditor(cols=2, name='context.previous_channels'), style='custom'), VGroup(Item('blank_file'), label="Autofluorescence"), VGroup(Item('bleedthrough_list', editor=VerticalListEditor(editor=InstanceEditor( view=self.bleedthrough_traits_view()), style='custom', mutable=False), style='custom'), label="Bleedthrough Correction", show_border=False, show_labels=False), VGroup(Item('beads_name', editor=EnumEditor(name='handler.beads_name_choices'), label="Beads", width=-125), Item('beads_file'), Item('beads_unit', editor=EnumEditor(name='handler.beads_units')), Item('bead_peak_quantile', label="Peak\nQuantile"), Item('bead_brightness_threshold', label="Peak\nThreshold "), Item('bead_brightness_cutoff', label="Peak\nCutoff"), label="Bead Calibration", show_border=False), VGroup(Item('to_channel', editor=EnumEditor(name='object.channels')), Item('mixture_model', label="Use mixture\nmodel?"), label="Color Translation"), VGroup(Item('translation_list', editor=VerticalListEditor(editor=InstanceEditor( view=self.translation_traits_view()), style='custom', mutable=False), style='custom'), show_labels=False), VGroup(Item( 'subset_list', show_label=False, editor=SubsetListEditor( conditions="context.previous_conditions", metadata="context.previous_metadata", when="'experiment' not in vars() or not experiment")), label="Subset", show_border=False, show_labels=False), Heading("WARNING: Very slow!"), Heading("Give it a few minutes..."), Item('context.do_estimate', editor=ButtonEditor(value=True, label="Estimate!"), show_label=False), shared_op_traits)
def default_traits_view(self): return View(Item('object.name'), Heading('THE HEXBIN PLUGIN IS BROKEN.'), Item('object.xchannel', editor=EnumEditor(name='handler.channels'), label = "X Channel"), Item('object.xscale', label = "X Scale"), Item('object.ychannel', editor=EnumEditor(name='handler.channels'), label = "Y Channel"), Item('object.yscale', label = "Y Scale"), Item('object.xfacet', editor=EnumEditor(name='handler.conditions'), label = "Horizontal\nFacet"), Item('object.yfacet', editor=EnumEditor(name='handler.conditions'), label = "Vertical\nFacet"), Item('object.huefacet', editor=EnumEditor(name='handler.conditions'), label="Color\nFacet"), Item('_'), Item('object.subset', label="Subset", editor = SubsetEditor(experiment = "handler.wi.result")), shared_view_traits)
class DemoButton(HasPrivateTraits): # ------------------------------------------------------------------------- # Trait definitions: # ------------------------------------------------------------------------- #: The demo to be launched via a button: demo = Instance(HasTraits) #: The demo view item to use: demo_item = Item( "demo", show_label=False, editor=InstanceEditor(label="Run demo...", kind="live"), ) # ------------------------------------------------------------------------- # Traits view definitions: # ------------------------------------------------------------------------- traits_view = View( VGroup( VGroup(Heading("Click the button to run the demo:"), "20"), HGroup(spring, Include("demo_item"), spring), ), resizable=True, )
class DemoButton ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The demo to be launched via a button: demo = Instance( HasTraits ) # The demo view item to use: demo_item = Item( 'demo', show_label = False, editor = InstanceEditor( label = 'Run demo...', kind = 'live' ) ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( VGroup( VGroup( Heading( 'Click the button to run the demo:' ), '20' ), HGroup( spring, Include( 'demo_item' ), spring ) ), resizable = True )
def _workflow_group_default(self): workflow_group = Group( Heading("Ray Example Settings"), Item("lower", label="Lower bound"), Item("upper", label="Upper bound"), Item("ray", label="Ray"), ) return workflow_group
def _workflow_group_default(self): workflow_group = Group( Heading("Power Example Settings"), Item("lower", label="Lower bound"), Item("upper", label="Upper bound"), Item("power", label="Exponent"), ) return workflow_group
def traits_view(self): v = View( VGroup( HGroup(Heading(self.name), UItem('visible')), self._get_group() ) ) return v
def traits_view(self): v = okcancel_view( VGroup( VGroup( HGroup(Heading('Lower Bound'), UItem('use_low_post')), UItem('low_post', style='custom', enabled_when='use_low_post')), VGroup( HGroup(Heading('Upper Bound'), UItem('use_high_post')), UItem('high_post', style='custom', enabled_when='use_high_post')), VGroup( HGroup(Heading('Named Range'), UItem('use_named_date_range')), UItem('named_date_range', enabled_when='use_named_date_range')))) return v
def _get_date_group(self): f_grp = HGroup( UItem('analysis_type', editor=EnumEditor(name='analysis_types')), UItem('mass_spectrometer', editor=EnumEditor(name='mass_spectrometers')), UItem('extraction_device', editor=EnumEditor(name='extraction_devices'))) grp = VGroup( f_grp, Heading('Start'), UItem('start_date', editor=DateEditor(allow_future=False), style='custom'), UItem('start_time', ), Item('_'), Heading('End'), UItem('end_date', editor=DateEditor(allow_future=False), style='custom'), UItem('end_time', )) return VSplit(grp, self._get_analysis_group(base='danalysis'), label='Date')
def default_traits_view(self): return View( VGroup( VGroup(Heading("WARNING: Very slow!"), Item('name'), Item('xchannel', editor=EnumEditor(name='context.channels'), label="X Channel"), Item('xscale', label="X Scale"), Item('ychannel', editor=EnumEditor(name='context.channels'), label="Y Channel"), Item('yscale', label="Y Scale"), Item('xfacet', editor=ExtendableEnumEditor( name='context.conditions_names', extra_items={"None": ""}), label="Horizontal\nFacet"), Item('yfacet', editor=ExtendableEnumEditor( name='context.conditions_names', extra_items={"None": ""}), label="Vertical\nFacet"), Item('huefacet', editor=ExtendableEnumEditor( name='context.conditions_names', extra_items={"None": ""}), label="Color\nFacet"), Item('plotfacet', editor=ExtendableEnumEditor( name='context.conditions_names', extra_items={"None": ""}), label="Tab\nFacet"), label="2D Kernel Density Estimate", show_border=False), VGroup(Item( 'subset_dict', show_label=False, editor=SubsetEditor(conditions="context.conditions")), label="Subset", show_border=False, show_labels=False), Item('context.view_warning', resizable=True, visible_when='context.view_warning', editor=ColorTextEditor(foreground_color="#000000", background_color="#ffff99")), Item('context.view_error', resizable=True, visible_when='context.view_error', editor=ColorTextEditor(foreground_color="#000000", background_color="#ff9191"))))
def default_traits_view(self): table_editor = TableEditor( columns=[ ObjectColumn(name='chemical', editor=EnumEditor(name='available')), ObjectColumn(name='concentration', editor=EnumEditor(name='available')) ], sortable=False, deletable=True, row_factory=self._row_factory, ) return View( Heading('Formulation Mapping'), Label("Select the variables that correspond to each " "formulation component's name and concentration"), UItem("table_rows", editor=table_editor), )
class DemoError(HasPrivateTraits): # ------------------------------------------------------------------------- # Trait definitions: # ------------------------------------------------------------------------- #: The error message text: msg = Code() # ------------------------------------------------------------------------- # Traits view definitions: # ------------------------------------------------------------------------- traits_view = View( VGroup( Heading("Error in source file"), Item("msg", style="custom", show_label=False), ))
class DemoError(HasPrivateTraits): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The error message text: msg = Code #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( VGroup( Heading('Error in source file'), Item('msg', style='custom', show_label=False), ))
class SensorOperationController(tui.Controller): """ UI for controlling the hardware. """ model = t.Instance(EEGSensor) connect = t.Button() disconnect = t.Button() def _connect_changed(self): self.model.connect() def _disconnect_changed(self): self.model.disconnect() traits_view = View( HGroup( spring, VGroup( HGroup(spring, Heading('EEG Sensor Controls'), spring), VGroup( Item('com_port', style='simple', enabled_when="not object.connected"), Item('object.connected', style='readonly'), # Item('history_length', style='readonly'), # Item('timeseries_length', style='readonly'), show_labels=True), HGroup( # spring, Item('controller.connect', enabled_when='not object.connected'), Item('controller.disconnect', enabled_when='object.connected'), spring, show_labels=False), Label('Last %d points saved to disk on exit.' % MAX_HISTORY_LENGTH), ), spring, tui.VGrid(Heading('Activate Ch:'), Item('channel_1_on', label='1', enabled_when='not channel_1_enabled'), Item('channel_2_on', label='2', enabled_when='not channel_2_enabled'), Item('channel_3_on', label='3', enabled_when='not channel_3_enabled'), Item('channel_4_on', label='4', enabled_when='not channel_4_enabled'), Item('channel_5_on', label='5', enabled_when='not channel_5_enabled'), Item('channel_6_on', label='6', enabled_when='not channel_6_enabled'), Item('channel_7_on', label='7', enabled_when='not channel_7_enabled'), Item('channel_8_on', label='8', enabled_when='not channel_8_enabled'), Heading('Deactivate Ch:'), Item('channel_1_off', label='1', enabled_when='channel_1_enabled'), Item('channel_2_off', label='2', enabled_when='channel_2_enabled'), Item('channel_3_off', label='3', enabled_when='channel_3_enabled'), Item('channel_4_off', label='4', enabled_when='channel_4_enabled'), Item('channel_5_off', label='5', enabled_when='channel_5_enabled'), Item('channel_6_off', label='6', enabled_when='channel_6_enabled'), Item('channel_7_off', label='7', enabled_when='channel_7_enabled'), Item('channel_8_off', label='8', enabled_when='channel_8_enabled'), show_labels=False, show_border=True, columns=9, enabled_when='object.connected'), spring, ), )
class Demo(HasTraits): list1 = List(Int) list2 = List(Float) list3 = List(Str, maxlen=3) list4 = List(Enum('red', 'green', 'blue', 2, 3)) list5 = List(Range(low=0.0, high=10.0)) # 'low' and 'high' are used to demonstrate lists containing dynamic ranges. low = Float(0.0) high = Float(1.0) list6 = List(Range(low=-1.0, high='high')) list7 = List(Range(low='low', high='high')) pop1 = Button("Pop from first list") sort1 = Button("Sort first list") # This will be str(self.list1). list1str = Property(Str, depends_on='list1') traits_view = \ View( HGroup( # This VGroup forms the column of CSVListEditor examples. VGroup( Item('list1', label="List(Int)", editor=CSVListEditor(ignore_trailing_sep=False), tooltip='options: ignore_trailing_sep=False'), Item('list1', label="List(Int)", style='readonly', editor=CSVListEditor()), Item('list2', label="List(Float)", editor=CSVListEditor(enter_set=True, auto_set=False), tooltip='options: enter_set=True, auto_set=False'), Item('list3', label="List(Str, maxlen=3)", editor=CSVListEditor()), Item('list4', label="List(Enum('red', 'green', 'blue', 2, 3))", editor=CSVListEditor(sep=None), tooltip='options: sep=None'), Item('list5', label="List(Range(low=0.0, high=10.0))", editor=CSVListEditor()), Item('list6', label="List(Range(low=-1.0, high='high'))", editor=CSVListEditor()), Item('list7', label="List(Range(low='low', high='high'))", editor=CSVListEditor()), springy=True, ), # This VGroup forms the right column; it will display the # Python str representation of the lists. VGroup( UItem('list1str', editor=TextEditor(), enabled_when='False', width=240), UItem('list1str', editor=TextEditor(), enabled_when='False', width=240), UItem('list2', editor=TextEditor(), enabled_when='False', width=240), UItem('list3', editor=TextEditor(), enabled_when='False', width=240), UItem('list4', editor=TextEditor(), enabled_when='False', width=240), UItem('list5', editor=TextEditor(), enabled_when='False', width=240), UItem('list6', editor=TextEditor(), enabled_when='False', width=240), UItem('list7', editor=TextEditor(), enabled_when='False', width=240), ), ), '_', HGroup('low', 'high', spring, UItem('pop1'), UItem('sort1')), Heading("Notes"), Label("Hover over a list to see which editor options are set, " "if any."), Label("The editor of the first list, List(Int), uses " "ignore_trailing_sep=False, so a trailing comma is " "an error."), Label("The second list is a read-only view of the first list."), Label("The editor of the List(Float) example has enter_set=True " "and auto_set=False; press Enter to validate."), Label("The List(Str) example will accept at most 3 elements."), Label("The editor of the List(Enum(...)) example uses sep=None, " "i.e. whitespace acts as a separator."), Label("The last two List(Range(...)) examples take one or both " "of their limits from the Low and High fields below."), width=720, title="CSVListEditor Demonstration", ) def _list1_default(self): return [1, 4, 0, 10] def _get_list1str(self): return str(self.list1) def _pop1_fired(self): if len(self.list1) > 0: x = self.list1.pop() print x def _sort1_fired(self): self.list1.sort()
class AtmosViewer(HasTraits): central_wavenumber = CFloat(1000) bandwidth = CFloat(10) selected_line_wavenumber = Float(-1.) figure = Instance(Figure, ()) all_on = Button() all_off = Button() selected_molecules = List(editor=CheckListEditor( values=molecules.keys(), cols=2, format_str='%s')) mplFigureEditor = MPLFigureEditor() trait_view = View(VGroup( Item('figure', editor=mplFigureEditor, show_label=False), HGroup( '10', VGroup('40', Item(name='central_wavenumber', editor=TextEditor(auto_set=False, enter_set=True)), Item(name='bandwidth', editor=TextEditor(auto_set=False, enter_set=True)), HGroup(Item(name='selected_line_wavenumber'), show_border=True), show_border=True), HGroup(VGroup('20', Heading("Molecules"), Item(name='all_on', show_label=False), Item(name='all_off', show_label=False)), Item(name='selected_molecules', style='custom', show_label=False), show_border=True), '10'), '10'), handler=MPLInitHandler, resizable=True, title=title, width=size[0], height=size[1]) def __init__(self): super(AtmosViewer, self).__init__() self.colors = {'telluric': 'black', 'orders': 'black'} self.molecules = molecules self.selected_molecules = [] orders_filename = resource_filename(__name__, 'orders.txt') self.texes_orders = pandas.io.parsers.read_csv(orders_filename, sep='\t', header=None, skiprows=3) atmos_filename = resource_filename(__name__, 'atmos.txt.gz') self.atmos = pandas.io.parsers.read_csv(gzip.open(atmos_filename, 'r'), sep='\t', skiprows=7, index_col='# wn') self.molecule_lookup_points = { } # keys are e.g. 'O3', with a dict of {'wn':..., 'y':...} self.axes = self.figure.add_subplot(111) self.axes.plot(self.atmos.index, self.atmos['trans1mm'], color=self.colors['telluric']) self.axes.plot(self.atmos.index, self.atmos['trans4mm'], color=self.colors['telluric']) for i in self.texes_orders.index: self.axes.plot(self.texes_orders.ix[i].values, [0.05, 0.07], color=self.colors['orders']) self.axes.set_xlim(self.central_wavenumber - self.bandwidth / 2., self.central_wavenumber + self.bandwidth / 2.) self.axes.set_ylim(0, 1.0) self.axes.set_xlabel('Wavenumber (cm-1)') self.axes.xaxis.set_major_formatter(FormatStrFormatter('%6.1f')) self.onclick_connected = False # I don't understand why I can't do the connection here. self.selected_line = None self.selected_line_text = None def on_click(self, event): if event.xdata is None or event.ydata is None: return if self.selected_line in self.axes.lines: self.axes.lines.pop(self.axes.lines.index(self.selected_line)) if self.selected_line_text in self.axes.texts: self.axes.texts.remove(self.selected_line_text) self.selected_line = None self.selected_line_text = None self.selected_line_wavenumber = -1 if len(self.molecule_lookup_points) == 0: return closest = {'name': None, 'wn': -1., 'dist': 9e9} for cur_molecule in self.molecule_lookup_points: wn = self.molecule_lookup_points[cur_molecule]['wn'] ys = self.molecule_lookup_points[cur_molecule]['y'] dist_x2 = (wn - event.xdata)**2 xlim = self.axes.get_xlim() scale = ((xlim[1] - xlim[0]) / # this is like wavenumbers/inch (self.axes.figure.get_figwidth() * self.axes.get_position().bounds[2])) dist_y2 = ((ys - event.ydata) * (self.axes.figure.get_figheight() * self.axes.get_position().bounds[3]) * scale)**2 dist = np.sqrt(dist_x2 + dist_y2) if dist.min() < closest['dist']: closest = { 'name': cur_molecule, 'wn': wn[dist.argmin()], 'dist': dist.min() } self.selected_line_wavenumber = closest['wn'] self.selected_line = self.axes.plot([closest['wn'], closest['wn']], [0, 1], '-.', color='black')[0] self.selected_line_text = self.axes.annotate( closest['name'] + ('%11.5f' % closest['wn']), (closest['wn'], 1.03), ha='center', annotation_clip=False) self.redraw() def on_scroll(self, event): self.central_wavenumber += self.bandwidth * event.step def _all_on_fired(self): self.selected_molecules = self.molecules.keys() def _all_off_fired(self): self.selected_molecules = [] def mpl_setup(self): self.axes_widget = AxesWidget(self.figure.gca()) self.axes_widget.connect_event('button_press_event', self.on_click) self.axes_widget.connect_event('scroll_event', self.on_scroll) @on_trait_change("central_wavenumber, bandwidth") def replot_molecular_overplots(self): for i, cur_molecule in enumerate(self.selected_molecules): if self.molecules[cur_molecule]['hitran'] is None: self.molecules[cur_molecule][ 'hitran'] = pandas.io.parsers.read_csv(gzip.open( self.molecules[cur_molecule]['hitran_filename'], 'r'), skiprows=2) wn = self.molecules[cur_molecule]['hitran']['wavenumber'] intensity = self.molecules[cur_molecule]['hitran']['intensity'] w = ((wn >= self.central_wavenumber - self.bandwidth / 2.) & (wn <= self.central_wavenumber + self.bandwidth / 2.)) wn = wn[w] intensity = intensity[w] plot_orders_of_magnitude = 2. max_line_intensity = intensity.max() min_line_intensity = max_line_intensity / 10**plot_orders_of_magnitude wn = wn[intensity >= min_line_intensity] intensity = intensity[intensity >= min_line_intensity] intensity = ( (np.log10(intensity) - np.log10(min_line_intensity)) / (np.log10(max_line_intensity) - np.log10(min_line_intensity))) intensity = intensity * 0.1 self.molecule_lookup_points[cur_molecule] = { 'wn': wn, 'y': intensity + (i * 0.1) + 0.05 } wn = wn.repeat(3) intensity = np.column_stack( (np.zeros(len(intensity)), intensity, np.zeros( len(intensity)))).flatten() + (i * 0.1) + 0.05 newplot = self.axes.plot(wn, intensity, self.molecules[cur_molecule]['color']) newtext = self.axes.annotate( cur_molecule, (self.central_wavenumber + self.bandwidth * 0.51, i * 0.1 + 0.065), ha='left', va='center', annotation_clip=False, color=self.molecules[cur_molecule]['color']) if self.molecules[cur_molecule]['plot_lines'] in self.axes.lines: self.axes.lines.pop( self.axes.lines.index( self.molecules[cur_molecule]['plot_lines'])) self.molecules[cur_molecule]['plot_lines'] = None if self.molecules[cur_molecule]['plot_text'] in self.axes.texts: self.axes.texts.remove( self.molecules[cur_molecule]['plot_text']) self.molecules[cur_molecule]['plot_text'] = None self.molecules[cur_molecule]['plot_lines'] = newplot[0] self.molecules[cur_molecule]['plot_text'] = newtext self.redraw() def _selected_molecules_changed(self, old, new): self.replot_molecular_overplots() for cur_molecule in old: if cur_molecule not in new: if self.molecules[cur_molecule][ 'plot_lines'] in self.axes.lines: self.axes.lines.pop( self.axes.lines.index( self.molecules[cur_molecule]['plot_lines'])) if self.molecules[cur_molecule][ 'plot_text'] in self.axes.texts: self.axes.texts.remove( self.molecules[cur_molecule]['plot_text']) self.molecules[cur_molecule]['plot_lines'] = None self.molecules[cur_molecule]['plot_text'] = None self.molecule_lookup_points.pop(cur_molecule, None) self.redraw() @on_trait_change("central_wavenumber, bandwidth") def redraw(self): self.axes.set_xlim(self.central_wavenumber - self.bandwidth / 2., self.central_wavenumber + self.bandwidth / 2.) self.axes.set_ylim(0, 1.0) self.figure.canvas.draw()
class MCOTemplate(BaseTemplate): """BaseTemplate subclass to generate MCO options for SurfactantContributedUI""" # ------------------ # Regular Attributes # ------------------ #: Name of the MCO for Workflow plugin id reference mco_name = Unicode("surfactant_mco") #: Template referring to the primary surfactant concentration primary_surfactant_conc = Instance(ParameterTemplate) #: Template referring to the secondary surfactant concentration secondary_surfactant_conc = Instance(ParameterTemplate) #: Template referring to the salt concentration salt_conc = Instance(ParameterTemplate) #: List of all template objects required to build Workflow parameter_templates = List(Instance(ParameterTemplate)) #: Determines whether or not to enable secondary surfactant UI #: options enable_secondary_surfactant = Bool(False) # ------------------ # Properties # ------------------ #: Factory ID for Workflow id = Property(Unicode, depends_on='plugin_id,mco_name') # ------------------ # View # ------------------ traits_view = View( HGroup( Group(Heading("Primary Surfactant"), Item("primary_surfactant_conc", editor=InstanceEditor(), style='custom'), show_labels=False), Group(Heading("Secondary Surfactant"), Item("secondary_surfactant_conc", editor=InstanceEditor(), style='custom', enabled_when='enable_secondary_surfactant'), show_labels=False), Group(Heading("Salt (NaCl)"), Item("salt_conc", editor=InstanceEditor(), style='custom'), show_labels=False))) # ------------------ # Defaults # ------------------ def _primary_surfactant_conc_default(self): return ParameterTemplate(plugin_id=self.id, name='primary_surfactant', parameter_type='Fixed') def _secondary_surfactant_conc_default(self): return ParameterTemplate(plugin_id=self.id, name='secondary_surfactant', parameter_type='Fixed') def _salt_conc_default(self): return ParameterTemplate(plugin_id=self.id, name='salt', parameter_type='Ranged') def _parameter_templates_default(self): return [self.primary_surfactant_conc, self.salt_conc] # ------------------ # Listeners # ------------------ def _get_id(self): return '.'.join([self.plugin_id, "factory", self.mco_name]) @on_trait_change('enable_secondary_surfactant') def update_secondary_surf_conc(self): if not self.enable_secondary_surfactant: self.secondary_surfactant_conc = ( self._secondary_surfactant_conc_default()) self.parameter_templates = self._parameter_templates_default() else: if self.secondary_surfactant_conc not in self.parameter_templates: self.parameter_templates.insert(1, self.secondary_surfactant_conc) @on_trait_change('id') def update_plugin_id(self): self.primary_surfactant_conc.plugin_id = self.id self.secondary_surfactant_conc.plugin_id = self.id self.salt_conc.plugin_id = self.id # ------------------ # Public Methods # ------------------ def create_template(self): return { "id": self.id, "model_data": { "parameters": [ parameter_template.create_template() for parameter_template in self.parameter_templates ], "kpis": [{ "name": "micelle", "objective": "MAXIMISE" }, { "name": "cost", "objective": "MINIMISE" }], }, }
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 NoDemo(HasPrivateTraits): view = View(Heading('No demo defined for this lab.'), resizable=True)