Ejemplo n.º 1
0
 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'))
Ejemplo n.º 2
0
 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')))
Ejemplo n.º 3
0
 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'))
Ejemplo n.º 4
0
 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
Ejemplo n.º 6
0
 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')))
Ejemplo n.º 7
0
 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)))))
Ejemplo n.º 8
0
    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
        )
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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')
        )
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
 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'))
Ejemplo n.º 14
0
    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