satpy icon indicating copy to clipboard operation
satpy copied to clipboard

Introduce `oblique_reflectance` calibration

Open mraspaud opened this issue 2 months ago • 5 comments

(related to #3271 )

As of today, the "reflectance" calibration level refers to both sunz normalized and not normalised "reflectance" quantities. In order to correct the situation, we need to differentiate these two quantities, and we thus need to add a new "oblique_reflectance" calibration level to refer no the non-normalised quantity.

The objective here is to get a minimal working solution, without bells and whistles to start with.

We have identified a few things to discuss/work on:

  • Need to add utilities for readers:
if data_id[“calibration”] == _obliquereflectance_name():
    # do oblique-reflectance calibration
elif data_id[“calibration] == “reflectance”:
    # do real-reflectance calibration
  • Update reader YAML files with new calibration names where necessary
  • Add oblique reflectance calibration name to builtin Enum and any appropriate custom reader YAML definitions for calibration
  • Satpy.config entry for using new calibration name for oblique-reflectance
  • Do “sunz_corrected” modifiers update the calibration name? Can the Dependency Tree handle that?
    • Would need to test:
scn.load([“C01”], modifiers=(“sunz_corrected”,))
scn.load([DataQuery(name=”C01”, calibration=”reflectance”, modifiers=(“sunz_corrected”,))]) (should this crash?)
scn.load([DataQuery(name=”C01”, calibration=”oblique_reflectance”, modifiers=(“sunz_corrected”,))])
  • Lazy workaround: Don’t update calibration in modifier(s)

mraspaud avatar Oct 22 '25 09:10 mraspaud

I strongly oppose the use of the term oblique_reflectance for two reasons:

  1. This term is rarely used in Earth Observation literature and is never used in any official standards documents (that I can find).
  2. This term introduces a source of confusion for sensors with multiangular viewing geometry, for which the off-nadir views are typically referred to as "oblique". S3/SLSTR is the primary example of this confusion, but others exist too.

Instead, I propose use of the term radiance_factor for the non-normalised term, which has previously been used by QA4EO. I would then suggest reflectance_factor for the normalised term, as this is the correct terminology used by QA4EO and CEOS.

simonrp84 avatar Oct 27 '25 19:10 simonrp84

The oblique_reflectance was my suggestion as the CF standard name for the non-SZA corrected TOA reflectance. The other suggestions tried to explain everything and so are ver,y very, very long.

This can't be radiance_* because it is not radiance, but already divided by the incoming solar radiation and thus unitless.

pnuu avatar Oct 27 '25 20:10 pnuu

Just to make this clear for anyone that becomes confused as I just was, when looking also at https://github.com/pytroll/satpy/pull/3292 and #3271 :

regarding the reflectance discussion, we have two pick two things, namely

  • the satpy-internal calibration level name (the one to use with scn.load)
  • and the standard name (the one that goes into the dataset attributes)

This is important as we may want to be scientifically rigorous for the standard name (CF etc.), but we can prioritise clarity and simplicity for the satpy calibration name.

ameraner avatar Nov 11 '25 14:11 ameraner

This being said, I agree with @pnuu, I would find it quite confusing if the default way of getting a solar channel would be called radiance_factor, since anyone seeing values between 0-100 for something with radiance in it would be confused. As a satpy calibration level, oblique_reflectance could actually do: it's clear enough to indicate that it's a reflectance, but still hints that there is a different type of reflectance available that can be loaded upon request. (sorry for stirring this up again, just my 2cents, feel free to ignore it)

ameraner avatar Nov 11 '25 14:11 ameraner

also the PR here is implementing this https://github.com/pytroll/satpy/pull/3292

mraspaud avatar Nov 11 '25 15:11 mraspaud