class MatplotlibDataViewerState(State): """ A base class that includes common attributes for viewers based on Matplotlib. """ x_min = DeferredDrawCallbackProperty( docstring='Lower limit of the visible x range') x_max = DeferredDrawCallbackProperty( docstring='Upper limit of the visible x range') y_min = DeferredDrawCallbackProperty( docstring='Lower limit of the visible y range') y_max = DeferredDrawCallbackProperty( docstring='Upper limit of the visible y range') x_log = DeferredDrawCallbackProperty( False, docstring='Whether the x axis is logarithmic') y_log = DeferredDrawCallbackProperty( False, docstring='Whether the y axis is logarithmic') aspect = DeferredDrawCallbackProperty( 'auto', docstring='Aspect ratio for the axes') layers = ListCallbackProperty( docstring='A collection of all layers in the viewer') @property def layers_data(self): return [layer_state.layer for layer_state in self.layers]
class OpenSpaceViewerState(ViewerState): mode = SelectionCallbackProperty(default_index=0) frame = SelectionCallbackProperty(default_index=0) lon_att = SelectionCallbackProperty(default_index=0) lat_att = SelectionCallbackProperty(default_index=1) alt_att = SelectionCallbackProperty(default_index=2) alt_unit = SelectionCallbackProperty(default_index=4) alt_type = SelectionCallbackProperty(default_index=0) layers = ListCallbackProperty() def __init__(self, **kwargs): super(OpenSpaceViewerState, self).__init__() OpenSpaceViewerState.mode.set_choices(self, MODES) OpenSpaceViewerState.frame.set_choices(self, CELESTIAL_FRAMES) OpenSpaceViewerState.alt_unit.set_choices(self, [str(x) for x in ALT_UNITS]) OpenSpaceViewerState.alt_type.set_choices(self, ALT_TYPES) self.lon_att_helper = ComponentIDComboHelper(self, 'lon_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False) self.lat_att_helper = ComponentIDComboHelper(self, 'lat_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False) self.alt_att_helper = ComponentIDComboHelper(self, 'alt_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False) self.add_callback('layers', self._on_layers_changed) self._on_layers_changed() self.update_from_dict(kwargs) def _on_layers_changed(self, *args): self.lon_att_helper.set_multiple_data(self.layers_data) self.lat_att_helper.set_multiple_data(self.layers_data) self.alt_att_helper.set_multiple_data(self.layers_data) def _update_priority(self, name): if name == 'layers': return 2 else: return 0
class ViewerState(State): """ A base class for all viewer states. """ layers = ListCallbackProperty(docstring='A collection of all layers in the viewer') @property def layers_data(self): return [layer_state.layer for layer_state in self.layers]
class WWTDataViewerState(State): foreground = SelectionCallbackProperty(default_index=0) background = SelectionCallbackProperty(default_index=1) foreground_opacity = CallbackProperty(50) galactic = CallbackProperty(False) layers = ListCallbackProperty() def __init__(self, **kwargs): super(WWTDataViewerState, self).__init__() self.add_callback('layers', self._sync_all_attributes) self.update_from_dict(kwargs) def set_imagery_layers(self, imagery_layers): WWTDataViewerState.foreground.set_choices(self, imagery_layers) WWTDataViewerState.background.set_choices(self, imagery_layers) def _sync_attributes_single(self, reference, layer_state): with delay_callback(layer_state, 'ra_att', 'dec_att'): layer_state.ra_att = reference.ra_att layer_state.dec_att = reference.dec_att def _sync_all_attributes(self, layers=None, reference=None): # Make sure attributes are in sync between datasets and subsets if reference is None: data_layers = [ layer for layer in self.layers if isinstance(layer, Data) ] subset_layers = [ layer for layer in self.layers if isinstance(layer, Subset) ] for data_layer in data_layers: for subset_layer in subset_layers: self._sync_attributes_single(data_layer, subset_layer) elif isinstance(reference.layer, Data): reference_data = reference.layer for layer_state in self.layers: if isinstance( layer_state.layer, Subset) and layer_state.layer.data is reference.layer: self._sync_attributes_single(reference, layer_state) elif isinstance(reference.layer, Subset): reference_data = reference.layer.data for layer_state in self.layers: if isinstance(layer_state.layer, Data) and layer_state.layer is reference_data: self._sync_attributes_single(reference, layer_state) elif isinstance( layer_state.layer, Subset) and layer_state.layer.data is reference_data: self._sync_attributes_single(reference, layer_state)
class MatplotlibDataViewerState(State): x_min = DeferredDrawCallbackProperty() x_max = DeferredDrawCallbackProperty() y_min = DeferredDrawCallbackProperty() y_max = DeferredDrawCallbackProperty() x_log = DeferredDrawCallbackProperty(False) y_log = DeferredDrawCallbackProperty(False) layers = ListCallbackProperty()
class SimpleTestState(State): a = CallbackProperty() b = CallbackProperty() flat = ListCallbackProperty() nested = ListCallbackProperty()
class Vispy3DViewerState(State): """ A common state object for all vispy 3D viewers """ x_att = SelectionCallbackProperty() x_min = CallbackProperty(0) x_max = CallbackProperty(1) x_stretch = CallbackProperty(1.) y_att = SelectionCallbackProperty(default_index=1) y_min = CallbackProperty(0) y_max = CallbackProperty(1) y_stretch = CallbackProperty(1.) z_att = SelectionCallbackProperty(default_index=2) z_min = CallbackProperty(0) z_max = CallbackProperty(1) z_stretch = CallbackProperty(1.) visible_axes = CallbackProperty(True) perspective_view = CallbackProperty(False) clip_data = CallbackProperty(True) native_aspect = CallbackProperty(False) layers = ListCallbackProperty() limits_cache = CallbackProperty() def _update_priority(self, name): if name == 'layers': return 2 elif name.endswith(('_min', '_max')): return 0 else: return 1 def __init__(self, **kwargs): super(Vispy3DViewerState, self).__init__(**kwargs) if self.limits_cache is None: self.limits_cache = {} self.x_lim_helper = StateAttributeLimitsHelper(self, attribute='x_att', lower='x_min', upper='x_max', cache=self.limits_cache) self.y_lim_helper = StateAttributeLimitsHelper(self, attribute='y_att', lower='y_min', upper='y_max', cache=self.limits_cache) self.z_lim_helper = StateAttributeLimitsHelper(self, attribute='z_att', lower='z_min', upper='z_max', cache=self.limits_cache) # TODO: if limits_cache is re-assigned to a different object, we need to # update the attribute helpers. However if in future we make limits_cache # into a smart dictionary that can call callbacks when elements are # changed then we shouldn't always call this. It'd also be nice to # avoid this altogether and make it more clean. self.add_callback('limits_cache', self._update_limits_cache) def reset_limits(self): self.x_lim_helper.log = False self.x_lim_helper.percentile = 100. self.x_lim_helper.update_values(force=True) self.y_lim_helper.log = False self.y_lim_helper.percentile = 100. self.y_lim_helper.update_values(force=True) self.z_lim_helper.log = False self.z_lim_helper.percentile = 100. self.z_lim_helper.update_values(force=True) def _update_limits_cache(self, *args): self.x_lim_helper._cache = self.limits_cache self.x_lim_helper._update_attribute() self.y_lim_helper._cache = self.limits_cache self.y_lim_helper._update_attribute() self.z_lim_helper._cache = self.limits_cache self.z_lim_helper._update_attribute() @property def aspect(self): # TODO: this could be cached based on the limits, but is not urgent aspect = np.array([1, 1, 1], dtype=float) if self.native_aspect: aspect[0] = 1. aspect[1] = (self.y_max - self.y_min) / (self.x_max - self.x_min) aspect[2] = (self.z_max - self.z_min) / (self.x_max - self.x_min) aspect /= aspect.max() return aspect def reset(self): pass def flip_x(self): self.x_lim_helper.flip_limits() def flip_y(self): self.y_lim_helper.flip_limits() def flip_z(self): self.z_lim_helper.flip_limits() @property def clip_limits(self): return (self.x_min, self.x_max, self.y_min, self.y_max, self.z_min, self.z_max) def set_limits(self, x_min, x_max, y_min, y_max, z_min, z_max): with delay_callback(self, 'x_min', 'x_max', 'y_min', 'y_max', 'z_min', 'z_max'): self.x_min = x_min self.x_max = x_max self.y_min = y_min self.y_max = y_max self.z_min = z_min self.z_max = z_max
class AladinLiteState(State): ra_att = CallbackProperty() dec_att = CallbackProperty() layers = ListCallbackProperty()
class MatplotlibDataViewerState(State): """ A base class that includes common attributes for viewers based on Matplotlib. """ x_min = DeferredDrawCallbackProperty( docstring='Lower limit of the visible x range') x_max = DeferredDrawCallbackProperty( docstring='Upper limit of the visible x range') y_min = DeferredDrawCallbackProperty( docstring='Lower limit of the visible y range') y_max = DeferredDrawCallbackProperty( docstring='Upper limit of the visible y range') x_log = DeferredDrawCallbackProperty( False, docstring='Whether the x axis is logarithmic') y_log = DeferredDrawCallbackProperty( False, docstring='Whether the y axis is logarithmic') aspect = DeferredDrawCallbackProperty( 'auto', docstring='Aspect ratio for the axes') x_axislabel = DeferredDrawCallbackProperty( '', docstring='Label for the x-axis') y_axislabel = DeferredDrawCallbackProperty( '', docstring='Label for the y-axis') x_axislabel_size = DeferredDrawCallbackProperty( 10, docstring='Size of the x-axis label') y_axislabel_size = DeferredDrawCallbackProperty( 10, docstring='Size of the y-axis label') x_axislabel_weight = DeferredDrawSelectionCallbackProperty( 1, docstring='Weight of the x-axis label') y_axislabel_weight = DeferredDrawSelectionCallbackProperty( 1, docstring='Weight of the y-axis label') x_ticklabel_size = DeferredDrawCallbackProperty( 8, docstring='Size of the x-axis tick labels') y_ticklabel_size = DeferredDrawCallbackProperty( 8, docstring='Size of the y-axis tick labels') layers = ListCallbackProperty( docstring='A collection of all layers in the viewer') def __init__(self, *args, **kwargs): MatplotlibDataViewerState.x_axislabel_weight.set_choices( self, VALID_WEIGHTS) MatplotlibDataViewerState.y_axislabel_weight.set_choices( self, VALID_WEIGHTS) super(MatplotlibDataViewerState, self).__init__(*args, **kwargs) def update_axes_settings_from(self, state): self.x_axislabel_size = state.x_axislabel_size self.y_axislabel_size = state.y_axislabel_size self.x_axislabel_weight = state.x_axislabel_weight self.y_axislabel_weight = state.y_axislabel_weight self.x_ticklabel_size = state.x_ticklabel_size self.y_ticklabel_size = state.y_ticklabel_size @property def layers_data(self): return [layer_state.layer for layer_state in self.layers] @defer_draw def _notify_global(self, *args, **kwargs): super(MatplotlibDataViewerState, self)._notify_global(*args, **kwargs)
class WWTDataViewerState(ViewerState): mode = SelectionCallbackProperty(default_index=0) frame = SelectionCallbackProperty(default_index=0) lon_att = SelectionCallbackProperty(default_index=0) lat_att = SelectionCallbackProperty(default_index=1) alt_att = SelectionCallbackProperty(default_index=0) alt_unit = SelectionCallbackProperty(default_index=0) alt_type = SelectionCallbackProperty(default_index=0) foreground = SelectionCallbackProperty(default_index=1) foreground_opacity = CallbackProperty(1) background = SelectionCallbackProperty(default_index=8) galactic = CallbackProperty(False) layers = ListCallbackProperty() # For now we need to include this here otherwise when loading files, the # imagery layers are only available asynchronously and the session loading # fails. imagery_layers = ListCallbackProperty() def __init__(self, **kwargs): super(WWTDataViewerState, self).__init__() WWTDataViewerState.mode.set_choices(self, ['Sky'] + MODES_3D + MODES_BODIES) WWTDataViewerState.frame.set_choices(self, CELESTIAL_FRAMES) WWTDataViewerState.alt_unit.set_choices(self, [str(x) for x in ALT_UNITS]) WWTDataViewerState.alt_type.set_choices(self, ALT_TYPES) self.add_callback('imagery_layers', self._update_imagery_layers) self.lon_att_helper = ComponentIDComboHelper(self, 'lon_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False) self.lat_att_helper = ComponentIDComboHelper(self, 'lat_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False) self.alt_att_helper = ComponentIDComboHelper(self, 'alt_att', numeric=True, categorical=False, world_coord=True, pixel_coord=False, none='None') self.add_callback('layers', self._on_layers_changed) self._on_layers_changed() self.update_from_dict(kwargs) def _on_layers_changed(self, *args): self.lon_att_helper.set_multiple_data(self.layers_data) self.lat_att_helper.set_multiple_data(self.layers_data) self.alt_att_helper.set_multiple_data(self.layers_data) def _update_imagery_layers(self, *args): WWTDataViewerState.foreground.set_choices(self, self.imagery_layers) WWTDataViewerState.background.set_choices(self, self.imagery_layers) def _update_priority(self, name): if name == 'layers': return 2 elif name == 'imagery_layers': return 1 else: return 0
class CustomState(State): a = CallbackProperty(1) b = CallbackProperty(2) sub = ListCallbackProperty()