def update_components(self, mapping): """ Change the numerical data associated with some of the Components in this Data object. All changes to component numerical data should use this method, which broadcasts the state change to the appropriate places. :param mapping: A dict mapping Components or ComponenIDs to arrays. This method has the following restrictions: - New compoments must have the same shape as old compoments - Component subclasses cannot be updated. """ for comp, data in mapping.items(): if isinstance(comp, ComponentID): comp = self.get_component(comp) data = np.asarray(data) if data.shape != self.shape: raise ValueError("Cannot change shape of data") comp._data = data # alert hub of the change if self.hub is not None: msg = NumericalDataChangedMessage(self) self.hub.broadcast(msg) for subset in self.subsets: clear_cache(subset.subset_state.to_mask)
def indices(self, value): if len(value) != self._original_data.ndim: raise ValueError( "The 'indices' tuple should have length {0}".format( self._original_data.ndim)) # For now we require the indices to be in the same position, i.e. we # don't allow changes in dimensionality of the derived dataset. if hasattr(self, '_indices'): changed = False for idim in range(self._original_data.ndim): before, after = self._indices[idim], value[idim] if type(before) != type(after): raise TypeError( "Can't change where the ``None`` values are in indices" ) elif before != after: changed = True else: changed = False self._indices = value # Compute a subset state that represents the indexing - this is used # for compute_statistic and compute_histogram slices = [slice(x) if x is None else x for x in self._indices] self._indices_subset_state = SliceSubsetState(self._original_data, slices) # Construct a list of original pixel component IDs self._original_pixel_cids = [] for idim in range(self._original_data.ndim): if self._indices[idim] is None: self._original_pixel_cids.append( self._original_data.pixel_component_ids[idim]) # Construct a list of original world component IDs self._original_world_cids = [] if len(self._original_data.world_component_ids) > 0: idim_new = 0 for idim in range(self._original_data.ndim): if self._indices[idim] is None: self._cid_to_original_cid[self.world_component_ids[ idim_new]] = self._original_data.world_component_ids[ idim] idim_new += 1 # Tell glue that the data has changed if changed and self.hub is not None: msg = NumericalDataChangedMessage(self) self.hub.broadcast(msg)
def accept(self): for data in self._components: cids_main = self._components[data]['main'] cids_derived = self._components[data]['derived'] cids_other = self._components[data]['other'] # First deal with renaming of components for cid_new in cids_main + cids_derived: label = self._state[data][cid_new]['label'] if label != cid_new.label: cid_new.label = label cids_all = data.pixel_component_ids + data.world_component_ids + cids_main + cids_derived + cids_other cids_existing = data.components for cid_old in cids_existing: if not any(cid_old is cid_new for cid_new in cids_all): data.remove_component(cid_old) components = dict((cid.uuid, cid) for cid in data.components) for cid_new in cids_derived: if any(cid_new is cid_old for cid_old in cids_existing): comp = data.get_component(cid_new) if comp.link._parsed._cmd != self._state[data][cid_new][ 'equation']._cmd: comp.link._parsed._cmd = self._state[data][cid_new][ 'equation']._cmd comp.link._parsed._references = components if data.hub: msg = NumericalDataChangedMessage(data) data.hub.broadcast(msg) else: pc = ParsedCommand( self._state[data][cid_new]['equation']._cmd, components) link = ParsedComponentLink(cid_new, pc) data.add_component_link(link) data.reorder_components(cids_all) super(ComponentManagerWidget, self).accept()
def accept(self): for data in self._components_derived: cids_derived = self._components_derived[data] cids_other = self._components_other[data] cids_all = cids_other + cids_derived cids_existing = data.components components = dict((cid.uuid, cid) for cid in data.components) # First deal with renaming of components for cid_new in cids_derived: label = self._state[data][cid_new]['label'] if label != cid_new.label: cid_new.label = label # Second deal with the removal of components for cid_old in cids_existing: if not any(cid_old is cid_new for cid_new in cids_all): data.remove_component(cid_old) # Third, update/add arithmetic expressions as needed for cid_new in cids_derived: if any(cid_new is cid_old for cid_old in cids_existing): comp = data.get_component(cid_new) if comp.link._parsed._cmd != self._state[data][cid_new][ 'equation']._cmd: comp.link._parsed._cmd = self._state[data][cid_new][ 'equation']._cmd comp.link._parsed._references = components if data.hub: msg = NumericalDataChangedMessage(data) data.hub.broadcast(msg) else: pc = ParsedCommand( self._state[data][cid_new]['equation']._cmd, components) link = ParsedComponentLink(cid_new, pc) data.add_component_link(link) # Findally, reorder components as needed data.reorder_components(cids_all) super(ArithmeticEditorWidget, self).accept()
def update_values_from_data(self, data): """ Replace numerical values in data to match values from another dataset. Notes ----- This method drops components that aren't present in the new data, and adds components that are in the new data that were not in the original data. The matching is done by component label, and components are resized if needed. This means that for components with matching labels in the original and new data, the :class:`~glue.core.component_id.ComponentID` are preserved, and existing plots and selections will be updated to reflect the new values. Note that the coordinates are also copied, but the style is **not** copied. """ old_labels = [cid.label for cid in self.components] new_labels = [cid.label for cid in data.components] if len(old_labels) == len(set(old_labels)): old_labels = set(old_labels) else: raise ValueError("Non-unique component labels in original data") if len(new_labels) == len(set(new_labels)): new_labels = set(new_labels) else: raise ValueError("Non-unique component labels in new data") # Remove components that don't have a match in new data for cname in old_labels - new_labels: cid = self.find_component_id(cname) self.remove_component(cid) # Update shape self._shape = data._shape # Update components that exist in both. Note that we can't just loop # over old_labels & new_labels since we need to make sure we preserve # the order of the components, and sets don't preserve order. for cid in self.components: cname = cid.label if cname in old_labels & new_labels: comp_old = self.get_component(cname) comp_new = data.get_component(cname) comp_old._data = comp_new._data # Add components that didn't exist in original one. As above, we try # and preserve the order of components as much as possible. for cid in data.components: cname = cid.label if cname in new_labels - old_labels: cid = data.find_component_id(cname) comp_new = data.get_component(cname) self.add_component(comp_new, cid.label) # Update data label self.label = data.label # Update data coordinates self.coords = data.coords # alert hub of the change if self.hub is not None: msg = NumericalDataChangedMessage(self) self.hub.broadcast(msg) for subset in self.subsets: clear_cache(subset.subset_state.to_mask)
def _check_for_original_changes(self, message): # If the parent's values are changed, we should assume the values # of the current dataset have changed too if message.data is self._original_data: msg = NumericalDataChangedMessage(self) self.hub.broadcast(msg)
def set_step(self, step_id): self.data_collection[0].current_step = step_id self.ui.text_step.setText("{0:6d}".format(step_id)) msg = NumericalDataChangedMessage(self.data_collection[0]) self.data_collection.hub.broadcast(msg)