1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
.. _log_units:
Logarithmic Units
=================
.. warning::
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 :doc:`contributing` 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 :ref:`nonmult`, so many of
the recommendations there apply here as well.
Setting up the ``UnitRegistry()``
---------------------------------
Many of the examples below will fail without supplying the
``autoconvert_offset_to_baseunit=True`` flag. To use logarithmic units,
intialize your ``UnitRegistry()`` like so:
.. doctest::
>>> 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
:ref:`using the Quantity() constructor<Using the 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 ``autoconvert...`` flag,
you can define simple logarithmic quantities like most others:
.. doctest::
>>> 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:
.. doctest::
>>> ureg('20 dBm').to('mW')
<Quantity(100.0, 'milliwatt')>
>>> ureg('20 dB').to_base_units()
<Quantity(100.0, 'dimensionless')>
.. note::
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:
.. doctest::
>>> (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
------------------
.. warning::
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:
.. doctest::
>>> 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:
.. doctest::
>>> -161.0 * ureg('dBm/Hz') == (-161.0 * ureg.dBm / ureg.Hz)
False
But this will:
.. doctest::
>>> 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.
|