Skip to content

Higher-order unit conversion with GWP context #36

@lewisjared

Description

@lewisjared

Describe the bug

Unit conversion fails when using a GWP context for units that have higher-order dimensionality. For example, one cannot convert kg CO2/EJ to kg CH4/EJ, but kg CO2/yr => kg CH4/yr works.

The above example fails with the following message:

Cannot convert from 'CO2 * metric_ton / exajoule' ([carbon] * [time] ** 2 / [length] ** 2) to 'CH4 * metric_ton / exajoule' ([methane] * [time] ** 2 / [length] ** 2)

Maybe I'm doing something wrong, but the dimensions match (except for carbon=>CH4 which should be handled by the GWP context).

Failing Test

def test_multidimensional_with_context():
    with unit_registry.context("AR6GWP100"):
        unit_registry("t CO2/EJ").to("t CH4/EJ")

This test fails with the following exception message:

test_units.py::test_multidimensional_with_context FAILED                 [100%]
tests/unit/test_units.py:373 (test_multidimensional_with_context)
def test_multidimensional_with_context():
        with unit_registry.context("AR6GWP100"):
>           unit_registry("t CO2/EJ").to("t CH4/EJ")

test_units.py:376: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../venv/lib/python3.9/site-packages/pint/quantity.py:716: in to
    magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
../../venv/lib/python3.9/site-packages/pint/quantity.py:665: in _convert_magnitude_not_inplace
    return self._REGISTRY.convert(self._magnitude, self._units, other)
../../venv/lib/python3.9/site-packages/pint/registry.py:1044: in convert
    return self._convert(value, src, dst, inplace)
../../venv/lib/python3.9/site-packages/pint/registry.py:1959: in _convert
    return super()._convert(value, src, dst, inplace)
../../venv/lib/python3.9/site-packages/pint/registry.py:1566: in _convert
    return super()._convert(value, src, dst, inplace)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <openscm_units._unit_registry.ScmUnitRegistry object at 0x7fb8bf642370>
value = 1.0, src = <UnitsContainer({'CO2': 1, 'exajoule': -1, 'metric_ton': 1})>
dst = <UnitsContainer({'CH4': 1, 'exajoule': -1, 'metric_ton': 1})>
inplace = False, check_dimensionality = True

    def _convert(self, value, src, dst, inplace=False, check_dimensionality=True):
        """Convert value from some source to destination units.
    
        Parameters
        ----------
        value :
            value
        src : UnitsContainer
            source units.
        dst : UnitsContainer
            destination units.
        inplace :
             (Default value = False)
        check_dimensionality :
             (Default value = True)
    
        Returns
        -------
        type
            converted value
    
        """
    
        if check_dimensionality:
    
            src_dim = self._get_dimensionality(src)
            dst_dim = self._get_dimensionality(dst)
    
            # If the source and destination dimensionality are different,
            # then the conversion cannot be performed.
            if src_dim != dst_dim:
>               raise DimensionalityError(src, dst, src_dim, dst_dim)
E               pint.errors.DimensionalityError: Cannot convert from 'CO2 * metric_ton / exajoule' ([carbon] * [time] ** 2 / [length] ** 2) to 'CH4 * metric_ton / exajoule' ([methane] * [time] ** 2 / [length] ** 2)

../../venv/lib/python3.9/site-packages/pint/registry.py:1077: DimensionalityError

Expected behavior

Units are able to be converted

System (please complete the following information):
Ubuntu
Python 3.9
commit f97fac6

@znicholls @rgieseke

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions