def update_profile(self, update_limits=True): if self._profile_cache is not None: return self._profile_cache if not self._viewer_callbacks_set: self.viewer_state.add_callback('x_att', self.reset_cache, priority=100000) self.viewer_state.add_callback('function', self.reset_cache, priority=100000) if self.is_callback_property('attribute'): self.add_callback('attribute', self.reset_cache, priority=100000) self._viewer_callbacks_set = True if self.viewer_state is None or self.viewer_state.x_att is None or self.attribute is None: raise IncompatibleDataException() # Check what pixel axis in the current dataset x_att corresponds to pix_cid = is_convertible_to_single_pixel_cid( self.layer, self.viewer_state.x_att_pixel) if pix_cid is None: raise IncompatibleDataException() # If we get here, then x_att does correspond to a single pixel axis in # the cube, so we now prepare a list of axes to collapse over. axes = tuple(i for i in range(self.layer.ndim) if i != pix_cid.axis) # We now get the y values for the data # TODO: in future we should optimize the case where the mask is much # smaller than the data to just average the relevant 'spaxels' in the # data rather than collapsing the whole cube. if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None profile_values = data.compute_statistic(self.viewer_state.function, self.attribute, axis=axes, subset_state=subset_state) if np.all(np.isnan(profile_values)): self._profile_cache = [], [] else: axis_view = [0] * data.ndim axis_view[pix_cid.axis] = slice(None) axis_values = data[self.viewer_state.x_att, tuple(axis_view)] self._profile_cache = axis_values, profile_values if update_limits: self.update_limits(update_profile=False)
def _on_collapse(self): if self.rng_mode.state.x_min is None or self.rng_mode.state.x_max is None: return func = self.collapse_function x_range = self.rng_mode.state.x_range for data in self._visible_data(): pix_cid = is_convertible_to_single_pixel_cid(data, self.viewer.state.x_att_pixel) for viewer in self._viewers_with_data_slice(data, pix_cid): slices = list(viewer.state.slices) # TODO: don't need to fetch axis twice axis, imin = self._get_axis_and_pixel_slice(data, x_range[0]) axis, imax = self._get_axis_and_pixel_slice(data, x_range[1]) current_slice = slices[axis] if isinstance(current_slice, AggregateSlice): current_slice = current_slice.center imin, imax = min(imin, imax), max(imin, imax) slices[axis] = AggregateSlice(slice(imin, imax), current_slice, func) viewer.state.slices = tuple(slices)
def _on_collapse(self): if self.rng_mode.state.x_min is None or self.rng_mode.state.x_max is None: return func = self.collapse_function x_range = self.rng_mode.state.x_range for data in self._visible_data(): pix_cid = is_convertible_to_single_pixel_cid(data, self.viewer.state.x_att) for viewer in self._viewers_with_data_slice(data, pix_cid): slices = list(viewer.state.slices) # TODO: don't need to fetch axis twice axis, imin = self._get_axis_and_pixel_slice(data, x_range[0]) axis, imax = self._get_axis_and_pixel_slice(data, x_range[1]) current_slice = slices[axis] if isinstance(current_slice, AggregateSlice): current_slice = current_slice.center slices[axis] = AggregateSlice(slice(imin, imax), current_slice, func) viewer.state.slices = tuple(slices)
def _on_nav_activate(self, *args): self._nav_data = self._visible_data() self._nav_viewers = {} for data in self._nav_data: pix_cid = is_convertible_to_single_pixel_cid( data, self.viewer.state.x_att) self._nav_viewers[data] = self._viewers_with_data_slice( data, pix_cid)
def _get_axis_and_pixel_slice(self, data, x): if self.viewer.state.x_att in data.pixel_component_ids: axis = self.viewer.state.x_att.axis slc = int(round(x)) else: pix_cid = is_convertible_to_single_pixel_cid(data, self.viewer.state.x_att_pixel) axis = pix_cid.axis axis_view = [0] * data.ndim axis_view[pix_cid.axis] = slice(None) axis_values = data[self.viewer.state.x_att, axis_view] slc = int(np.argmin(np.abs(axis_values - x))) return axis, slc
def _get_axis_and_pixel_slice(self, data, x): if self.viewer.state.x_att in data.pixel_component_ids: axis = self.viewer.state.x_att.axis slc = int(round(x)) else: pix_cid = is_convertible_to_single_pixel_cid(data, self.viewer.state.x_att) axis = pix_cid.axis axis_view = [0] * data.ndim axis_view[pix_cid.axis] = slice(None) axis_values = data[self.viewer.state.x_att, axis_view] slc = int(np.argmin(np.abs(axis_values - x))) return axis, slc
def update_profile(self, update_limits=True): if self._profile_cache is not None: return self._profile_cache if not self._viewer_callbacks_set: self.viewer_state.add_callback('x_att', self.reset_cache, priority=100000) self.viewer_state.add_callback('function', self.reset_cache, priority=100000) if self.is_callback_property('attribute'): self.add_callback('attribute', self.reset_cache, priority=100000) self._viewer_callbacks_set = True if self.viewer_state is None or self.viewer_state.x_att is None or self.attribute is None: raise IncompatibleDataException() # Check what pixel axis in the current dataset x_att corresponds to pix_cid = is_convertible_to_single_pixel_cid(self.layer, self.viewer_state.x_att_pixel) if pix_cid is None: raise IncompatibleDataException() # If we get here, then x_att does correspond to a single pixel axis in # the cube, so we now prepare a list of axes to collapse over. axes = tuple(i for i in range(self.layer.ndim) if i != pix_cid.axis) # We now get the y values for the data # TODO: in future we should optimize the case where the mask is much # smaller than the data to just average the relevant 'spaxels' in the # data rather than collapsing the whole cube. if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None profile_values = data.compute_statistic(self.viewer_state.function, self.attribute, axis=axes, subset_state=subset_state) if np.all(np.isnan(profile_values)): self._profile_cache = [], [] else: axis_view = [0] * data.ndim axis_view[pix_cid.axis] = slice(None) axis_values = data[self.viewer_state.x_att, tuple(axis_view)] self._profile_cache = axis_values, profile_values if update_limits: self.update_limits(update_profile=False)
def _update_profile(self, *event): if self.viewer_state is None or self.viewer_state.x_att is None or self.attribute is None: self._profile = None, None return # Check what pixel axis in the current dataset x_att corresponds to pix_cid = is_convertible_to_single_pixel_cid(self.layer, self.viewer_state.x_att) if pix_cid is None: self._profile = None, None return # If we get here, then x_att does correspond to a single pixel axis in # the cube, so we now prepare a list of axes to collapse over. axes = tuple(i for i in range(self.layer.ndim) if i != pix_cid.axis) # We now get the y values for the data # TODO: in future we should optimize the case where the mask is much # smaller than the data to just average the relevant 'spaxels' in the # data rather than collapsing the whole cube. try: if isinstance(self.layer, Data): data = self.layer data_values = data[self.attribute] else: data = self.layer.data if isinstance(self.layer.subset_state, SliceSubsetState): data_values = self.layer.subset_state.to_array( self.layer.data, self.attribute) else: # We need to force a copy *and* convert to float just in case data_values = np.array(data[self.attribute], dtype=float) mask = self.layer.to_mask() if np.sum(mask) == 0: self._profile = [], [] return data_values[~mask] = np.nan except IncompatibleAttribute: self._profile = None, None return # Collapse along all dimensions except x_att if self.layer.ndim > 1: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) profile_values = self.viewer_state.function(data_values, axis=axes) else: profile_values = data_values # Finally, we get the coordinate values for the requested axis axis_view = [0] * data.ndim axis_view[pix_cid.axis] = slice(None) axis_values = data[self.viewer_state.x_att, axis_view] with delay_callback(self, 'v_min', 'v_max'): self._profile = axis_values, profile_values self.v_min = nanmin(profile_values) self.v_max = nanmax(profile_values)
def independent_x_att(self): return is_convertible_to_single_pixel_cid( self.layer, self.viewer_state.x_att) is not None
def _on_nav_activate(self, *args): self._nav_data = self._visible_data() self._nav_viewers = {} for data in self._nav_data: pix_cid = is_convertible_to_single_pixel_cid(data, self.viewer.state.x_att) self._nav_viewers[data] = self._viewers_with_data_slice(data, pix_cid)
def independent_x_att(self): return is_convertible_to_single_pixel_cid(self.layer, self.viewer_state.x_att) is not None