Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FCI L2 CF harmonization #2665

Merged
merged 39 commits into from
Feb 20, 2024
Merged

Conversation

samain-eum
Copy link
Contributor

Added when necessary:

  • standard names
  • better long names
  • fill value
  • flag_values/meanings
  • option to import flag_values/meanings from netCDF4 enumerations

Copy link

codecov bot commented Dec 5, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (bca22b4) 95.40% compared to head (8ccae17) 95.89%.
Report is 28 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2665      +/-   ##
==========================================
+ Coverage   95.40%   95.89%   +0.48%     
==========================================
  Files         371      371              
  Lines       52825    52870      +45     
==========================================
+ Hits        50399    50701     +302     
+ Misses       2426     2169     -257     
Flag Coverage Δ
behaviourtests 4.15% <0.00%> (-0.01%) ⬇️
unittests 95.99% <100.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@coveralls
Copy link

coveralls commented Dec 5, 2023

Pull Request Test Coverage Report for Build 7814337362

Warning: This coverage report may be inaccurate.

We've detected an issue with your CI configuration that might affect the accuracy of this pull request's coverage report.
To ensure accuracy in future PRs, please see these guidelines.
A quick fix for this PR: rebase it; your next report should be accurate.

  • 0 of 55 (100.0%) changed or added relevant lines in 2 files are covered.
  • 7 unchanged lines in 4 files lost coverage.
  • Overall coverage increased (+0.009%) to 95.977%

Files with Coverage Reduction New Missed Lines %
satpy/readers/fy4_base.py 1 99.32%
satpy/tests/test_readers.py 1 99.36%
satpy/tests/writer_tests/test_cf.py 1 99.14%
satpy/readers/init.py 4 98.65%
Totals Coverage Status
Change from base Build 7472442128: 0.009%
Covered Lines: 50573
Relevant Lines: 52693

💛 - Coveralls

Copy link
Collaborator

@strandgren strandgren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comments inline.

satpy/readers/fci_l2_nc.py Outdated Show resolved Hide resolved
satpy/readers/fci_l2_nc.py Outdated Show resolved Hide resolved
satpy/readers/fci_l2_nc.py Outdated Show resolved Hide resolved
satpy/readers/fci_l2_nc.py Show resolved Hide resolved
satpy/etc/readers/fci_l2_nc.yaml Outdated Show resolved Hide resolved
satpy/etc/readers/fci_l2_nc.yaml Outdated Show resolved Hide resolved
satpy/etc/readers/fci_l2_nc.yaml Outdated Show resolved Hide resolved
Comment on lines 1200 to 1280
cloud_test_cmrt2:
name: cloud_test_cmrt2
resolution: 2000
file_type: nc_fci_test_clm
file_key: cloud_mask_test_result
long_name: cloud_mask_test_cmrt2
extract_byte: 17
flag_values: [0,1]
flag_meanings: ['Cloud undetected','Cloud detected']
standard_name: status_flag

cloud_test_cmrt3:
name: cloud_test_cmrt3
resolution: 2000
file_type: nc_fci_test_clm
file_key: cloud_mask_test_result
long_name: cloud_mask_test_cmrt3
extract_byte: 18
flag_values: [0,1]
flag_meanings: ['Cloud undetected','Cloud detected']
standard_name: status_flag

cloud_test_cmrt4:
name: cloud_test_cmrt4
resolution: 2000
file_type: nc_fci_test_clm
file_key: cloud_mask_test_result
long_name: cloud_mask_test_cmrt4
extract_byte: 19
flag_values: [0,1]
flag_meanings: ['Cloud undetected','Cloud detected']
standard_name: status_flag

cloud_test_cmrt5:
name: cloud_test_cmrt5
resolution: 2000
file_type: nc_fci_test_clm
file_key: cloud_mask_test_result
long_name: cloud_mask_test_cmrt5
extract_byte: 20
flag_values: [0,1]
flag_meanings: ['Cloud undetected','Cloud detected']
standard_name: status_flag
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use flag_meanings from FCIL2FS. Those are restoration tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For better clarity I would propose:

  • For cloud_test_cmrt2-4: flag_meanings: ['Clear unchanged', 'Cloud detected (restored from clear sky)']
  • For cloud_test_cmrt5: flag_meanings: ['Clear sky restored', 'Cloud unchanged'] for better clarity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this was also partly unfixed with commit: 1c02d1c

At least cloud_test_cmrt3 should have flag_meanings: ['Clear unchanged', 'Cloud detected (restored from clear sky)'] which it does no longer have.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed cloud_test_cmrt3

satpy/etc/readers/fci_l2_nc.yaml Show resolved Hide resolved
satpy/etc/readers/fci_l2_nc.yaml Outdated Show resolved Hide resolved

n_acc:
name: n_acc
resolution: 1000
file_type: nc_fci_crm
file_key: number_of_accumulations
long_name: number_of_accumulations
standard_name: number_of_accumulations

historical_data:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

historical_data is a categorical dataset and we should be able to read flag_values and flag_meanings information from the enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added enum import flag


retrieved_cloud_optical_thickness_upper_layer:
name: retrieved_cloud_optical_thickness_upper_layer
resolution: 2000
file_type: nc_fci_oca
file_key: retrieved_cloud_optical_thickness
layer: 0
long_name: cloud_optical_depth
Copy link
Collaborator

@strandgren strandgren Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(upper layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

file_type: nc_fci_oca
file_key: retrieval_error_cloud_optical_thickness
layer: 0
standard_name: atmosphere_optical_thickness_due_to_cloud standard_error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(upper layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names


retrieved_cloud_optical_thickness_lower_layer:
name: retrieved_cloud_optical_thickness_lower_layer
resolution: 2000
file_type: nc_fci_oca
file_key: retrieved_cloud_optical_thickness
layer: 1
long_name: cloud_optical_depth
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(lower layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

file_type: nc_fci_oca
file_key: retrieval_error_cloud_optical_thickness
layer: 1
standard_name: atmosphere_optical_thickness_due_to_cloud standard_error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(lower layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names


retrieved_cloud_particle_effective_radius:
name: retrieved_cloud_particle_effective_radius
name: retrieved_cloud_particle_effective_radius_upper_layer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "_upper_layer" since this a 2D dataset, which is independent of the retrieved layers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

retrieved_cloud_top_temperature:
name: retrieved_cloud_top_temperature
retrieval_error_cloud_particle_effective_radius:
name: retrieval_error_cloud_particle_effective_radius_upper_layer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "_upper_layer" since this a 2D dataset, which is independent of the retrieved layers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

resolution: 2000
file_type: nc_fci_oca
file_key: retrieved_cloud_particle_effective_radius
standard_name: effective_radius_of_cloud_condensed_water_particles_at_cloud_top
standard_name: effective_radius_of_cloud_particles
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

effective_radius_of_cloud_particles --> effective_radius_of_cloud_particles_at_cloud_top

file_key: retrieved_cloud_top_temperature
standard_name: air_temperature_at_cloud_top
file_key: retrieval_error_cloud_particle_effective_radius
standard_name: effective_radius_of_cloud_particles standard_error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

effective_radius_of_cloud_particles --> effective_radius_of_cloud_particles_at_cloud_top

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "_at_cloud_top" to both retrieved effective radius and its error

@@ -340,6 +401,14 @@ datasets:
layer: 0
standard_name: air_pressure_at_cloud_top
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(upper layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

file_type: nc_fci_oca
file_key: retrieval_error_cloud_top_pressure
layer: 0
standard_name: air_pressure_at_cloud_top standard_error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(upper layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

@@ -348,163 +417,147 @@ datasets:
layer: 1
standard_name: air_pressure_at_cloud_top
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(lower layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

layer: 1
long_name: cloud_optical_depth
standard_name: air_pressure_at_cloud_top standard_erro
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would add the long_name from the FCIL2FS but with the addition "(lower layer)" at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appended "for upper/lower layer" to the long names

layer: 1
long_name: cloud_optical_depth
standard_name: air_pressure_at_cloud_top standard_erro
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard_erro --> standard_error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

retrieval_error_cloud_top_pressure_upper_layer:
name: retrieval_error_cloud_top_pressure_upper_layer
retrieved_cloud_top_temperature:
name: retrieved_cloud_top_temperature_upper_layer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "_upper_layer" since this a 2D dataset, which is independent of the retrieved layers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

retrieval_error_cloud_top_pressure_lower_layer:
name: retrieval_error_cloud_top_pressure_lower_layer
retrieved_cloud_top_height:
name: retrieved_cloud_top_height_upper_layer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "_upper_layer" since this a 2D dataset, which is independent of the retrieved layers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -1250,7 +1349,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: bt_std
long_name: brightness_temperature_standard_deviation_in_segment
long_name: TOA Brightess Temperature standard deviation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard deviation --> segment standard deviation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1260,7 +1361,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: radiance_max
long_name: maximum_radiance_in_segment
long_name: TOA max Radiance
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align with naming above: TOA radiance segment max

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1270,7 +1373,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: radiance_mean
long_name: mean_radiance_in_segment
long_name: TOA mean Radiance
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align with naming above: TOA radiance segment mean

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1280,7 +1385,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: radiance_min
long_name: minimum_radiance_in_segment
long_name: TOA min Radiance
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align with naming above: TOA radiance segment min

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1290,7 +1397,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: radiance_std
long_name: radiance_standard_deviation_in_segment
long_name: TOA Outgoing Radiance standard deviation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align with naming above: TOA radiance segment standard deviation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1330,7 +1445,9 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: reflectance_std
long_name: reflectance_standard_deviation_in_segment
long_name: TOA Bidirectional Reflectance standard deviation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align with naming above: TOA Bidirectional Reflectance segment standard deviation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

coordinates:
- longitude
- latitude

quality_radiance:
name: quality_radiance
resolution: 32000
wavelength: []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed
I had a few of those because if I don't include that line in the script, the writing of the full bloc is messed up somehow. So I had to remove it manually afterward.

@@ -1373,7 +1494,7 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: land_pixel_percent
long_name: land_pixel_percentage_in_segment
standard_name: land_area_fraction
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add units: %, set to none in netcdf file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1383,7 +1504,7 @@ datasets:
resolution: 32000
file_type: nc_fci_asr
file_key: water_pixel_percent
long_name: water_pixel_percentage_in_segment
standard_name: water_area_fraction
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add units: %, set to none in netcdf file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@samain-eum samain-eum marked this pull request as ready for review January 11, 2024 08:36
Copy link
Collaborator

@sjoro sjoro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few comments:

  1. use of segmented-keyword in _set_attributes-method and then checking this (lines 84-89 in fci_l2_nc.py) and renaming dimensions accordingly should be simplified. as the dimension names are fixed they should be set in respective classes as class (or instant) variables , e.g.:
class FciL2NCFileHandler(FciL2CommonFunctions, BaseFileHandler):
    """Reader class for FCI L2 products in NetCDF4 format."""

    xdim, ydim = "number_of_columns", "number_of_rows"

    def __init__(self, filename, filename_info, filetype_info, with_area_definition=True):
        """Open the NetCDF file with xarray and prepare for dataset reading."""
    ...

then the method could be simplified as

    def _set_attributes(self, variable, dataset_info):
        """Set dataset attributes."""
        if dataset_info["file_key"] not in ["product_quality", "product_completeness", "product_timeliness"]:
            variable = variable.rename({self.ydim: "y", self.xdim: "x"})
        ...
  1. fci_l2_nc.yaml -file has a lot of duplicate datasets. for example, quality_illumination is defined for clm as quality_illumination_clm, the same dataset is defined in ct-product as quality_illumination_ct. this dataset should only be defined once and use file_type to assign the dataset to respective products:
  quality_illumination:
    name: quality_illumination
    resolution: 2000
    file_type: [nc_fci_clm, nc_fci_ct]
    file_key: quality_illumination
    long_name: illumination_classification
    standard_name: status_flag
    fill_value: -127
    import_enum_information: True

multiple similar cases can be found, e.g. quality_nwp_parameters, quality_MTG_parameters, quality_overall_processing, etc...

  1. a nitpick comment on the order of the keys for datasets... i would prefer to see the order name, long_name, standard_name, resolution, file_type, and then the other keys... please see seviri_l2_grib.yaml as an example. similar ordering was done there.

  2. last nitpick... i would rename file_key to nc_key for clarity. maybe this is just me but reading dataset_info["file_key"] confuses me everytime. i know file_key is used in other readers, too. i find it equally bad there too :D

thanks for working on this olivier! much appreciated to get this reader sorted out!

variable.attrs.update(dataset_info)
variable.attrs.update(self._get_global_attributes())

import_enum_information = dataset_info.get("import_enum_information", False)
if (import_enum_information):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order to reduce complexity, this block, i.e. adding flag_values and flag_meanings as attributes should be a separate method, e.g. _set_flag_values_and_meanings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

long_name: quality_index
standard_name: status_flag
fill_value: -127
import_enum_information: True

quality_MTG_parameters_clm:
Copy link
Collaborator

@sjoro sjoro Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataset names are typically all lower case, please rename to quality_mtg_parameters (also remove _clm, see other comment)

@sjoro sjoro added component:readers cleanup Code cleanup but otherwise no change in functionality labels Jan 12, 2024
@samain-eum samain-eum marked this pull request as draft January 15, 2024 12:52
@samain-eum samain-eum marked this pull request as ready for review January 29, 2024 10:27
@strandgren
Copy link
Collaborator

This PR is now ready for review. The main modifications are related to CF harmonization of the dataset attributes, so no real change in the reader code itself, except for improved handing on the unit in order to comply with CF as well as the extraction of the flag_values and flag_meanings from the netcdf file if available.

For the quality assessment datasets the dataset names have been simplified thanks to the use of list of applicable file_types instead (e.g. product_quality_clm -> product_quality). However, since neither test nor real FCI L2 data have been released, this should not be an issue and users should benefit from the harmonized naming convention.

Copy link
Member

@mraspaud mraspaud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm, thanks for adding the new tests!

@mraspaud mraspaud merged commit 6c19e44 into pytroll:main Feb 20, 2024
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cleanup Code cleanup but otherwise no change in functionality component:readers
Projects
Development

Successfully merging this pull request may close these issues.

5 participants