-
Notifications
You must be signed in to change notification settings - Fork 320
Add a reader for EUMETSAT HSAF SEVIRI H60 and H63 #3287
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
base: main
Are you sure you want to change the base?
Conversation
ameraner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! I would propose to actually have only one yaml file for this reader, and you can have different file types inside the same yaml (see e.g. the other PR here https://github.com/pytroll/satpy/pull/2793/files#diff-4ce2f1c002c4dae06506b9ad57f5a0504f278028002abc6263d2cd90ae50c8c6 ). This way it's more user friendly as there is only one reader for all HSAF products, and it's easier to maintain.
Also, there are a few things to fix from the pre-commit checks.
|
Also, would it be possible to add support for the H90 product as well, if it's not a lot of work? That way we could close the other PR #2793 for good |
|
Hi @ameraner, there’s now support for H90 products. It uses the same reader and enhancements as H60 and H63. Please let us know if there’s anything else missing. Thanks for the support! |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3287 +/- ##
========================================
Coverage 96.33% 96.33%
========================================
Files 463 466 +3
Lines 58870 59036 +166
========================================
+ Hits 56711 56874 +163
- Misses 2159 2162 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ameraner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the updates! I took a closer looks and gave some more comments. The area definition assignments needs to be revised, otherwise only minor things.
|
Also, seems that the gzip decompression things are not well coverd by tests, according to codecov... satpy/satpy/readers/hrit_jma.py Lines 74 to 90 in 3e2edf2
maybe the same could be done here for simplicity? |
|
Actually, @mraspaud pointed me to the satpy/satpy/readers/core/utils.py Lines 346 to 350 in 6cdfea4
|
This commit introduces a reader enhancement for HSAF precipitation products h60b, h63 and h90. The reader includes handling for externally compressed (.gz) files by automatically unzipping them to a local temporary location.
This commit restructures and improves the reader following initial review feedback. Key changes: - Unified all file_type definitions into a single YAML configuration file - Simplified and cleaned up reader logic, removing redundant code - Expanded and clarified docstrings across the reader implementation - Improved handling of area definitions in the HSAF NetCDF reader - Generalized dataset definitions so they can be reused by multiple file types
ab49c96 to
f91dcc7
Compare
Replaced the custom logic for handling externally zipped NetCDF files with Satpy's generic_open helper, which transparently supports both compressed and uncompressed inputs. This simplifies the reader implementation and removes compression-detection code. Because generic_open uses a context manager and closes the file as soon as the reader exits the `with` block, the dataset must now be fully loaded immediately. The reader therefore calls `.compute()` on the xarray dataset to ensure all data is available after the context closes.
f91dcc7 to
4e28107
Compare
ameraner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates! Looks good - only one point on the use of compute, and a minor point on the attributes
…mains accessible - Replace the short-lived with generic_open(...) usage with manual __enter__() / __exit__() handling - Avoid loading the entire dataset via .compute(), preserving lazy operation while preventing “seek of closed file” errors. - Ensure the NetCDF file remains open for Dask-backed arrays until the reader is destroyed. - Add safe cleanup in __del__() using explicit context-manager exit and catching expected cleanup-related exceptions.
...as they're added automatically through the property methods
ameraner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for taking the initiative to add this reader and all the updates!
ReadTheDocs is currently failing, but only due to a warning regarding not being able to fetch a numpy inventory due to HTTP error, so probably just a glitch and nothing related to the PR.
|
There are some failing tests. I think the others are glitches, but I think this I fixed in an earlier PR that was merged: The same error is in few other tests, but all of them hopefully go away if you merge the current |
|
Ah, the fix is still unmerged in #3294 |
Thanks to you all for supporting us in the process. I think we can learn a lot from you guys and we will for sure add more as soon as time allows. |
|
Ok, we merged couple of PRs to |
Pull Request Test Coverage Report for Build 19674468060Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
mraspaud
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the work on supporting these HSAF products!
I especially appreciate the clarity of the code.
I have some comments, questions and suggestions inline, but I think this is almost ready :)
satpy/readers/hsaf_nc.py
Outdated
| """ | ||
|
|
||
| def __init__(self, filename, filename_info, filetype_info): | ||
| """Opens the nc file and store the nc data.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| """Opens the nc file and store the nc data.""" | |
| """Open the nc file and store the nc data.""" |
satpy/readers/hsaf_nc.py
Outdated
| super().__init__(filename, filename_info, filetype_info) | ||
| self._area_name = None | ||
| self._lon_0 = None | ||
| # use generic_open contextmanager to handle compression transparently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # use generic_open contextmanager to handle compression transparently |
satpy/readers/hsaf_nc.py
Outdated
| self._lon_0 = None | ||
| # use generic_open contextmanager to handle compression transparently | ||
| self._cm = generic_open(filename, mode="rb", compression="infer") | ||
| # manually enter the context manager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # manually enter the context manager |
satpy/readers/hsaf_nc.py
Outdated
| self._cm = generic_open(filename, mode="rb", compression="infer") | ||
| # manually enter the context manager | ||
| fp = self._cm.__enter__() | ||
| # lazily load nc file through h5netcdf without forcing read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # lazily load nc file through h5netcdf without forcing read |
satpy/readers/hsaf_nc.py
Outdated
| def __del__(self): | ||
| """Instruct the context manager to clean up and close the file.""" | ||
| try: | ||
| if hasattr(self, "_cm") and self._cm: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if hasattr(self, "_cm") and self._cm: |
I don't think this is needed: self._cm will we be present and have a value as long as the class has been instantiated. If not, this __del__ function will never be called anyway.
satpy/readers/hsaf_nc.py
Outdated
| self._area_name = self.filetype_info["area"] | ||
| self._lon_0 = float(self._nc_data.attrs["sub_satellite_longitude"].rstrip("f")) | ||
|
|
||
| # Add global attributes which are shared across datasets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # Add global attributes which are shared across datasets |
satpy/readers/hsaf_nc.py
Outdated
| @property | ||
| def end_time(self): | ||
| """Get end time.""" | ||
| return self.start_time + dt.timedelta(minutes=15) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
15: So these products will never contain rss or fci data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the products supported so far are all SEVIRI full-discs - when someone will add support for the FCI counterparts, this will need some refactoring
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, how do we keep track of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like Alexandra made it configurable now, so it's solved I'd say
| with mock.patch("satpy.readers.hsaf_nc.generic_open") as mock_generic_open, \ | ||
| mock.patch("satpy.readers.hsaf_nc.xr.open_dataset") as mock_open_dataset: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have now as policy to try to create a stub file in tmp_path instead of mocking. I think here, it's a simple matter of writing the xarray dataset to disk and use that as input file. With the added benefit that you can (g/b)zip it to test the decompression...
| @pytest.mark.parametrize( | ||
| ("file_type", "loadable_ids"), | ||
| [ | ||
| (FILE_PARAMS[FILE_TYPE_H60], ["rr", "qind"]), | ||
| (FILE_PARAMS[FILE_TYPE_H63], ["rr", "qind"]), | ||
| (FILE_PARAMS[FILE_TYPE_H90], ["acc_rr", "qind"]), | ||
| ], | ||
| ) | ||
| @pytest.mark.skipif(not os.path.exists(FILE_PARAMS[FILE_TYPE_H60]["real_file"]) or | ||
| not os.path.exists(FILE_PARAMS[FILE_TYPE_H63]["real_file"]), | ||
| reason="Real HSAF file not present") | ||
| def test_real_hsaf_file(self, file_type, loadable_ids): | ||
| """Test the reader with a real HSAF NetCDF file.""" | ||
| # Select files | ||
| loadables = file_type["reader"].select_files_from_pathnames([file_type["real_file"]]) | ||
| assert loadables, "No loadables found for the real file" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when are these real files available? are they easily downloadable from somewhere so that the user can test this?
Otherwise, I think it's as good to create stub files that mimic these files closely.
This will make it possible to use this reader for other H-SAF products (e.g. H40/H40B) in the future, provided that the corresponding file type is configured.
...so that it complies with the guidelines for the use of stub files.
...so the defined enhancement will only be applied to `rr`.
|
@ameraner @mraspaud The So thanks again for your exceptional support and feedback (also to @pnuu)! |
With this commit the tear down method of the `TestHSAFNCReader` will be correctly called and the test for the enhancement will no longer fail.
The H SAF product owners recently changed the output format of these products, and EUMETSAT requested support for the new format in EUMETView.
AUTHORS.mdif not there already