Example #1
0
    def __init__(self,
                 windows=None,
                 name=None,
                 category=None,
                 icon=None,
                 description=None):
        super(SelectionTool, self).__init__(windows)
        self.widget2d_r = RectangleWidget(None)
        self.widget2d_r.set_on(False)
        self.widget1d_r = RangeWidget(None)
        self.widget1d_r.set_on(False)
        self.widget2d = SquareWidget(None)
        self.widget2d.set_on(False)
        self.widget1d = VerticalLineWidget(None)
        self.widget1d.set_on(False)
        self._widgets = [
            self.widget2d_r, self.widget1d_r, self.widget2d, self.widget1d
        ]
        self.valid_dimensions = [1, 2]
        self.ranged = True

        self.name = name or "Selection tool"
        self.category = category or 'Signal'
        self.description = description
        self.icon = icon
        self.cancel_on_accept = False
Example #2
0
    def _make_position_adjuster(self, component, fix_it, show_label):
        if (component._position is None or component._position.twin):
            return
        axis = self.axes_manager.signal_axes[0]
        # Create the vertical line and labels
        widgets = [VerticalLineWidget(self.axes_manager)]
        if show_label:
            label = LabelWidget(self.axes_manager)
            label.string = component._get_short_description().replace(
                ' component', '')
            widgets.append(label)

        self._position_widgets[component._position] = widgets
        for w in widgets:
            # Setup widget
            w.axes = (axis, )
            w.snap_position = False
            w.position = (component._position.value, )
            w.set_mpl_ax(self._plot.signal_plot.ax)
            # Create widget -> parameter connection
            w.events.moved.connect(self._on_widget_moved, {'obj': 'widget'})
            # Create parameter -> widget connection
            component._position.events.value_changed.connect(
                w._set_position, dict(value='position'))
            # Map relation for close event
            w.events.closed.connect(self._on_position_widget_close,
                                    {'obj': 'widget'})
Example #3
0
    def switch_on_off(self, obj, trait_name, old, new):
        if not self.signal._plot.is_active():
            return

        if new is True and old is False:
            self._line = VerticalLineWidget(self.axes_manager)
            self._line.set_mpl_ax(self.signal._plot.signal_plot.ax)
            self._line.patch.set_linewidth(2)
            self._color_changed("black", "black")
            # There is not need to call draw because setting the
            # color calls it.

        elif new is False and old is True:
            self._line.close()
            self._line = None
            self.draw()
Example #4
0
    def switch_on_off(self, obj, trait_name, old, new):
        if not self.signal._plot.is_active():
            return

        if new is True and old is False:
            self._line = VerticalLineWidget(self.axes_manager)
            self._line.set_mpl_ax(self.signal._plot.signal_plot.ax)
            self._line.patch.set_linewidth(2)
            self._color_changed("black", "black")
            # There is not need to call draw because setting the
            # color calls it.

        elif new is False and old is True:
            self._line.close()
            self._line = None
            self.draw()
Example #5
0
 def _add_widget(self, signal):
     if signal is None:
         return None
     if self.ndim(signal) == 1:
         if self.ranged:
             w = RangeWidget(None)
         else:
             w = VerticalLineWidget(None)
     else:
         if self.ranged:
             w = RectangleWidget(None)
         else:
             w = SquareWidget(None)
     if signal in self.widgets:
         self.widgets[signal].append(w)
     else:
         self.widgets[signal] = [w]
     w.set_on(False)
     return w
Example #6
0
    def __init__(self, windows=None, name=None, category=None, icon=None,
                 description=None):
        super(SelectionTool, self).__init__(windows)
        self.widget2d_r = RectangleWidget(None)
        self.widget2d_r.set_on(False)
        self.widget1d_r = RangeWidget(None)
        self.widget1d_r.set_on(False)
        self.widget2d = SquareWidget(None)
        self.widget2d.set_on(False)
        self.widget1d = VerticalLineWidget(None)
        self.widget1d.set_on(False)
        self._widgets = [self.widget2d_r, self.widget1d_r, self.widget2d,
                         self.widget1d]
        self.valid_dimensions = [1, 2]
        self.ranged = True

        self.name = name or "Selection tool"
        self.category = category or 'Signal'
        self.description = description
        self.icon = icon
        self.cancel_on_accept = False
Example #7
0
class SelectionTool(SignalFigureTool):

    """
    Tool to select a ROI on a  signal interactively. Simply click and drag in a
    figure to create an ROI, and then press enter to indicate that the
    selection is complete, or ESC to cancel. The selection can also be aborted
    by simply selecting a different tool.
    """

    accepted = QtCore.Signal([BaseInteractiveROI],
                             [BaseInteractiveROI, SignalFigureTool])
    updated = QtCore.Signal([BaseInteractiveROI],
                            [BaseInteractiveROI, SignalFigureTool]) # TODO: Use
    cancelled = QtCore.Signal()

    def __init__(self, windows=None, name=None, category=None, icon=None,
                 description=None):
        super(SelectionTool, self).__init__(windows)
        self.widget2d_r = RectangleWidget(None)
        self.widget2d_r.set_on(False)
        self.widget1d_r = RangeWidget(None)
        self.widget1d_r.set_on(False)
        self.widget2d = SquareWidget(None)
        self.widget2d.set_on(False)
        self.widget1d = VerticalLineWidget(None)
        self.widget1d.set_on(False)
        self._widgets = [self.widget2d_r, self.widget1d_r, self.widget2d,
                         self.widget1d]
        self.valid_dimensions = [1, 2]
        self.ranged = True

        self.name = name or "Selection tool"
        self.category = category or 'Signal'
        self.description = description
        self.icon = icon
        self.cancel_on_accept = False

    @property
    def widget(self):
        if self.ndim == 1:
            if self.ranged:
                return self.widget1d_r
            else:
                return self.widget1d
        else:
            if self.ranged:
                return self.widget2d_r
            else:
                return self.widget2d

    @property
    def ndim(self):
        if self.axes is None:
            return 0
        return len(self.axes)

    def is_on(self):
        return self.widget.is_on()

    def in_ax(self, ax):
        return ax == self.widget.ax

    def get_name(self):
        return self.name

    def get_category(self):
        return self.category

    def get_icon(self):
        return self.icon

    def make_cursor(self):
        return crosshair_cursor()

    def is_selectable(self):
        return True

    def on_mousedown(self, event):
        # Only accept mouse down inside axes
        if event.inaxes is None:
            return

        axes = self._get_axes(event)
        # Make sure we have a figure with valid dimensions
        if len(axes) not in self.valid_dimensions:
            return
        self.axes = axes
        # If we already have a widget, make sure dragging is passed through
        if self.is_on():
            if any([p.contains(event)[0] == True for p in self.widget.patch]):
                return              # Moving, handle in widget
            # Clicked outside existing widget, check for resize handles
            if self.ndim > 1 and self.widget.resizers:
                for r in self.widget._resizer_handles:
                    if r.contains(event)[0] == True:
                        return      # Leave the event to widget
            # Cancel previous and start new
            self.cancel()
            # Cancel reset axes, so set again
            self.axes = axes

        # Find out which axes of Signal are plotted in figure
        s = self._get_signal(event.inaxes.figure)
        if s is None:
            return
        am = s.axes_manager

        self.widget.axes = axes
        if self.ndim > 0:
            self.widget.axes_manager = am

        # Have what we need, create widget
        x, y = event.xdata, event.ydata
        self.widget.set_mpl_ax(event.inaxes)  # connects
        if self.ndim == 1:
            self.widget.position = (x,)
            self.widget.size = axes[0].scale
            self.widget.set_on(True)
            if self.ranged:
                span = self.widget.span
                span.buttonDown = True
                span.on_move_cid = \
                    span.canvas.mpl_connect('motion_notify_event',
                                            span.move_right)
            else:
                self.widget.picked = True
        else:
            self.widget.position = (x, y)
            self.widget.size = [ax.scale for ax in axes]
            if self.ranged:
                self.widget.resizer_picked = 3
            self.widget.picked = True
            self.widget.set_on(True)

    def on_keyup(self, event):
        if event.key == 'enter':
            self.accept()
        elif event.key == 'escape':
            self.cancel()

    def accept(self):
        if self.is_on():
            if self.ndim == 1:
                if self.ranged:
                    roi = SpanROI(0, 1)
                else:
                    roi = Point1DROI(0)
            elif self.ndim > 1:
                if self.ranged:
                    roi = RectangularROI(0, 0, 1, 1)
                else:
                    roi = Point2DROI(0, 0)
            else:
                raise RuntimeWarning("No figure could be found.")
                return
            roi._on_widget_change(self.widget)  # ROI gets coords from widget
            self.accepted[BaseInteractiveROI].emit(roi)
            self.accepted[BaseInteractiveROI, SignalFigureTool].emit(roi, self)
        if self.cancel_on_accept:
            self.cancel()

    def cancel(self):
        for w in self._widgets:
            if w.is_on():
                w.set_on(False)
        self.axes = None
        self.cancelled.emit()

    def disconnect_windows(self, windows):
        super(SelectionTool, self).disconnect_windows(windows)
        self.cancel()
Example #8
0
class LineInSignal1D(t.HasTraits):
    """Adds a vertical draggable line to a spectrum that reports its
    position to the position attribute of the class.

    Attributes:
    -----------
    position : float
        The position of the vertical line in the one dimensional signal. Moving
        the line changes the position but the reverse is not true.
    on : bool
        Turns on and off the line
    color : wx.Colour
        The color of the line. It automatically redraws the line.

    """
    position = t.Float()
    is_ok = t.Bool(False)
    on = t.Bool(False)
    color = t.Color("black")

    def __init__(self, signal):
        if signal.axes_manager.signal_dimension != 1:
            raise SignalDimensionError(signal.axes_manager.signal_dimension, 1)

        self.signal = signal
        self.signal.plot()
        axis_dict = signal.axes_manager.signal_axes[0].get_axis_dictionary()
        am = AxesManager([
            axis_dict,
        ])
        am._axes[0].navigate = True
        # Set the position of the line in the middle of the spectral
        # range by default
        am._axes[0].index = int(round(am._axes[0].size / 2))
        self.axes_manager = am
        self.axes_manager.events.indices_changed.connect(
            self.update_position, [])
        self.on_trait_change(self.switch_on_off, 'on')

    def draw(self):
        self.signal._plot.signal_plot.figure.canvas.draw()

    def switch_on_off(self, obj, trait_name, old, new):
        if not self.signal._plot.is_active():
            return

        if new is True and old is False:
            self._line = VerticalLineWidget(self.axes_manager)
            self._line.set_mpl_ax(self.signal._plot.signal_plot.ax)
            self._line.patch.set_linewidth(2)
            self._color_changed("black", "black")
            # There is not need to call draw because setting the
            # color calls it.

        elif new is False and old is True:
            self._line.close()
            self._line = None
            self.draw()

    def update_position(self, *args, **kwargs):
        if not self.signal._plot.is_active():
            return
        self.position = self.axes_manager.coordinates[0]

    def _color_changed(self, old, new):
        if self.on is False:
            return

        self._line.patch.set_color((
            self.color.Red() / 255.,
            self.color.Green() / 255.,
            self.color.Blue() / 255.,
        ))
        self.draw()
Example #9
0
class LineInSpectrum(t.HasTraits):

    """Adds a vertical draggable line to a spectrum that reports its
    position to the position attribute of the class.

    Attributes:
    -----------
    position : float
        The position of the vertical line in the spectrum. Moving the
        line changes the position but the reverse is not true.
    on : bool
        Turns on and off the line
    color : wx.Colour
        The color of the line. It automatically redraws the line.

    """
    position = t.Float()
    is_ok = t.Bool(False)
    on = t.Bool(False)
    color = t.Color("black")

    def __init__(self, signal):
        if signal.axes_manager.signal_dimension != 1:
            raise SignalDimensionError(
                signal.axes_manager.signal_dimension, 1)

        self.signal = signal
        self.signal.plot()
        axis_dict = signal.axes_manager.signal_axes[0].get_axis_dictionary()
        am = AxesManager([axis_dict, ])
        am._axes[0].navigate = True
        # Set the position of the line in the middle of the spectral
        # range by default
        am._axes[0].index = int(round(am._axes[0].size / 2))
        self.axes_manager = am
        self.axes_manager.events.indices_changed.connect(
            self.update_position, [])
        self.on_trait_change(self.switch_on_off, 'on')

    def draw(self):
        self.signal._plot.signal_plot.figure.canvas.draw()

    def switch_on_off(self, obj, trait_name, old, new):
        if not self.signal._plot.is_active():
            return

        if new is True and old is False:
            self._line = VerticalLineWidget(self.axes_manager)
            self._line.set_mpl_ax(self.signal._plot.signal_plot.ax)
            self._line.patch.set_linewidth(2)
            self._color_changed("black", "black")
            # There is not need to call draw because setting the
            # color calls it.

        elif new is False and old is True:
            self._line.close()
            self._line = None
            self.draw()

    def update_position(self, *args, **kwargs):
        if not self.signal._plot.is_active():
            return
        self.position = self.axes_manager.coordinates[0]

    def _color_changed(self, old, new):
        if self.on is False:
            return

        self._line.patch.set_color((self.color.Red() / 255.,
                                    self.color.Green() / 255.,
                                    self.color.Blue() / 255.,))
        self.draw()
Example #10
0
class SelectionTool(SignalFigureTool):
    """
    Tool to select a ROI on a  signal interactively. Simply click and drag in a
    figure to create an ROI, and then press enter to indicate that the
    selection is complete, or ESC to cancel. The selection can also be aborted
    by simply selecting a different tool.
    """

    accepted = QtCore.Signal([BaseInteractiveROI],
                             [BaseInteractiveROI, SignalFigureTool])
    updated = QtCore.Signal(
        [BaseInteractiveROI],
        [BaseInteractiveROI, SignalFigureTool])  # TODO: Use
    cancelled = QtCore.Signal()

    def __init__(self,
                 windows=None,
                 name=None,
                 category=None,
                 icon=None,
                 description=None):
        super(SelectionTool, self).__init__(windows)
        self.widget2d_r = RectangleWidget(None)
        self.widget2d_r.set_on(False)
        self.widget1d_r = RangeWidget(None)
        self.widget1d_r.set_on(False)
        self.widget2d = SquareWidget(None)
        self.widget2d.set_on(False)
        self.widget1d = VerticalLineWidget(None)
        self.widget1d.set_on(False)
        self._widgets = [
            self.widget2d_r, self.widget1d_r, self.widget2d, self.widget1d
        ]
        self.valid_dimensions = [1, 2]
        self.ranged = True

        self.name = name or "Selection tool"
        self.category = category or 'Signal'
        self.description = description
        self.icon = icon
        self.cancel_on_accept = False

    @property
    def widget(self):
        if self.ndim == 1:
            if self.ranged:
                return self.widget1d_r
            else:
                return self.widget1d
        else:
            if self.ranged:
                return self.widget2d_r
            else:
                return self.widget2d

    @property
    def ndim(self):
        if self.axes is None:
            return 0
        return len(self.axes)

    def is_on(self):
        return self.widget.is_on()

    def in_ax(self, ax):
        return ax == self.widget.ax

    def get_name(self):
        return self.name

    def get_category(self):
        return self.category

    def get_icon(self):
        return self.icon

    def make_cursor(self):
        return crosshair_cursor()

    def is_selectable(self):
        return True

    def on_mousedown(self, event):
        # Only accept mouse down inside axes
        if event.inaxes is None:
            return

        axes = self._get_axes(event)
        # Make sure we have a figure with valid dimensions
        if len(axes) not in self.valid_dimensions:
            return
        self.axes = axes
        # If we already have a widget, make sure dragging is passed through
        if self.is_on():
            if any([p.contains(event)[0] == True for p in self.widget.patch]):
                return  # Moving, handle in widget
            # Clicked outside existing widget, check for resize handles
            if self.ndim > 1 and self.widget.resizers:
                for r in self.widget._resizer_handles:
                    if r.contains(event)[0] == True:
                        return  # Leave the event to widget
            # Cancel previous and start new
            self.cancel()
            # Cancel reset axes, so set again
            self.axes = axes

        # Find out which axes of Signal are plotted in figure
        s = self._get_signal(event.inaxes.figure)
        if s is None:
            return
        am = s.axes_manager

        self.widget.axes = axes
        if self.ndim > 0:
            self.widget.axes_manager = am

        # Have what we need, create widget
        x, y = event.xdata, event.ydata
        self.widget.set_mpl_ax(event.inaxes)  # connects
        if self.ndim == 1:
            self.widget.position = (x, )
            self.widget.size = axes[0].scale
            self.widget.set_on(True)
            if self.ranged:
                span = self.widget.span
                span.buttonDown = True
                span.on_move_cid = \
                    span.canvas.mpl_connect('motion_notify_event',
                                            span.move_right)
            else:
                self.widget.picked = True
        else:
            self.widget.position = (x, y)
            self.widget.size = [ax.scale for ax in axes]
            if self.ranged:
                self.widget.resizer_picked = 3
            self.widget.picked = True
            self.widget.set_on(True)

    def on_keyup(self, event):
        if event.key == 'enter':
            self.accept()
        elif event.key == 'escape':
            self.cancel()

    def accept(self):
        if self.is_on():
            if self.ndim == 1:
                if self.ranged:
                    roi = SpanROI(0, 1)
                else:
                    roi = Point1DROI(0)
            elif self.ndim > 1:
                if self.ranged:
                    roi = RectangularROI(0, 0, 1, 1)
                else:
                    roi = Point2DROI(0, 0)
            else:
                raise RuntimeWarning("No figure could be found.")
                return
            roi._on_widget_change(self.widget)  # ROI gets coords from widget
            self.accepted[BaseInteractiveROI].emit(roi)
            self.accepted[BaseInteractiveROI, SignalFigureTool].emit(roi, self)
        if self.cancel_on_accept:
            self.cancel()

    def cancel(self):
        for w in self._widgets:
            if w.is_on():
                w.set_on(False)
        self.axes = None
        self.cancelled.emit()

    def disconnect_windows(self, windows):
        super(SelectionTool, self).disconnect_windows(windows)
        self.cancel()