Support for logarithmic units in Pint is currently in Beta. Please take careful note of the information below, particularly around compound log units to avoid calculation errors. Bug reports and pull requests are always welcome, please see Contributing to Pint for more information on how you can help improve this feature (and Pint in general).
Pint supports some logarithmic units, including dB, dBm, octave, and decade as well as some conversions between them and their base units where applicable. These units behave much like those described in Temperature conversion, so many of the recommendations there apply here as well.
Setting up the
Many of the examples below will fail without supplying the
autoconvert_offset_to_baseunit=True flag. To use logarithmic units,
UnitRegistry() like so:
>>> from pint import UnitRegistry >>> ureg = UnitRegistry(autoconvert_offset_to_baseunit=True) >>> Q_ = ureg.Quantity
If you can’t pass that flag you will need to define all logarithmic units using the Quantity() constructor, and you will be restricted in the kinds of operations you can do without explicitly calling .to_base_units() first.
Defining log quantities¶
After you’ve set up your
UnitRegistry() with the
you can define simple logarithmic quantities like most others:
>>> 20.0 * ureg.dBm <Quantity(20.0, 'decibelmilliwatt')> >>> ureg('20.0 dBm') <Quantity(20.0, 'decibelmilliwatt')> >>> ureg('20 dB') <Quantity(20, 'decibel')>
Converting to and from base units¶
Get a sense of how logarithmic units are handled by using the .to() and .to_base_units() methods:
>>> ureg('20 dBm').to('mW') <Quantity(100.0, 'milliwatt')> >>> ureg('20 dB').to_base_units() <Quantity(100.0, 'dimensionless')>
Notice in the above example how the dB unit is defined for power quantities (10*log(p/p0)) not field (amplitude) quantities (20*log(v/v0)). Take care that you’re only using it to multiply power levels, and not e.g. Voltages.
Convert back from a base unit to a logarithmic unit using the .to() method:
>>> (100.0 * ureg('mW')).to('dBm') <Quantity(20.0, 'decibelmilliwatt')> >>> shift = Q_(4, '') >>> shift <Quantity(4, 'dimensionless')> >>> shift.to('octave') <Quantity(2.0, 'octave')>
Compound log units¶
Support for compound logarithmic units is not comprehensive. The following examples work, but many others will not. Consider converting the logarithmic portion to base units before adding more units.
Pint sometimes works with mixtures of logarithmic and other units. Below is an example of computing RMS noise from a noise density and a bandwidth:
>>> noise_density = -161.0 * ureg.dBm / ureg.Hz >>> bandwidth = 10.0 * ureg.kHz >>> noise_power = noise_density * bandwidth >>> noise_power.to('dBm') <Quantity(-121.0, 'decibelmilliwatt')> >>> noise_power.to('mW') <Quantity(7.94328235e-13, 'milliwatt')>
There are still issues with parsing compound units, so for now the following will not work:
>>> -161.0 * ureg('dBm/Hz') == (-161.0 * ureg.dBm / ureg.Hz) False
But this will:
>>> ureg('-161.0 dBm/Hz') == (-161.0 * ureg.dBm / ureg.Hz) True >>> Q_(-161.0, 'dBm') / ureg.Hz == (-161.0 * ureg.dBm / ureg.Hz) True
To begin using this feature while avoiding problems, define logarithmic units as single-unit quantities and convert them to their base units as quickly as possible.