cf-xarray icon indicating copy to clipboard operation
cf-xarray copied to clipboard

updates to unit support

Open dcherian opened this issue 3 years ago • 16 comments

Current todo list remaining:

  • [ ] add documentation
    • Examples of using cf-xarray and pint-xarray together
    • ~Instructing users to either import cf-xarray before pint-xarray or set~ not necessary with pint>=0.18
    • List current known shortfalls of this registry compared to full UDUNITS support (namely case sensitivity)
      • xref #450 , #446
  • [ ] add tests of this registry's quantities being used within xarray, and not just correctly parsing units with the customized features.

Originally posted by @jthielen in https://github.com/xarray-contrib/cf-xarray/pull/197#issuecomment-816038767

dcherian avatar May 18 '21 17:05 dcherian

I've run across this discussion and work now and am interested in using it! Is the pint unit stuff sort of separate from the other cf-xarray stuff? I am looking to interpret units in xarray Datasets but with units including psu and for example m s-1.

kthyng avatar Jun 02 '21 14:06 kthyng

indeed, the only thing it does for now is provide a special pint.UnitRegistry object so datasets with cfunits style "units" attributes can be used with pint-xarray.

The documentation for this feature of cf-xarray is still missing, though, and we need to get pint's application registry to work reliably but it should be usable right now. In any case I encourage you to try it out and report any issues you run into.

keewis avatar Jun 02 '21 17:06 keewis

Thanks @keewis! I haven't actually used pint before today so it's slow going, but I'll see what I can figure out.

kthyng avatar Jun 02 '21 22:06 kthyng

if you're willing to take the time I'd also be interested in feedback on what you found difficult to understand: we didn't check the documentation of pint-xarray in that regard, yet.

keewis avatar Jun 02 '21 22:06 keewis

I've gotten a little bit into this and get something to work, so that has been exciting. I've immediately hit another unit problem though: salinity units as 1e-3. Is this one that can be added into the registry here?

kthyng avatar Jun 03 '21 19:06 kthyng

I don't know a lot about the units used in oceanography (for example, what is the difference between those and the "psu" that are already in the registry?) so I will leave this request to @dcherian or anyone else with more knowledge.

In general, if you can provide a unit name and the dimensionality / scale I think that should be possible.

keewis avatar Jun 03 '21 21:06 keewis

Here is just a basic example I was able to cobble together from the pint-xarray docs and looking at the commits in the new unit changes here in cf-xarray got me far:

import pint
# order apparently matters
from cf_xarray.units import units
import pint_xarray

ds = xr.open_dataset([your dataset])
ds = ds.pint.quantify()  # to interpret units
# units like m s-1 will be interpretable by pint with the cf_xarray unit registry
ds['temp'] = ds['temp'].pint.to('degree_Celsius')  # convert units
ds = ds.pint.dequantify()  # to go back to normal use

kthyng avatar Jun 03 '21 22:06 kthyng

@keewis Unfortunately salinity is represented by a bunch of "essentially" interchangeable units so of course I immediately have one!

@dcherian Can I add a line in the new units file for salinity units of 1e-3?

kthyng avatar Jun 03 '21 22:06 kthyng

a tip:

ds['temp'] = ds['temp'].pint.to('degree_Celsius')

can also be written as

ds = ds.pint.to({"temp": "degree_Celsius"})

and while right now most operations are supported, some of the most important ones (e.g. sel and interp) are not. For that, there's wrapper methods on the .pint accessors. In the future, I hope we can eliminate the dequantify call (altogether or except from immediately before saving / converting to a different library).

keewis avatar Jun 03 '21 23:06 keewis

Can I add a line in the new units file for salinity units of 1e-3?

At first I was skeptical but it looks like this is widespread (https://github.com/Unidata/UDUNITS-2/issues/27).

So i think it's OK to have 1e-3 as a synonym for psu.

There are a few other aliases in this comment: https://github.com/PCMDI/pcmdi_metrics/issues/162#issuecomment-94022531 (1 psu = 1 PSS-78 = 1 Practical Salinity Scale 78 = 1.e-3)

@keewis if you want to waste some time on the history of salinity measurements see http://www.coastalwiki.org/wiki/Salinity

I like the rant by frank Millero which ends with

If the field of oceanography is to become a recognized science, it must adopt the units that are basic to the fields of chemistry and physics. It also should not adopt new units for variables that are unitless.

dcherian avatar Jun 07 '21 18:06 dcherian

Ok so should I change the line

https://github.com/xarray-contrib/cf-xarray/blob/main/cf_xarray/units.py#L44 to be the following (not sure if I need the change in capitalization for "E")

units.define("practical_salinity_unit = [] = psu  = 1 PSS-78 = 1 Practical Salinity Scale 78 = 1.e-3 = 1E-3")

kthyng avatar Jun 10 '21 19:06 kthyng

If anyone has some time, I would like to move this forward but I am stuck on knowing where to start. I tried my suggestion above and that didn't work.

kthyng avatar Jun 16 '21 14:06 kthyng

May be easier if you open a PR and posted the error message. I assume you've looked at https://pint.readthedocs.io/en/stable/defining.html?

dcherian avatar Jun 16 '21 15:06 dcherian

I am now at least!! Thanks. I'll try more and go via the PR route.

kthyng avatar Jun 16 '21 15:06 kthyng

PR #238

kthyng avatar Jun 16 '21 19:06 kthyng

FYI this:

Instructing users to either import cf-xarray before pint-xarray or set

will not be necessary anymore with hgrecco/pint#1366

keewis avatar Aug 09 '21 14:08 keewis