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

Parsing of logarithmic units

Open mraspaud opened this issue 1 year ago • 2 comments

Hi, I'm working with data files having units provided as lg(re mg.m-3), which according to the udunits documentation here is valid. However trying to parse this with the units module of cf_xarrays seems to crash:

In [5]: from cf_xarray.units import units

In [6]: units("lg(re mg.m-3)")
---------------------------------------------------------------------------
UndefinedUnitError                        Traceback (most recent call last)
Cell In[6], line 1
----> 1 units("lg(re mg.m-3)")

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/facets/plain/registry.py:1264, in PlainRegistry.parse_expression(self, input_string, case_sensitive, use_decimal, **values)
   1261 input_string = string_preprocessor(input_string)
   1262 gen = tokenizer(input_string)
-> 1264 return build_eval_tree(gen).evaluate(
   1265     lambda x: self._eval_token(x, case_sensitive=case_sensitive, **values)
   1266 )

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/pint_eval.py:114, in EvalTreeNode.evaluate(self, define_op, bin_op, un_op)
    112     if op_text not in bin_op:
    113         raise DefinitionSyntaxError('missing binary operator "%s"' % op_text)
--> 114     left = self.left.evaluate(define_op, bin_op, un_op)
    115     return bin_op[op_text](left, self.right.evaluate(define_op, bin_op, un_op))
    116 elif self.operator:
    117     # unary operator

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/pint_eval.py:124, in EvalTreeNode.evaluate(self, define_op, bin_op, un_op)
    121     return un_op[op_text](self.left.evaluate(define_op, bin_op, un_op))
    122 else:
    123     # single value
--> 124     return define_op(self.left)

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/facets/plain/registry.py:1265, in PlainRegistry.parse_expression.<locals>.<lambda>(x)
   1261 input_string = string_preprocessor(input_string)
   1262 gen = tokenizer(input_string)
   1264 return build_eval_tree(gen).evaluate(
-> 1265     lambda x: self._eval_token(x, case_sensitive=case_sensitive, **values)
   1266 )

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/facets/plain/registry.py:1151, in PlainRegistry._eval_token(self, token, case_sensitive, use_decimal, **values)
   1146         return self.Quantity(values[token_text])
   1147     else:
   1148         return self.Quantity(
   1149             1,
   1150             self.UnitsContainer(
-> 1151                 {self.get_name(token_text, case_sensitive=case_sensitive): 1}
   1152             ),
   1153         )
   1154 elif token_type == NUMBER:
   1155     return ParserHelper.eval_token(token, non_int_type=self.non_int_type)

File ~/mambaforge/envs/satpy/lib/python3.11/site-packages/pint/facets/plain/registry.py:599, in PlainRegistry.get_name(self, name_or_alias, case_sensitive)
    597 candidates = self.parse_unit_name(name_or_alias, case_sensitive)
    598 if not candidates:
--> 599     raise UndefinedUnitError(name_or_alias)
    600 elif len(candidates) == 1:
    601     prefix, unit_name, _ = candidates[0]

UndefinedUnitError: 'lg' is not defined in the unit registry

I guess this is not implemented. Anything I can do to help with this?

mraspaud avatar Jun 07 '23 13:06 mraspaud

This is cf_xarray 0.8.1 by the way

mraspaud avatar Jun 07 '23 13:06 mraspaud

From https://github.com/xarray-contrib/cf-xarray/issues/446#issuecomment-1572266735

I believe pint is "missing" support for the "scaled", "offset". "logarithmic" and "grouped" string types. Indeed, this is a shortfall as discussed in https://github.com/xarray-contrib/cf-xarray/issues/225.

dcherian avatar Jun 07 '23 14:06 dcherian