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

Add arbitrary window smoother and refactor existing smoothers #1223

Merged
merged 8 commits into from
Jan 14, 2020
Merged

Add arbitrary window smoother and refactor existing smoothers #1223

merged 8 commits into from
Jan 14, 2020

Conversation

jthielen
Copy link
Collaborator

@jthielen jthielen commented Oct 29, 2019

Description Of Changes

I've had a good part of this sitting in my repo for a while, and I've neglected to do anything with it since I don't have tests yet. While I still don't have tests yet, #1221 gave me the idea of going back to it and put it up as a PR to get any early feedback on it, since it does strip and reattach units in the smoother. Plus, this may motivate me to finally put together the tests.

This PR adds an arbitrary window smoother that utilizes a weighted sum over offset array subsets. Convenience methods for rectangular and circular windows are also added, along with refactoring the n-point smoother to use the new window smoother (which allows more flexible dimensionality). In an attempt to be compatible with base ndarrays, pint Quantities, and xarray DataArrays, there is also a array wrapping decorator added, which may be able to be generalized to other functions for makeshift xarray support.

Checklist

@jthielen
Copy link
Collaborator Author

I've finally gotten the chance to go back through and update this. Tests and an example of the smoothers are now included. I also rebuilt the array type wrapping helper to be a decorator that should easily generalize to most calculations (any calculation which has an output that matches the dimensionality of one of its inputs). I do want to leave the WIP label on for right now though, since the wrapping helper is a mess of conditional statements and could use a refactor. But, it is much closer to being ready, and I wanted to get this out there now to hopefully help with what is needed for xarray compatibility for v1.0. Between this helper and implementing #893 as a follow-up to #1260, I think most of metpy.calc should be able to be covered?

@jthielen jthielen changed the title WIP: Add arbitrary window smoother and refactor existing smoothers Add arbitrary window smoother and refactor existing smoothers Jan 12, 2020
@jthielen
Copy link
Collaborator Author

I was able to go back and refactor the output wrapping decorator. I realized that a cleaner implementation would be to make two assumptions I think are quite reasonable:

  • we always want output as either a Pint Quantity or xarray DataArray
  • we can wrap anything that isn't a Pint Quantity or xarray DataArray as a dimensionless Quantity

So, this should be ready for a full review now!

@jthielen
Copy link
Collaborator Author

Also, one other note, since the wrapper added here is meant to generalize to most other functions to help bring greater xarray compatibility, here are the steps I would see remaining after this PR:

  • refactor preprocess_xarray to automatically broadcast xarray inputs against each other (so we can get rid of all those previously needed broadcasting hacks)
  • either refactor preprocess_xarray or add a new decorator to automatically fill in all coordinate-dependent arguments (dx, dy, latitude, f)
  • Propagate dim order independence features made capable by Refactor xarray grid deltas calculation to handle axis order flexibly #1260 throughout kinematics
  • include this new wrapper on most functions in the library (except those that already have xarray handling or do not have outputs that match the dimensionality of one of its inputs)

@dopplershift dopplershift added this to the 1.0 milestone Jan 13, 2020
@dopplershift dopplershift added Area: Calc Pertains to calculations Type: Feature New functionality labels Jan 13, 2020
Copy link
Contributor

@jrleeman jrleeman left a comment

Choose a reason for hiding this comment

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

Just a few minor comments - mostly to clarify code or docs. I didn't follow the numerics through rigorously, but it looks pretty good to me. The cleanup in the codebase is a big net plus here!

src/metpy/calc/basic.py Show resolved Hide resolved
for _ in range(passes):
# Set values corresponding to smoothing weights by summing over each weight and
# applying offsets in needed dimensions
data[_trailing_dims(_offset(_pad(n), 0) for n in weights.shape)] = sum(
Copy link
Contributor

Choose a reason for hiding this comment

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

Readability of this isn't great - maybe be a bit more explicit/verbose. Shouldn't be a performance hit, correct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since I'm iteratively modifying the array that is used in the calculation, replacing the sum with a loop would require another temporary array that would be cleared each pass, which I think would be a hit on memory? I could assign some of the indexers to temporary variables or internal functions to try making it more readable though.


"""
# Generate the circle
size = 2 * radius + 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Plus one so it's inclusive in the radius? Maybe note that in the docs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Plus one since the window has to have odd shape in all dimensions. I'll definitely add a note to the docs.

+ r * (smooth_grid[2:, 2:] + smooth_grid[2:, :-2] +
+ smooth_grid[:-2, 2:] + smooth_grid[:-2, :-2]))
return smooth_grid
return smooth_window(scalar_grid, window=weights, passes=passes, normalize_weights=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes me 😄

@jthielen
Copy link
Collaborator Author

jthielen commented Jan 14, 2020

Updates addressing the feedback have been added, and all tests are green except the codecov tests coverage, which I have no idea why it isn't 100%.

Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

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

I’ll approve and merge, but we’ll have to figure out the tests issue unless it happens to disappear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Calc Pertains to calculations Type: Feature New functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Circular/Rectangular Aperture Smoother
3 participants