-
Notifications
You must be signed in to change notification settings - Fork 94
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
Add optional metadata to Pyresample 2.0 AreaDefinition #464
Conversation
Codecov Report
@@ Coverage Diff @@
## main #464 +/- ##
==========================================
- Coverage 94.33% 94.27% -0.07%
==========================================
Files 74 78 +4
Lines 12947 12910 -37
==========================================
- Hits 12214 12171 -43
- Misses 733 739 +6
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
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 starting this! a few questions
) | ||
|
||
|
||
class AreaDefinition(LegacyAreaDefinition): |
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.
Do we want the new area def to inherit all the methods of the legacy one, or do we want to split responsibility a bit?
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.
Yeah I struggled with this decision. Initially this class in the future
subpackage didn't have anything custom about it so it was just a basic import. I think for ease of transitioning to future we might want it to be a subclass so that isinstance
checks still work? Or maybe usages of stuff like that should be fixed to be more duck-typing-friendly?
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.
I vote for more duck typing.
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.
Please read my other comments. That is the plan, but I don't want to throw that all into one PR and I also don't want to deal with all the tests failing because I didn't implement one of 50 methods on the legacy AreaDefinition class. The plan is to do this work in one of the next 2 or 3 PRs.
Co-authored-by: Martin Raspaud <martin.raspaud@smhi.se>
I think my biggest TODO on this is to move the area ID to an optional "name" metadata key in |
Includes major rewrite of future area tests to test both legacy and future area class with pytest fixtures
@mraspaud So my last commits add a new pytest fixture which returns a function that automatically handles keyword argument rearranging and defaulting so the tests in Some things I thought of or noticed while doing this and/or things that I see as needing to be done. @pnuu @gerritholl @ghiggi I'm curious on your opinions about this as well.
All of these things deserve their own PR in my opinion. It looks like I still need to fix some tests, but otherwise I think I'd like to merge this. Since it only affects the future interfaces merging this shouldn't break anything. |
Unstable CI is failing because matplotlib needs Edit: If we bumped to Python 3.10 it would work fine. |
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.
I added some inline comments on the current PR.
Other minor comments/ideas related to AreaDefinition attributes and properties:
- For AreaDefinition, many methods are not clear if they return data in xy or lat/lon; the pixel centroid or the outermost pixel corner. Maybe would be worth adding a common suffix (i.e.
_ll
) when they return lat/lons, and otherwise expect they return xy coords. This will enhance code readability.
Example:area_def.corners
currently returns the centroid lat/lon coords in the very old spherical objectarea_def.outer_boundary_corners
currently returns the corners lat/lon coords in the very old spherical object
--> Possible new methods:corners_centroids
,corners
,corners_centroids_ll
,corners_ll
... or see next bullet point
- Add utility properties like
upper_left_corner_ll
,upper_left_centroid_ll
,
A possible pattern:<lower/upper>_<right/left>_<''/'ll'>
(or bottom instead of lower).
Currently theupper_left_corner
is provided byupper_left_extent
- Add
xy_bbox
andll_bbox
properties for consistency with satpy? Equivalent toarea_extent
andarea_extent_ll
- Current
area_extent_<>
and<>_bbox
follow the(xmin, ymin, xmax, ymax)
convention. More precisely thearea_extent
is defined as(lower_left_x, lower_left_y, upper_right_x, upper_right_y)
.- This is also the convention adopted by rasterio/rioxarray/shapely object
bounds
method.
--> Maybe we could add abounds
property? - When retrieving the
area_extent_ll
(in lat/lon) the lower-left and upper-right corners do not necessarily currently define the outermost lat/lon coordinates of the area. Maybe this method should be changed! And maybe we could also add abounds_ll
method. - Additionally, the area_extent convention differs from the i.e. matplotlib cartopy and matplotlib
extent
which is defined as(xmin, xmax, ymin, ymax)
--> Maybe we could add a<mpl/cartopy>_area_extent_<''/ll>
property?
- This is also the convention adopted by rasterio/rioxarray/shapely object
- For GEO AreaDef, all the above _ll methods currently return
np.nan
/np.inf
values. Maybe ad-hoc processing usingget_geostationary_bounding_box_in_lonlats
could be implemented forarea_extent_ll
, but the corners would remain undefined ! Maybe would be worth raising an error to avoid downstream bugs !
y dimension in number of pixels, aka number of grid rows | ||
size (int): | ||
Number of points in grid | ||
area_extent_ll (tuple): |
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.
In the attributes, it should be listed also the area_extent
.
height: | ||
y dimension in number of pixels, aka number of grid rows | ||
area_extent: | ||
Area extent as a list (lower_left_x, lower_left_y, upper_right_x, upper_right_y) |
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.
Area extent as a list (lower_left_x, lower_left_y, upper_right_x, upper_right_y) | |
Area extent (in projection coordinates) provided as a list (lower_left_x, lower_left_y, upper_right_x, upper_right_y) |
Pixel width in projection units | ||
pixel_size_y (float): | ||
Pixel height in projection units | ||
upper_left_extent (tuple): |
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.
upper_left_extent
is a misleading name. I would rather call it upper_left_corner
. It's used only in AreaDefinition.from_ul_corner
btw
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.
extent
is the extreme border in all extent definitions I've seen, also outside of Pytroll, so I don't see that as very misleading.
Pixel height in projection units | ||
upper_left_extent (tuple): | ||
Coordinates (x, y) of upper left corner of upper left pixel in projection units | ||
pixel_upper_left (tuple): |
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.
Just a thought: maybe pixel_upper_left
could be renamed upper_left_centroid
(see previous comment)
Thanks for all the feedback @ghiggi, but I think there's been a misunderstanding. The tests added here (with a few exception for the new metadata handling) are all copies from the original AreaDefinition tests. None of these coordinate features/names are new/different. I think we should maybe move the discussion of changes to the AreaDefinition interface somewhere else...I thought I had an issue for that 🤔 I have my own ideas for changing interfaces and some of us have discussed them in the past. For example, put all coordinate operations (ex. Looks like there are no "here's all the area stuff we want to change" issues. We have these for v2.0: https://github.com/pytroll/pyresample/issues?q=is%3Aopen+is%3Aissue+milestone%3Av2.0 |
@ghiggi do you have any additional comments about the stuff I did in this PR? Mainly my comment just before your last comment, the idea of metadata in the AreaDefinition (in pyresample 2.0), or the pytest fixture I'm using to test both legacy areas and new areas? |
Sorry for the very late reply (and the misunderstanding) @djhoese ... I am having super busy days. |
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 PR. Some comments inline
) | ||
|
||
|
||
class AreaDefinition(LegacyAreaDefinition): |
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.
I vote for more duck typing.
area_def.area_extent = (-1000000, -900000, 1000000, 1500000) | ||
|
||
|
||
class TestAreaDefinitionMetadata: |
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.
I'm not sure about the name here. At least, should this class and all that is future-specific be moved to a future test 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.
I thought about this a lot when I started this PR and I think I still agree with past Dave. Or at least I'm 50/50 on it so I can't say I feel that strongly. The original plan (and how it is being implemented now) is that this module will test legacy and future implementations and the legacy test module will eventually be removed. So I didn't want to confuse contributions for the legacy area definition by telling people "I know you want to put the tests in test/
, but they should actually go in test/future/
even though that's not where your changes went.
@@ -0,0 +1,2003 @@ | |||
# Copyright (C) 2010-2022 Pyresample developers |
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.
Feels like this is a copy of existing tests? Is this really needed? can't we have just one version 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.
"one version" of what? Of the AreaDefinition tests? Please read my comments with my questions and my plans to remove the legacy-only tests right after this PR is merged.
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.
...and yes this copyright is here like this because these tests were copied from the original/legacy geometry tests so I guess the copyright still stands?
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.
yeah, this wasn't about the copyright :)
Ok, so I think it's a good idea to have have tests for both legacy and future in one module. But I would like to avoid being in a limbo for a while where we have duplicated tests. Do you think it's possible to remove the legacy tests already in this PR?
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 that's really what you want. The idea was that I was going to make a ton of PRs right away after this merge a week or so ago when I had time. Now I'm not so sure how fast I can do that so I guess I can put it here.
Strange. Github complained about merge conflicts but when I merged it locally it did it perfectly fine. 🤷♂️ Now to start on converting all the old tests... |
@mraspaud Ok I think this is ready from the "no duplicate tests" point of view. The tests are much more organized and are all pytest-based now. The remaining tests in the legacy module are for classes that don't currently have a future-pyresample version. |
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.
I think we're good for now, let's merge this and see what happens
As part of one of my projects it has been requested that AreaDefinition's officially support a container of metadata. This is inline with what we had planned for Pyresample 2.0. This PR is the initial support of this functionality.
Note: At the time of writing this is mostly just a refactor of pyresample's future geometry objects to prepare for this functionality.
git diff origin/main **/*py | flake8 --diff