A question on astropy logarithmic units behaviour

Hi all,

I’m posting this one because I’ve encountered strange behaviours in logarithmic astropy units. It looks like with the most recent version of astropy (conda create -n test_env astropy) the issue still persists. I’m not sure if it’s a bug, so I first wanted to check if that’s an intended behaviour of astropy.units.dB

Let’s take the base example:

from astropy import units as u
gain = 5 * u.dB(1)

This produces a nice 5 dB value. However, let’s in case if we have some calculations done before:

gain = ((15*u.m)/(3*u.m)) * u.dB(1)
or
gain = ((15*u.m)/(3*u.m)).to(u.dB(1))

The result is 6.989700043360188 dB, which is somewhat unexpected as it looks like “* u.dB(1)” automatically applies the 10*log10 operation.

Another example is

power = 5*u.dB(u.W)

Which produces a nice 5 dBW value. However, the same u.dB(u.W) can’t be applied to

power = ((15*u.m)/(3*u.m)) * u.dB(u.W)

Which will just throw an error that they are of different types and can’t be multiplied.

I’m aware of u.Decibel and u.DecibelUnit, but I wonder if u.dB was intended to operate this way.

Many thanks in advance!

Kind and best regards,
Boris

I don’t have answers for you, but I figured I’d make your report a bit more stark:

The product of a number and DecibelUnit creates a Decibel:

>>> 5*u.dB(1)
<Decibel 5. dB>
>>> 5*u.dB(u.W)
<Decibel 5. dB(W)>

The product of a Quantity and a dimensionless Decibel gives “natural” results:

>>> (5*u.one) * (1*u.dB(1))
<Decibel 5. dB>
>>> (5*u.m) * (1*u.dB(1))
<Quantity 5. dB m>

The product of a Quantity and a dimensioned Decibel is not allowed:

>>> (5*u.one) * (1*u.dB(u.W))
...
UnitTypeError: Cannot multiply function quantities which are not dimensionless with anything.

The product of a dimensionless Quantity and a dimensionless DecibelUnit triggers a logarithmic conversion of the Quantity:

>>> (5*u.one) * u.dB(1)
<Decibel 6.98970004 dB>

But the product of a Quantity and a DecibelUnit raises an error if either are dimensioned:

>>> (5*u.m) * u.dB(1)
...
TypeError: unsupported operand type(s) for *: 'Quantity' and 'DecibelUnit'
>>> (5*u.one) * u.dB(u.W)
...
TypeError: unsupported operand type(s) for *: 'Quantity' and 'DecibelUnit'

As a workaround, if your calculation is guaranteed to be dimensionless, you can call .to_value(u.one) to turn it back to a simple number before attaching the decibel unit.

Hi ayshih, many thanks for your replies! Regarding the workaround - indeed, that’s very similar to what I did in my project. I just added .value to get the raw number.

Sure, calling .value instead of .to_value(u.one) can be fine as long as you’re certain that that the units exactly cancel out, including not having stuff like u.m / u.mm.

1 Like