Getting started¶
When taking measurements, one usually has to keep track of three things: The actual value of the measurement, the unit in which the quantity is measured and an uncertainty which quantifies how precise the measurement is. The package pyveu was created to simplify the work with real-life quantities.
The main class of the package is the pyveu.Quantity
. This section is
devoted to show typical ways in which the pyveu.Quantity
objects are
used.
Create quantities¶
There are several ways to create a pyveu.Quantity
.
String expressions¶
The easiest is probably to class the constructor with a string expression. The expression can consist of three parts:
1. The first part specifies the value of the quantity. This part is mandatory. The value expression can be any int, float in regular or scientific notation.
2. The second part specifies the uncertainty. This part is optional. If it is specified, it must start with “+-” followed by a positive number.
3. The last portion specifies the unit. This part is optional. If it is omitted, the quantities is a pure scalar quantity without unit. The unit is specified by products and ratios of unit symbols (such as
m
for meter ors
for seconds). Unit symbols can be raised to a power by suffixing it with^n
wheren
is the (positive or negative) exponent.Parenthesis cannot be used.
Often, a unit is build by a ratio with a product in the denominator. To avoid cluttering the string with many
/
characters, it is possible to omit the*
character in the product of the denominator. A space between two unit symbols multiplies the two units and has precedence of the ratio. This means the string1 / m^2 s
is equivalent tom^-2 * s^-1
.
The following example creates quantities from valid expressions.
>>> from pyveu import Quantity
>>> Quantity("42")
<Quantity: 42>
>>> Quantity("137 +- 1")
<Quantity: 137 +- 1>
>>> Quantity("1.6 km")
<Quantity: 1600 m>
>>> Quantity("-8.22 +- 0.32 m / s")
<Quantity: (-8.22 +- 0.32) m s^(-1)>
>>> Quantity("3.2e-3 +- 34e-4 K / W")
<Quantity: (0.0032 +- 0.0034) m^(-2) kg^(-1) s^3 K>
Programmatically¶
When quantities are created programmatically, for example when reading a file,
it looks quite painful to build a string with value, error, and unit.
The constructor of the class pyveu.Quantity
accepts all these arguments
separately. The first three positional arguments are
- The value of the quantity as an int or float,
- The error of the quantities as an int or float; or
None
,- The unit of the quantities as a unit vector; or
None
.
The first two arguments should be self-explanatory. The third argument, the unit
vector, specifies the unit of the quantity. Unit vectors are how units are
handled internally. When working with the default SI units, a unit vector is an
8-dimension vector, or simply a list with eight items. The items specify the
exponents of the SI base units. It’s best to copy the unit vector from
existing pyveu.Unit
objects.
>>> import pyveu.si as si
>>> myunit = si.kelvin / si.watt
>>> myunit.unit_vector()
array([-2., -1., 3., 0., 1., 0., 0., 0.])
The following quantity is equivalent to the one created from the string
3.2e-3 +- 34e-4 K / W
.
>>> Quantity(3.2e-3, 34e-4, myunit.unit_vector())
<Quantity: (0.0032 +- 0.0034) m^(-2) kg^(-1) s^3 K>
Named quantities¶
Quantities can be annotated with a label
, symbol
, and a latex
alternative symbol. The names of the quantities are used when the quantity is
printed. The information can also be used by a user program or a third-party
library. For example, if a named quantity is passed to a plotting library, the
label could be used as the axis label.
label
- The label is a human-readable description of the quantity.
Current
,Fine structure constant
,Heat conductivity
are examples of good labels. symbol
- The symbol is the mathematical symbol used for the quantity.
I
,a
orp
are examples of good symbols. latex
alternative- Sometimes, the common mathematical symbol needs latex typesetting. In that
case, you can specify the
latex
alternative, which is used instead of the symbol if the output medium is latex document.\\alpha
orp_i
are examples of good latex alternative symbols. If latex typesetting is not needed, this should beNone
.
We can name a quantity by passing the names via keyword arguments to the constructor. This work when using expression strings or when creating a unit programmatically.
>>> Quantity("42", label="The answer")
<Quantity The answer: 42>
>>> Quantity("0.00729", label="Fine structure constant",
... symbol="a", latex="\\alpha")
<Quantity Fine structure constant: a = 0.00729>
>>> Quantity("-8.22 +- 0.32 m / s", symbol="v")
<Quantity: v = (-8.22 +- 0.32) m s^(-1)>
Arithmetics with quantities¶
Calculating with quantities is as easy as doing it with simple numbers in
Python. The pyveu.Quantity
overload the operators +
, -
, *
,
/
and **
. Arithmetic operations are carried out for the value of the
quantity, for the unit. The uncertainties of the quantities are propagated to
the result.
>>> duration = Quantity("28 +- 1 min")
>>> distance = Quantity("1000 +- 50 m")
>>> speed = distance / duration
>>> speed
<Quantity: (0.595238 +- 0.0365745) m s^(-1) | depends=[9, 10]>
The package also brings common mathematical methods, such as
pyveu.exp()
and pyveu.log()
. Calling these methods will also
propagate the uncertainty.
>>> from pyveu import log
>>> log(Quantity("431 +- 13"))
<Quantity: 6.06611 +- 0.0301624 | depends=[12]>
The depnds
part of the printout indicates that the quantity depends on
another quantity (here the quantity with id 12). This
information is required to keep track of the correlations between quantities.
What are correlations between quantities? When you call Quantity()
, you
create a new, statistically independent quantity. The difference between
independent and correlated quantities will become apparent with an example.
Assume you have two statically independent measurements of a physical quantity, you should
call Quantity()
twice. The quantity object a
and b
are independent.
>>> a = Quantity("1 +- 0.1")
>>> b = Quantity("1 +- 0.1")
When we add them, we see that the relative uncertainty gets reduced because the up and down fluctuations of both quantities cancel on average.
>>> a + b
<Quantity: 2 +- 0.141421 | depends=[14, 15]>
On the other hand, we can also create two quantities c
and d
whose
uncertainties are correlated.
>>> parent = Quantity("1 +- 0.1")
>>> c = 1 * parent
>>> d = 1 * parent
Adding c
and d
is identical to 2 * parent
, so the result should be
the same.
>>> c + d
<Quantity: 2 +- 0.2 | depends=[17]>
>>> 2 * parent
<Quantity: 2 +- 0.2 | depends=[17]>
Notice that when adding the quantities, the error is simply scaled by the factor two. The up and down fluctuations cannot cancel, because they are always in the same direction.
Retrieve the result¶
The properties of a quantity can be access programmatically with the
pyveu.Quantity.value()
,
pyveu.Quantity.error()
and
pyveu.Quantity.unit_vector()
methods.
>>> height = Quantity("178 +- 2 cm")
>>> height.value()
1.78
>>> height.error()
0.02
>>> height.unit_vector()
array([1., 0., 0., 0., 0., 0., 0., 0.])
By default, these methods return the value in multiples of the base units, here
meter and not centimeter. To get the values in a different unit, pass a unit
object or a unit expression to the pyveu.Quantity.value()
and
pyveu.Quantity.error()
methods.
>>> height = Quantity("178 +- 2 cm")
>>> height.value("mm")
1780.0
>>> height.error("mm")
20.0
Quantities come with the pyveu.Quantity.str()
method, which generates a
string representation with sensible rounding.
>>> height = Quantity("178.12345 +- 2.12345 cm")
>>> height.str()
'(1.78 +- 0.02) m'
As with pyveu.Quantity.value()
and pyveu.Quantity.error()
,
pyveu.Quantity.str()
accepts an argument to print the quantity in another
unit. Unlike the other two methods, the unit passed to
pyveu.Quantity.str()
does not need to be a scalar multiple of the
quantity. The print out will automatically append any missing arguments.
>>> speed = Quantity("10 +- 0.1 m / s")
>>> speed.str("km / hr")
'(36.0 +- 0.4) km / hr'
>>> speed.str("km") # missing 1/second added automatically
'(0.01000 +- 0.00010) km * 1 / s'
The default set of units contains the speed of light, Planck’s constant and electron volts. This makes it easy to convert between natural and SI units.
>>> electron_mass = Quantity("0.5 MeV / c^2")
>>> electron_mass
<Quantity: 8.91331e-31 kg>
>>> red_h_c = Quantity("1 h c") / (2 * math.pi) # Note: hbar = 100 * bar
>>> red_h_c.str("MeV fm")
'197.326978809195 MeV * fm'