satpy icon indicating copy to clipboard operation
satpy copied to clipboard

Cannot load ABI L1 datasets from Scene combining L1 and L2

Open gerritholl opened this issue 2 years ago • 6 comments

Describe the bug

When I load ABI L1 and L2 data into the same Scene, I can't load L1 datasets.

To Reproduce

from satpy import Scene
from satpy.utils import debug_on; debug_on()

files_l1b = ["/media/nas/x21308/abi/G16-ABI-L1B-RadC/2021/OR_ABI-L1b-RadC-M6C10_G16_s20213332001177_e20213332003561_c20213332004003.nc"]
files_l2 = ["/media/nas/x21308/abi/G16-L2-ACHAC/OR_ABI-L2-ACHAC-M6_G16_s20213332001177_e20213332003550_c20213332007025.nc"]
global_scene = Scene({"abi_l1b": files_l1b, "abi_l2_nc": files_l2})

global_scene.load(["C10"])

Expected behavior

I expect the loading to work just as it would (and does) when I pass only L1 files upon Scene initiation.

Actual results

It fails to load channel 10 because it says the file types abi_l2_cmip_c10 and abi_l2_cmip are missing. That's wrong. I shouldn't and don't need L2 CMIP data to load L1 channel 10.

[DEBUG: 2021-12-01 14:08:30 : satpy.readers.yaml_reader] Reading ('/data/gholl/checkouts/satpy/satpy/etc/readers/abi_l1b.yaml',)
[DEBUG: 2021-12-01 14:08:30 : satpy.readers.yaml_reader] Assigning to abi_l1b: ['/media/nas/x21308/abi/G16-ABI-L1B-RadC/2021/OR_ABI-L1b-RadC-M6C10_G16_s20213332001177_e20213332003561_c20213332004003.nc']
[DEBUG: 2021-12-01 14:08:31 : satpy.readers.yaml_reader] Reading ('/data/gholl/checkouts/satpy/satpy/etc/readers/abi_l2_nc.yaml',)
[DEBUG: 2021-12-01 14:08:31 : satpy.readers.yaml_reader] Assigning to abi_l2_nc: ['/media/nas/x21308/abi/G16-L2-ACHAC/OR_ABI-L2-ACHAC-M6_G16_s20213332001177_e20213332003550_c20213332007025.nc']
[DEBUG: 2021-12-01 14:08:31 : satpy.composites.config_loader] Looking for composites config file abi.yaml
[DEBUG: 2021-12-01 14:08:31 : satpy.composites.config_loader] Looking for composites config file visir.yaml
[WARNING: 2021-12-01 14:08:31 : satpy.readers.yaml_reader] Required file type '['abi_l2_cmip_c10', 'abi_l2_mcmip']' not found or loaded for 'C10'
[WARNING: 2021-12-01 14:08:31 : satpy.scene] The following datasets were not created and may require resampling to be generated: DataID(name='C10', wavelength=WavelengthRange(min=7.24, central=7.34, max=7.44, unit='µm'), calibration=<calibration.brightness_temperature>, modifiers=())

Resampling does not generate C10 either.

Environment Info:

  • OS: openSUSE Leap 15.3
  • Satpy Version: v0.31.0-158-g5dae1e6c

gerritholl avatar Dec 01 '21 13:12 gerritholl

Oh very interesting. So the problem is that the ABI L2 reader has a C10 that it can load:

https://github.com/pytroll/satpy/blob/4950ccde2304d82fb7463289febe17f86a232fc4/satpy/etc/readers/abi_l2_nc.yaml#L80-L85

If you asked for the "calibration='radiance'" version of that channel I would suspect it to work. I'm not sure there is an easy way to fix this. It would require the portion of the Scene/DependencyTree that is asking the reader for a dataset to check all readers that know about a dataset and attempt to load the dataset from each one until it is successful (or fails).

djhoese avatar Dec 01 '21 16:12 djhoese

I vote for renaming the ABI L2 C10 product...

gerritholl avatar Dec 08 '21 15:12 gerritholl

The only issue with that is then they can't be used when making composites as most of the composites use the specific product name.

djhoese avatar Dec 08 '21 15:12 djhoese

Possibly related? https://github.com/pytroll/satpy/issues/2331

gerritholl avatar Jun 19 '23 09:06 gerritholl

Wow, can't believe this issue already exists. @simonrp84 brought this up on slack which I'm guessing is why you commented here. In his case he was able to get a L1b + L2 composite to work when he updated the composites using L1b channels to specify a resolution: X since the L2 reader's DataID doesn't include resolution, but the L1b reader does. This is a workaround, but only lucky in this particular case since logically the L2 reader should be able (allowed) to be specify the resolution. Also important to note, he was not provided the L2 files that provided the equivalent of the L1b channels so the dependency tree wanted to use DataIDs that weren't available/loadable.

The main issue(s) I discovered after last diving into the dependency tree code is that the dependency tree looks at all known DataIDs and doesn't consider whether or not the DataIDs are available. Also the dep tree says "here are all the DataIDs from all the readers that match the request, which one matches most closely". In the L1b/L2 case, just by chance of the way it was coded, when a resolution isn't specified in the request, the resolution in the DataID is ignored and the L2 (no resolution) DataID is considered a "better match". If the L2 DataID did define a resolution I have a feeling we'd get a TooManyResults exception meaning that the dependency tree found two or more DataIDs that matched equally well to the requested DataQuery.

Regardless of the above, even if L2 specified resolution for its DataIDs and even if the user provided the necessary L2 data files, the dependency tree should probably be able to resolve/choose these conflicts based on:

  1. What's available. For example, L2's version isn't available but L1b is, use L1b.
  2. Some inherent order or user provided order. The user may initialize the Scene with a filenames={"reader": [...], "reader2": [...]} dictionary where the dict has some order associated with it depending on how it was created. Or the readers could have some relationship/understanding that the L2 reader is reading "descendant" datasets of the L1b data. I'm not sure if in that case the dependency tree should prefer L2 (the descendant/child) or L1b (the ancestor/parent).

djhoese avatar Jun 19 '23 14:06 djhoese

On your second point, I think that if both L1 and L2 dataset files are provided by the user them the higher level dataset should be used by default.

simonrp84 avatar Jun 19 '23 14:06 simonrp84