Beispiel #1
0
def test_valid_data_mask():
    from xarray import DataArray, Dataset
    import numpy as np
    attrs = {
        'nodata': -999,
    }

    expected_data_array = DataArray(np.array([[True, False, False], [True, True, False], [False, False, False]],
                                             dtype='bool'))

    data_array = DataArray([[1, -999, -999], [2, 3, -999], [-999, -999, -999]], attrs=attrs)
    dataset = Dataset(data_vars={'var_one': data_array})

    output_ds = valid_data_mask(dataset)
    assert output_ds.data_vars['var_one'].equals(expected_data_array)

    output_da = valid_data_mask(data_array)
    assert output_da.equals(expected_data_array)
Beispiel #2
0
    def compute(self, data) -> Dataset:

        print(data.geobox)
        print(repr(data.geobox))

        masking_used = fmask_filter
        if self.c2:
            masking_used = fmask_filter_c2
            # The C2 data needs to be scaled
            bands = [
                'nbart_blue', 'nbart_green', 'nbart_red', 'nbart_nir',
                'nbart_swir_1', 'nbart_swir_2'
            ]

            for band in bands:
                dtype = data[band].dtype
                nodata = data[band].attrs['nodata']
                attrs = data[band].attrs

                is_valid_array = valid_data_mask(data[band])

                data[band] = data[band].where(is_valid_array)
                data[band] = numpy.clip((data[band] * 2.75e-5 - 0.2) * 10000,
                                        0, 10000)
                data[band] = data[band].astype(dtype).where(
                    is_valid_array, nodata)
                data[band].attrs = attrs

        if self.dsm_path is not None:
            dsm = self._load_dsm(
                data.geobox.buffered(self.terrain_buffer, self.terrain_buffer))

        time_selectors = data.time.values
        wofs = []
        for time in time_selectors:
            if self.dsm_path is None:
                wofs.append(
                    woffles_ard_no_terrain_filter(
                        data.sel(time=time),
                        masking_filter=masking_used).to_dataset(name='water'))
            else:
                wofs.append(
                    woffles_ard(
                        data.sel(time=time), dsm,
                        masking_filter=masking_used).to_dataset(name='water'))
        wofs = xr.concat(wofs, dim='time')
        wofs.attrs['crs'] = data.attrs['crs']
        return wofs
 def var_name(self, key):
     # pylint: disable=invalid-unary-operand-type
     return ~valid_data_mask(data[key.value])
Beispiel #4
0
def fractional_cover(nbar_tile,
                     measurements=None,
                     regression_coefficients=None):
    """
    Given a tile of spectral observations compute the fractional components.
    The data should be a 2D array

    :param xarray.Dataset nbar_tile:
        A dataset with the following data variables (0-10000):
            * green
            * red
            * nir
            * swir1
            * swir2

    :param list(dict) measurements:
        A list of measurement item dicts, each containing:
            * name - name of output data_var
            * src_var - (optional) if `name` is not one of `['PV', 'NPV', 'BS', 'UE']`, use one of them here
            * dtype - dtype to use, eg `'int8'`
            * nodata - value to fill in for no data, eg `-1`
            * units' - eg `'percent'`

    :param dict regression_coefficients:
        A dictionary with six pairs of coefficients to apply to the green, red, nir, swir1 and swir2 values
        (blue is not used)

    :return:
        An xarray.Dataset containing:
            * Green vegetation (PV)
            * Non-green vegetation (NPV)
            * Bare soil (BS)
            * Unmixing error (UE)

    :rtype:
        xarray.Dataset
    """
    if measurements is None:
        measurements = DEFAULT_MEASUREMENTS

    # Ensure the bands are all there and in the right order
    nbar_tile = nbar_tile[['green', 'red', 'nir', 'swir1', 'swir2']]

    # Set nodata to 0
    no_data = 0
    is_valid_array = valid_data_mask(nbar_tile).to_array(dim='band').all(
        dim='band')

    nbar = nbar_tile.to_array(dim='band')
    nbar.data[:, ~is_valid_array.data] = no_data

    output_data = compute_fractions(nbar.data, regression_coefficients)

    def data_func(measurement):
        band_names = ['PV', 'NPV', 'BS', 'UE']
        src_var = measurement.get('src_var', None) or measurement.get('name')
        i = band_names.index(src_var)

        # Set nodata value into output array
        band_nodata = numpy.dtype(measurement['dtype']).type(
            measurement['nodata'])
        compute_error = (output_data[i, :, :] == -1)
        output_data[i, compute_error] = band_nodata
        output_data[i, ~is_valid_array.data] = band_nodata

        return output_data[i, :, :]

    dataset = Datacube.create_storage({}, nbar_tile.geobox, measurements,
                                      data_func)

    return dataset