Exemple #1
0
def test_dataid():
    """Test the DataID object."""
    from satpy.dataset import DataID, WavelengthRange, ModifierTuple, ValueList

    # Check that enum is translated to type.
    did = make_dataid()
    assert issubclass(did._id_keys['calibration']['type'], ValueList)
    assert 'enum' not in did._id_keys['calibration']

    # Check that None is never a valid value
    did = make_dataid(name='cheese_shops', resolution=None)
    assert 'resolution' not in did
    assert 'None' not in did.__repr__()
    with pytest.raises(ValueError):
        make_dataid(name=None, resolution=1000)

    # Check that defaults are applied correctly
    assert did['modifiers'] == ModifierTuple()

    # Check that from_dict creates a distinct instance...
    did2 = did.from_dict(dict(name='cheese_shops', resolution=None))
    assert did is not did2
    # ...But is equal
    assert did2 == did

    # Check that the instance is immutable
    with pytest.raises(TypeError):
        did['resolution'] = 1000

    # Check that a missing required field crashes
    with pytest.raises(ValueError):
        make_dataid(resolution=1000)

    # Check to_dict
    assert did.to_dict() == dict(name='cheese_shops', modifiers=tuple())

    # Check repr
    did = make_dataid(name='VIS008', resolution=111)
    assert repr(did) == "DataID(name='VIS008', resolution=111, modifiers=())"

    # Check inequality
    default_id_keys_config = {'name': None,
                              'wavelength': {
                                'type': WavelengthRange,
                              },
                              'resolution': None,
                              'calibration': {
                                'enum': [
                                    'reflectance',
                                    'brightness_temperature',
                                    'radiance',
                                    'counts'
                                    ]
                              },
                              'modifiers': {
                                'default': ModifierTuple(),
                                'type': ModifierTuple,
                              },
                              }
    assert DataID(default_id_keys_config, wavelength=10) != DataID(default_id_keys_config, name="VIS006")
Exemple #2
0
    def test_compare_no_wl(self):
        """Compare fully qualified wavelength ID to no wavelength ID."""
        from satpy.dataset import DataID, default_id_keys_config as dikc
        d1 = DataID(dikc, name="a", wavelength=(0.1, 0.2, 0.3))
        d2 = DataID(dikc, name="a", wavelength=None)

        # this happens when sorting IDs during dependency checks
        self.assertFalse(d1 < d2)
        self.assertTrue(d2 < d1)
Exemple #3
0
    def update_ds_ids_from_file_handlers(self):
        """Add or modify available dataset information.

        Each file handler is consulted on whether or not it can load the
        dataset with the provided information dictionary.
        See
        :meth:`satpy.readers.file_handlers.BaseFileHandler.available_datasets`
        for more information.

        """
        avail_datasets = self._file_handlers_available_datasets()
        new_ids = {}
        for is_avail, ds_info in avail_datasets:
            # especially from the yaml config
            coordinates = ds_info.get('coordinates')
            if isinstance(coordinates, list):
                # xarray doesn't like concatenating attributes that are
                # lists: https://github.com/pydata/xarray/issues/2060
                ds_info['coordinates'] = tuple(ds_info['coordinates'])

            ds_info.setdefault('modifiers', tuple())  # default to no mods

            # Create DataID for this dataset
            ds_id = DataID(self._id_keys, **ds_info)
            # all datasets
            new_ids[ds_id] = ds_info
            # available datasets
            # False == we have the file type but it doesn't have this dataset
            # None == we don't have the file type object to ask
            if is_avail:
                self.available_ids[ds_id] = ds_info
        self.all_ids = new_ids
Exemple #4
0
 def id(self):
     """Return the DataID of the object."""
     try:
         return self.attrs['_satpy_id']
     except KeyError:
         id_keys = self.attrs.get('_satpy_id_keys', minimal_default_keys_config)
         return DataID(id_keys, **self.attrs)
Exemple #5
0
def test_dataid_copy():
    """Test copying a DataID."""
    from satpy.dataset import DataID, default_id_keys_config as dikc
    from copy import deepcopy

    did = DataID(dikc, name="a", resolution=1000)
    did2 = deepcopy(did)
    assert did2 == did
    assert did2.id_keys == did.id_keys
Exemple #6
0
 def _se(datasets, optional_datasets=None, ds_id=ds_id, **kwargs):
     if ds_id['name'] == 'comp14':
         # used as a test when composites update the dataset id with
         # information from prereqs
         ds_id = DataID(ds_id.id_keys, resolution=555, **ds_id)
     if len(datasets) != len(prereqs):
         raise ValueError("Not enough prerequisite datasets passed")
     return DataArray(data=np.arange(75).reshape(5, 5, 3),
                      attrs=ds_id.to_dict(),
                      dims=['y', 'x', 'bands'],
                      coords={'bands': ['R', 'G', 'B']})
Exemple #7
0
def test_dataid_equal_if_enums_different():
    """Check that dataids with different enums but same items are equal."""
    from satpy.dataset import DataID, WavelengthRange, ModifierTuple
    id_keys_config1 = {'name': None,
                       'wavelength': {
                           'type': WavelengthRange,
                       },
                       'resolution': None,
                       'calibration': {
                           'enum': [
                               'c1',
                               'c2',
                               'c3',
                           ]
                       },
                       'modifiers': {
                           'default': ModifierTuple(),
                           'type': ModifierTuple,
                       },
                       }

    id_keys_config2 = {'name': None,
                       'wavelength': {
                           'type': WavelengthRange,
                       },
                       'resolution': None,
                       'calibration': {
                           'enum': [
                               'c1',
                               'c1.5',
                               'c2',
                               'c2.5',
                               'c3'
                           ]
                       },
                       'modifiers': {
                           'default': ModifierTuple(),
                           'type': ModifierTuple,
                       },
                       }
    assert DataID(id_keys_config1, name='ni', calibration='c2') == DataID(id_keys_config2, name="ni", calibration='c2')
Exemple #8
0
    def __setitem__(self, key, value):
        """Support assigning 'Dataset' objects or dictionaries of metadata."""
        value_dict = value
        if hasattr(value, 'attrs'):
            # xarray.DataArray objects
            value_dict = value.attrs
        # use value information to make a more complete DataID
        if not isinstance(key, DataID):
            if not isinstance(value_dict, dict):
                raise ValueError(
                    "Key must be a DataID when value is not an xarray DataArray or dict"
                )
            old_key = key
            try:
                key = self.get_key(key)
            except KeyError:
                if isinstance(old_key, str):
                    new_name = old_key
                else:
                    new_name = value_dict.get("name")
                # this is a new key and it's not a full DataID tuple
                if new_name is None and value_dict.get('wavelength') is None:
                    raise ValueError("One of 'name' or 'wavelength' attrs "
                                     "values should be set.")
                try:
                    id_keys = value_dict['_satpy_id'].id_keys
                except KeyError:
                    try:
                        id_keys = value_dict['_satpy_id_keys']
                    except KeyError:
                        id_keys = minimal_default_keys_config
                value_dict['name'] = new_name
                key = DataID(id_keys, **value_dict)
                if hasattr(value, 'attrs') and 'name' not in value.attrs:
                    value.attrs['name'] = new_name

        # update the 'value' with the information contained in the key
        try:
            new_info = key.to_dict()
        except AttributeError:
            new_info = key
        if isinstance(value_dict, dict):
            value_dict.update(new_info)

        if hasattr(value, 'attrs'):
            if isinstance(key, DataID):
                value.attrs['_satpy_id'] = key

        return super(DatasetDict, self).__setitem__(key, value)
Exemple #9
0
    def test_basic_init(self):
        """Test basic ways of creating a DataID."""
        from satpy.dataset import DataID, default_id_keys_config as dikc, minimal_default_keys_config as mdkc

        did = DataID(dikc, name="a")
        assert did['name'] == 'a'
        assert did['modifiers'] == tuple()
        DataID(dikc, name="a", wavelength=0.86)
        DataID(dikc, name="a", resolution=1000)
        DataID(dikc, name="a", calibration='radiance')
        DataID(dikc, name="a", wavelength=0.86, resolution=250,
               calibration='radiance')
        DataID(dikc, name="a", wavelength=0.86, resolution=250,
               calibration='radiance', modifiers=('sunz_corrected',))
        with pytest.raises(ValueError):
            DataID(dikc, wavelength=0.86)
        did = DataID(mdkc, name='comp24', resolution=500)
        assert did['resolution'] == 500
Exemple #10
0
    def load_ds_ids_from_config(self):
        """Get the dataset ids from the config."""
        ids = []
        for dataset in self.datasets.values():
            # xarray doesn't like concatenating attributes that are lists
            # https://github.com/pydata/xarray/issues/2060
            if 'coordinates' in dataset and \
                    isinstance(dataset['coordinates'], list):
                dataset['coordinates'] = tuple(dataset['coordinates'])
            id_keys = get_keys_from_config(self._id_keys, dataset)

            # Build each permutation/product of the dataset
            id_kwargs = []
            for key, idval in id_keys.items():
                val = dataset.get(key, idval.get('default') if idval is not None else None)
                val_type = None
                if idval is not None:
                    val_type = idval.get('type')
                if val_type is not None and issubclass(val_type, tuple):
                    # special case: wavelength can be [min, nominal, max]
                    # but is still considered 1 option
                    id_kwargs.append((val, ))
                elif isinstance(val, (list, tuple, set)):
                    # this key has multiple choices
                    # (ex. 250 meter, 500 meter, 1000 meter resolutions)
                    id_kwargs.append(val)
                elif isinstance(val, dict):
                    id_kwargs.append(val.keys())
                else:
                    # this key only has one choice so make it a one
                    # item iterable
                    id_kwargs.append((val,))
            for id_params in itertools.product(*id_kwargs):
                dsid = DataID(id_keys, **dict(zip(id_keys, id_params)))
                ids.append(dsid)

                # create dataset infos specifically for this permutation
                ds_info = dataset.copy()
                for key in dsid.keys():
                    if isinstance(ds_info.get(key), dict):
                        ds_info.update(ds_info[key][dsid.get(key)])
                    # this is important for wavelength which was converted
                    # to a tuple
                    ds_info[key] = dsid.get(key)
                self.all_ids[dsid] = ds_info
        return ids
Exemple #11
0
def make_dataid(**items):
    """Make a data id."""
    return DataID(local_id_keys_config, **items)
Exemple #12
0
def make_cid(**items):
    """Make a DataID with a minimal set of keys to id composites."""
    return DataID(minimal_default_keys_config, **items)
Exemple #13
0
def make_dataid(**items):
    """Make a DataID with default keys."""
    return DataID(default_id_keys_config, **items)
Exemple #14
0
 def test_bad_calibration(self):
     """Test that asking for a bad calibration fails."""
     from satpy.dataset import DataID, default_id_keys_config as dikc
     with pytest.raises(ValueError):
         DataID(dikc, name='C05', calibration='_bad_')
Exemple #15
0
def test_id_query_interactions():
    """Test interactions between DataIDs and DataQuery's."""
    from satpy.dataset import DataQuery, DataID, WavelengthRange, ModifierTuple, minimal_default_keys_config

    default_id_keys_config = {'name': {
                                'required': True,
                              },
                              'wavelength': {
                                'type': WavelengthRange,
                            },
                            'resolution': None,
                            'calibration': {
                                'enum': [
                                    'reflectance',
                                    'brightness_temperature',
                                    'radiance',
                                    'counts'
                                    ]
                            },
                            'modifiers': {
                                'default': ModifierTuple(),
                                'type': ModifierTuple,
                            },
                            }

    # Check hash equality
    dq = DataQuery(modifiers=tuple(), name='cheese_shops')
    did = DataID(default_id_keys_config, name='cheese_shops')
    assert hash(dq) == hash(did)

    # Check did filtering
    did2 = DataID(default_id_keys_config, name='ni')
    res = dq.filter_dataids([did2, did])
    assert len(res) == 1
    assert res[0] == did

    dataid_container = [DataID(default_id_keys_config,
                               name='ds1',
                               resolution=250,
                               calibration='reflectance',
                               modifiers=tuple())]
    dq = DataQuery(wavelength=0.22, modifiers=tuple())
    assert len(dq.filter_dataids(dataid_container)) == 0
    dataid_container = [DataID(minimal_default_keys_config,
                               name='natural_color')]
    dq = DataQuery(name='natural_color', resolution=250)
    assert len(dq.filter_dataids(dataid_container)) == 1

    dq = make_dsq(wavelength=0.22, modifiers=('mod1',))
    did = make_cid(name='static_image')
    assert len(dq.filter_dataids([did])) == 0

    # Check did sorting
    dq = DataQuery(name='cheese_shops', wavelength=2, modifiers='*')
    did = DataID(default_id_keys_config, name='cheese_shops', wavelength=(1, 2, 3))
    did2 = DataID(default_id_keys_config, name='cheese_shops', wavelength=(1.1, 2.1, 3.1))
    dsids, distances = dq.sort_dataids([did2, did])
    assert list(dsids) == [did, did2]
    assert np.allclose(distances, [0, 0.1])

    dq = DataQuery(name='cheese_shops')
    did = DataID(default_id_keys_config, name='cheese_shops', resolution=200)
    did2 = DataID(default_id_keys_config, name='cheese_shops', resolution=400)
    dsids, distances = dq.sort_dataids([did2, did])
    assert list(dsids) == [did, did2]
    assert distances[0] < distances[1]

    did = DataID(default_id_keys_config, name='cheese_shops', calibration='counts')
    did2 = DataID(default_id_keys_config, name='cheese_shops', calibration='reflectance')
    dsids, distances = dq.sort_dataids([did2, did])
    assert list(dsids) == [did2, did]
    assert distances[0] < distances[1]

    did = DataID(default_id_keys_config, name='cheese_shops', modifiers=tuple())
    did2 = DataID(default_id_keys_config, name='cheese_shops', modifiers=tuple(['out_of_stock']))
    dsids, distances = dq.sort_dataids([did2, did])
    assert list(dsids) == [did, did2]
    assert distances[0] < distances[1]

    # Check (in)equality
    assert DataQuery(wavelength=10) != DataID(default_id_keys_config, name="VIS006")