What are “compatible units”?¶
Pinttrs’s concept of “compatible units” extends beyond the sole dimensionality. In many contexts, adding presumably dimensionless quantities together can be irrelevant.
The need for going beyond dimensionality actually emerged when manipulating angles. Pint usually behaves well when converting angles:
>>> import pint
>>> ureg = pint.UnitRegistry()
>>> from math import pi
>>> pi * ureg.rad + 180 * ureg.deg
<Quantity(6.28318531, 'radian')>
However, operations involving unitless values can lead to unintuitive behaviour. While this is quite natural:
>>> 1 + 1 * ureg.rad
<Quantity(2, 'dimensionless')>
this can be a bit harder to anticipate:
>>> 1 + 1 * ureg.deg
<Quantity(1.01745329, 'dimensionless')>
Things can get even more confusing when mixing angles and solid angles:
>>> 1 * ureg.deg + 1 * ureg.sr
<Quantity(58.2957795, 'degree')>
Whaaat??? While this behaviour is, in the end, comprehensive, it emphasises the fact that Pint doesn’t recognise angle units as a special case and does not offer facilities to prevent conversion from, say, degree to steradian. It will neither declare as incompatible quantities which should not be mixed such as radiance (W/m²/sr) and irradiance (W/m²).
For this reason, Pinttrs implements a stricter unit compatibility checker
function, :func:~pinttrs.util.units_compatible, that will declare dimensionless
quantities with inconvertible units as incompatible. For instance, while this
will return True
>>> u1 = ureg.Unit("W/m^2/sr")
>>> u2 = ureg.Unit("W/m^2")
>>> u1.is_compatible_with(u2)
True
the following will not
>>> import pinttrs
>>> pinttrs.util.units_compatible(u1, u2)
False
Although this does not prevent the addition of radiances and irradiances, it provides at least a means to check that attributes which should be passed a radiance will not receive an irradiance.