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: New function - Apply to sweeps #202

Merged
merged 14 commits into from
Sep 30, 2024
Merged

Conversation

syedhamidali
Copy link
Contributor

@syedhamidali syedhamidali commented Aug 31, 2024

Description:

This PR introduces a new utility function, apply_to_sweeps, that allows users to apply a custom function to each sweep within a radar volume stored in a DataTree object. This is particularly useful for tasks where you need to perform the same operation across multiple sweeps, such as calculating derived quantities like rain rate from radar reflectivity.

Example Usage:

Here’s an example of how to use the apply_to_sweeps function to calculate rain rates using the Marshall-Palmer power law:

import xradar as xd
from open_radar_data import DATASETS

# Fetch a sample radar file
file = DATASETS.fetch('KATX20130717_195021_V06')

# Open the radar file into a DataTree object
dtree = xd.io.open_nexradlevel2_datatree(file)

# Define the function to calculate rain rate using the Marshall-Palmer relation
def xradar_rain_rate(ds):
    def _rain_rate(dbz, a=200.0, b=1.6):
        """Calculates the inverse of input decibel values
        Convert to rain rate using the Marshall-Palmer relation
        """
        Z = 10.0 ** (dbz / 10.0)  # Convert dBZ to linear Z
        return (Z / a) ** (1.0 / b)  # Apply the Marshall-Palmer power law

    # Apply the rain rate calculation to the DBZH field
    ds['RAIN_RATE'] = _rain_rate(ds['DBZH'])
    ds['RAIN_RATE'].attrs = {'unit': 'mm/h',
                             'long_name': 'Rain Rate'}
    return ds

# Apply the rain rate function to all sweeps in the DataTree
dtree = xd.util.apply_to_sweeps(dtree, xradar_rain_rate)

# Check that the rain_rate variable has been added to one of the sweeps
for var in dtree['sweep_3']:
     print(var)
DBZH
VRADH
WRADH
sweep_mode
sweep_number
prt_mode
follow_mode
sweep_fixed_angle
RAIN_RATE

Here's another example for example using filter_radar function

file = DATASETS.fetch('RAW_NA_000_125_20080411183259')
dtree = xd.io.open_iris_datatree(file)

def filter_radar(ds):
    ds['DBZH_F'] = ds.where((ds['DBZH']>10) & (ds['DBZH']<60))['DBZH']
    return ds

dtree = xd.util.apply_to_sweeps(dtree, filter_radar)
dtree = dtree.xradar.georeference()

fig, ax = plt.subplots(1, 2, figsize=(10, 4))
dtree['sweep_0']['DBZH'].plot(x='x', y='y', vmin=-10, vmax=60, cmap='Spectral_r', ax=ax[0])
dtree['sweep_0']['DBZH_F'].plot(x='x', y='y', vmin=-10, vmax=60, cmap='Spectral_r', ax=ax[1])

image

# If you want to apply this filter on all other fields
def filter_radar(ds):
    ds = ds.where((ds['DBZH']>10) & (ds['DBZH']<60))
    return ds

@syedhamidali syedhamidali changed the title ENH: New function - Apply to sweeps ADD: New function - Apply to sweeps Aug 31, 2024
Copy link

codecov bot commented Aug 31, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.97%. Comparing base (7ff84a7) to head (bc842ff).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #202      +/-   ##
==========================================
+ Coverage   91.95%   91.97%   +0.01%     
==========================================
  Files          23       23              
  Lines        4562     4573      +11     
==========================================
+ Hits         4195     4206      +11     
  Misses        367      367              
Flag Coverage Δ
notebooktests 78.24% <58.33%> (-0.06%) ⬇️
unittests 90.24% <100.00%> (+0.02%) ⬆️

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.

@kmuehlbauer
Copy link
Collaborator

@syedhamidali Great idea!

We already have implemented the georeferencing to work over a tree. We might think to generalize that approach using this Pull Request.

For the georeferencing we used accessors and the .pipe method under the hood.

From my perspective it would make sense to implement your approach as accessor, too.

The API would be like this:

dtree = dtree.xradar.apply(function, *args, **kwargs)

Where apply would be your apply_to_sweep and function the function to be applied. If done the right way with the accessors the function can be applied to DataArrays, Datasets and DataTrees.

Does that make sense?

@syedhamidali
Copy link
Contributor Author

@kmuehlbauer Thanks!

Yeah, I agree that dtree = dtree.xradar.apply(function, *args, **kwargs) would be a great enhancement. It would make the approach more versatile and consistent with the existing API. However, I’m not yet familiar with how these accessors are built, so I’d appreciate any guidance or examples on how to implement this. Or, if you have the time to implement it yourself, that would be great too!

@syedhamidali syedhamidali self-assigned this Aug 31, 2024
@syedhamidali syedhamidali added the enhancement New feature or request label Aug 31, 2024
@kmuehlbauer
Copy link
Collaborator

@syedhamidali I'll respond with some more details later this weekend. Thanks for being supportive of the overall idea!

@syedhamidali
Copy link
Contributor Author

@kmuehlbauer, when you get a chance, could you take a quick look at PR #203? I’d really appreciate your feedback.

Copy link
Collaborator

@mgrover1 mgrover1 left a comment

Choose a reason for hiding this comment

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

I like this approach - to @kmuehlbauer 's point, we can follow up with that in another PR, I think this functionality will be useful! Please address the comment related to only including the updates related to this PR

docs/history.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@kmuehlbauer kmuehlbauer left a comment

Choose a reason for hiding this comment

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

LGTM, let's get this in!

@kmuehlbauer kmuehlbauer merged commit c998f25 into openradar:main Sep 30, 2024
11 checks passed
@kmuehlbauer
Copy link
Collaborator

Thanks @syedhamidali!

rcjackson pushed a commit to rcjackson/xradar that referenced this pull request Nov 26, 2024
* ENH: New function - Apply to sweeps
* ADD: Added new function for volume operation
* ADD: Test apply_to_sweeps
* FIX: test_util apply_to_sweeps
* FIX: Pytest fix for apply_to_sweeps
* FIX: Cfradial1 writer
* FIX: Cfradial1 writer + pre-commit
* ENH: Improvment in Cfradial1 Writer
* FIX: Apply_to_sweeps
* Update apply_to_sweeps
* FIX: fix missing doc link
* MNT: Drop unrelated comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
3 participants