Skip to content

Commit

Permalink
Rename wishlist
Browse files Browse the repository at this point in the history
  • Loading branch information
sfinkens committed Jun 14, 2024
1 parent 039ef69 commit a2ed4bd
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 32 deletions.
67 changes: 37 additions & 30 deletions satpy/readers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,23 +486,26 @@ def __init__(self, coefs, default="nominal"):
self.coefs = coefs
self.default = default

def parse(self, wishlist):
"""Parse user-defined calibration coefficients."""
if wishlist is None:
def parse(self, calib_wishlist):
"""Parse user's calibration wishlist."""
if calib_wishlist is None:
return self._get_coefs_set(self.default)
elif isinstance(wishlist, str):
return self._get_coefs_set(wishlist)
elif isinstance(wishlist, dict):
return self._parse_dict(wishlist)
raise TypeError(f"Unsupported wishlist type. Expected dict/str, got {type(wishlist)}")
elif isinstance(calib_wishlist, str):
return self._get_coefs_set(calib_wishlist)
elif isinstance(calib_wishlist, dict):
return self._parse_dict(calib_wishlist)
raise TypeError(
f"Unsupported wishlist type. Expected dict/str, "
f"got {type(calib_wishlist)}"
)

def _parse_dict(self, wishlist):
wishlist = self._flatten_multi_channel_keys(wishlist)
return self._replace_calib_mode_with_actual_coefs(wishlist)
def _parse_dict(self, calib_wishlist):
calib_wishlist = self._flatten_multi_channel_keys(calib_wishlist)
return self._replace_calib_mode_with_actual_coefs(calib_wishlist)

def _flatten_multi_channel_keys(self, wishlist):
def _flatten_multi_channel_keys(self, calib_wishlist):
flat = {}
for channels, coefs in wishlist.items():
for channels, coefs in calib_wishlist.items():
if self._is_multi_channel(channels):
flat.update({channel: coefs for channel in channels})
else:
Expand All @@ -512,10 +515,10 @@ def _flatten_multi_channel_keys(self, wishlist):
def _is_multi_channel(self, key):
return isinstance(key, tuple)

def _replace_calib_mode_with_actual_coefs(self, wishlist):
def _replace_calib_mode_with_actual_coefs(self, calib_wishlist):
res = {}
for channel in self.coefs[self.default]:
mode_or_coefs = wishlist.get(channel, self.default)
mode_or_coefs = calib_wishlist.get(channel, self.default)
coefs = self._get_coefs(mode_or_coefs, channel)
if coefs:
res[channel] = coefs
Expand All @@ -540,12 +543,12 @@ def _get_coefs_set(self, mode):
modes = list(self.coefs.keys())
raise KeyError(f"Unknown calibration mode: {mode}. Choose one of {modes}")

def get_calib_mode(self, wishlist, channel):
def get_calib_mode(self, calib_wishlist, channel):
"""Get desired calibration mode for the given channel."""
if isinstance(wishlist, str):
return wishlist
elif isinstance(wishlist, dict):
flat = self._flatten_multi_channel_keys(wishlist)
if isinstance(calib_wishlist, str):
return calib_wishlist
elif isinstance(calib_wishlist, dict):
flat = self._flatten_multi_channel_keys(calib_wishlist)
return flat[channel]


Expand Down Expand Up @@ -581,7 +584,7 @@ class CalibrationCoefficientSelector:
# ch3 coefficients are missing
}
}
wishlist = {
calib_wishlist = {
"ch1": "meirink",
("ch2", "ch3"): "gsics"
"ch4": {"mygain": 123},
Expand All @@ -591,7 +594,7 @@ class CalibrationCoefficientSelector:
.. code-block:: python
>>> s = CalibrationCoefficientSelector(coefs, wishlist)
>>> s = CalibrationCoefficientSelector(coefs, calib_wishlist)
>>> s.get_coefs("ch1")
"meirink_ch1"
>>> s.get_coefs("ch2")
Expand All @@ -607,35 +610,35 @@ class CalibrationCoefficientSelector:
.. code-block:: python
>>> s = CalibrationCoefficientSelector(coefs, wishlist, fallback="nominal")
>>> s = CalibrationCoefficientSelector(coefs, calib_wishlist, fallback="nominal")
>>> s.get_coefs("ch3")
"nominal_ch3"
"""

def __init__(self, coefs, wishlist, default="nominal", fallback=None):
def __init__(self, coefs, calib_wishlist, default="nominal", fallback=None):
"""Initialize the coefficient selector.
Args:
coefs (dict): One set of calibration coefficients for each
calibration mode. The actual coefficients can be of any type
(reader-specific).
wishlist (str or dict): Desired calibration coefficients. Use a
calib_wishlist (str or dict): Desired calibration coefficients. Use a
dictionary to specify channel-specific coefficients. Use a
string to specify one mode for all channels.
default (str): Default coefficients to be used if nothing was
specified in the wishlist. Default: "nominal".
specified in the calib_wishlist. Default: "nominal".
fallback (str): Fallback coefficients if the desired coefficients
are not available for some channel. By default, an exception is
raised if coefficients are missing.
"""
if fallback and fallback not in coefs:
raise KeyError("No fallback coefficients")
raise KeyError("No fallback calibration coefficients")
self.coefs = coefs
self.wishlist = wishlist
self.calib_wishlist = calib_wishlist
self.default = default
self.fallback = fallback
self.parser = _CalibrationCoefficientParser(coefs, default)
self.parsed_wishlist = self.parser.parse(wishlist)
self.parsed_wishlist = self.parser.parse(calib_wishlist)

def get_coefs(self, channel):
"""Get calibration coefficients for the given channel.
Expand All @@ -646,7 +649,11 @@ def get_coefs(self, channel):
try:
return self.parsed_wishlist[channel]
except KeyError:
mode = self.parser.get_calib_mode(self.calib_wishlist, channel)
if self.fallback:
LOGGER.warning(
f"No {mode} calibration coefficients for {channel}. "
f"Falling back to {self.fallback}."
)
return self.coefs[self.fallback][channel]
mode = self.parser.get_calib_mode(self.wishlist, channel)
raise KeyError(f"No {mode} calibration coefficients for {channel}")
5 changes: 3 additions & 2 deletions satpy/tests/reader_tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,11 @@ def test_missing_coefs(self, coefs, wishlist):
@pytest.mark.parametrize(
"wishlist", ["mode1", {"ch2": "mode1"}, {("ch1", "ch2"): "mode1"}]
)
def test_fallback_to_nominal(self, coefs, wishlist):
def test_fallback_to_nominal(self, coefs, wishlist, caplog):
"""Test falling back to nominal coefficients."""
s = hf.CalibrationCoefficientSelector(coefs, wishlist, fallback="nominal")
assert s.get_coefs("ch2") == "nominal_ch2"
assert "Falling back" in caplog.text

def test_no_default_coefs(self):
"""Test initialization without default coefficients."""
Expand All @@ -597,7 +598,7 @@ def test_no_default_coefs(self):

def test_no_fallback(self):
"""Test initialization without fallback coefficients."""
with pytest.raises(KeyError, match="No fallback coefficients"):
with pytest.raises(KeyError, match="No fallback calibration"):
hf.CalibrationCoefficientSelector({"nominal": 123}, {}, fallback="foo")

def test_invalid_wishlist_type(self):
Expand Down

0 comments on commit a2ed4bd

Please sign in to comment.