-
Notifications
You must be signed in to change notification settings - Fork 367
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
precompute finite value mask for kdtree query #2201
precompute finite value mask for kdtree query #2201
Conversation
@@ -268,16 +268,24 @@ def regrid(array, source_x_coords, source_y_coords, source_proj, target_proj, | |||
target_x_points.flatten(), | |||
target_y_points.flatten()) | |||
|
|||
# Find mask of valid points before querying kdtree: scipy >= 1.11 errors | |||
# when querying nan points, might as well use for pykdtree too. | |||
indices = np.zeros(target_xyz.shape[0], dtype=int) |
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.
was I right in having the indices
array default to 0? I based this on the indices[mask]=0
line after this, wasn't entirely certain.
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 this is fine to use 0 here as you noted because I think it is just settting it to some valid index. But, I think we still need to add these non-finite locations you found here into the mask
below as well? Something like mask = ~finite_xyz | (indices >= len(xyz))
@greglucas I think the actual code changes are ready for (final?) review. The main outstanding question I have is how to handle tests. To actually test these changes with scipy, I'd need to refactor how the scipy/pykdtree choice happens. I'm happy to do that -- my initial inclination is to add a function to set which package to use (defaulting to pykdtree) so that there is a way to toggle between the two in the test environment. Is it OK to add that to this PR or would it be better as a followup PR? Edit: it's also hard for me to tell if these test failures are from this PR, so any tips on checking that would be useful... |
I may have misunderstood but, for testing, could you monkeypatch |
not exactly -- because the scipy kdtree import only happens on initial module import. So if you monkeypatch |
One option would be to store the kdtree function handle in a variable to allow monkey patching during tests. In pseudo-code, I was thinking along the lines of:
and then using that |
OK, found a simple-ish solution. Realized that if the scipy and pykdtree kdtree object handles were imported into a module attribute similar to So I don't see anything else to add here at the moment, let me know if anything more is needed (or if there's a better approach to testing both scipy and pykdtree here). And from what I can tell, the failing tests look to be the same tests that are failing in other PRs, so I don't think this PR is causing any new failures. |
oops, forgot to setup pre-commit locally... will fix that in a moment. |
pre-commit.ci autofix |
for more information, see https://pre-commit.ci
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 this is good to go from a code perspective, I've just made a few minor nits that you can take or leave.
_ = img_trans.regrid(data, lons, lats, data_trans, target_prj, | ||
target_x, target_y) | ||
else: | ||
_ = img_trans.regrid(data, lons, lats, data_trans, target_prj, | ||
target_x, target_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.
Can you dedent this and only keep one of them and only do the monkeypatching in the if-block, but the regridding outside?
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.
Yes! Will do
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.
done!
lib/cartopy/img_transform.py
Outdated
@@ -13,11 +13,11 @@ | |||
|
|||
|
|||
try: | |||
import pykdtree.kdtree | |||
from pykdtree.kdtree import KDTree as _kdtree_handle |
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.
from pykdtree.kdtree import KDTree as _kdtree_handle | |
from pykdtree.kdtree import KDTree as _kdtreeClass |
Thoughts on making this explicit that it is a Class you're using below? I wasn't entirely clear what handle meant at first glance.
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.
also done!
Thanks for the review! Will address the changes in the next few days. (edit: done!) |
Totally OK with keeping this open til #2209 is merged then merging here to make extra sure that I'm not actually breaking any tests here. |
Thank you @chrishavlin! This was a very nice fix. |
Rationale
scipy>=1.11 now raises an error when querying a kdtree object with coordinate arrays that contain
nan
orinf
values. This PR adds a mask for finite values before that query occurs.Implications
Closes #2199