def test_spectrum(self): roi = RectangularROI() roi.update_limits(0, 0, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id["x"], roi, (0, "x", "y"), 0) np.testing.assert_array_almost_equal(expected, actual)
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 test_collapse(self, tmpdir): roi = RectangularROI() roi.update_limits(0, 2, 0, 2) self.tool._update_profile() self._save(tmpdir)
def test_apply_roi(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert self.layer_data_correct(data.edit_subset, x, y)
def test_spectrum(self): roi = RectangularROI() roi.update_limits(0.5, 1.5, 2.5, 2.5) expected = self.x[:, 1:3, 2:3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum( self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual)
def test_apply_roi_results(self, roi_limits, mask): # Regression test for glue-viz/glue#718 data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*roi_limits) x, y = self.roi_points self.client.apply_roi(roi) np.testing.assert_equal(data.edit_subset.to_mask(), mask)
def test_spectrum(self): roi = RectangularROI() roi.update_limits(0, 0, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual)
def test_apply_roi_adds_on_empty(self): data = self.add_data_and_attributes() data._subsets = [] data.edit_subset = None roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert data.edit_subset is not None
def test_visibility_sticky(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) assert self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) self.client.set_visible(data.edit_subset, False) assert not self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) assert not self.client.is_visible(data.edit_subset)
def test_extract(self): roi = RectangularROI() roi.update_limits(0, 0, 2, 3) expected = self.data['x'][:, :2, :3, 1].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id['x'], roi, (0, 'x', 'y', 1), 0) np.testing.assert_array_equal(expected, actual)
def test_apply_roi_doesnt_add_if_any_selection(self): d1 = self.add_data_and_attributes() d2 = self.add_data() d1.edit_subset = None d2.edit_subset = d2.new_subset() ct = len(d1.subsets) roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert len(d1.subsets) == ct
def test_apply_roi_applies_to_all_editable_subsets(self): d1 = self.add_data_and_attributes() d2 = self.add_data() state1 = d1.edit_subset.subset_state state2 = d2.edit_subset.subset_state roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert d1.edit_subset.subset_state is not state1 assert d1.edit_subset.subset_state is not state2
def test_4d_single_channel(): x = np.random.random((1, 7, 5, 9)) d = Data(x=x) slc = (0, 0, 'x', 'y') zaxis = 1 expected = x[0, :, :, :].mean(axis=1).mean(axis=1) roi = RectangularROI() roi.update_limits(0, 0, 10, 10) _, actual = Extractor.spectrum(d, d.id['x'], roi, slc, zaxis) np.testing.assert_array_almost_equal(expected, actual)
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()
def test_collapse(self, tmpdir): roi = RectangularROI() roi.update_limits(0, 2, 0, 2) self.tool._update_profile() self._save(tmpdir) # For some reason we need to close and dereference the image and tool # here (and not in teardown_method) otherwise we are left with # references to the image viewer. self.image.close() self.image = None self.tool.close() self.tool = None
def test_multior_region(self): rects = [(1, 2, 3, 4), (1.5, 2.5, 3.5, 4.5), (2, 3, 4, 5)] states = [ RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(*rect)) for rect in rects ] multior_subset_state = MultiOrState(states) self.dc.new_subset_group(subset_state=multior_subset_state, label='multiorstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, CompoundPixelRegion) assert isinstance(reg.region2, RectanglePixelRegion) assert isinstance(reg.region1.region1, RectanglePixelRegion) assert isinstance(reg.region1.region2, RectanglePixelRegion) assert reg.contains(PixCoord(1.25, 3.25)) assert reg.contains(PixCoord(1.75, 3.75)) assert reg.contains(PixCoord(2.25, 3.75)) assert reg.contains(PixCoord(2.25, 4.25)) assert reg.contains(PixCoord(2.75, 4.75)) assert not reg.contains(PixCoord(5, 7))
def test_apply_roi_polar(self): self.viewer.add_data(self.data) viewer_state = self.viewer.state roi = RectangularROI(0, 0.5, 0, 0.5) viewer_state.plot_mode = 'polar' viewer_state.full_circle() assert len(self.viewer.layers) == 1 self.viewer.apply_roi(roi) assert len(self.viewer.layers) == 2 assert len(self.data.subsets) == 1 assert_allclose(self.data.subsets[0].to_mask(), [1, 0, 0, 0]) state = self.data.subsets[0].subset_state assert isinstance(state, RoiSubsetState) assert state.pretransform pretrans = state.pretransform assert isinstance(pretrans, ProjectionMplTransform) assert pretrans._state['projection'] == 'polar' assert_allclose(pretrans._state['x_lim'], [viewer_state.x_min, viewer_state.x_max]) assert_allclose(pretrans._state['y_lim'], [viewer_state.y_min, viewer_state.y_max]) assert pretrans._state['x_scale'] == 'linear' assert pretrans._state['y_scale'] == 'linear' self.data.subsets[0].delete() viewer_state.y_log = True self.viewer.apply_roi(roi) state = self.data.subsets[0].subset_state assert state.pretransform pretrans = state.pretransform assert isinstance(pretrans, ProjectionMplTransform) assert pretrans._state['y_scale'] == 'log'
def test_region_spectral_spatial(jdaviz_app, spectral_cube_wcs): data = Data(flux=np.ones((256, 128, 128)), label='Test Flux', coords=spectral_cube_wcs) jdaviz_app.data_collection.append(data) jdaviz_app.add_data_to_viewer('spectrum-viewer', 'Test Flux') jdaviz_app.add_data_to_viewer('flux-viewer', 'Test Flux') jdaviz_app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(5, 15.5)) flux_viewer = jdaviz_app.get_viewer("flux-viewer") # We set the active tool here to trigger a reset of the Subset state to "Create new" flux_viewer.toolbar.active_tool = flux_viewer.toolbar.tools['bqplot:rectangle'] flux_viewer.apply_roi(RectangularROI(1, 3.5, -0.2, 3.3)) subsets = jdaviz_app.get_subsets_from_viewer('spectrum-viewer', subset_type='spectral') reg = subsets.get('Subset 1') print(reg) assert len(subsets) == 1 assert isinstance(reg, SpectralRegion) assert_quantity_allclose(reg.lower, 5.0 * u.Hz) assert_quantity_allclose(reg.upper, 14 * u.Hz) subsets = jdaviz_app.get_subsets_from_viewer('flux-viewer', subset_type='spatial') reg = subsets.get('Subset 2') assert len(subsets) == 1 assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5)
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.corner2 is not None: r = RectangularROI(*self.bounds) mask_dict = {} self.set_progress(0) for layer_artist in self.iter_data_layer_artists(): def selection(x, y): return r.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 test_reordered_pixel_components(self): self.data._pixel_component_ids = self.data._pixel_component_ids[::-1] range_state = RangeSubsetState(105.5, 107.7, self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=range_state, label='reordered_range') rect_state = RoiSubsetState(self.data.pixel_component_ids[0], self.data.pixel_component_ids[1], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=rect_state, label='reordered_rectangular') range_region = self.data.get_selection_definition( subset_id='reordered_range', format='astropy-regions') rect_region = self.data.get_selection_definition( subset_id='reordered_rectangular', format='astropy-regions') assert isinstance(range_region, RectanglePixelRegion) assert_allclose(range_region.center.x, 128) assert_allclose(range_region.center.y, 106.6) assert_allclose(range_region.width, 256) assert_allclose(range_region.height, 2.2) assert isinstance(rect_region, RectanglePixelRegion) assert_allclose(rect_region.center.x, 2.25) assert_allclose(rect_region.center.y, 1.55) assert_allclose(rect_region.width, 2.5) assert_allclose(rect_region.height, 3.5)
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))
def test_apply_roi_fullsphere(self): self.viewer.add_data(self.data) viewer_state = self.viewer.state roi = RectangularROI(0, 0.5, 0, 0.5) for proj in fullsphere_projections: viewer_state.plot_mode = proj assert len(self.viewer.layers) == 1 self.viewer.apply_roi(roi) assert len(self.viewer.layers) == 2 assert len(self.data.subsets) == 1 subset = self.data.subsets[0] state = subset.subset_state assert isinstance(state, RoiSubsetState) assert state.pretransform pretrans = state.pretransform assert isinstance(pretrans, ProjectionMplTransform) assert pretrans._state['projection'] == proj assert_allclose(pretrans._state['x_lim'], [viewer_state.x_min, viewer_state.x_max]) assert_allclose(pretrans._state['y_lim'], [viewer_state.y_min, viewer_state.y_max]) assert pretrans._state['x_scale'] == 'linear' assert pretrans._state['y_scale'] == 'linear' subset.delete()
def update_selection(selection, viewer): """Called after an ImageJ selection keypress. Assumes first dataset contains the 'x' and 'y' components. Builds a Glue SubsetState and applies it using Glue's current settings. Selection consists of (xmin, xmax, ymin, ymax) """ xmin, xmax, ymin, ymax = selection roi = RectangularROI(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) xatt = lasagna.config.app.data_collection[0].data.find_component_id('x') yatt = lasagna.config.app.data_collection[0].data.find_component_id('y') xy_state = RoiSubsetState(xatt=xatt, yatt=yatt, roi=roi) file_state = CategorySubsetState(viewer.source_id, viewer.source_val) # selection only applies to data in displayed file subset_state = AndState(xy_state, file_state) data_collection = lasagna.config.app.data_collection # if no subset groups selected, make a new one layers = (lasagna.config.app._layer_widget.selected_layers()) subset_groups = [s for s in layers if isinstance(s, SubsetGroup)] if len(subset_groups) == 0: global fiji_label new_label = 'Fiji %d' % fiji_label fiji_label += 1 data_collection.new_subset_group(label=new_label, subset_state=subset_state) else: edit_mode = EditSubsetMode() edit_mode.update(data_collection, subset_state)
def update_selection(self, *args): 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 roi = RectangularROI(xmin=min(x), xmax=max(x), ymin=min(y), ymax=max(y)) self.viewer.apply_roi(roi)
def update_brush(self, *ignore): with self.output_widget: if not self.brush.brushing: # only select when we ended (x1, y1), (x2, y2) = self.brush.selected x = [x1, x2] y = [y1, y2] roi = RectangularROI(xmin=min(x), xmax=max(x), ymin=min(y), ymax=max(y)) self.apply_roi(roi)
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()
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 roi = RectangularROI(xmin=min(x), xmax=max(x), ymin=min(y), ymax=max(y)) self.viewer.apply_roi(roi) if self.finalize_callback is not None: self.finalize_callback()
def release(self, event): if event.button == 1: if self.corner2 is not None: roi = Projected3dROI(roi_2d=RectangularROI(*self.bounds), projection_matrix=self.projection_matrix) self.apply_roi(roi) self.reset() self.viewer.toolbar.active_tool = None
def release(self, event): if event.button == 1: if self.corner2 is not None: r = RectangularROI(*self.bounds) indices_dict = {} for layer_artist in self.iter_data_layer_artists(): data = get_map_data(layer_artist, self.viewer) mask = r.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 test_update_clears_subset_cache(self): from glue.core.roi import RectangularROI d = Data(x=[1, 2, 3], y=[1, 2, 3]) s = d.new_subset() state = core.subset.RoiSubsetState() state.xatt = d.id['x'] state.yatt = d.id['y'] state.roi = RectangularROI(xmin=1.5, xmax=2.5, ymin=1.5, ymax=2.5) s.subset_state = state np.testing.assert_array_equal(s.to_mask(), [False, True, False]) d.update_components({d.id['x']: [10, 20, 30]}) np.testing.assert_array_equal(s.to_mask(), [False, False, False])
def test_range_rois_preserved(self): data = self.add_data_and_attributes() assert self.client.xatt is not self.client.yatt roi = XRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert isinstance(data.edit_subset.subset_state, RangeSubsetState) assert data.edit_subset.subset_state.att == self.client.xatt roi = RectangularROI() roi = YRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert data.edit_subset.subset_state.att == self.client.yatt
def test_mpl_roi(self): rect_roi = RectangularROI(1, 3.5, -0.2, 3.3) subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], AbstractMplRoi(None, rect_roi)) self.dc.new_subset_group(subset_state=subset_state, label='mpl_rectangular') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5)
def test_apply_roi(self): self.viewer.add_data(self.image1) roi = RectangularROI(0.4, 1.6, -0.6, 0.6) assert len(self.viewer.layers) == 1 self.viewer.apply_roi(roi) assert len(self.viewer.layers) == 2 assert len(self.image1.subsets) == 1 assert_allclose(self.image1.subsets[0].to_mask(), [[0, 1], [0, 0]]) state = self.image1.subsets[0].subset_state assert isinstance(state, RoiSubsetState)
def test_apply_roi(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi)
def build_spectrum(self): roi = RectangularROI() roi.update_limits(0, 2, 0, 2) self.tool._update_profile()