Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)