Skip to content
Open
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
3 changes: 3 additions & 0 deletions satpy/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
"readers": {
"clip_negative_radiances": False,
},
# 8< v1.0
"oscar_compliant_attributes": False,
# >8 v1.0
}

# Satpy main configuration object
Expand Down
8 changes: 6 additions & 2 deletions satpy/composites/config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def _load_config(composite_configs):
sensor_modifiers = {}

dep_id_keys = None
sensor_deps = sensor_name.split("/")[:-1]
sensor_deps = conf.get("dependencies", sensor_name.split("/")[:-1])
if sensor_deps:
# get dependent
for sensor_dep in sensor_deps:
Expand Down Expand Up @@ -246,6 +246,10 @@ def _update_cached_wrapper(wrapper, cached_func):
return wrapper


def sensor_to_filename(sensor_name: str) -> str:
"""Get filename tag for the given sensor."""
return sensor_name.lower().replace("-", "").replace(" ", "_").replace("/", "-")

@_lru_cache_with_config_path
def load_compositor_configs_for_sensor(sensor_name: str) -> tuple[dict[str, dict], dict[str, dict], dict]:
"""Load compositor, modifier, and DataID key information from configuration files for the specified sensor.
Expand All @@ -268,7 +272,7 @@ def load_compositor_configs_for_sensor(sensor_name: str) -> tuple[dict[str, dict
DataID key -> key properties

"""
config_filename = sensor_name + ".yaml"
config_filename = sensor_to_filename(sensor_name) + ".yaml"
logger.debug("Looking for composites config file %s", config_filename)
paths = get_entry_points_config_dirs("satpy.composites")
composite_configs = config_search_paths(
Expand Down
1 change: 0 additions & 1 deletion satpy/etc/composites/abi.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
sensor_name: visir/abi

modifiers:
rayleigh_corrected_crefl:
modifier: !!python/name:satpy.modifiers.atmosphere.ReflectanceCorrector
Expand Down
7 changes: 5 additions & 2 deletions satpy/modifiers/atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from satpy.modifiers import ModifierBase
from satpy.modifiers._crefl import ReflectanceCorrector # noqa
from satpy.modifiers.angles import compute_relative_azimuth, get_angles, get_satellite_zenith_angle
from satpy.modifiers.base import _convert_to_pyspectral

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -104,7 +105,8 @@ def __call__(self, projectables, optional_datasets=None, **info):
logger.info("Removing Rayleigh scattering with atmosphere '%s' and "
"aerosol type '%s' for '%s'",
atmosphere, aerosol_type, vis.attrs["name"])
corrector = Rayleigh(vis.attrs["platform_name"], vis.attrs["sensor"],
sensor = _convert_to_pyspectral(vis.attrs["sensor"])
corrector = Rayleigh(vis.attrs["platform_name"], sensor,
atmosphere=atmosphere,
aerosol_type=aerosol_type)

Expand Down Expand Up @@ -158,8 +160,9 @@ def __call__(self, projectables, optional_datasets=None, **info):
satz = satz.data # get dask array underneath

logger.info("Correction for limb cooling")
sensor = _convert_to_pyspectral(band.attrs["sensor"])
corrector = AtmosphericalCorrection(band.attrs["platform_name"],
band.attrs["sensor"])
sensor)

atm_corr = da.map_blocks(_call_mapped_correction, satz, band.data,
corrector=corrector,
Expand Down
5 changes: 5 additions & 0 deletions satpy/modifiers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ class ModifierBase(CompositeBase):
def __call__(self, datasets, optional_datasets=None, **info):
"""Generate a modified copy of the first provided dataset."""
raise NotImplementedError()


def _convert_to_pyspectral(sensor: str) -> str:
"""Convert sensor name to format expected by pyspectral."""
return sensor.lower()
4 changes: 3 additions & 1 deletion satpy/modifiers/spectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import xarray as xr

from satpy.modifiers import ModifierBase
from satpy.modifiers.base import _convert_to_pyspectral

try:
from pyspectral.near_infrared_reflectance import Calculator
Expand Down Expand Up @@ -132,7 +133,8 @@ def _init_reflectance_calculator(self, metadata):
logger.info("Couldn't load pyspectral")
raise ImportError("No module named pyspectral.near_infrared_reflectance")

reflectance_3x_calculator = Calculator(metadata["platform_name"], metadata["sensor"], metadata["name"],
sensor = _convert_to_pyspectral(metadata["sensor"])
reflectance_3x_calculator = Calculator(metadata["platform_name"], sensor, metadata["name"],
sunz_threshold=self.sun_zenith_threshold,
masking_limit=self.masking_limit)
return reflectance_3x_calculator
Expand Down
80 changes: 76 additions & 4 deletions satpy/readers/core/yaml_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from satpy.coords import add_crs_xy_coords
from satpy.dataset import DataID, DataQuery, get_key
from satpy.dataset.dataid import default_co_keys_config, default_id_keys_config, get_keys_from_config
from satpy.readers.core.file_handlers import BaseFileHandler
from satpy.utils import recursive_dict_update

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -483,6 +484,7 @@ def __init__(self,
self.file_handlers = {}
self.available_ids = {}
self.register_data_files()
self.attribute_composer = AttributeComposer(self.name)

@property
def sensor_names(self):
Expand Down Expand Up @@ -737,10 +739,8 @@ def _load_dataset_data(self, file_handlers, dsid, **kwargs):
ds_info = self.all_ids[dsid]
proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
# FIXME: areas could be concatenated here
# Update the metadata
proj.attrs["start_time"] = file_handlers[0].start_time
proj.attrs["end_time"] = file_handlers[-1].end_time
proj.attrs["reader"] = self.name
attrs = self.attribute_composer.get_attrs(proj, file_handlers)
proj.attrs.update(attrs)
return proj

def _preferred_filetype(self, filetypes):
Expand Down Expand Up @@ -985,6 +985,78 @@ def _get_coordinates_for_dataset_key(self, dsid):
return cids


# 8< v1.0
LEGACY_SENSORS = {
"ABI": "abi"
}
LEGACY_PLATFORMS: dict[str, str] = {}

from functools import wraps # noqa: E402

import satpy # noqa: E402


def with_legacy_attributes(func):
"""Adds option to get legacy attributes back."""
@wraps(func)
def translate_attrs(*args, **kwargs):
attrs = func(*args, **kwargs)
if not satpy.config.get("oscar_compliant_attributes", False):
_make_legacy_attrs(attrs)
return attrs
return translate_attrs

def _make_legacy_attrs(attrs: dict) -> None:
sensor = attrs.get("sensor")
if sensor:
attrs["sensor"] = _get_legacy_sensor(sensor)
platform = attrs.get("platform")
if platform:
attrs["platform_name"] = _get_legacy_platform(platform)


def _get_legacy_sensor(sensor: str|set[str]) -> str|set[str]:
if isinstance(sensor, set):
return {
LEGACY_SENSORS.get(s, s)
for s in sensor
}
return LEGACY_SENSORS.get(sensor, sensor)


def _get_legacy_platform(platform: str) -> str:
return LEGACY_PLATFORMS.get(platform, platform)
# >8 v1.0


class AttributeComposer:
"""Compose dataset attributes."""

def __init__(self, reader_name: str) -> None:
"""Initialize the composer."""
self.reader_name = reader_name

def get_attrs(self, data: xr.DataArray, file_handlers: list[BaseFileHandler]) -> dict:
"""Get dataset attributes."""
attrs = {
"start_time": file_handlers[0].start_time,
"end_time": file_handlers[-1].end_time,
"reader": self.reader_name,
}
return attrs | self._get_platform_sensor(data)

# 8< v1.0
@with_legacy_attributes
# >8 v1.0
def _get_platform_sensor(self, data: xr.DataArray) -> dict:
keys = ["platform_name", "sensor"]
return {
key: value
for key in keys
if (value := data.attrs.get(key))
}


def _load_area_def(dsid, file_handlers):
"""Load the area definition of *dsid*."""
area_defs = [fh.get_area_def(dsid) for fh in file_handlers]
Expand Down
8 changes: 8 additions & 0 deletions satpy/tests/reader_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,11 @@ def aws_mwr_l1c_handler(aws_mwr_l1c_file):
filetype_info["file_type"] = "aws1_mwr_l1c"
filetype_info["feed_horn_group_name"] = None
return AWS_MWR_L1CFile(aws_mwr_l1c_file, filename_info, filetype_info)

# 8< v1.0
@pytest.fixture(scope="module", autouse=True)
def oscar_compliant_attrs():
"""Request oscar compliant dataset attributes."""
import satpy
satpy.config.set(oscar_compliant_attributes=False)
# >8 v1.0
Loading