Skip to content

Commit

Permalink
fixes the issue #54
Browse files Browse the repository at this point in the history
  • Loading branch information
siligam committed Nov 8, 2024
1 parent 367a1fc commit 7d9d910
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
2 changes: 2 additions & 0 deletions data/dimensionless_mappings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
# cmor_unit_string: pint_friendly_SI_units
so:
"0.001": g/kg
so:
"0.001": g/kg
2 changes: 1 addition & 1 deletion examples/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pymorize:
fixed_jobs: 12
# minimum_jobs: 8
# maximum_jobs: 30
dimensionless_mapping_table: ./data/dimensionless_mappings.yaml
dimensionless_mapping_table: ../data/dimensionless_mappings.yaml
rules:
- name: paul_example_rule
description: "You can put some text here"
Expand Down
35 changes: 16 additions & 19 deletions src/pymorize/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@
In case the units in model files differ from CMIP Tables, this module attempts to
convert them automatically.
In case of missing units in either model files or CMIP Tables, this module can
not convert from a dimentionless base to something with dimension. Dealing with
such thing have to done with `action` section in the Rules module on a per
variable basis.
Additionally, the cmip frequencies are mapped here. The CMIP6 frequency
names and corresponding number of days are available as a dictionary in the
``CMIP_FREQUENCIES`` variable. Assignment of these frequencies to the unit registry
can be done with the ``assign_frequency_to_unit_registry`` function.
Conversion to-or-from a dimensionless quantity is ambiguous. In this case,
provide a mapping of what this dimensionless quantity represents and that
is used for the conversion. `data/dimensionless_mappings.yaml` contains some
examples on how the mapping is written.
"""

import re
Expand All @@ -27,19 +22,12 @@
import xarray as xr
from chemicals import periodic_table

from .frequency import CMIP_FREQUENCIES
from .logging import logger
from .rule import Rule

ureg = pint_xarray.unit_registry


def assign_frequency_to_unit_registry():
"""Assign the CMIP6 frequencies to the unit registry."""
for freq_name, days in CMIP_FREQUENCIES.items():
ureg.define(f"{freq_name} = {days} * d")


def handle_chemicals(
s: Union[str, None] = None, pattern: Pattern = re.compile(r"mol(?P<symbol>\w+)")
):
Expand Down Expand Up @@ -110,15 +98,24 @@ def handle_unit_conversion(da: xr.DataArray, rule: Rule) -> xr.DataArray:
model_unit = rule.get("model_unit")
from_unit = da.attrs.get("units")
if model_unit is not None:
logger.debug(
logger.info(
f"using user defined unit ({model_unit}) instead of ({from_unit}) from DataArray "
)
from_unit = model_unit
handle_chemicals(from_unit)
handle_chemicals(to_unit)
new_da = da.pint.quantify(from_unit)
logger.debug(f"Converting units: {from_unit} -> {to_unit}")
new_da = new_da.pint.to(to_unit).pint.dequantify()
dimless = rule.get("dimensionless_unit_mappings", {})
cmor_variable = rule.get("cmor_variable")
if cmor_variable in dimless:
_to_unit = dimless[cmor_variable][to_unit]
else:
_to_unit = to_unit
if _to_unit == to_unit:
logger.info(f"Converting units: ({da.name} -> {cmor_variable}) {from_unit} -> {to_unit}")
else:
logger.info(f"Converting units: ({da.name} -> {cmor_variable}) {from_unit} -> {_to_unit} ({to_unit})")
new_da = new_da.pint.to(_to_unit).pint.dequantify()
if new_da.attrs.get("units") != to_unit:
logger.debug(
"Pint auto-unit attribute setter different from requested unit string, setting manually."
Expand Down

0 comments on commit 7d9d910

Please sign in to comment.