def _default_layout_default(self): return TaskLayout(left=Splitter(Splitter(PaneItem('pychron.pipeline.pane', width=200), PaneItem('pychron.pipeline.analyses', width=200)), PaneItem('pychron.pipeline.repository'), orientation='vertical'))
def _default_layout_default(self): return TaskLayout(left=Splitter(Splitter( PaneItem('pychron.sys_mon.connection'), PaneItem('pychron.processing.controls'), orientation='vertical'), PaneItem('pychron.sys_mon.analyses'), orientation='horizontal'), right=VSplitter( Tabbed(PaneItem('pychron.console'), PaneItem('pychron.plot_editor')), PaneItem('pychron.dashboard.client')))
def _default_layout_default(self): return TaskLayout( left=Splitter( PaneItem('pychron.labnumber.irradiation'), Tabbed( # PaneItem('pychron.labnumber.extractor'), PaneItem('pychron.labnumber.editor')), orientation='vertical'), right=Splitter(PaneItem('pychron.entry.level'), PaneItem('pychron.entry.chronology'), PaneItem('pychron.entry.irradiation_canvas'), orientation='vertical'))
def _default_layout_default(self): return TaskLayout( left=Splitter( PaneItem('pychron.wait', height=100), Tabbed(PaneItem('pychron.experiment.factory'), PaneItem('pychron.experiment.isotope_evolution')), orientation='vertical'), right=Splitter(Tabbed( PaneItem('pychron.experiment.stats'), PaneItem('pychron.console', height=425), PaneItem('pychron.experiment.explanation', height=425), PaneItem('pychron.experiment.connection_status')), PaneItem('pychron.extraction_line.canvas_dock'), orientation='vertical'), top=PaneItem('pychron.experiment.controls'))
def get_layout(self): """ Returns a LayoutItem that reflects the layout of the current splitter. """ ORIENTATION_MAP = {QtCore.Qt.Horizontal: 'horizontal', QtCore.Qt.Vertical: 'vertical'} # obtain layout based on children layouts if not self.is_leaf(): layout = Splitter(self.leftchild.get_layout(), self.rightchild.get_layout(), orientation=ORIENTATION_MAP[self.orientation()]) # obtain the Tabbed layout else: if self.is_empty(): layout = Tabbed(PaneItem(id=-1, width=self.width(), height=self.height()), active_tab=0) else: items = [] for i in range(self.tabwidget().count()): widget = self.tabwidget().widget(i) # mark identification for empty_widget editor = self.editor_area._get_editor(widget) item_id = self.editor_area.editors.index(editor) item_width = self.width() item_height = self.height() items.append(PaneItem(id=item_id, width=item_width, height=item_height)) layout = Tabbed(*items, active_tab=self.tabwidget().currentIndex()) return layout
def _default_layout_default(self): return TaskLayout( left=Splitter( PaneItem('pychron.spectrometer.controls'), orientation='vertical'), right=VSplitter(PaneItem('pychron.spectrometer.intensities'), PaneItem('pychron.spectrometer.readout')))
def _default_layout_default(self): return TaskLayout( left=PaneItem('{}.stage'.format(self.id)), top=Splitter( PaneItem('{}.control'.format(self.id), width=200), PaneItem('pychron.lasers.pulse', width=300), Tabbed(PaneItem('pychron.lasers.optics'), PaneItem('{}.supplemental'.format(self.id)))))
def _default_layout_default(self): return TaskLayout( # top=PaneItem('pychron.extraction_line.gauges'), left=Splitter(PaneItem('pychron.video.source'), PaneItem('pychron.video.controls'), orientation='vertical'), # width=500, # height=500 )
def _default_layout_default(self): #c=PaneItem('pychron.smart_selection.configure') search = Tabbed(browser_pane_item()) #PaneItem('pychron.search.query')) #a=Splitter(d,orientation='vertical') unk = PaneItem('pychron.processing.unknowns') left = Splitter(search, unk) return TaskLayout(id='pychron.processing.batch', left=left)
def _default_layout_default(self): return TaskLayout( left=Splitter(PaneItem('pychron.spectrometer.controls'), Tabbed(PaneItem('pychron.spectrometer.intensities'), PaneItem('pychron.spectrometer.readout')), orientation='vertical') # right=Splitter( # PaneItem('pychron.experiment.stats'), # PaneItem('pychron.experiment.console'), # orientation='vertical' # ), # bottom=PaneItem('pychron.experiment.console'), # top=PaneItem('pychron.experiment.controls') )
class S4LVisualizationTask(Task): # pylint: disable=too-many-instance-attributes """ A task for visualizing Sim4Life EM fields from scES simulations """ #: The task's identifier. id = "s4l.main_task" #: The task's user-visible name. name = "S4L Visualization" #: Configuration parser. configuration = Instance(ConfigParser) #: Current participant's ID participant_id = Str() #: Temporary dictionary for editing user configuration _to_edit = Dict() #: Plane attributes dock pane. plane_attributes_pane = Instance(PlaneAttributes) #: Line attributes dock pane. line_attributes_pane = Instance(LineAttributes) #: Participant ID dock pane. part_id_pane = Instance(ParticipantIDPane) #: The currently active editor. active_editor = Property(Instance(IEditor), depends_on="editor_area.active_editor") #: The editor area in which the editor belongs. editor_area = Instance(IEditorAreaPane) #: The opening page's editor. start_page = Instance(StartPage) #: The object containing the field data. fields_model = Instance(EMFields) #: The 3D view panel. mayavi_scene = Instance(Mayavi3DScene) #: The slice figure panel. slice_figure = Instance(SliceFigureModel) #: The line figure panel. line_figure = Instance(LineFigureModel) #: Has the main window been initialized? model_initialized = Bool(False) #: Action to run :py:meth:`toggle_full_model`. toggle_model_action = TaskAction(name='Full Model', method='toggle_full_model', style='toggle', enabled_name='model_initialized') #: Action to run :py:meth:`change_cord_model`. new_cord_action = TaskAction(name='New Cord Model', method='change_cord_model', enabled_name='model_initialized') #: Action to run :py:meth:`toggle_log_scale`. toggle_scale_action = TaskAction(name='Log Scale', method='toggle_log_scale', style='toggle', checked=True, enabled_name='model_initialized') #: Action to run :py:meth:`toggle_line_cross_marker`. toggle_line_cross_action = TaskAction(name='Line Cross Marker', method='toggle_line_cross_marker', style='toggle', checked=True, enabled_name='model_initialized') #: The task's menu bar. menu_bar = SMenuBar( SMenu( TaskAction(name="&Open...", method="open", accelerator="Ctrl+O"), SMenu( TaskAction(name="Export &Slice", method="export_slice"), TaskAction(name="Export &Line", method="export_line"), id="File.Export", name="&Export", ), TaskAction(name="&Settings", method="edit_configuration"), id="File", name="&File", ), SMenu(SMenu(DockPaneToggleGroup(), id='View.Panes', name='&Panes'), toggle_model_action, toggle_scale_action, toggle_line_cross_action, id="View", name="&View"), SMenu( new_cord_action, SMenu(FieldSelectionGroup(), id='Edit.Fields', name='&Choose Field'), id='Edit', name='&Edit', ), ) # ------------------------------------------------------------------------ # 'Task' interface. # ------------------------------------------------------------------------ @observe('editor_area.active_tabwidget') def _update_tabwidgets(self, event): # pylint: disable=unused-argument try: self.editor_area.active_tabwidget.setTabsClosable(False) except AttributeError: pass def initialized(self): for tabwidget in self.editor_area.tabwidgets(): tabwidget.setTabsClosable(False) self.start_page = StartPage(task=self) self.editor_area.add_editor(self.start_page) self.editor_area.activate_editor(self.start_page) self.activated() def activated(self): self.editor_area.active_tabwidget.setTabsClosable(False) def create_central_pane(self): self.editor_area = SplitEditorAreaPane( callbacks={'open': self._new_file}) return self.editor_area def create_dock_panes(self): """ Create the attribute editor panes. """ self.plane_attributes_pane = PlaneAttributes( configuration=self.configuration) self.plane_attributes_pane.sync_trait('participant_id', self) self.line_attributes_pane = LineAttributes( configuration=self.configuration) self.line_attributes_pane.sync_trait('participant_id', self) self.part_id_pane = ParticipantIDPane() self.part_id_pane.sync_trait('participant_id', self) return [ self.plane_attributes_pane, self.line_attributes_pane, self.part_id_pane ] # ------------------------------------------------------------------------ # 'S4L_Visualization_task' interface. # ------------------------------------------------------------------------ def open(self): """ Show a dialog to open a new data source. """ dialog = FileDialog( title='Choose Data File', parent=self.window.control, wildcard=FileDialog.create_wildcard('Data Files', ['*.mat']) + FileDialog.WILDCARD_ALL) if dialog.open() == OK: if not self.model_initialized: self._new_file(dialog.path) def export_slice(self): """ Export data for current slice. """ dialog = FileDialog( title='Export Slice Plane', action='save as', parent=self.window.control, wildcard='' + FileDialog.create_wildcard('Excel Files', ['*.xlsx']) + FileDialog.create_wildcard('CSV Files', ['*.csv', '*.txt']) + FileDialog.WILDCARD_ALL) if dialog.open() == OK: self.slice_figure.export_slice(dialog.path) def export_line(self): """ Export data for current line. """ dialog = FileDialog( title='Export Line Data', action='save as', parent=self.window.control, wildcard='' + FileDialog.create_wildcard('Excel Files', ['*.xlsx']) + FileDialog.create_wildcard('CSV Files', ['*.csv', '*.txt']) + FileDialog.WILDCARD_ALL) if dialog.open() == OK: self.line_figure.export_line(dialog.path) def toggle_full_model(self): """ Toggle between showing the full spinal cord model and showing only below the cut plane. """ self.mayavi_scene.show_full_model = not self.mayavi_scene.show_full_model def toggle_log_scale(self): """ Toggle between using a logarithmic scale and a linear scale. """ self.mayavi_scene.log_scale = not self.mayavi_scene.log_scale self.slice_figure.log_scale = not self.slice_figure.log_scale def toggle_line_cross_marker(self): """ Toggle visibility of the line cross marker on the slice figure. """ self.slice_figure.draw_cross = not self.slice_figure.draw_cross def change_cord_model(self): """ Change the spinal cord model file used for the 3D display. """ dialog = FileDialog( title='Choose Spinal Cord Model', parent=self.window.control, wildcard=FileDialog.create_wildcard('VTK Model', ['*.vtk']) + FileDialog.WILDCARD_ALL) if dialog.open() == OK: self.mayavi_scene.csf_model = dialog.path def reset_camera(self): """ Set the camera for the Mayavi scene to a pre-determined perspective. """ self.mayavi_scene.initialize_camera() def edit_configuration(self): preferences = PreferenceDialog(configuration=self.configuration, title="S4L Visualization Preferences") ui = preferences.edit_traits(kind='modal') if ui.result: self.configuration.remove_section('') with open('config.ini', 'w') as out_file: self.configuration.write(out_file) def update_participant_id(self): if self.model_initialized: self.line_attributes_pane.set_participant_defaults() self.mayavi_scene.reset_participant_defaults() # ------------------------------------------------------------------------ # Protected interface. # ------------------------------------------------------------------------ def _new_file(self, filename): """ Change the data source to the file at the specified path Parameters ---------- filename : :py:class:`os.PathLike` Path to data source file """ GUI.set_busy(True) if m := re.search(r"\D(\d{3})\D", filename): self.participant_id = m.group(1) if self.participant_id is not None: if self.participant_id not in self.configuration: self.configuration[self.participant_id] = {} default_points = self.configuration[self.participant_id]['points'] self.line_attributes_pane.set_points(default_points) self.part_id_pane.participant_id = self.participant_id self.editor_area.remove_editor(self.start_page) self.window.set_layout( TaskLayout(bottom=PaneItem('s4l.plane_attributes'), left=VSplitter(PaneItem('s4l.line_attributes'), PaneItem('s4l.participant_id_pane')), top_left_corner='top', top_right_corner='top', bottom_left_corner='left', bottom_right_corner='right')) self.fields_model = EMFields(configuration=self.configuration, data_path=filename) self.fields_model.sync_trait('participant_id', self) self.plane_attributes_pane.fields_model = self.fields_model self.mayavi_scene = Mayavi3DScene(fields_model=self.fields_model, configuration=self.configuration) self.mayavi_scene.sync_trait('participant_id', self) self.mayavi_scene.sync_trait('normal', self.plane_attributes_pane) self.mayavi_scene.sync_trait('origin', self.plane_attributes_pane) self.line_attributes_pane.sync_trait('points', self.mayavi_scene, mutual=False) self.mayavi_scene.create_plot() editor = self.mayavi_scene self.editor_area.add_editor(editor) self.editor_area.activate_editor(editor) self.editor_area.active_tabwidget.setTabsClosable(False) self.activated() self.slice_figure = SliceFigureModel(fields_model=self.fields_model, mayavi_scene=self.mayavi_scene, configuration=self.configuration) self.slice_figure.sync_trait('participant_id', self) self.slice_figure.create_plot() self.editor_area.add_editor(self.slice_figure) self.editor_area.activate_editor(self.slice_figure) self.editor_area.active_tabwidget.setTabsClosable(False) self.activated() self.line_figure = LineFigureModel(fields_model=self.fields_model) self.line_figure.sync_trait('points', self.line_attributes_pane) self.line_figure.create_plot(None) self.editor_area.add_editor(self.line_figure) self.editor_area.activate_editor(self.line_figure) self.editor_area.active_tabwidget.setTabsClosable(False) self.activated() self.mayavi_scene.disable_widgets() while self.editor_area.active_tabwidget.parent().is_collapsible(): self.editor_area.active_tabwidget.parent().collapse() layout = Splitter( Tabbed(PaneItem(1), PaneItem(2), active_tab=0), Tabbed(PaneItem(0), active_tab=0), ) self.editor_area.set_layout(layout) self.editor_area.control.setSizes([900, 295]) self.editor_area.activate_editor(self.slice_figure) self.editor_area.active_tabwidget.setTabsClosable(False) for tabwidget in self.editor_area.tabwidgets(): tabwidget.setTabsClosable(False) self.model_initialized = True
def split_editors(self, a, b, h1=-1, h2=-1, orientation='horizontal'): layout = Splitter(PaneItem(id=a, height=h1), PaneItem(id=b, height=h2), orientation=orientation) self.set_editor_layout(layout)
def _default_layout_default(self): return TaskLayout(left=Splitter( PaneItem('pychron.laser_calibration.execute', width=200), PaneItem('pychron.laser_calibration.control', width=200), orientation='vertical'))
def _default_layout_default(self): #return TaskLayout(left=PaneItem('pychron.lasers.client')) return TaskLayout( left=Splitter( PaneItem('pychron.experiment.wait', height=100), Tabbed( PaneItem('pychron.experiment.factory'), PaneItem('pychron.experiment.isotope_evolution'), # PaneItem('pychron.experiment.summary'), ), orientation='vertical' ), right=Splitter( Tabbed( PaneItem('pychron.experiment.stats'), PaneItem('pychron.console', height=425), PaneItem('pychron.experiment.explanation', height=425), ), # PaneItem('pychron.extraction_line.canvas_dock'), # PaneItem('pychron.experiment.wait'), orientation='vertical' ), top=PaneItem('pychron.experiment.controls') ) #============= EOF ============================================= # editor = self.active_editor # if editor is None: # if self.editor_area.editors: # editor = self.editor_area.editors[0] # # if editor: # p = editor.path # p = add_extension(p, '.txt') # # if os.path.isfile(p): # # make a backup copy of the original experiment file # shutil.copyfile(p, '{}.orig'.format(p)) # # # group = editor.group # # min_idx = editor.merge_id # # text = open(p, 'r').read() # # hash_val = hashlib.sha1(text).hexdigest() # # qs = [ei.queue # # for ei in self.editor_area.editors # # if ei.group == group and ei.merge_id >= min_idx] # qs = [ei.queue for ei in self.editor_area.editors] # # launch execution thread # # if successful open an auto figure task # # if self.manager.execute_queues(qs, p, text, hash_val): # if self.manager.execute_queues(qs, p): # self._open_auto_figure() # def merge(self): # eqs = [self.active_editor.queue] # self.active_editor.merge_id = 1 # self.active_editor.group = self.group_count # self.group_count += 1 # for i, ei in enumerate(self.editor_area.editors): # if not ei == self.active_editor: # eqs.append(ei.queue) # ei.merge_id = i + 2 # ei.group = self.group_count # # path = self.save_file_dialog() # if path: # self.active_editor.save(path, eqs) # for ei in self.editor_area.editors: # ei.path = path