def add_coordset(self, *coords, dims=None, **kwargs): """ Add one or a set of coordinates from a dataset. Parameters ---------- *coords : iterable Coordinates object(s). dims : list Name of the coordinates. **kwargs Optional keyword parameters passed to the coordset. """ if not coords and not kwargs: # reset coordinates self._coordset = None return if self._coordset is None: # make the whole coordset at once self._coordset = CoordSet(*coords, dims=dims, **kwargs) else: # add one coordinate self._coordset._append(*coords, **kwargs) if self._coordset: # set a notifier to the updated traits of the CoordSet instance HasTraits.observe(self._coordset, self._dims_update, "_updated") # force it one time after this initialization self._coordset._updated = True
def _create_output_widget(self, outputs: HasTraits) -> Widget: print("Creating output widget") output = Output() def output_value_changed(change): output.clear_output() with output: print("XXXXXXXXXXXXXX") print(change.new) outputs.observe(output_value_changed, names=All) return output
def __init__(self, *coords, **kwargs): self._copy = kwargs.pop("copy", True) self._sorted = kwargs.pop("sorted", True) keepnames = kwargs.pop("keepnames", False) # if keepnames is false and the names of the dimensions are not passed in kwargs, then use dims if not none dims = kwargs.pop("dims", None) self.name = kwargs.pop("name", None) # initialise the coordinate list self._coords = [] # First evaluate passed args # -------------------------- # some cleaning if coords: if all([(isinstance(coords[i], (np.ndarray, NDArray, list, CoordSet)) or coords[i] is None) for i in range(len(coords))]): # Any instance of a NDArray can be accepted as coordinates for a dimension. # If an instance of CoordSet is found, this means that all # coordinates in this set describe the same axis coords = tuple(coords) elif is_sequence(coords) and len(coords) == 1: # if isinstance(coords[0], list): # coords = (CoordSet(*coords[0], sorted=False),) # else: coords = coords[0] if isinstance(coords, dict): # we have passed a dict, postpone to the kwargs evaluation process kwargs.update(coords) coords = None else: raise ValueError("Did not understand the inputs") # now store the args coordinates in self._coords (validation is fired when this attribute is set) if coords: for coord in coords[::-1]: # we fill from the end of the list # (in reverse order) because by convention when the # names are not specified, the order of the # coords follow the order of dims. if not isinstance(coord, CoordSet): if isinstance(coord, list): coord = CoordSet(*coord[::-1], sorted=False) elif not isinstance(coord, LinearCoord): # else coord = Coord(coord, copy=True) else: coord = cpy.deepcopy(coord) if not keepnames: if dims is None: # take the last available name of available names list coord.name = self.available_names.pop(-1) else: # use the provided list of dims coord.name = dims.pop(-1) self._append(coord) # append the coord (but instead of append, # use assignation -in _append - to fire the validation process ) # now evaluate keywords argument # ------------------------------ for key, coord in list(kwargs.items())[:]: # remove the already used kwargs (Fix: deprecation warning in Traitlets - all args, kwargs must be used) del kwargs[key] # prepare values to be either Coord, LinearCoord or CoordSet if isinstance(coord, (list, tuple)): coord = CoordSet( *coord, sorted=False ) # make sure in this case it becomes a CoordSet instance elif isinstance(coord, np.ndarray) or coord is None: coord = Coord( coord, copy=True ) # make sure it's a Coord # (even if it is None -> Coord(None) elif isinstance(coord, str) and coord in DEFAULT_DIM_NAME: # may be a reference to another coordinates (e.g. same coordinates for various dimensions) self._references[key] = coord # store this reference continue # Populate the coords with coord and coord's name. if isinstance(coord, (NDArray, Coord, LinearCoord, CoordSet)): # NDArray, if key in self.available_names or ( len(key) == 2 and key.startswith("_") and key[1] in list("123456789")): # ok we can find it as a canonical name: # this will overwrite any already defined coord value # which means also that kwargs have priority over args coord.name = key self._append(coord) elif not self.is_empty and key in self.names: # append when a coordinate with this name is already set in passed arg. # replace it idx = self.names.index(key) coord.name = key self._coords[idx] = coord else: raise KeyError( f"Probably an invalid key (`{key}`) for coordinates has been passed. " f"Valid keys are among:{DEFAULT_DIM_NAME}") else: raise ValueError( f"Probably an invalid type of coordinates has been passed: {key}:{coord} " ) # store the item (validation will be performed) # self._coords = _coords # inform the parent about the update self._updated = True # set a notifier on the name traits name of each coordinates for coord in self._coords: if coord is not None: HasTraits.observe(coord, self._coords_update, "_name") # initialize the base class with the eventual remaining arguments super().__init__(**kwargs)
def __init__(self, *coords, **kwargs): """ A collection of Coord objects for a NDArray object with validation. This object is an iterable containing a collection of Coord objects. Parameters ---------- *coords : |NDarray|, |NDArray| subclass or |CoordSet| sequence of objects. If an instance of CoordSet is found, instead of an array, this means that all coordinates in this coords describe the same axis. It is assumed that the coordinates are passed in the order of the dimensions of a nD numpy array ( `row-major <https://docs.scipy.org/doc/numpy-1.14.1/glossary.html#term-row-major>`_ order), i.e., for a 3d object : 'z', 'y', 'x'. **kwargs: dict See other parameters. Other Parameters ---------------- x : |NDarray|, |NDArray| subclass or |CoordSet| A single coordinate associated to the 'x'-dimension. If a coord was already passed in the argument, this will overwrite the previous. It is thus not recommended to simultaneously use both way to initialize the coordinates to avoid such conflicts. y, z, u, ... : |NDarray|, |NDArray| subclass or |CoordSet| Same as `x` for the others dimensions. dims : list of string, optional Names of the dims to use corresponding to the coordinates. If not given, standard names are used: x, y, ... See Also -------- Coord : Explicit coordinates object. LinearCoord : Implicit coordinates object. NDDataset: The main object of SpectroChempy which makes use of CoordSet. Examples -------- >>> from spectrochempy import Coord, CoordSet Define 4 coordinates, with two for the same dimension >>> coord0 = Coord.linspace(10., 100., 5, units='m', title='distance') >>> coord1 = Coord.linspace(20., 25., 4, units='K', title='temperature') >>> coord1b = Coord.linspace(1., 10., 4, units='millitesla', title='magnetic field') >>> coord2 = Coord.linspace(0., 1000., 6, units='hour', title='elapsed time') Now create a coordset >>> cs = CoordSet(t=coord0, u=coord2, v=[coord1, coord1b]) Display some coordinates >>> cs.u Coord: [float64] hr (size: 6) >>> cs.v CoordSet: [_1:temperature, _2:magnetic field] >>> cs.v_1 Coord: [float64] K (size: 4) """ self._copy = kwargs.pop('copy', True) self._sorted = kwargs.pop('sorted', True) keepnames = kwargs.pop('keepnames', False) # if keepnames is false and the names of the dimensions are not passed in kwargs, then use dims if not none dims = kwargs.pop('dims', None) self.name = kwargs.pop('name', None) # initialise the coordinate list self._coords = [] # First evaluate passed args # -------------------------- # some cleaning if coords: if all([(isinstance(coords[i], (np.ndarray, NDArray, list, CoordSet)) or coords[i] is None) for i in range(len(coords))]): # Any instance of a NDArray can be accepted as coordinates for a dimension. # If an instance of CoordSet is found, this means that all # coordinates in this set describe the same axis coords = tuple(coords) elif is_sequence(coords) and len(coords) == 1: # if isinstance(coords[0], list): # coords = (CoordSet(*coords[0], sorted=False),) # else: coords = coords[0] if isinstance(coords, dict): # we have passed a dict, postpone to the kwargs evaluation process kwargs.update(coords) coords = None else: raise ValueError('Did not understand the inputs') # now store the args coordinates in self._coords (validation is fired when this attribute is set) if coords: for coord in coords[::-1]: # we fill from the end of the list # (in reverse order) because by convention when the # names are not specified, the order of the # coords follow the order of dims. if not isinstance(coord, CoordSet): if isinstance(coord, list): coord = CoordSet(*coord, sorted=False) elif not isinstance(coord, LinearCoord): # else coord = Coord(coord, copy=True) else: coord = cpy.deepcopy(coord) if not keepnames: if dims is None: # take the last available name of available names list coord.name = self.available_names.pop(-1) else: # use the provided list of dims coord.name = dims.pop(-1) self._append(coord) # append the coord (but instead of append, # use assignation -in _append - to fire the validation process ) # now evaluate keywords argument # ------------------------------ for key, coord in list(kwargs.items())[:]: # remove the already used kwargs (Fix: deprecation warning in Traitlets - all args, kwargs must be used) del kwargs[key] # prepare values to be either Coord, LinearCoord or CoordSet if isinstance(coord, (list, tuple)): coord = CoordSet( *coord, sorted=False ) # make sure in this case it becomes a CoordSet instance elif isinstance(coord, np.ndarray) or coord is None: coord = Coord( coord, copy=True ) # make sure it's a Coord # (even if it is None -> Coord(None) elif isinstance(coord, str) and coord in DEFAULT_DIM_NAME: # may be a reference to another coordinates (e.g. same coordinates for various dimensions) self._references[key] = coord # store this reference continue # Populate the coords with coord and coord's name. if isinstance(coord, (NDArray, Coord, LinearCoord, CoordSet)): # NDArray, if key in self.available_names or ( len(key) == 2 and key.startswith('_') and key[1] in list("123456789")): # ok we can find it as a canonical name: # this will overwrite any already defined coord value # which means also that kwargs have priority over args coord.name = key self._append(coord) elif not self.is_empty and key in self.names: # append when a coordinate with this name is already set in passed arg. # replace it idx = self.names.index(key) coord.name = key self._coords[idx] = coord else: raise KeyError( f'Probably an invalid key (`{key}`) for coordinates has been passed. ' f'Valid keys are among:{DEFAULT_DIM_NAME}') else: raise ValueError( f'Probably an invalid type of coordinates has been passed: {key}:{coord} ' ) # store the item (validation will be performed) # self._coords = _coords # inform the parent about the update self._updated = True # set a notifier on the name traits name of each coordinates for coord in self._coords: if coord is not None: HasTraits.observe(coord, self._coords_update, '_name') # initialize the base class with the eventual remaining arguments super().__init__(**kwargs)