[Python] Difficulty with custom conversion factor using contexts with pint

Discussão em 'Python' iniciado por Stack, Agosto 28, 2025.

  1. Stack

    Stack Membro Participativo

    I am looking to set up a fixed conversion factor between two specific units that cause a DimensionalityError in pint.

    I have daily accumulated solar radiation data that is in J/m2 and want to convert it into W/m2. Since this is a daily accumulation, we just need to multiply by (1/86400). (See, e.g. https://confluence.ecmwf.int/displa...mentation#ERA5:datadocumentation-Monthlymeans).

    When trying to convert with pint, it understandably gives an error.

    import pint
    ureg = pint.UnitRegistry()
    q = 1 * ureg.Unit('joule / meter ** 2')
    q.to('watt / meter ** 2')


    DimensionalityError: Cannot convert from 'joule / meter ** 2' ([mass] / [time] ** 2) to 'watt / meter ** 2' ([mass] / [time] ** 3)


    I am trying to create a custom context to deal with this, but I'm still getting the same error.

    # Arbitrary name for the context following the tutorial
    c = pint.Context('ab')

    # Add transformation between dimensionality of J/m2 to dimensionality of W/m2
    c.add_transformation(
    '[mass] / [time] ** 2',
    '[mass] / [time] ** 3',
    lambda ureg, x: x * (1/86400)
    )
    ureg.add_context(c)
    ureg("1 joule / meter ** 2").to("watt / meter ** 2", 'ab')


    DimensionalityError: Cannot convert from 'joule / meter ** 2' ([mass] / [time] ** 2) to 'watt / meter ** 2' ([mass] / [time] ** 3)


    I've also tried to re-define them as custom units with conversions and it doesn't work either.

    # Trying to be extremely explicit with these unit names.
    ureg.define('solar_irradiance_joules = 86400 * solar_irradiance_watts = joule / meter ** 2 = _') ureg.define('solar_irradiance_watts = (1/86400) * solar_irradiance_joules = watt / meter ** 2 = _')

    q = ureg.Quantity(1, 'solar_irradiance_joules')
    q.to('solar_irradiance_watts')


    RecursionError: maximum recursion depth exceeded while calling a Python object


    Or more simply...

    ureg.define('watt / meter ** 2 = 86400 * joule / meter ** 2')
    q = ureg.Quantity(1, 'joule / meter ** 2')
    q.to('watt / meter ** 2')


    DimensionalityError: Cannot convert from 'joule / meter ** 2' ([mass] / [time] ** 2) to 'watt / meter ** 2' ([mass] / [time] ** 3)```

    Continue reading...

Compartilhe esta Página