def apply_roi(self, roi): # every editable subset is updated # using specified ROI if isinstance(roi, RangeROI): lo, hi = roi.range() att = self.xatt if roi.ori == 'x' else self.yatt if self._check_categorical(att): comp = list(self._get_data_components(roi.ori)) if comp: subset_state = CategoricalRoiSubsetState.from_range(comp[0], att, lo, hi) else: subset_state = None else: subset_state = RangeSubsetState(lo, hi, att) else: if self._check_categorical(self.xatt) or self._check_categorical(self.yatt): subset_state = self._process_categorical_roi(roi) else: subset_state = RoiSubsetState() subset_state.xatt = self.xatt subset_state.yatt = self.yatt x, y = roi.to_polygon() subset_state.roi = PolygonalROI(x, y) mode = EditSubsetMode() visible = [d for d in self._data if self.is_visible(d)] focus = visible[0] if len(visible) > 0 else None mode.update(self._data, subset_state, focus_data=focus)
def apply_roi(self, roi): x, _ = roi.to_polygon() lo = min(x) hi = max(x) # expand roi to match bin edges bins = self.bins if lo >= bins.min(): lo = bins[bins <= lo].max() if hi <= bins.max(): hi = bins[bins >= hi].min() if self.xlog: lo = 10 ** lo hi = 10 ** hi comp = list(self._get_data_components('x')) if comp: comp = comp[0] if comp.categorical: state = CategoricalRoiSubsetState.from_range(comp, self.component, lo, hi) else: state = RangeSubsetState(lo, hi) state.att = self.component mode = EditSubsetMode() visible = [d for d in self.data if self.is_layer_visible(d)] focus = visible[0] if len(visible) > 0 else None mode.update(self.data, state, focus_data=focus)
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 test_invalid_range_subset(self): subset_state = RangeSubsetState(0, 1, self.data.main_components[0]) self.dc.new_subset_group(subset_state=subset_state, label='invalidrange') with pytest.raises(ValueError) as exc: self.data.get_selection_definition(format='astropy-regions') expect_message = 'Range subset state att should be either x or y pixel coordinate' assert exc.value.args[0] == expect_message
def test_vert_range_subset(self): subset_state = RangeSubsetState(105.5, 107.7, self.data.pixel_component_ids[0]) self.dc.new_subset_group(subset_state=subset_state, label='vertrange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 128) assert_allclose(reg.center.y, 106.6) assert_allclose(reg.width, 256) assert_allclose(reg.height, 2.2)
def test_horiz_range_subset(self): subset_state = RangeSubsetState(26, 27.5, self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=subset_state, label='horizrange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 26.75) assert_allclose(reg.center.y, 64) assert_allclose(reg.width, 1.5) assert_allclose(reg.height, 128)
def _process_categorical_roi(self, roi): """ Returns a RoiSubsetState object. """ if isinstance(roi, RectangularROI): subsets = [] axes = [('x', roi.xmin, roi.xmax), ('y', roi.ymin, roi.ymax)] for coord, lo, hi in axes: comp = list(self._get_data_components(coord)) if comp: if comp[0].categorical: subset = CategoricalROISubsetState.from_range( comp[0], self._get_attribute(coord), lo, hi) else: subset = RangeSubsetState(lo, hi, self._get_attribute(coord)) else: subset = None subsets.append(subset) else: raise AssertionError return AndState(*subsets)
def _load_range_subset_state(rec, context): return RangeSubsetState(rec['lo'], rec['hi'], context.object(rec['att']))
def subset_from_roi(self, att, roi, other_comp=None, other_att=None, coord='x'): """ Create a SubsetState object from an ROI. This encapsulates the logic for creating subset states with Components. See the documentation for CategoricalComponents for caveats involved with mixed-type plots. :param att: attribute name of this Component :param roi: an ROI object :param other_comp: The other Component for 2D ROIs :param other_att: The attribute name of the other Component :param coord: The orientation of this Component :param is_nested: True if this was passed from another Component. :return: A SubsetState (or subclass) object """ if coord not in ('x', 'y'): raise ValueError('coord should be one of x/y') other_coord = 'y' if coord == 'x' else 'x' if isinstance(roi, RangeROI): # The selection is either an x range or a y range if roi.ori == coord: # The selection applies to the current component lo, hi = roi.range() subset_state = RangeSubsetState(lo, hi, att) else: # The selection applies to the other component, so we delegate return other_comp.subset_from_roi(other_att, roi, other_comp=self, other_att=att, coord=other_coord) else: # The selection is polygon-like. Categorical components require # special care, so if the other component is categorical, we need to # delegate to CategoricalComponent.subset_from_roi. if isinstance(other_comp, CategoricalComponent): return other_comp.subset_from_roi(other_att, roi, other_comp=self, other_att=att, is_nested=True, coord=other_coord) else: subset_state = RoiSubsetState() subset_state.xatt = att subset_state.yatt = other_att x, y = roi.to_polygon() subset_state.roi = PolygonalROI(x, y) return subset_state