def on_mouse_release(self, event):

        # Get the visible datasets
        if event.button == 1 and self.mode is not None:
            visible_data, visual = self.get_visible_data()
            data = self.get_map_data()

            if len(self.line_pos) == 0:
                self.lasso_reset()
                return

            elif self.mode is 'lasso':
                selection_path = path.Path(self.line_pos, closed=True)
                mask = selection_path.contains_points(data)

            elif self.mode is 'ellipse':
                xmin, ymin = np.min(self.line_pos[:, 0]), np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), np.max(self.line_pos[:, 1])
                c = CircularROI((xmax + xmin) / 2., (ymax + ymin) / 2., (xmax - xmin) / 2.)  # (xc, yc, radius)
                mask = c.contains(data[:, 0], data[:, 1])

            elif self.mode is 'rectangle':
                xmin, ymin = np.min(self.line_pos[:, 0]), np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), np.max(self.line_pos[:, 1])
                r = RectangularROI(xmin, xmax, ymin, ymax)
                mask = r.contains(data[:, 0], data[:, 1])

            else:
                raise ValueError("Unknown mode: {0}".format(self.mode))

            self.mark_selected(mask, visible_data)

            self.lasso_reset()
Exemple #2
0
    def on_mouse_release(self, event):
        """
        Get the mask of selected data and get them highlighted.
        :param event:
        """
        # Get the visible datasets
        if event.button == 1 and self.mode and self.mode is not 'point':
            visible_data, visual = self.get_visible_data()
            data = self.get_map_data()
            if len(self.line_pos) == 0:
                self.lasso_reset()
                return

            elif self.mode is 'lasso':
                # Note, we use points_inside_poly here instead of calling e.g.
                # matplotlib directly, because we include some optimizations
                # in points_inside_poly
                vx, vy = np.array(self.line_pos).transpose()
                x, y = data.transpose()
                mask = points_inside_poly(x, y, vx, vy)

            elif self.mode is 'ellipse':
                xmin, ymin = np.min(self.line_pos[:, 0]), \
                             np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), \
                             np.max(self.line_pos[:, 1])

                # (xc, yc, radius)
                c = CircularROI((xmax+xmin)/2., (ymax+ymin)/2., (xmax-xmin)/2.)
                mask = c.contains(data[:, 0], data[:, 1])

            elif self.mode is 'rectangle':
                xmin, ymin = np.min(self.line_pos[:, 0]), \
                             np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), \
                             np.max(self.line_pos[:, 1])
                r = RectangularROI(xmin, xmax, ymin, ymax)
                mask = r.contains(data[:, 0], data[:, 1])

            else:
                raise ValueError("Unknown mode: {0}".format(self.mode))

            # Mask matches transposed volume data set rather than the original one.
            # The ravel here is to make mask compatible with ElementSubsetState input.
            new_mask = np.reshape(mask, self.trans_ones_data.shape)
            new_mask = np.ravel(np.transpose(new_mask))
            self.mark_selected(new_mask, self.visible_data)

            self.lasso_reset()
Exemple #3
0
 def update_selection(self, *args):
     if self.interact.brushing:
         return
     with self.viewer._output_widget:
         if self.interact.selected_x is not None and self.interact.selected_y is not None:
             x = self.interact.selected_x
             y = self.interact.selected_y
             # similar to https://github.com/glue-viz/glue/blob/b14ccffac6a5
             # 271c2869ead9a562a2e66232e397/glue/core/roi.py#L1275-L1297
             # We should now check if the radius in data coordinates is the same
             # along x and y, as if so then we can return a circle, otherwise we
             # should return an ellipse.
             xc = x.mean()
             yc = y.mean()
             rx = abs(x[1] - x[0]) / 2
             ry = abs(y[1] - y[0]) / 2
             # We use a tolerance of 1e-2 below to match the tolerance set in glue-core
             # https://github.com/glue-viz/glue/blob/6b968b352bc5ad68b95ad5e3bb25550782a69ee8/glue/viewers/matplotlib/state.py#L198
             if np.allclose(rx, ry, rtol=1e-2):
                 roi = CircularROI(xc=xc, yc=yc, radius=rx)
             else:
                 roi = EllipticalROI(xc=xc, yc=yc, radius_x=rx, radius_y=ry)
             self.viewer.apply_roi(roi)
             if self.finalize_callback is not None:
                 self.finalize_callback()
Exemple #4
0
 def on_selection(self, data, other=None):
     with self.output_widget:
         W = np.matrix(self.figure.matrix_world).reshape((4, 4)).T
         P = np.matrix(self.figure.matrix_projection).reshape((4, 4)).T
         M = np.dot(P, W)
         if data['device']:
             if data['type'] == 'lasso':
                 region = data['device']
                 vx, vy = zip(*region)
                 roi_2d = PolygonalROI(vx=vx, vy=vy)
             elif data['type'] == 'circle':
                 x1, y1 = data['device']['begin']
                 x2, y2 = data['device']['end']
                 dx = x2 - x1
                 dy = y2 - y1
                 r = (dx**2 + dy**2)**0.5
                 roi_2d = CircularROI(xc=x1, yc=y1, radius=r)
             elif data['type'] == 'rectangle':
                 x1, y1 = data['device']['begin']
                 x2, y2 = data['device']['end']
                 x = [x1, x2]
                 y = [y1, y2]
                 roi_2d = RectangularROI(xmin=min(x),
                                         xmax=max(x),
                                         ymin=min(y),
                                         ymax=max(y))
             roi = Projected3dROI(roi_2d, M)
             self.apply_roi(roi)
    def release(self, event):

        if event.button == 1:

            if self.radius > 0:
                c = CircularROI(self.center[0], self.center[1], self.radius)

                mask_dict = {}

                self.set_progress(0)

                for layer_artist in self.iter_data_layer_artists():

                    def selection(x, y):
                        return c.contains(x, y)

                    mask = get_mask_for_layer_artist(layer_artist, self.viewer,
                                                     selection, progress=self.set_progress)

                    mask_dict[layer_artist.layer] = mask

                self.mark_selected_dict(mask_dict)

                self.set_progress(-1)

            self.reset()
def reg_to_roi(reg):
    """
    Function to convert a region to an ROI
    This might be implementable as a dictionary/registry,
    but hard-coding it isn't more difficult...
    """

    if isinstance(reg, regions.CirclePixelRegion):
        return CircularROI(xc=reg.center.x, yc=reg.center.y, radius=reg.radius)
    elif isinstance(reg, regions.PointPixelRegion):
        return PointROI(x=reg.center.x, y=reg.center.y)
    elif isinstance(reg, regions.RectanglePixelRegion):
        if reg.angle == 0:
            xmin, xmax = reg.center.x - reg.width / 2, reg.center.x + reg.width / 2
            ymin, ymax = reg.center.y - reg.height / 2, reg.center.y + reg.height / 2
            return RectangularROI(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
        else:
            if hasattr(reg, 'corners'):
                xverts = [c[0] for c in reg.corners]
                yverts = [c[1] for c in reg.corners]
                return PolygonalROI(vx=xverts, vy=yverts)
            else:
                raise NotImplementedError("Rectangles need to convert to polygons.")
    elif isinstance(reg, regions.PolygonPixelRegion):
        return PolygonalROI(vx=reg.vertices.x, vy=reg.vertices.y)
    else:
        raise NotImplementedError("Region {0} not recognized".format(reg))
Exemple #7
0
 def setup(self):
     self.data_collection, self.viewer = get_data_collection_and_viewer()
     load_wcs_data(self.data_collection)
     self.viewer.add_data(self.data_collection[0])
     self.viewer.add_data(self.data_collection[1])
     roi = CircularROI(256, 256, 120)
     py1, px1 = self.data_collection[0].pixel_component_ids
     self.subset_state = RoiSubsetState(px1, py1, roi)
     self.viewer.register_to_hub(self.data_collection.hub)
    def on_mouse_release(self, event):

        visible_data, visual = self.get_visible_data()

        # Get the visible datasets
        if event.button == 1 and self.mode is not None:

            visible_data, visual = self.get_visible_data()
            data = self.get_map_data()
            if len(self.line_pos) == 0:
                self.lasso_reset()
                return

            elif self.mode is 'lasso':
                # Note, we use points_inside_poly here instead of calling e.g.
                # matplotlib directly, because we include some optimizations
                # in points_inside_poly
                vx, vy = np.array(self.line_pos).transpose()
                x, y = data.transpose()
                mask = points_inside_poly(x, y, vx, vy)

            elif self.mode is 'ellipse':
                xmin, ymin = np.min(self.line_pos[:, 0]), np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), np.max(self.line_pos[:, 1])
                c = CircularROI((xmax + xmin) / 2., (ymax + ymin) / 2., (xmax - xmin) / 2.)  # (xc, yc, radius)
                mask = c.contains(data[:, 0], data[:, 1])

            elif self.mode is 'rectangle':
                xmin, ymin = np.min(self.line_pos[:, 0]), np.min(self.line_pos[:, 1])
                xmax, ymax = np.max(self.line_pos[:, 0]), np.max(self.line_pos[:, 1])
                r = RectangularROI(xmin, xmax, ymin, ymax)
                mask = r.contains(data[:, 0], data[:, 1])

            else:
                raise ValueError("Unknown mode: {0}".format(self.mode))

            # Mask matches transposed volume data set rather than the original one.
            # The ravel here is to make mask compatible with ElementSubsetState input.
            new_mask = np.reshape(mask, self.trans_ones_data.shape)
            new_mask = np.ravel(np.transpose(new_mask))
            self.mark_selected(new_mask, visible_data)

            self.lasso_reset()
Exemple #9
0
    def on_mouse_release(self, event):

        # Get the visible datasets
        if event.button == 1 and self.mode is not None:
            visible_data, visual = self.get_visible_data()
            data = self.get_map_data()

            if len(self.line_pos) == 0:
                self.lasso_reset()
                return

            elif self.mode is 'lasso':
                selection_path = path.Path(self.line_pos, closed=True)
                mask = selection_path.contains_points(data)

            elif self.mode is 'ellipse':
                xmin, ymin = np.min(self.line_pos[:,
                                                  0]), np.min(self.line_pos[:,
                                                                            1])
                xmax, ymax = np.max(self.line_pos[:,
                                                  0]), np.max(self.line_pos[:,
                                                                            1])
                c = CircularROI((xmax + xmin) / 2., (ymax + ymin) / 2.,
                                (xmax - xmin) / 2.)  # (xc, yc, radius)
                mask = c.contains(data[:, 0], data[:, 1])

            elif self.mode is 'rectangle':
                xmin, ymin = np.min(self.line_pos[:,
                                                  0]), np.min(self.line_pos[:,
                                                                            1])
                xmax, ymax = np.max(self.line_pos[:,
                                                  0]), np.max(self.line_pos[:,
                                                                            1])
                r = RectangularROI(xmin, xmax, ymin, ymax)
                mask = r.contains(data[:, 0], data[:, 1])

            else:
                raise ValueError("Unknown mode: {0}".format(self.mode))

            self.mark_selected(mask, visible_data)

            self.lasso_reset()
    def release(self, event):

        if event.button == 1:

            if self.radius > 0:
                c = CircularROI(self.center[0], self.center[1], self.radius)

                indices_dict = {}

                for layer_artist in self.iter_data_layer_artists():

                    data = get_map_data(layer_artist, self.viewer)
                    mask = c.contains(data[:, 0], data[:, 1])

                    shape_mask = np.reshape(mask, layer_artist.layer.shape[::-1])
                    shape_mask = np.ravel(np.transpose(shape_mask))

                    indices_dict[layer_artist.layer] = np.where(shape_mask)[0]

                self.mark_selected_dict(indices_dict)

            self.reset()
    def release(self, event):

        if event.button == 1:

            if self.radius > 0:
                roi = Projected3dROI(roi_2d=CircularROI(
                    self.center[0], self.center[1], self.radius),
                                     projection_matrix=self.projection_matrix)
                self.apply_roi(roi)

            self.reset()

            self.viewer.toolbar.active_tool = None
Exemple #12
0
    def release(self, event):

        if event.button == 1:

            if self.radius > 0:
                c = CircularROI(self.center[0], self.center[1], self.radius)

                indices_dict = {}

                for layer_artist in self.iter_data_layer_artists():

                    data = get_map_data(layer_artist, self.viewer)
                    mask = c.contains(data[:, 0], data[:, 1])

                    shape_mask = np.reshape(mask,
                                            layer_artist.layer.shape[::-1])
                    shape_mask = np.ravel(np.transpose(shape_mask))

                    indices_dict[layer_artist.layer] = np.where(shape_mask)[0]

                self.mark_selected_dict(indices_dict)

            self.reset()
Exemple #13
0
    def on_selection(self, data, other=None):

        if data['type'] != self.selector:
            return

        if data['device']:
            with self.viewer.output_widget:
                x1, y1 = data['device']['begin']
                x2, y2 = data['device']['end']
                dx = x2 - x1
                dy = y2 - y1
                r = (dx**2 + dy**2)**0.5
                roi_2d = CircularROI(xc=x1, yc=y1, radius=r)
                roi = Projected3dROI(roi_2d, self.projection_matrix)
                self.viewer.apply_roi(roi)
Exemple #14
0
    def test_circular_roi(self):

        subset_state = RoiSubsetState(self.data.pixel_component_ids[1],
                                      self.data.pixel_component_ids[0],
                                      CircularROI(1, 3.5, 0.75))

        self.dc.new_subset_group(subset_state=subset_state, label='circular')

        reg = self.data.get_selection_definition(format='astropy-regions')

        assert isinstance(reg, CirclePixelRegion)

        assert_equal(reg.center.x, 1)
        assert_equal(reg.center.y, 3.5)
        assert_equal(reg.radius, 0.75)
Exemple #15
0
    def test_or_region(self):
        subset_state1 = RoiSubsetState(self.data.pixel_component_ids[1],
                                       self.data.pixel_component_ids[0],
                                       RectangularROI(1, 5, 2, 6))
        subset_state2 = RoiSubsetState(self.data.pixel_component_ids[1],
                                       self.data.pixel_component_ids[0],
                                       CircularROI(4.75, 5.75, 0.5))
        or_subset_state = OrState(subset_state1, subset_state2)
        self.dc.new_subset_group(subset_state=or_subset_state, label='orstate')

        reg = self.data.get_selection_definition(format='astropy-regions')

        assert isinstance(reg, CompoundPixelRegion)
        assert isinstance(reg.region1, RectanglePixelRegion)
        assert isinstance(reg.region2, CirclePixelRegion)

        assert reg.contains(PixCoord(4.5, 5.5))
        assert reg.contains(PixCoord(3, 4))
        assert reg.contains(PixCoord(5.1, 6.1))
        assert not reg.contains(PixCoord(11, 12))
Exemple #16
0
 def update_selection(self, *args):
     if self.interact.brushing:
         return
     with self.viewer._output_widget:
         if self.interact.selected_x is not None and self.interact.selected_y is not None:
             x = self.interact.selected_x
             y = self.interact.selected_y
             # similar to https://github.com/glue-viz/glue/blob/b14ccffac6a5
             # 271c2869ead9a562a2e66232e397/glue/core/roi.py#L1275-L1297
             # We should now check if the radius in data coordinates is the same
             # along x and y, as if so then we can return a circle, otherwise we
             # should return an ellipse.
             xc = x.mean()
             yc = y.mean()
             rx = abs(x[1] - x[0])/2
             ry = abs(y[1] - y[0])/2
             if np.allclose(rx, ry):
                 roi = CircularROI(xc=xc, yc=yc, radius=rx)
             else:
                 roi = EllipticalROI(xc=xc, yc=yc, radius_x=rx, radius_y=ry)
             self.viewer.apply_roi(roi)
             if self.finalize_callback is not None:
                 self.finalize_callback()
Exemple #17
0
    def test_invalid_combos(self):
        good_subset = RoiSubsetState(self.data.pixel_component_ids[1],
                                     self.data.pixel_component_ids[0],
                                     RectangularROI(1, 5, 2, 6))
        bad_subset = RoiSubsetState(self.data.pixel_component_ids[1],
                                    self.data.main_components[0],
                                    CircularROI(4.75, 5.75, 0.5))
        and_sub = AndState(good_subset, bad_subset)
        or_sub = OrState(good_subset, bad_subset)
        xor_sub = XorState(good_subset, bad_subset)
        multior = MultiOrState([good_subset, bad_subset])
        self.dc.new_subset_group(subset_state=and_sub, label='and')
        self.dc.new_subset_group(subset_state=or_sub, label='or')
        self.dc.new_subset_group(subset_state=xor_sub, label='xor')
        self.dc.new_subset_group(subset_state=multior, label='multior')

        expected_error = 'Subset state yatt should be y pixel coordinate'

        with pytest.raises(ValueError) as exc:
            self.data.get_selection_definition(subset_id='and',
                                               format='astropy-regions')
        assert exc.value.args[0] == expected_error

        with pytest.raises(ValueError) as exc:
            self.data.get_selection_definition(subset_id='or',
                                               format='astropy-regions')
        assert exc.value.args[0] == expected_error

        with pytest.raises(ValueError) as exc:
            self.data.get_selection_definition(subset_id='xor',
                                               format='astropy-regions')
        assert exc.value.args[0] == expected_error

        with pytest.raises(ValueError) as exc:
            self.data.get_selection_definition(subset_id='multior',
                                               format='astropy-regions')
        assert exc.value.args[0] == expected_error
Exemple #18
0
    def test_datetime64_support(self, tmpdir):

        self.data.add_component(np.array([100, 200, 300, 400], dtype='M8[D]'),
                                't1')
        self.data.add_component(np.array([200, 300, 400, 500], dtype='M8[D]'),
                                't2')
        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['t1']
        self.viewer.state.y_att = self.data.id['y']

        # Matplotlib deals with dates by converting them to the number of days
        # since 01-01-0001, so we can check that the limits are correctly
        # converted (and not 100 to 400)
        assert self.viewer.axes.get_xlim() == (719248.0, 719578.0)
        assert self.viewer.axes.get_ylim() == (3.2 - 0.015, 3.5 + 0.015)

        # Apply an ROI selection in plotting coordinates
        roi = RectangularROI(xmin=719313, xmax=719513, ymin=3, ymax=4)
        self.viewer.apply_roi(roi)

        # Check that the two middle elements are selected
        assert_equal(self.data.subsets[0].to_mask(), [0, 1, 1, 0])

        # Now do the same with the y axis
        self.viewer.state.y_att = self.data.id['t2']

        assert self.viewer.axes.get_xlim() == (719248.0, 719578.0)
        assert self.viewer.axes.get_ylim() == (719348.0, 719678.0)

        # Apply an ROI selection in plotting coordinates
        edit = self.session.edit_subset_mode
        edit.edit_subset = []
        roi = CircularROI(xc=719463, yc=719563, radius=200)
        self.viewer.apply_roi(roi)
        assert_equal(self.data.subsets[1].to_mask(), [0, 1, 1, 1])

        # Make sure that the Qt labels look ok
        self.viewer.state.y_att = self.data.id['y']
        options = self.viewer.options_widget().ui
        assert options.valuetext_x_min.text() == '1970-03-27'
        assert options.valuetext_x_max.text() == '1971-02-20'
        assert options.valuetext_y_min.text() == '3.185'
        assert options.valuetext_y_max.text() == '3.515'

        # Make sure that we can set the xmin/xmax to a string date
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-03-27', 'D'))
        options.valuetext_x_min.setText('1970-04-14')
        options.valuetext_x_min.editingFinished.emit()
        assert self.viewer.axes.get_xlim() == (719266.0, 719578.0)
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        # Make sure that everything works fine after saving/reloading
        filename = tmpdir.join('test_datetime64.glu').strpath
        self.session.application.save_session(filename)
        with open(filename, 'r') as f:
            session = f.read()
        state = GlueUnSerializer.loads(session)
        ga = state.object('__main__')
        viewer = ga.viewers[0][0]
        options = viewer.options_widget().ui

        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        assert options.valuetext_x_min.text() == '1970-04-14'
        assert options.valuetext_x_max.text() == '1971-02-20'
        assert options.valuetext_y_min.text() == '3.185'
        assert options.valuetext_y_max.text() == '3.515'