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/display/CKB/ERA5%3A+data+documentation#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)```
@MatBailie pointed out some unit errors in the way I was thinking here.
This works with the following: