Skip to content

Higher-order unit conversion with GWP context #36

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions