Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions doc/source/reading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,24 @@ time etc. The following attributes are standardized across all readers:
* ``sensor``: The name of the sensor that recorded the data. For full support through Satpy this
should be all lowercase. If the dataset is the result of observations from multiple sensors a
``set`` object can be used to specify more than one sensor name.

.. versionremoved:: 1.0

The ``sensor`` attribute has been replaced by ``instruments`` in Satpy v1.0. During
a transition phase the attribute can be restored by setting

.. code-block:: python

import satpy
satpy.config.set(legacy_sensor_attribute=True)

This option will be removed in Satpy v1.1.

* ``instruments``: Names of instruments that recorded the data, stored in a ``set`` object.
Instrument names follow the WMO OSCAR naming conventions.

.. versionadded:: 1.0

* ``reader``: The name of the Satpy reader that produced the dataset.
* ``orbital_parameters``: Dictionary of orbital parameters describing the satellite's position.
See the :ref:`orbital_parameters` section below for more information.
Expand Down
3 changes: 2 additions & 1 deletion satpy/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"readers": {
"clip_negative_radiances": False,
},
"instruments_key": "sensor"
"instruments_key": "sensor",
"legacy_sensor_attribute": False
}

# Satpy main configuration object
Expand Down
21 changes: 21 additions & 0 deletions satpy/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from pyresample.geometry import AreaDefinition, BaseDefinition, CoordinateDefinition, SwathDefinition
from xarray import DataArray

import satpy
import satpy._instruments as inst_utils
from satpy.area import get_area_def
from satpy.composites.config_loader import load_compositor_configs_for_sensors
Expand Down Expand Up @@ -841,8 +842,28 @@ def __getitem__(self, key):
"""Get a dataset or create a new 'slice' of the Scene."""
if isinstance(key, tuple):
return self.slice(key)
# 8< v1.1
data_array = self._datasets[key]
if self._should_add_legacy_sensor_attribute(data_array):
self._set_legacy_sensor_attribute(data_array)
return data_array
# >8 v1.1
return self._datasets[key]

# 8< v1.1
def _should_add_legacy_sensor_attribute(self, data_array: xr.DataArray) -> bool:
instruments = inst_utils.get_instruments_from_attrs(data_array.attrs)
return bool(instruments) and satpy.config.get("legacy_sensor_attribute")

def _set_legacy_sensor_attribute(self, data_array: xr.DataArray) -> None:
instruments = inst_utils.get_instruments_from_attrs(data_array.attrs)
if len(instruments) == 1:
# In satpy < v1.0 single sensors are provided as string
data_array.attrs["sensor"] = inst_utils.wmo_to_internal(list(instruments)[0])
else:
data_array.attrs["sensor"] = {inst_utils.wmo_to_internal(inst) for inst in instruments}
# >8 v1.1

def __setitem__(self, key, value):
"""Add the item to the scene."""
self._datasets[key] = value
Expand Down
27 changes: 27 additions & 0 deletions satpy/tests/scene_tests/test_data_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import xarray as xr
from dask import array as da

import satpy
from satpy import Scene
from satpy.dataset.dataid import default_id_keys_config
from satpy.tests.utils import FAKE_FILEHANDLER_END, FAKE_FILEHANDLER_START, make_cid, make_dataid
Expand Down Expand Up @@ -393,3 +394,29 @@ def test_chunk_pass_through(self):
scene.load(["ds1"])
scene = scene.chunk(chunks=2)
assert scene["ds1"].data.chunksize == (2, 2)


class TestLegacySensorAttribute:
"""Tests for legacy sensor attribute."""

@pytest.mark.parametrize(
("instruments", "expected"),
[
({"inst1"}, "inst1"),
({"inst1", "inst2"}, {"inst1", "inst2"})
]
)
def test_getting_dataset_with_sensor_attribute(self, instruments, expected):
"""Test getting dataset with sensor attribute."""
scene = Scene()
scene["ds"] = xr.DataArray(attrs={"instruments": instruments})
assert "sensor" not in scene["ds"].attrs
with satpy.config.set(legacy_sensor_attribute=True):
assert scene["ds"].attrs["sensor"] == expected

def test_no_instruments_no_sensor(self):
"""Test setting sensor only if instruments are present."""
scene = Scene()
scene["ds"] = xr.DataArray()
with satpy.config.set(legacy_sensor_attribute=True):
assert "sensor" not in scene["ds"].attrs
Loading