示例#1
0
def test_append(ax0, ax1):
    # test copy/ref behaviour when appending an object
    axes = Axes()
    axes.append(ax0)
    assert ax0 is axes[0]
    axes.append(ax1)
    assert ax1 is axes[1]
示例#2
0
    def __init__(self, values=None, axes=None, time=None, lat=None, lon=None, **kwargs):
        """ 
        """
        keyword = (time is not None or lat is not None or lon is not None)
        assert not (axes is not None and keyword), "can't input both `axes=` and keyword arguments!"

        # construct the axes
        if keyword:
            axes = Axes()
            if time is not None: axes.append(Axis(time, 'time'))
            if lat is not None: axes.append(Axis(lat, 'lat'))
            if lon is not None: axes.append(Axis(lon, 'lon'))

        super(GeoArray, self).__init__(values, axes, **kwargs) # order dimensions

        # add weight on latitude
        for ax in self.axes:
            if is_latitude(ax.name):
                ax.weights = lambda x: np.cos(np.radians(x))
            if is_longitude(ax.name):
                ax.modulo = 360
示例#3
0
    def __init__(self,
                 values=None,
                 axes=None,
                 time=None,
                 lat=None,
                 lon=None,
                 **kwargs):
        """ 
        """
        keyword = (time is not None or lat is not None or lon is not None)
        assert not (axes is not None and
                    keyword), "can't input both `axes=` and keyword arguments!"

        # construct the axes
        if keyword:
            axes = Axes()
            if time is not None: axes.append(Axis(time, 'time'))
            if lat is not None: axes.append(Axis(lat, 'lat'))
            if lon is not None: axes.append(Axis(lon, 'lon'))

        super(GeoArray, self).__init__(values, axes,
                                       **kwargs)  # order dimensions

        # add weight on latitude
        for ax in self.axes:
            if is_latitude(ax.name):
                ax.weights = lambda x: np.cos(np.radians(x))
            if is_longitude(ax.name):
                ax.modulo = 360
示例#4
0
def getaxes_broadcast(obj, indices):
    """ broadcast array-indices & integers, numpy's classical

    Examples
    --------
    >>> import dimarray as da
    >>> a = da.zeros(shape=(3,4,5,6))
    >>> a.take((slice(None),[0, 1],slice(None),2), broadcast=True).shape
    (2, 3, 5)
    >>> a.take((slice(None),[0, 1],2,slice(None)), broadcast=True).shape
    (3, 2, 6)
    """
    from dimarray import Axis, Axes

    # new axes: broacast indices (should do the same as above, since integers are just broadcast)
    indices2 = broadcast_indices(indices)
    # assert np.all(newval == obj.values[indices2])

    # make a multi-axis with tuples
    is_array2 = np.array([np.iterable(ix) for ix in indices2])
    nb_array2 = is_array2.sum()

    # If none or one array is present, easy
    if nb_array2 <= 1:
        newaxes = [obj.axes[i][ix] for i, ix in enumerate(indices) if not np.isscalar(ix)] # indices or indices2, does not matter

    # else, finer check needed
    else:
        # same stats but on original indices
        is_array = np.array([np.iterable(ix) for ix in indices])
        array_ix_pos = np.where(is_array)[0]

        # Determine where the axis will be inserted
        # - need to consider the integers as well (broadcast as arrays)
        # - if two indexed dimensions are not contiguous, new axis placed at first position...
        # obj = zeros((3,4,5,6))
            # obj[:,[1,2],:,0].shape ==> (2, 3, 5)
            # obj[:,[1,2],0,:].shape ==> (3, 2, 6)
        array_ix_pos2 = np.where(is_array2)[0]
        if np.any(np.diff(array_ix_pos2) > 1):  # that mean, if two indexed dimensions are not contiguous
            insert = 0
        else: 
            insert = array_ix_pos2[0]

        # Now determine axis value
        # ...if originally only one array was provided, use these values correspondingly
        if len(array_ix_pos) == 1:
            i = array_ix_pos[0]
            values = obj.axes[i].values[indices[i]]
            name = obj.axes[i].name

        # ...else use a list of tuples
        else:
            values = list(zip(*[obj.axes[i].values[indices2[i]] for i in array_ix_pos]))
            name = ",".join([obj.axes[i].name for i in array_ix_pos])

        broadcastaxis = Axis(values, name)

        newaxes = Axes()
        for i, ax in enumerate(obj.axes):

            # axis is already part of the broadcast axis: skip
            if is_array2[i]:
                continue

            else:
                newaxis = ax[indices2[i]]

                ## do not append axis if scalar
                #if np.isscalar(newaxis):
                #    continue

            newaxes.append(newaxis)

        # insert the right new axis at the appropriate position
        newaxes.insert(insert, broadcastaxis)

    return newaxes
示例#5
0
    def __init__(
        self,
        values=None,
        axes=None,
        time=None,
        z=None,
        y=None,
        x=None,
        lat=None,
        lon=None,
        dims=None,
        standard_name=None,
        long_name=None,
        units=None,
        **kwargs
    ):
        """ 
        Parameters
        ----------
        values : array-like
        axes : list of array-like or Axis objects, optional
        time, z, y, x, lat, lon: spatiotemporal coordinates, optional
           These keyword arguments are provided for convenience. They
           can be used instead of (but not in addition to) the `axes` 
           parameter. See notes below about implied array shape.
        dims : sequence, optional
            sequence of axis names (dimensions)
            This is needed when axes are defined via keywords but 
            array-shape does not conform with CF-conventions.
        standard_name, long_name, units : str, optional
            standard attributes according to the CF-1.4 netCDF 
            conventions. Will be added to metadata.
        **kwargs : keyword arguments, optional
            Passed to dimarray.DimArray

        Notes
        -----
        When coordinate axes are passed via keyword arguments 
        it is assumed that the array shape follows the CF-conventions:
        time, vertical coordinate (z), northing coordinate (y or lat), 
        easting coordinate (x or lon).
        If it is not the case, please indicate the `dims` parameters or 
        pass axes via the `axes=` parameter instead of keyword arguments.

        See Also
        --------
        dimarray.DimArray : base class with no "geo" specificities
        dimarray.geo.Coordinate : base class for geo-axes
        dimarray.geo.Time 
        dimarray.geo.Latitude, dimarray.geo.Longitude
        dimarray.geo.Z, dimarray.geo.Y, dimarray.geo.X
        """
        keyword = (
            time is not None or lat is not None or lon is not None or x is not None or y is not None or z is not None
        )
        if axes is not None and keyword:
            msg = "Axes can be provided EITHER via `axes=` OR keyword arguments"
            raise ValueError(msg)

        # construct the axes
        if keyword:
            axes = Axes()
            if time is not None:
                axes.append(Time(time, "time"))
            if z is not None:
                axes.append(Z(z, "z"))
            if y is not None:
                axes.append(Y(y, "y"))
            if lat is not None:
                axes.append(Latitude(lat, "lat"))
            if x is not None:
                axes.append(X(x, "x"))
            if lon is not None:
                axes.append(Longitude(lon, "lon"))
            if dims is not None:
                if len(dims) != len(axes):
                    msg = "dims ({}) and axes ({}) lengths \
                            do not match".format(
                        len(dims), len(axes)
                    )
                    raise ValueError(msg)
                axes = [axes[nm] for nm in dims]

        # if metadata is not None:
        #    for k in metadata.keys():
        #        assert k not in kwargs, "{} was provided multiple times".format(k)
        #    kwargs.update(metadata) # TODO: make metadata a parameter in DimArray as well

        self._grid_mapping = None

        super(GeoArray, self).__init__(values, axes, **kwargs)  # order dimensions

        # add metadata
        if units:
            self.units = units
        if standard_name:
            self.standard_name = standard_name
        if long_name:
            self.long_name = long_name

        # Do some guessing to define coordinates
        for i, ax in enumerate(self.axes):
            if isinstance(ax, Coordinate):
                continue
            elif is_latitude(ax.name) or (hasattr(ax, "standard_name") and ax.standard_name == "latitude"):
                self.axes[i] = Latitude.from_axis(ax)
            elif is_longitude(ax.name) or (hasattr(ax, "standard_name") and ax.standard_name == "longitude"):
                self.axes[i] = Longitude.from_axis(ax)
            elif is_time(ax.name):
                self.axes[i] = Time.from_axis(ax)
            # 'x', 'y', 'z' are too general to be used.
            elif ax.name == "x" or (hasattr(ax, "standard_name") and ax.standard_name == "projection_x_coordinate"):
                self.axes[i] = X.from_axis(ax)
            elif ax.name == "y" or (hasattr(ax, "standard_name") and ax.standard_name == "projection_y_coordinate"):
                self.axes[i] = Y.from_axis(ax)
            elif ax.name in ("z", "height", "depth"):
                self.axes[i] = Z.from_axis(ax)

        # Check unicity of coordinates.
        time_coords = filter(lambda ax: isinstance(ax, Time), self.axes)
        x_coords = filter(lambda ax: isinstance(ax, X), self.axes)
        y_coords = filter(lambda ax: isinstance(ax, Y), self.axes)
        z_coords = filter(lambda ax: isinstance(ax, Z), self.axes)

        if len(time_coords) > 1:
            raise ValueError("More than one time coordinate found")
        if len(x_coords) > 1:
            raise ValueError("More than one x coordinate found")
        if len(y_coords) > 1:
            raise ValueError("More than one y coordinate found")
        if len(z_coords) > 1:
            raise ValueError("More than one z coordinate found")