-
Notifications
You must be signed in to change notification settings - Fork 41
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 unit support to cf-xarray #197
Conversation
Thanks @jthielen! This is very exciting to see.
For 2) would the registry would be set at import? I think we may want the user to opt in with
Optional. I'd like for cf_xarray to be an easy import that really only depends on xarray for most things.
This is very cool! But since the user needs to set units manually on the axes, perhaps we can also expect them to call
I think we can test quantifying DataArrays with units like |
Actually is there any downside to calling |
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 good to me.
The only thing I still have to figure out is how the registry would be set. Using pint.set_application_registry
doesn't really work because pint_xarray
sets its default registry on import, which means that we'd have to make sure pint_xarray
is imported after cf_xarray
(should be fine if isort
is used).
Edit: requiring the user to set the unit registry themselves would work, too:
pint_xarray.unit_registry = cf_xarray.units.units
Codecov Report
@@ Coverage Diff @@
## main #197 +/- ##
==========================================
- Coverage 96.47% 96.45% -0.02%
==========================================
Files 12 14 +2
Lines 1561 1609 +48
==========================================
+ Hits 1506 1552 +46
- Misses 55 57 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Now that you mention it, no, I don't believe so, as it just sets
Yes, that is what I was envisioning, however, I wasn't thinking this module would be available on the top level by default (deliberate lack of inclusion in |
Current todo list remaining:
|
Perfect.
Is there a reason someone using cf-xarray (requiring xarray) would want the units registry (requiring pint) without using pint_xarray (requires both xarray and pint)? If not, shall we set
I don't know enough to have an opinion here. Up to you, @keewis and @jthielen |
Test failure is real. =================================== FAILURES ===================================
__________________________ test_udunits_power_syntax ___________________________
def test_udunits_power_syntax():
"""Test that UDUNITS style powers are properly parsed and interpreted."""
> assert units("m2 s-2").units == units.m ** 2 / units.s ** 2
cf_xarray/tests/test_units.py:54:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/cf_xarray_test/lib/python3.7/site-packages/pint/registry.py:1264: in parse_expression
lambda x: self._eval_token(x, case_sensitive=case_sensitive, **values)
/usr/share/miniconda/envs/cf_xarray_test/lib/python3.7/site-packages/pint/pint_eval.py:93: in evaluate
return bin_op[op_text](left, self.right.evaluate(define_op, bin_op, un_op))
/usr/share/miniconda/envs/cf_xarray_test/lib/python3.7/site-packages/pint/pint_eval.py:93: in evaluate
return bin_op[op_text](left, self.right.evaluate(define_op, bin_op, un_op))
/usr/share/miniconda/envs/cf_xarray_test/lib/python3.7/site-packages/pint/quantity.py:115: in wrapped
return f(self, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Quantity(1, 'second')>, other = -2
@check_implemented
def __pow__(self, other):
...
new_self = self
if other == 1:
return self
elif other == 0:
exponent = 0
units = self.UnitsContainer()
else:
if not self._is_multiplicative:
if self._REGISTRY.autoconvert_offset_to_baseunit:
new_self = self.to_root_units()
else:
raise OffsetUnitCalculusError(self._units)
if getattr(other, "dimensionless", False):
exponent = other.to_root_units().magnitude
units = new_self._units ** exponent
elif not getattr(other, "dimensionless", True):
raise DimensionalityError(other._units, "dimensionless")
else:
exponent = _to_magnitude(
other, self.force_ndarray, self.force_ndarray_like
)
units = new_self._units ** exponent
> magnitude = new_self._magnitude ** exponent
E ValueError: Integers to negative integer powers are not allowed. |
that's a In [3]: np.array(2) ** -1
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-8b4168950dcb> in <module>
----> 1 np.array(2) ** -1
ValueError: Integers to negative integer powers are not allowed. which can be fixed by casting the value or the exponent to Edit: not sure how to do that in the |
Sorry for the delayed response here!
Not that I can see! While we could set
I really do intend for that test to pass as-is, since if we're trying to support UDUNITS syntax, I'd think that we don't want to just support it in the units attribute/being parsed with the verbose method, but through the full standard usage of pint; i.e., something like the following should "just work": new_thing = (2 * units("s-1")) * quantified_data_array If we don't want to hold up this PR for such a fix (such as resolving the scalar issue that necessitates using |
Co-authored-by: keewis <keewis@users.noreply.github.com>
I think that's the way to go: having What do you think about adding an additional test for |
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.
@dcherian, with a fix being discussed in hgrecco/pint#1295 I think we should xfail the __call__
/ parse_expression
test and add a new one for use with parse_units
(we might be able to remove that new test should pint
change __call__
to to call parse_units
). That would leave only the documentation and examples (I don't think testing pint
+ xarray
with the new unit registry is really necessary, but I would check that the unit registry is used by pint-xarray
)
Co-authored-by: keewis <keewis@users.noreply.github.com>
FYI the bug in |
so... is this ready to go in? |
the code should be ready (if you don't count the integration test mentioned by @jthielen), but the docs are still missing. If you don't mind a separate PR for that I think this can be merged. |
* upstream/main: Update README.rst Add earthcube 2021 notebook link to readme v0.5.2 Some CMIP6 support Add pooch to binder environment (xarray-contrib#223) `add_bounds` uses `keys` rather than `dims` (xarray-contrib#221)
* main: (57 commits) Add CITATION.cff, tributors, zenodo.json (xarray-contrib#231) Add zenodo badge Improve `rename_like` (xarray-contrib#222) Don't apply mappers to DataArrays (xarray-contrib#227) Add unit support to cf-xarray (xarray-contrib#197) Update README.rst Add earthcube 2021 notebook link to readme v0.5.2 Some CMIP6 support Add pooch to binder environment (xarray-contrib#223) `add_bounds` uses `keys` rather than `dims` (xarray-contrib#221) Add .cf.formula_terms (xarray-contrib#213) Update whats-new.rst (xarray-contrib#217) add bounds property (xarray-contrib#214) Update some tests. Compile regexes Fix black Add __version__ (xarray-contrib#208) add skip to rename_like (xarray-contrib#206) Refactor out coordinate criteria to criteria.py (xarray-contrib#205) ...
Closes xarray-contrib/pint-xarray#26
As discussed in xarray-contrib/pint-xarray#26, this PR adds a copy of MetPy's Pint registry (which has some customization to better support CF/UDUNITS-style units most commonly found in CF-compliant NetCDF files) to cf-xarray. However, right now that is all that this does at this point, and so, I'd like to put this up now as a work-in-progress and hopefully start a more detailed conversation about how to move forward with this:
.pint
accessor in the.cf
accessor and use with this registry?pint-xarray
? <-- my preferencepint-xarray
into common CF-related workflows?units.setup_matplotlib()
) and testing?However, feel free to bring up any other related discussion points as well!
cc @dcherian, @keewis