[1]:
import numpy as np
[2]:
import spectrochempy as scp
from spectrochempy import Quantity, ur # to simplify further writing
SpectroChemPy's API - v.0.6.5 © Copyright 2014-2023 - A.Travert & C.Fernandez @ LCS |
Units & Quantities¶
SpectroChemPy can do calculations with units - it uses pint to define and perform operation on data with units.
Two objects, ur
and Quantity
, allow the manipulation of data with units:
ur
: stands for unit registry, is used to define and handle many type of units as well as making conversion between them.Quantity
: is a scalar or an array of scalars with some units.
Units¶
For instance, a unit of speed can be defined as:
[3]:
ur.cm / ur.s
[3]:
Create quantities¶
to create quantity, use for instance, one of the following expression:
[4]:
Quantity("10.0 cm^-1")
[4]:
[5]:
Quantity(1.0, "cm^-1/hour")
[5]:
[6]:
Quantity(10.0, ur.cm / ur.km)
[6]:
or may be (?) simpler,
[7]:
10.0 * ur.cm / ur.km
[7]:
Do arithmetic with units¶
[8]:
a = 900 * ur.km
b = 4.5 * ur.hours
a / b
[8]:
Such calculations can also be done using the following syntax, using a string expression
[9]:
Quantity("900 km / (4.5 hours)")
[9]:
Conversion between units¶
[10]:
c = a / b
d = c.to("cm/s")
As shown below to()
has generated a new variable and does not affect the initial one:
[11]:
print(f"initial quantity: c = {c}")
print(f"converted quantity: d = {d}")
initial quantity: c = 200.0 km.h⁻¹
converted quantity: d = 5555.555555555556 cm.s⁻¹
We can make the conversion inplace using ito()
instead of to()
:
[12]:
c.ito("m/s")
print(f"converted quantity: c = {c}")
converted quantity: c = 55.55555555555556 m.s⁻¹
Do math operations with consistent units¶
The units are transformed consistently in maths operations:
[13]:
x = 10 * ur.meters
np.sqrt(x)
[13]:
[14]:
x = 10 * ur.radians
np.sin(x)
[14]:
Consistency of the units are checked and errors are generated if quantities have not appropriate units with the math operation…
[15]:
x = 10 * ur.meters
try:
np.cos(x)
except scp.DimensionalityError as e: # catch the error
scp.error_(
scp.DimensionalityError, e
) # generate the error message (see API configuration)
# Consistency of the units are checked and errors are generated if quantities have not appropriate units
# with the math operation...
ERROR | DimensionalityError: Cannot convert from 'meter' ([length]) to 'radian' (dimensionless)
Stripping the units¶
If for any reason - including quick and dirty checks - unitless numbers are needed, the magnitude
field can be used:
[16]:
x = 10 * ur.meters
np.cos(x.magnitude)
[16]:
-0.8390715290764524
Units can be set for NDDataset data and/or Coordinates
[17]:
ds = scp.NDDataset([1.0, 2.0, 3.0], units="g/cm^3", title="concentration")
ds
[17]:
name | NDDataset_373ec80a |
author | runner@fv-az626-878 |
created | 2023-06-06 01:34:01+00:00 |
DATA | |
title | concentration |
values | [ 1 2 3] g.cm⁻³ |
size | 3 |
[18]:
ds.to("kg/m^3")
[18]:
name | NDDataset_374025ba |
author | runner@fv-az626-878 |
created | 2023-06-06 01:34:01+00:00 |
DATA | |
title | concentration |
values | [ 1000 2000 3000] kg.m⁻³ |
size | 3 |
One can do transparent calculation using the units
[19]:
volume = Quantity("2 m^3")
ds1 = ds * volume
ds1
[19]:
name | NDDataset_3741fb4c |
author | runner@fv-az626-878 |
created | 2023-06-06 01:34:01+00:00 |
history | 2023-06-06 01:34:01+00:00> Binary operation mul with `2 m³` has been performed |
DATA | |
title | concentration |
values | [ 2 4 6] g.m³.cm⁻³ |
size | 3 |
[20]:
ds1 / ds
[20]:
name | NDDataset_3743afb4 |
author | runner@fv-az626-878 |
created | 2023-06-06 01:34:01+00:00 |
history | 2023-06-06 01:34:01+00:00> Binary operation mul with `2 m³` has been performed 2023-06-06 01:34:01+00:00> Binary operation truediv with `NDDataset_373ec80a` has been performed |
DATA | |
title | concentration |
values | [ 2 2 2] m³ |
size | 3 |