Example #1
0
class DateEditor(EditorFactory):
    """ Editor factory for date/time editors.
    """

    # -------------------------------------------------------------------------
    #  Trait definitions:
    # -------------------------------------------------------------------------

    # -- ReadonlyEditor traits ------------------------------------------------

    #: Message to show when Date is None.
    message = Str("Undefined")

    #: The string representation of the date to show.  Uses time.strftime
    #: format.
    strftime = Str("%B %d %Y (%a)")

    #: An optional view to display when a read-only text editor is clicked:
    view = AView

    # -- CustomEditor traits --------------------------------------------------

    #: Should users be able to pick future dates when using the CustomEditor?
    allow_future = Bool(True)

    #: How many months to show at a time.
    months = Int(3)

    #: True: Must be a List of Dates.  False: Must be a Date instance.
    multi_select = Bool(False)

    #: When a user multi-selects entries and some of those entries are already
    #: selected and some are not, what should be the behavior for the seletion?
    #:
    #: Options:
    #:
    #: - 'toggle': Toggle each day to the opposite of the current state.
    #: - 'on': Always turn them on.
    #: - 'off': Always turn them off.
    #: - 'max_change': Change all to same state, with most days changing.
    #:   For example 1 selected and 9 not, then they would all get selected.
    #: - 'min_change': Change all to same state, with min days changing.
    #:   For example 1 selected and 9 not, then they would all get unselected.
    on_mixed_select = Enum("toggle", "on", "off", "max_change", "min_change")

    #: How much space to put between the individual months.
    padding = Int(5)

    #: Does the user have to hold down Shift for the left-click multiselect?
    shift_to_select = Bool(False)

    #: Style used when a date is selected.
    selected_style = Instance(
        CellFormat,
        kw={
            "bold": True,
            "fgcolor": (255, 255, 255),
            "bgcolor": (0, 128, 0)
        },
    )
class BackgroundHandler(Handler):

    # The UIInfo object associated with the UI:
    info = Instance(UIInfo)

    # Is the demo currently running:
    running = Bool(True)

    # Is the thread still alive?
    alive = Bool(True)

    def init(self, info):
        self.info = info
        Thread(target=self._update).start()

    def closed(self, info, is_ok):
        self.running = False
        while self.alive:
            time.sleep(.05)

    def _update(self):
        try:
            while self.running:
                self.loop()
                time.sleep(0.1)
        except Exception:
            traceback.print_exc()
            os._exit(1)
        self.alive = False

    def loop(self):
        ''
Example #3
0
class Array2DAdapter(TabularAdapter):
    columns = List
    show_index = Bool(True)
    count_from_one = Bool(True)
    ncolumns = Int

    data_format = Str('%s')

    font = 'Courier 10'
    alignment = 'right'
    format = data_format
    index_text = Property
    index_alignment = Property
    width = 60

    def _get_index_text(self):
        return '- {} -'.format(self.row)

    def _get_index_alignment(self):
        return 'left'

    def _columns_default(self):
        if self.count_from_one:
            columns = [('%d' % (i + 1), i) for i in range(self.ncolumns)]
        else:
            columns = [('%d' % i, i) for i in range(self.ncolumns)]

        if self.show_index:
            columns.insert(0, ('items', 'index'))
        return columns
class PosteriorView(HasTraits):

    show_maximum = Bool(False)
    show_majority_vote = Bool(False)
    posterior_plot = Instance(PosteriorPlot)
    annotations = Array

    def traits_view(self):
        height = 760 if is_display_small() else 900
        traits_view = View(VGroup(VGroup(
            Item('show_maximum', label='Show MAP estimate (circle)'),
            Item('show_majority_vote', label='Show majority vote (triangle)'),
        ),
                                  VGroup(
                                      Item('posterior_plot',
                                           editor=InstanceEditor(),
                                           style='custom',
                                           show_label=False), ),
                                  padding=0),
                           height=height,
                           scrollable=True,
                           resizable=True)

        return traits_view

    def _show_maximum_changed(self):
        plot = self.posterior_plot
        if self.show_maximum:
            maximum = plot.posterior.argmax(1)
            plot.add_markings(maximum,
                              'MAP',
                              'circle',
                              0.,
                              0.,
                              marker_size=3,
                              line_width=2.,
                              marker_color='gray')
        else:
            plot.remove_markings('MAP')
        plot.plot_posterior.request_redraw()

    def _show_majority_vote_changed(self):
        plot = self.posterior_plot
        if self.show_majority_vote:
            majority = majority_vote(self.annotations)
            plot.add_markings(majority,
                              'majority',
                              'triangle',
                              0.,
                              0.,
                              marker_size=3,
                              line_width=1.,
                              marker_color='green')
        else:
            plot.remove_markings('majority')
        plot.plot_posterior.request_redraw()
Example #5
0
class DateEditor(EditorFactory):
    """ Editor factory for date/time editors.
    """

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    #-- ReadonlyEditor traits ------------------------------------------------

    # Message to show when Date is None.
    message = Str('Undefined')

    # The string representation of the date to show.  Uses time.strftime
    # format.
    strftime = Str('%B %d %Y (%a)')

    # An optional view to display when a read-only text editor is clicked:
    view = AView

    #-- CustomEditor traits --------------------------------------------------

    # Should users be able to pick future dates when using the CustomEditor?
    allow_future = Bool(True)

    # How many months to show at a time.
    months = Int(3)

    # True: Must be a List of Dates.  False: Must be a Date instance.
    multi_select = Bool(False)

    # When a user multi-selects entries and some of those entries are already
    # selected and some are not, what should be the behavior for the seletion?
    # Options::
    #
    #     'toggle'     -- Toggle each day to the opposite of the current state.
    #     'on'         -- Always turn them on.
    #     'off'        -- Always turn them off.
    #     'max_change' -- Change all to same state, with most days changing.
    #                     For example 1 selected and 9 not, then they would
    #                     all get selected.
    #     'min_change' -- Change all to same state, with min days changing.
    #                     For example 1 selected and 9 not, then they would
    #                     all get unselected.
    on_mixed_select = Enum('toggle', 'on', 'off', 'max_change', 'min_change')

    # How much space to put between the individual months.
    padding = Int(5)

    # Does the user have to hold down Shift for the left-click multiselect?
    shift_to_select = Bool(False)
class VisibleWhenProblem(HasTraits):

    which = Enum("one", "two")

    on = Bool()
    txt = Str()

    onoff_group = HGroup(
        VGroup(
            Item("on", resizable=False, width=-100, height=-70),
            show_left=False,
            show_border=True,
            visible_when='which == "one"',
        )
    )

    text_group = VGroup(
        Item("txt", width=-_TEXT_WIDTH, height=-_TEXT_HEIGHT),
        visible_when='which == "two"',
        show_border=True,
    )

    traits_view = View(
        Item("which"),
        VGroup(Include("onoff_group"), Include("text_group")),
        resizable=True,
        buttons=["OK", "Cancel"],
    )
Example #7
0
class ExtendedListenerInList(HasTraits):
    # Used in regression test for enthought/traits#403.

    dummy = Instance(Dummy)

    changed = Bool(False)

    @on_trait_change(["dummy:x"])
    def set_changed(self):
        self.changed = True
Example #8
0
class ShowRightLabelsDialog(HasTraits):
    """Dialog with labels on the left/right to test the label text."""

    bool_item = Bool(True)

    traits_view = View(
        VGroup(
            VGroup(Item("bool_item"), show_left=False),
            VGroup(Item("bool_item"), show_left=True),
        ))
Example #9
0
class ButtonListView(HasStrictTraits):
    """ Provides a view for a dict of str:str conversions to Buttons

    Give this class a `dict`, and it will turn those `key:value` pairs
    into a view full of `Buttons`. Clicking any `Button` calls the
    `handler` with the key as the `event.name`.
    The keys must be strings that are usable as trait names; the values can
    be any string.
    """

    #: Dict of trait-valid name strings as keys and any string as values
    traits_and_names = Dict

    #: Function to call when any of the resulting `Button` objects are clicked
    handler = Callable

    #: Class to use to create TraitsUI window to open controls
    view_klass = Any(default_value=View)

    #: Option setting the orientation of the buttons (default: "vertical")
    orientation = Orientation

    #: Name for the List Group
    group_label = Str

    #: Flag to set whether to allow scrolling
    scrollable = Bool(False)

    #: Internal list of trait names
    _trait_names = List

    #: List of tooltips (in the same order as `traits_and_names`) for buttons
    tooltips = List

    def __init__(self, **traits):
        super(ButtonListView, self).__init__(**traits)
        self._make_trait_names()

    def _make_trait_names(self):
        # add the trait names to this object, and connect the handler function
        for trait_name, label in self.traits_and_names.items():
            self._trait_names.append(trait_name)
            self.add_trait(trait_name, Button(str(label)))
            self.observe(self.handler, trait_name)

    def traits_view(self):
        items = [Item(n, show_label=False) for n in self._trait_names]

        for i, tip in enumerate(self.tooltips):
            items[i].tooltip = tip

        return self.view_klass(Group(*items,
                                     label=self.group_label,
                                     orientation=self.orientation),
                               scrollable=self.scrollable)
Example #10
0
class CodeView(ModelView):
    model = Instance(CodeModel)
    show_line_numbers = Bool(True)
    style = Enum('simple', 'readonly')

    def default_traits_view(self):
        traits_view = View(
            Item('model.code',
                 editor=CodeEditor(show_line_numbers=self.show_line_numbers),
                 style=self.style))
        return traits_view
Example #11
0
class NoLabelResizeTestDialog(HasTraits):
    """ Test the combination show_label=False, show_left=False.
    """

    bool_item = Bool(True)

    traits_view = View(VGroup(Item('bool_item',
                                   resizable=True,
                                   show_label=False),
                              show_left=False),
                       resizable=True)
Example #12
0
class AbstractWnd(HasTraits):
    figure = Instance(Figure)

    def _figure_default(self):
        pass

    alive = Bool()
    auto_update = Bool(False)
    enable_update = Bool()
    start = Button()

    def _start_fired(self):
        self.enable_update = True
        Thread(target=self._loop).start()

    stop = Button()

    def _stop_fired(self):
        self.enable_update = False

    def _loop(self):
        if self.auto_update:
            while self.auto_update and self.enable_update:
                self._update()
        else:
            self._update()

    def _update(self):
        self.alive = True

        def stop_condition(t, tstart):
            return not self.enable_update

        data = self.measure(self.conf, stop_condition)
        self.alive = False

        fig = Figure()
        self.plot(data, fig)
        self.figure = fig
Example #13
0
class Band(HasTraits):
    center = Int(enter_set=True, auto_set=False)
    threshold = Int(enter_set=True, auto_set=False)
    color = Color
    use = Bool(False)

    def traits_view(self):
        v = View(
            HGroup(UItem('use'), Item('center'), Item('threshold'),
                   UItem('color')))
        return v


#============= EOF =============================================
Example #14
0
class EnableWhenDialog(HasTraits):
    """ Test labels for enable when. """

    bool_item = Bool(True)

    labelled_item = Str('test')

    unlabelled_item = Str('test')

    traits_view = View(VGroup(
        Item('bool_item', ),
        Item('labelled_item', enabled_when='bool_item'),
        Item('unlabelled_item', enabled_when='bool_item', show_label=False),
    ),
                       resizable=True)
Example #15
0
class VResizeTestDialog(HasTraits):
    """ Dialog with checkbox and text elements and labels on the right.
    We test the separation between element and label in VGroups.
    """

    bool_item = Bool(True)
    txt_item = Str

    traits_view = View(VGroup(
        VGroup(Item('bool_item', resizable=True), show_left=False),
        VGroup(Item('txt_item', resizable=True), show_left=False),
    ),
                       width=_DIALOG_WIDTH,
                       height=100,
                       resizable=True)
Example #16
0
class EnableWhenDialog(HasTraits):
    """ Test labels for enable when. """

    bool_item = Bool(True)

    labelled_item = Str("test")

    unlabelled_item = Str("test")

    traits_view = View(
        VGroup(
            Item("bool_item"),
            Item("labelled_item", enabled_when="bool_item"),
            Item("unlabelled_item", enabled_when="bool_item",
                 show_label=False),
        ),
        resizable=True,
    )
Example #17
0
class FluxTool(HasTraits):
    calculate_button = Button('Calculate')
    monitor_age = Property(depends_on='monitor')
    color_map_name = Str('jet')
    levels = Int(10, auto_set=False, enter_set=True)
    model_kind = Str('Plane')

    data_source = Str('database')
    # plot_kind = Str('Contour')
    plot_kind=Enum('Contour','Hole vs J')

    # def _plot_kind_default(self,):
    monitor=Any
    monitors=List

    group_positions=Bool(False)
    def _monitor_default(self):
        return DummyFluxMonitor()

    def _get_monitor_age(self):
        ma = 28.02e6
        if self.monitor:
            ma=self.monitor.age

        return ma

    def traits_view(self):
        contour_grp = VGroup(Item('color_map_name',
                                  label='Color Map',
                                  editor=EnumEditor(values=sorted(color_map_name_dict.keys()))),
                             Item('levels'),
                             visible_when='plot_kind=="Contour"')
        monitor_grp=Item('monitor', editor=EnumEditor(name='monitors'))
        v = View(
            VGroup(HGroup(UItem('calculate_button'),
                          UItem('data_source', editor=EnumEditor(values=['database', 'file'])),
                          monitor_grp),
                   HGroup(Item('group_positions'), Item('object.monitor.sample', style='readonly',label='Sample')),
                   HGroup(UItem('plot_kind'),
                          Item('model_kind', label='Fit Model',
                            editor=EnumEditor(values=['Bowl', 'Plane']))),
                          # UItem('plot_kind', editor=EnumEditor(values=['Contour', 'Hole vs J']))),
                   contour_grp))
        return v
Example #18
0
class DialogWithToolbar(HasTraits):
    """Test dialog with toolbar and menu."""

    action_successful = Bool(False)

    def test_clicked(self):
        self.action_successful = True

    menubar = MenuBar(Menu(ActionGroup(TestAction), name='&Test menu'), )

    toolbar = ToolBar(ActionGroup(TestAction), )

    traits_view = View(
        Item(label="Click the button on the toolbar or the menu item.\n"
             "The 'Action successful' element should turn to True."),
        Item('action_successful', style='readonly'),
        menubar=menubar,
        toolbar=toolbar,
        buttons=['OK'])
Example #19
0
class DialogWithToolbar(HasTraits):
    """Test dialog with toolbar and menu."""

    action_successful = Bool(False)

    def test_clicked(self):
        print("perform action")
        self.action_successful = True

    menubar = MenuBar(Menu(ActionGroup(TestAction), name="&Test menu"))

    toolbar = ToolBar(ActionGroup(TestAction))

    traits_view = View(
        Item(label="Click the button on the toolbar or the menu item.\n"
             "The 'Action successful' element should turn to True."),
        Item("action_successful", style="readonly"),
        menubar=menubar,
        toolbar=toolbar,
        buttons=[TestAction, "OK"],
    )
Example #20
0
class DelegateMess(HasTraits):
    dummy1 = Instance(Dummy, args=())
    dummy2 = Instance(Dummy2)

    y = DelegatesTo("dummy2")

    handler_called = Bool(False)

    def _dummy2_default(self):
        # Create `self.dummy1`
        return Dummy2(dummy=self.dummy1)

    @on_trait_change("dummy1.x")
    def _on_dummy1_x(self):
        self.handler_called = True

    def _init_trait_listeners(self):
        """ Force the DelegatesTo listener to hook up first to exercise the
        worst case.
        """
        for name in ["y", "_on_dummy1_x"]:
            data = self.__class__.__listener_traits__[name]
            getattr(self, "_init_trait_%s_listener" % data[0])(name, *data)
Example #21
0
class DialogWithSchema(HasTraits):
    """Test dialog with toolbar and menu schemas."""

    action_successful = Bool(False)

    def test_clicked(self):
        self.action_successful = True

    menubar = SMenuBar(
        SMenu(
            SGroup(
                ActionSchema(
                    action_factory=lambda **traits: TestAction,
                ),
            ),
            name="&Test menu",
        ),
    )

    toolbar = SToolBar(
        SGroup(
            ActionSchema(
                action_factory=lambda **traits: TestAction,
            ),
        ),
    )

    traits_view = View(
        Item(
            label="Click the button on the toolbar or the menu item.\n"
            "The 'Action successful' element should turn to True."
        ),
        Item("action_successful", style="readonly"),
        menubar=menubar,
        toolbar=toolbar,
        buttons=[TestAction, "OK"],
    )
Example #22
0
class FitSelector(HasTraits):
    fits = List(Fit)
    update_needed = Event
    suppress_refresh_unknowns = Bool
    save_event = Event

    fit_klass = Fit
    command_key = Bool
    auto_update = Bool(True)

    plot_button = Button('Plot')
    default_error_type = 'SD'

    show_all_button = Event
    show_state = Bool
    show_all_label = Property(depends_on='show_state')

    use_all_button = Button('Toggle Save')
    use_state = Bool
    global_fit = Str('Fit')
    global_error_type = Str('Error')

    fit_types = List(['Fit', ''] + FIT_TYPES)
    error_types = List(['Error', ''] + FIT_ERROR_TYPES)

    selected = Any

    def _get_show_all_label(self):
        return 'Hide All' if self.show_state else 'Show All'

    def _plot_button_fired(self):
        self.update_needed = True

    def _auto_update_changed(self):
        self.update_needed = True

    def _get_fits(self):
        fs = self.selected
        if not fs:
            fs = self.fits
        return fs

    def _show_all_button_fired(self):
        self.show_state = not self.show_state
        fs = self._get_fits()
        for fi in fs:
            fi.show = self.show_state

    def _use_all_button_fired(self):
        self.use_state = not self.use_state
        fs = self._get_fits()
        for fi in fs:
            fi.use = self.use_state

    def _global_fit_changed(self):
        if self.global_fit in self.fit_types:
            fs = self._get_fits()
            for fi in fs:
                fi.fit = self.global_fit

    def _global_error_type_changed(self):
        if self.global_error_type in FIT_ERROR_TYPES:
            fs = self._get_fits()
            for fi in fs:
                fi.error_type = self.global_error_type

    def _get_auto_group(self):
        return VGroup(
            HGroup(
                icon_button_editor(
                    'plot_button',
                    'refresh',
                    tooltip='Replot the isotope evolutions. '
                    'This may take awhile if many analyses are selected'),
                icon_button_editor('save_event',
                                   'database_save',
                                   tooltip='Save fits to database'),
                Item(
                    'auto_update',
                    label='Auto Plot',
                    tooltip=
                    'Should the plot refresh after each change ie. "fit" or "show". '
                    'It is not advisable to use this option with many analyses'
                )),
            HGroup(
                UItem('global_fit', editor=EnumEditor(name='fit_types')),
                UItem('global_error_type',
                      editor=EnumEditor(name='error_types'))))

    def traits_view(self):
        v = View(
            VGroup(self._get_auto_group(), self._get_toggle_group(),
                   self._get_fit_group()))
        return v

    def _get_toggle_group(self):
        g = HGroup(
            # UItem('global_fit',editor=EnumEditor(name='fit_types')),
            # UItem('global_error_type', editor=EnumEditor(name='error_types')),
            UItem('show_all_button',
                  editor=ButtonEditor(label_value='show_all_label')),
            UItem('use_all_button'))
        return g

    def _get_columns(self):
        cols = [
            ObjectColumn(name='name', editable=False),
            CheckboxColumn(name='show'),
            CheckboxColumn(name='use', label='Save'),
            ObjectColumn(name='fit',
                         editor=EnumEditor(name='fit_types'),
                         width=150),
            ObjectColumn(name='error_type',
                         editor=EnumEditor(name='error_types'),
                         width=50)
        ]

        return cols

    def _get_fit_group(self):
        cols = self._get_columns()
        editor = myTableEditor(columns=cols,
                               selected='selected',
                               selection_mode='rows',
                               sortable=False,
                               edit_on_first_click=False,
                               clear_selection_on_dclicked=True,
                               on_command_key=self._update_command_key,
                               cell_bg_color='red',
                               cell_font='modern 10')
        grp = UItem('fits', style='custom', editor=editor)
        return grp

    @on_trait_change('fits:[show, fit, use]')
    def _fit_changed(self, obj, name, old, new):
        if self.command_key:
            for fi in self.fits:
                fi.trait_set(**{name: new})
            self.command_key = False

        if self.auto_update:
            if name in ('show', 'fit'):
                self.update_needed = True

    def load_fits(self, keys, fits):

        nfs = []
        for ki, fi in zip(keys, fits):
            pf = next((fa for fa in self.fits if fa.name == ki), None)
            fit, et, fod = fi
            if pf is None:
                pf = self.fit_klass(name=ki)

            pf.fit = fit
            pf.filter_outliers = fod.get('filter_outliers', False)

            pf.filter_iterations = fod.get('iterations', 0)
            pf.filter_std_devs = fod.get('std_devs', 0)
            pf.error_type = et

            nfs.append(pf)

        self.fits = nfs

    # def load_baseline_fits(self, keys):
    # fits = self.fits
    # if not fits:
    # fits = []
    #
    #     fs = [
    #         self.fit_klass(name='{}bs'.format(ki), fit='average')
    #         for ki in keys]
    #
    #     fits.extend(fs)
    #     self.fits = fits

    # def add_peak_center_fit(self):
    #     fits = self.fits
    #     if not fits:
    #         fits = []
    #
    #     fs = self.fit_klass(name='PC', fit='average')
    #
    #     fits.append(fs)
    #     self.fits = fits
    #
    # def add_derivated_fits(self, keys):
    #     fits = self.fits
    #     if not fits:
    #         fits = []
    #
    #     fs = [
    #         self.fit_klass(name='{}E'.format(ki), fit='average')
    #         for ki in keys
    #     ]
    #
    #     fits.extend(fs)
    #     self.fits = fits

    def _update_command_key(self, new):
        self.command_key = new
Example #23
0
class ProjectInfoUI(cmp.project.ProjectInfo):
    """Class that extends the :class:`ProjectInfo` with graphical components.

    It supports graphically the setting of all processing properties / attributes
    of an :class:`ProjectInfo` instance.

    Attributes
    -----------
    creation_mode : traits.Enum
        Mode for loading the dataset. Valid values are
        'Load BIDS dataset', 'Install Datalad BIDS dataset'

    install_datalad_dataset_via_ssh : traits.Bool
        If set to True install the datalad dataset from a remote server
        via ssh.(True by default)

    ssh_user : traits.Str
        Remote server username.
        (Required if ``install_datalad_dataset_via_ssh`` is True)

    ssh_pwd <traits.Password>
        Remote server password.
        (Required if ``install_datalad_dataset_via_ssh`` is True)

    ssh_remote : traits.Str
        Remote server IP or URL.
        (Required if ``install_datalad_dataset_via_ssh`` is True)

    datalad_dataset_path : traits.Directory
        Path to the datalad dataset on the remote server.
        (Required if ``install_datalad_dataset_via_ssh`` is True)

    summary_view_button : traits.ui.Button
        Button that shows the pipeline processing summary table

    pipeline_processing_summary_view : traits.ui.VGroup
        TraitsUI VGroup that contains ``Item('pipeline_processing_summary')``

    dataset_view : traits.ui.View
        TraitsUI View that shows a summary of project settings and
        modality available for a given subject

    traits_view : QtView
        TraitsUI QtView that includes the View 'dataset_view'

    create_view : traits.ui.View
        Dialog view to create a BIDS Dataset

    subject_view : traits.ui.View
        Dialog view to select of subject

    subject_session_view : traits.ui.View
        Dialog view to select the subject session

    dmri_bids_acq_view : traits.ui.View
        Dialog view to select the diffusion acquisition model

    anat_warning_view : traits.ui.View
        View that displays a warning message regarding
        the anatomical T1w data

    anat_config_error_view : traits.ui.View
        Error view that displays an error message regarding
        the configuration of the anatomical pipeline

    dmri_warning_view : traits.ui.View
        View that displays a warning message regarding
        the diffusion MRI data

    dmri_config_error_view : traits.ui.View
        View that displays an error message regarding
        the configuration of the diffusion pipeline

    fmri_warning_view : traits.ui.View
        View that displays a warning message regarding
        the functional MRI data

    fmri_config_error_view : traits.ui.View
        View that displays an error message regarding
        the configuration of the fMRI pipeline

    open_view : traits.ui.View
        Dialog view to load a BIDS Dataset

    anat_select_config_to_load : traits.ui.View
        Dialog view to load the configuration file of the anatomical pipeline

    diffusion_imaging_model_select_view : traits.ui.View
        Dialog view to select the diffusion acquisition model

    dmri_select_config_to_load : traits.ui.View
        Dialog view to load the configuration file of the diffusion MRI pipeline

    fmri_select_config_to_load : traits.ui.View
        Dialog view to load the configuration file of the fMRI pipeline
    """

    creation_mode = Enum("Load BIDS dataset", "Install Datalad BIDS dataset")
    install_datalad_dataset_via_ssh = Bool(True)
    ssh_user = String("remote_username")
    ssh_pwd = Password("")
    ssh_remote = String("IP address/ Machine name")
    datalad_dataset_path = Directory(
        "/shared/path/to/existing/datalad/dataset")

    anat_runs = List()
    anat_run = Enum(values="anat_runs")

    dmri_runs = List()
    dmri_run = Enum(values="dmri_runs")

    fmri_runs = List()
    fmri_run = Enum(values="fmri_runs")

    summary_view_button = Button("Pipeline processing summary")

    pipeline_processing_summary_view = VGroup(
        Item("pipeline_processing_summary"))

    dataset_view = VGroup(
        VGroup(
            HGroup(
                Item(
                    "base_directory",
                    width=-0.3,
                    style="readonly",
                    label="",
                    resizable=True,
                ),
                Item(
                    "number_of_subjects",
                    width=-0.3,
                    style="readonly",
                    label="Number of participants",
                    resizable=True,
                ),
                "summary_view_button",
            ),
            label="BIDS Dataset",
        ),
        spring,
        HGroup(
            Group(
                Item("subject",
                     style="simple",
                     show_label=True,
                     resizable=True)),
            Group(
                Item("subject_session",
                     style="simple",
                     label="Session",
                     resizable=True),
                visible_when='subject_session!=""',
            ),
            springy=True,
        ),
        spring,
        Group(
            Item("t1_available", style="readonly", label="T1", resizable=True),
            HGroup(
                Item(
                    "dmri_available",
                    style="readonly",
                    label="Diffusion",
                    resizable=True,
                ),
                Item(
                    "diffusion_imaging_model",
                    label="Model",
                    resizable=True,
                    enabled_when="dmri_available",
                ),
            ),
            Item("fmri_available",
                 style="readonly",
                 label="BOLD",
                 resizable=True),
            label="Modalities",
        ),
        spring,
        Group(
            Item(
                "anat_last_date_processed",
                label="Anatomical pipeline",
                style="readonly",
                resizable=True,
                enabled_when="t1_available",
            ),
            Item(
                "dmri_last_date_processed",
                label="Diffusion pipeline",
                style="readonly",
                resizable=True,
                enabled_when="dmri_available",
            ),
            Item(
                "fmri_last_date_processed",
                label="fMRI pipeline",
                style="readonly",
                resizable=True,
                enabled_when="fmri_available",
            ),
            label="Last date processed",
        ),
        spring,
        Group(Item("number_of_cores", resizable=True),
              label="Processing configuration"),
        "550",
        spring,
        springy=True,
    )

    traits_view = QtView(Include("dataset_view"))

    create_view = View(
        Item("creation_mode", style="custom"),
        Group(
            Group(
                Item("base_directory", label="BIDS Dataset"),
                visible_when='creation_mode=="Load BIDS dataset"',
            ),
            Group(
                Item("install_datalad_dataset_via_ssh"),
                visible_when='creation_mode=="Install Datalad/BIDS dataset"',
            ),
            Group(
                Item(
                    "ssh_remote",
                    label="Remote ssh server",
                    visible_when="install_datalad_dataset_via_ssh",
                ),
                Item(
                    "ssh_user",
                    label="Remote username",
                    visible_when="install_datalad_dataset_via_ssh",
                ),
                Item(
                    "ssh_pwd",
                    label="Remote password",
                    visible_when="install_datalad_dataset_via_ssh",
                ),
                Item(
                    "datalad_dataset_path",
                    label="Datalad/BIDS Dataset Path/URL to be installed",
                ),
                Item("base_directory", label="Installation directory"),
                visible_when='creation_mode=="Install Datalad/BIDS dataset"',
            ),
        ),
        kind="livemodal",
        title="Data creation: BIDS dataset selection",
        # style_sheet=style_sheet,
        width=modal_width,
        buttons=["OK", "Cancel"],
    )

    subject_view = View(
        Group(Item("subject", label="Selected Subject")),
        kind="modal",
        title="Subject and session selection",
        # style_sheet=style_sheet,
        width=modal_width,
        buttons=["OK", "Cancel"],
    )

    subject_session_view = View(
        Group(
            Item("subject", style="readonly", label="Selected Subject"),
            Item("subject_session", label="Selected Session"),
        ),
        kind="modal",
        title="Session selection",
        # style_sheet=style_sheet,
        width=modal_width,
        buttons=["OK", "Cancel"],
    )

    dmri_bids_acq_view = View(
        Group(Item("dmri_bids_acq", label="Selected model"), ),
        kind="modal",
        title="Selection of diffusion acquisition model",
        # style_sheet=style_sheet,
        width=modal_width,
        buttons=["OK", "Cancel"],
    )

    anat_warning_view = View(
        Group(Item("anat_warning_msg", style="readonly", show_label=False), ),
        title="Warning : Anatomical T1w data",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    anat_config_error_view = View(
        Group(
            Item("anat_config_error_msg", style="readonly",
                 show_label=False), ),
        title="Error",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    dmri_warning_view = View(
        Group(Item("dmri_warning_msg", style="readonly", show_label=False), ),
        title="Warning : Diffusion MRI data",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    dmri_config_error_view = View(
        Group(
            Item("dmri_config_error_msg", style="readonly",
                 show_label=False), ),
        title="Error",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    fmri_warning_view = View(
        Group(Item("fmri_warning_msg", style="readonly", show_label=False), ),
        title="Warning : fMRI data",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    fmri_config_error_view = View(
        Group(
            Item("fmri_config_error_msg", style="readonly",
                 show_label=False), ),
        title="Error",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    open_view = View(
        Item("creation_mode", label="Mode"),
        Group(
            Item("install_datalad_dataset_via_ssh"),
            Item(
                "ssh_remote",
                label="Remote ssh server",
                visible_when="install_datalad_dataset_via_ssh",
            ),
            Item(
                "ssh_user",
                label="Remote username",
                visible_when="install_datalad_dataset_via_ssh",
            ),
            Item(
                "ssh_pwd",
                label="Remote password",
                visible_when="install_datalad_dataset_via_ssh",
            ),
            Item(
                "datalad_dataset_path",
                label="Datalad/BIDS Dataset Path/URL to be installed",
            ),
            Item("base_directory", label="Installation directory"),
            visible_when='creation_mode=="Install Datalad BIDS dataset"',
        ),
        Group(
            Item("base_directory", label="BIDS Dataset"),
            visible_when='creation_mode=="Load BIDS dataset"',
        ),
        kind="livemodal",
        title="BIDS Dataset Creation/Loading",
        # style_sheet=style_sheet,
        width=600,
        height=250,
        buttons=["OK", "Cancel"],
    )

    anat_select_config_to_load = View(
        Group(
            Item("anat_config_to_load_msg", style="readonly",
                 show_label=False),
            Item(
                "anat_config_to_load",
                style="custom",
                editor=EnumEditor(name="anat_available_config"),
                show_label=False,
            ),
        ),
        title="Select configuration for anatomical pipeline",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    anat_custom_map_view = View(
        Group(
            Item(
                "anat_custom_last_stage",
                editor=EnumEditor(name="anat_stage_names"),
                style="custom",
                show_label=False,
            ), ),
        title="Select until which stage to process the anatomical pipeline.",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    diffusion_imaging_model_select_view = View(
        Group(Item("diffusion_imaging_model",
                   label="Diffusion MRI modality"), ),
        title="Please select diffusion MRI modality",
        kind="modal",
        width=modal_width,
        buttons=["OK", "Cancel"],
    )

    dmri_select_config_to_load = View(
        Group(
            Item("dmri_config_to_load_msg", style="readonly",
                 show_label=False), ),
        Item(
            "dmri_config_to_load",
            style="custom",
            editor=EnumEditor(name="dmri_available_config"),
            show_label=False,
        ),
        title="Select configuration for diffusion pipeline",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    dmri_custom_map_view = View(
        Group(
            Item(
                "dmri_custom_last_stage",
                editor=EnumEditor(name="dmri_stage_names"),
                style="custom",
                show_label=False,
            ), ),
        title="Select until which stage to process the diffusion pipeline.",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    fmri_select_config_to_load = View(
        Group(
            Item("fmri_config_to_load_msg", style="readonly",
                 show_label=False), ),
        Item(
            "fmri_config_to_load",
            style="custom",
            editor=EnumEditor(name="fmri_available_config"),
            show_label=False,
        ),
        title="Select configuration for fMRI pipeline",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    fmri_custom_map_view = View(
        Group(
            Item(
                "fmri_custom_last_stage",
                editor=EnumEditor(name="fmri_stage_names"),
                style="custom",
                show_label=False,
            ), ),
        title="Select until which stage to process the fMRI pipeline.",
        kind="modal",
        width=modal_width,
        # style_sheet=style_sheet,
        buttons=["OK", "Cancel"],
    )

    def _summary_view_button_fired(self):
        self.configure_traits(view="pipeline_processing_summary_view")
Example #24
0
class BoardWrapper(HasTraits):
    pins = List(PinWrapper)
    digital_pins = List(PinWrapper)
    analog_pins = List(PinWrapper)
    defines = List(GuiDefine)
    port_type = Enum('serial',
                     [
                         'none',
                         'serial',
                     ]
                     )
    serial_device = Enum(_auto_detect_serial_unix())
    baudrate = Int(115200)
    sleep_after_connect = Int(2)
    timeout = Int(1)
    uptime = Float()
    tree = None
    vcc = Float()
    avr_name = Str()
    arduino_version = Str()
    firmware_build_time = Str()
    gcc_version = Str()
    libc_version = Str()
    libc_date = Str()

    connected = Bool(False)
    connect = Button()
    disconnect = Button()

    def _connect_fired(self):
            try:
                connection = SerialManager(device=self.serial_device,
                                           baudrate=self.baudrate,
                                           sleep_after_connect=self.sleep_after_connect,
                                           timeout=self.timeout)
                connection.open()
                print ArduinoApi(connection=connection).millis()
            except Exception as e:
                traceback.print_exc()
                message(traceback.format_exc(), buttons=['OK'])
                return

            a = self.tree = ArduinoTree(connection=connection)

            d = a.define.as_dict
            s = [GuiDefine(name=k, value=str(v)) for k, v in d.items()]
            s.sort(key=lambda x: x.name)
            self.defines = s
            self.digital_pins = [PinWrapper(pin=a.pin.get(x))
                                 for x in a.pin.names_digital]
            self.analog_pins = [PinWrapper(pin=a.pin.get(x))
                                for x in a.pin.names_analog]
            self.pins = self.digital_pins + self.analog_pins

            fw = a.firmware_info
            self.arduino_version = fw.get('arduino_version')
            self.firmware_build_time = str(fw.get('compile_datetime'))
            self.avr_name = fw.get('avr_name')
            self.gcc_version = fw.get('gcc_version')
            self.libc_version = fw.get('libc_version')
            self.libc_date = str(fw.get('libc_date'))
            self.connected = True

    def _disconnect_fired(self):
            self.digital_pins = []
            self.analog_pins = []
            self.pins = []
            self.defines = []
            self.avr_name = ''
            self.arduino_version = ''
            self.firmware_build_time = ''
            self.gcc_version = ''
            self.libc_version = ''
            self.libc_date = ''

            self.tree.connection.close()
            del self.tree
            self.tree = None
            self.connected = False

    update_interval = Int(1000, desc='interval in msec')
    update_enable = Bool(True)

    def update(self):
        if self.update_enable and self.connected and self.tree:
            for x in self.pins:
                x.update()
            self.uptime = self.tree.api.millis() / 1000.0
            self.vcc = self.tree.vcc.read() if self.tree.vcc else -1
        time.sleep(self.update_interval / 1000.0)

    traits_view = View(
        Tabbed(
            Group(
                HGroup(
                    Group(
                        button('connect', enabled_when='not connected'),
                        button('disconnect', enabled_when='connected'),
                        Item(
                            'port_type', enabled_when='not connected', width=300,
                        ),
                        Group(
                            'serial_device',
                            'baudrate',
                            'sleep_after_connect',
                            'timeout',
                            visible_when='port_type=="serial"',
                            enabled_when='not connected',
                        ),
                    ),
                    Group(
                        'avr_name',
                        'arduino_version',
                        'firmware_build_time',
                        'gcc_version',
                        'libc_version',
                        'libc_date',
                        #                     'baudrate',
                        #                     'sleep_after_connect',
                        # visible_when='port_type=="serial"',
                        springy=True,
                    ),
                ),
                label='connection',
            ),
            Group(
                'uptime',
                'vcc',
                label='misc',
            ),
            Item(name='digital_pins',
                      editor=ListEditor(
                     style='custom',
                 ),
                 style='readonly',
                 show_label=False,
                 ),
            Item(name='analog_pins',
                      editor=ListEditor(
                 style='custom',
                 ),
                 style='readonly',
                 show_label=False,
                 ),
            Group(
                  'update_enable',
                Item(name='update_interval',
                     editor=RangeEditor(
                     mode='slider',
                     low=1,
                     high=1000,
                     ),
                     style='custom',
                     ),
                label='settings',
            ),
            Item('defines',
                show_label=False,
                editor=ListEditor(
#                     auto_size=False,
#                     editable=False,
#                     configurable=False,
                 style='custom',
                ),
                style='readonly',
                 )
        ),
        width=800,
        height=600,
        buttons=['Undo', 'Revert', 'OK', 'Cancel'],
        kind='live',
        resizable=True,
        handler=Handler(),
    )
print ports


class BoardWrapper(HasTraits):
    port = Enum(ports)

    def _port_changed(self):
        if self.serialobj:
            self.serialobj.close()
            self.serialobj = None
        try:
            self.serialobj = serial.Serial(self.port)
        except serial.serialutil.SerialException, e:
            print '%s %s' % (self.port, e)

    DCD = Bool(label='DCD (1)', desc='Data Carrier Detect')
    #    RxD = String(label='RxD (2)')
    #    TxD = String(label='TxD (3)')
    DTR = Bool(label='DTR (4)', desc='Data Terminal Ready')
    #    GND = String(label='GND (5)')
    DSR = Bool(label='DSR (6)', desc='Data Set Ready')
    RTS = Bool(label='RTS (7)', desc='Request to Send')
    CTS = Bool(label='CTS (8)', desc='Clear To Send')
    RI = Bool(label='RI (9)', desc='Ring Indicator')

    serialobj = None
    update_interval = Int(100, desc='interval in msec')

    def update(self):
        if self.serialobj:
            self.DSR = self.serialobj.getDSR()
Example #26
0
class DeviceConfigurer(Loggable):
    config_path = Str
    config_name = Str
    save_button = Button
    _config = None

    kind = Enum('ethernet', 'serial')
    communication_grp = Instance(CommunicationGroup)
    scan_grp = Instance(ScanGroup, ())
    comms_visible = Bool(False)

    def set_device(self, device):
        p = device.config_path
        self._load_configuration(p)

    def _load_configuration(self, path):
        self.config_path = path
        self.config_name = os.path.relpath(path, paths.device_dir)
        self._config = cfg = six.moves.configparser.ConfigParser()

        cfg.read(path)

        section = 'Communications'
        if cfg.has_section(section):
            kind = cfg.get(section, 'type')
            klass = CKLASS_DICT.get(kind)
            if klass:
                self.communication_grp = klass()

                def func(option, cast=None, default=None, **kw):
                    f = getattr(cfg, 'get{}'.format(cast if cast else ''))
                    try:
                        v = f(section, option, **kw)
                    except six.moves.configparser.NoOptionError:
                        v = default
                        if v is None:
                            if cast == 'boolean':
                                v = False
                            elif cast in ('float', 'int'):
                                v = 0
                    return v

                self.communication_grp.load_from_config(func)
                self.communication_grp.config_obj = cfg
                self.comms_visible = True
        else:
            self.comms_visible = False
            self.communication_grp = CommunicationGroup()

        section = 'Scan'
        if cfg.has_section(section):
            bfunc = lambda *args: cfg.getboolean(*args)
            ffunc = lambda *args: cfg.getfloat(*args)
        else:
            bfunc = lambda *args: False
            ffunc = lambda *args: 0

        sgrp = self.scan_grp
        for attr in ('enabled', 'graph', 'record', 'auto_start'):
            try:
                v = bfunc(section, attr)
            except six.moves.configparser.NoOptionError:
                v = False
            setattr(sgrp, attr, v)

        for attr in ('period', ):
            try:
                v = ffunc(section, attr)
            except six.moves.configparser.NoOptionError:
                v = 0
            setattr(sgrp, attr, v)

    def _save_button_fired(self):
        self._dump()

    def _dump(self):
        # backup previous file
        # putting the device dir under git control is a good idea

        self._backup()
        with open(self.config_path, 'w') as wfile:
            self._config.write(wfile)

    def _backup(self):
        bp, pp = backup(self.config_path,
                        paths.backup_device_dir,
                        extension='.cfg')
        self.info('{} - saving a backup copy to {}'.format(bp, pp))
Example #27
0
class FitSelector(HasTraits):
    fits = List(Fit)
    update_needed = Event
    suppress_refresh_unknowns = Bool
    save_event = Event

    fit_klass = Fit
    command_key = Bool
    auto_update = Bool(True)

    plot_button = Button('Plot')

    def _plot_button_fired(self):
        self.update_needed = True

    def _auto_update_changed(self):
        self.update_needed = True

    def _get_auto_group(self):
        return HGroup(
            icon_button_editor(
                'plot_button',
                'chart_curve_go',
                tooltip='Replot the isotope evolutions. '
                'This may take awhile if many analyses are selected'),
            icon_button_editor('save_event',
                               'database_save',
                               tooltip='Save fits to database'), spring,
            Item(
                'auto_update',
                label='Auto Plot',
                tooltip=
                'Should the plot refresh after each change ie. "fit" or "show". '
                'It is not advisable to use this option with many analyses'))

    def traits_view(self):

        v = View(VGroup(self._get_auto_group(), self._get_fit_group()))
        return v

    def _get_columns(self):
        cols = [
            ObjectColumn(name='name', editable=False),
            CheckboxColumn(name='show'),
            ObjectColumn(name='fit',
                         editor=EnumEditor(name='fit_types'),
                         width=150),
            ObjectColumn(name='error_type',
                         editor=EnumEditor(name='error_types'),
                         width=50),
            CheckboxColumn(name='use', label='Save DB')
        ]

        return cols

    def _get_fit_group(self):
        cols = self._get_columns()
        editor = myTableEditor(columns=cols,
                               sortable=False,
                               on_command_key=self._update_command_key)
        grp = UItem('fits', style='custom', editor=editor)
        return grp

    @on_trait_change('fits:[show, fit, use]')
    def _fit_changed(self, obj, name, old, new):
        if self.command_key:
            for fi in self.fits:
                fi.trait_set(trait_change_notify=False, **{name: new})

        if self.auto_update:
            if name in ('show', 'fit'):
                self.update_needed = True

    def load_fits(self, keys, fits):

        nfs = []
        for ki, fi in zip(keys, fits):
            pf = next((fa for fa in self.fits if fa.name == ki), None)
            if pf is None:
                pf = self.fit_klass(name=ki, fit=fi)
            else:
                pf.fit = fi
            nfs.append(pf)

        self.fits = nfs

    #         self.fits = [
    #                      self.fit_klass(name=ki, fit=fi)
    #                      for ki, fi in zip(ks, fs)
    #                     ]

    def load_baseline_fits(self, keys):
        fits = self.fits
        if not fits:
            fits = []

        fs = [
            self.fit_klass(name='{}bs'.format(ki), fit='average')
            for ki in keys
        ]

        fits.extend(fs)
        self.fits = fits

    def add_peak_center_fit(self):
        fits = self.fits
        if not fits:
            fits = []

        fs = self.fit_klass(name='PC', fit='average')

        fits.append(fs)
        self.fits = fits

    def add_derivated_fits(self, keys):
        fits = self.fits
        if not fits:
            fits = []

        fs = [
            self.fit_klass(name='{}E'.format(ki), fit='average') for ki in keys
        ]

        fits.extend(fs)
        self.fits = fits

    def _update_command_key(self, new):
        self.command_key = new
Example #28
0
class MarkerLabel(Label):
    rotate_angle = 0

    zero_y = 0
    xoffset = 10
    indicator_width = 4
    indicator_height = 10
    visible = Bool(True)
    component_height = 100
    x = Float
    y = Float
    data_y = Float
    vertical = False
    horizontal_line_visible = False
    label_with_intensity = False

    text = Property(depends_on='_text, label_with_intensity')
    _text = Str

    def _set_text(self, text):
        self._text = text

    def _get_text(self):
        if self.label_with_intensity:
            return '{:0.4f}'.format(self.data_y)
        else:
            return self._text

    def draw(self, gc, component_height):
        if not self.text:
            self.text = ''

        if self.bgcolor != "transparent":
            gc.set_fill_color(self.bgcolor_)

        #draw tag border
        with gc:
            if self.vertical:
                self.rotate_angle = 90
                width, height = self.get_bounding_box(gc)
                gc.translate_ctm(self.x, self.zero_y_vert - 35 - height)
            else:
                if self.horizontal_line_visible:
                    self._draw_horizontal_line(gc)

                gc.translate_ctm(self.x + self.xoffset, self.y)
                self._draw_tag_border(gc)

            super(MarkerLabel, self).draw(gc)

        with gc:
            gc.translate_ctm(self.x - self.indicator_width / 2.0, self.zero_y)
            self._draw_index_indicator(gc, component_height)

    def _draw_horizontal_line(self, gc):
        with gc:
            # print self.x, self.y
            gc.set_stroke_color((0, 0, 0, 1))
            gc.set_line_width(2)
            oy = 7 if self.text else 4
            y = self.y + oy
            gc.move_to(0, y)
            gc.line_to(self.x, y)
            gc.stroke_path()

    def _draw_index_indicator(self, gc, component_height):
        # gc.set_fill_color((1, 0, 0, 1))
        w, h = self.indicator_width, self.indicator_height
        gc.draw_rect((0, 0, w, h), FILL)

        gc.draw_rect((0, component_height, w, h), FILL)

    def _draw_tag_border(self, gc):
        gc.set_stroke_color((0, 0, 0, 1))
        gc.set_line_width(2)

        # gc.set_fill_color((1, 1, 1, 1))
        bb_width, bb_height = self.get_bounding_box(gc)

        offset = 2
        xoffset = self.xoffset
        gc.lines([(-xoffset, (bb_height + offset) / 2.0),
                  (0, bb_height + 2 * offset),
                  (bb_width + offset, bb_height + 2 * offset),
                  (bb_width + offset, -offset), (0, -offset),
                  (-xoffset, (bb_height + offset) / 2.0)])

        gc.draw_path()
Example #29
0
class ModelDataView(ModelView):

    #### Information about available models

    model_name = Enum(
        'Model B-with-theta',
        'Model B-with-theta (loop design)',
        'Model B',
        'Model A (loop design)',
    )

    _model_name_to_class = {
        'Model B-with-theta': ModelBt,
        'Model B-with-theta (loop design)': ModelBtLoopDesign,
        'Model B': ModelB,
        'Model A (loop design)': ModelA
    }

    _model_class_to_view = {
        ModelBt: ModelBtView,
        ModelBtLoopDesign: ModelBtLoopDesignView,
        ModelB: ModelBView,
        ModelA: ModelAView
    }

    #### Application-related traits

    # reference to pyanno application
    application = Any

    #### Model-related traits

    # the annotations model
    model = Any

    # Traits UI view of the model
    model_view = Instance(ModelView)

    # fired when the model is updates
    model_updated = Event

    # parameters view should not update when this trait is False
    model_update_suspended = Bool(False)

    #### Annotation-related traits

    # File trait to load a new annotations file
    annotations_file = File

    # True then annotations are loaded correctly
    annotations_are_defined = Bool(False)

    # fired when annotations are updated
    annotations_updated = Event

    # Traits UI view of the annotations
    annotations_view = Instance(AnnotationsView)

    # Traits UI view of the annotations' statistics
    annotations_stats_view = Instance(AnnotationsStatisticsView)

    # shortcut to the annotations
    annotations = Property

    def _get_annotations(self):
        return self.annotations_view.annotations_container.annotations

    # property that combines information from the model and the annotations
    # to give a consistent number of classes
    nclasses = Property

    def _get_nclasses(self):
        return max(self.model.nclasses, self.annotations.max() + 1)

    # info string -- currently not used
    info_string = Str

    # used to display the current log likelihood
    log_likelihood = Float

    def _annotations_view_default(self):
        anno = AnnotationsContainer.from_array([[0]], name='<undefined>')
        return AnnotationsView(annotations_container=anno,
                               nclasses=self.model.nclasses,
                               application=self.application,
                               model=HasTraits())

    @on_trait_change('annotations_file')
    def _update_annotations_file(self):
        logger.info('Load file {}'.format(self.annotations_file))
        anno = AnnotationsContainer.from_file(self.annotations_file)
        self.set_annotations(anno)

    @on_trait_change('annotations_updated,model_updated')
    def _update_log_likelihood(self):
        if self.annotations_are_defined:
            if not self.model.are_annotations_compatible(self.annotations):
                self.log_likelihood = np.nan
            else:
                self.log_likelihood = self.model.log_likelihood(
                    self.annotations)

    @on_trait_change('model.nclasses')
    def _update_nclasses(self):
        self.annotations_view.nclasses = self.model.nclasses
        self.annotations_view.annotations_updated = True

    @on_trait_change('model,model:theta,model:gamma')
    def _fire_model_updated(self):
        if not self.model_update_suspended:
            self.model_updated = True
            if self.model_view is not None:
                self.model_view.model_updated = True

    ### Control content #######################################################

    def set_model(self, model):
        """Update window with a new model.
        """
        self.model = model
        model_view_class = self._model_class_to_view[model.__class__]
        self.model_view = model_view_class(model=model)
        self.model_updated = True

    def set_annotations(self, annotations_container):
        """Update window with a new set of annotations."""
        self.annotations_view = AnnotationsView(
            annotations_container=annotations_container,
            nclasses=self.model.nclasses,
            application=self.application,
            model=HasTraits())
        self.annotations_stats_view = AnnotationsStatisticsView(
            annotations=self.annotations, nclasses=self.nclasses)

        self.annotations_are_defined = True
        self.annotations_updated = True

    def set_from_database_record(self, record):
        """Set main window model and annotations from a database record."""
        self.set_model(record.model)
        self.set_annotations(record.anno_container)

    ### Actions ##############################################################

    #### Model creation actions

    # create a new model
    new_model = Button(label='Create...')

    # show informations about the selected model
    get_info_on_model = Button(label='Info...')

    #### Annotation creation actions

    # create new annotations
    new_annotations = Button(label='Create...')

    #### Model <-> data computations

    # execute Maximum Likelihood estimation of parameters
    ml_estimate = Button(label='ML estimate...',
                         desc=('Maximum Likelihood estimate of model '
                               'parameters'))

    # execute MAP estimation of parameters
    map_estimate = Button(label='MAP estimate...')

    # draw samples from the posterior over accuracy
    sample_posterior_over_accuracy = Button(label='Sample parameters...')

    # compute posterior over label classes
    estimate_labels = Button(label='Estimate labels...')

    #### Database actions

    # open database window
    open_database = Button(label="Open database")

    # add current results to database
    add_to_database = Button(label="Add to database")

    def _new_model_fired(self):
        """Create new model."""

        # delegate creation to associated model_view
        model_name = self.model_name
        model_class = self._model_name_to_class[model_name]
        responsible_view = self._model_class_to_view[model_class]

        # if annotations are loaded, set default values for number of
        # annotations and annotators to the ones in the data set
        kwargs = {}
        if self.annotations_are_defined:
            anno = self.annotations_view.annotations_container
            kwargs['nclasses'] = anno.nclasses
            kwargs['nannotators'] = anno.nannotators

        # model == None if the user cancelled the action
        model = responsible_view.create_model_dialog(self.info.ui.control,
                                                     **kwargs)
        if model is not None:
            self.set_model(model)

    def _new_annotations_fired(self):
        """Create an empty annotations set."""
        annotations = CreateNewAnnotationsDialog.create_annotations_dialog()
        if annotations is not None:
            name = self.application.database.get_available_id()
            anno_cont = AnnotationsContainer.from_array(annotations, name=name)
            self.set_annotations(anno_cont)

    def _open_database_fired(self):
        """Open database window."""
        if self.application is not None:
            self.application.open_database_window()

    def _get_info_on_model_fired(self):
        """Open dialog with model description."""
        model_class = self._model_name_to_class[self.model_name]
        message(message=model_class.__doc__, title='Model info')

    def _add_to_database_fired(self):
        """Add current results to database."""
        if self.application is not None:
            self.application.add_current_state_to_database()

    def _action_finally(self):
        """Operations that need to be executed both in case of a success and
        a failure of the long-running action.
        """
        self.model_update_suspended = False

    def _action_success(self, result):
        self._action_finally()
        self._fire_model_updated()

    def _action_failure(self, err):
        self._action_finally()

        if isinstance(err, PyannoValueError):
            errmsg = err.args[0]
            if 'Annotations' in errmsg:
                # raised when annotations are incompatible with the model
                error('Error: ' + errmsg)
            else:
                # re-raise exception if it has not been handled
                raise err

    def _action_on_model(self,
                         message,
                         method,
                         args=None,
                         kwargs=None,
                         on_success=None,
                         on_failure=None):
        """Call long running method on model.

        While the call is running, a window with a pulse progress bar is
        displayed.

        An error message is displayed if the call raises a PyannoValueError
        (raised when annotations are incompatible with the current model).
        """

        if args is None: args = []
        if kwargs is None: kwargs = {}

        if on_success is None: on_success = self._action_success
        if on_failure is None: on_failure = self._action_failure

        self.model_update_suspended = True

        call = LongRunningCall(
            parent=None,
            title='Calculating...',
            message=message,
            callable=method,
            args=args,
            kw=kwargs,
            on_success=on_success,
            on_failure=on_failure,
        )
        call()

    def _ml_estimate_fired(self):
        """Run ML estimation of parameters."""

        message = 'Computing maximum likelihood estimate'
        self._action_on_model(message, self.model.mle, args=[self.annotations])

    def _map_estimate_fired(self):
        """Run ML estimation of parameters."""

        message = 'Computing maximum a posteriori estimate'
        self._action_on_model(message, self.model.map, args=[self.annotations])

    def _sample_posterior_success(self, samples):
        if (samples is not None
                and hasattr(self.model_view, 'plot_theta_samples')):
            self.model_view.plot_theta_samples(samples)

        self._action_finally()

    def _sample_posterior_over_accuracy_fired(self):
        """Sample the posterior of the parameters `theta`."""

        message = 'Sampling from the posterior over accuracy'

        # open dialog asking for number of samples
        params = _SamplingParamsDialog()
        dialog_ui = params.edit_traits(kind='modal')

        if not dialog_ui.result:
            # user pressed "Cancel"
            return

        nsamples = params.nsamples

        self._action_on_model(message,
                              self.model.sample_posterior_over_accuracy,
                              args=[self.annotations, nsamples],
                              kwargs={
                                  'burn_in_samples': params.burn_in_samples,
                                  'thin_samples': params.thin_samples
                              },
                              on_success=self._sample_posterior_success)

    def _estimate_labels_success(self, posterior):
        if posterior is not None:
            post_plot = PosteriorPlot(posterior=posterior,
                                      title='Posterior over classes')

            post_view = PosteriorView(posterior_plot=post_plot,
                                      annotations=self.annotations)

            post_view.edit_traits()

        self._action_finally()

    def _estimate_labels_fired(self):
        """Compute the posterior over annotations and show it in a new window"""

        message = 'Computing the posterior over classes'
        self._action_on_model(message,
                              self.model.infer_labels,
                              args=[self.annotations],
                              on_success=self._estimate_labels_success)

    ### Views ################################################################

    def traits_view(self):
        ## Model view

        # adjust sizes to display size
        if is_display_small():
            # full view size
            w_view, h_view = 1024, 768
            w_data_create_group = 350
            w_data_info_group = 500
            h_annotations_stats = 270
        else:
            w_view, h_view = 1300, 850
            w_data_create_group = 400
            w_data_info_group = 700
            h_annotations_stats = 330

        model_create_group = (VGroup(HGroup(
            UItem(name='model_name', width=200),
            UItem(name='new_model', width=100),
            UItem(name='get_info_on_model', width=100, height=25),
        ),
                                     label='Create new model'))

        model_group = (VGroup(
            model_create_group,
            VGroup(
                Item('model_view', style='custom', show_label=False,
                     width=400),
                label='Model view',
            ),
        ), )

        ## Data view

        data_create_group = VGroup(
            #Label('Open annotation file:', width=800),
            HGroup(
                Item('annotations_file',
                     style='simple',
                     label='Open file:',
                     width=w_data_create_group,
                     height=25), UItem('new_annotations', height=25)),
            label='Load/create annotations',
            show_border=False,
        )

        data_info_group = VGroup(
            Item(
                'annotations_view',
                style='custom',
                show_label=False,
                visible_when='annotations_are_defined',
                width=w_data_info_group,
            ),
            Item('annotations_stats_view',
                 style='custom',
                 show_label=False,
                 visible_when='annotations_are_defined',
                 height=h_annotations_stats),
            label='Data view',
        )

        data_group = (VGroup(
            data_create_group,
            data_info_group,
        ), )

        ## (Model,Data) view

        model_data_group = (
            VGroup(
                #Item('info_string', show_label=False, style='readonly'),
                Item('log_likelihood',
                     label='Log likelihood',
                     style='readonly'),
                HGroup(
                    Item('ml_estimate',
                         enabled_when='annotations_are_defined'),
                    Item('map_estimate',
                         enabled_when='annotations_are_defined'),
                    Item('sample_posterior_over_accuracy',
                         enabled_when='annotations_are_defined'),
                    Item('estimate_labels',
                         enabled_when='annotations_are_defined'),
                    Spring(),
                    Item('add_to_database',
                         enabled_when='annotations_are_defined'),
                    Item('open_database'),
                    show_labels=False,
                ),
                label='Model-data view',
            ))

        ## Full view

        full_view = View(
            VGroup(
                HGroup(model_group, data_group),
                model_data_group,
            ),
            title='PyAnno - Models of data annotations by multiple curators',
            width=w_view,
            height=h_view,
            resizable=False)

        return full_view
Example #30
0
class SmoothInputSpec(BaseInterfaceInputSpec):
    fmri_prep = ImageFile(desc='Preprocessed fMRI file')
    is_file_mandatory = Bool(default=True)
    output_directory = Directory(exists=True, )