Units¶
Units are handled via language-specific libraries described blow with every
effort made to ensure that the same units are available in each by updating
the unit registries where needed. Units are specified via strings
associated with the units (usually the abbreviation; e.g.
'cm'
for centimeters or 'umol'
for micromoles). In addition, units can be
expressed as composites via symbolic arithmetic (e.g. 'km/s'
for kilometers
per second or 'km**2'
for square kilometer)
Schema Datatypes¶
The primary case where users will encounter units is within types associated with model inputs and outputs in model specification YAML files. If a YAML specifies a connection between a model output and input that do not have the same units, yggdrasil will automatically perform the conversion from the units of the sending model to the units of the receiving model. If the units are not compatible, an error will be raised.
Units can be added to numeric scalars and arrays.
Language Specific Support¶
Python¶
Backwards Compatibility¶
Prior to version 2.0, yggdrasil used unyt for unit support in Python. After 2.0, yggdrasil migrating to using a Python wrapped C++ units system based on unyt that is now used in C++ as well. yggdrasil still supports the use of unyt classes for backwards compatibility, but unyt class instances will be normalized to the analagous new classes during serialization by rapidjson.
Scalar Creation¶
>>> from yggdrasil.units import Quantity
>>> x = Quantity(1., 'cm')
>>> x
Quantity(1., 'cm')
>>> str(x)
'1.0 cm'
>>> str(x.units)
'cm'
>>> x.value
1.0
Array Creation¶
>>> from yggdrasil.units import QuantityArray
>>> import numpy as np
>>> y = QuantityArray(np.ones(5), 'km/s')
>>> y
QuantityArray([1., 1., 1., 1., 1.], 'km*(s**-1)')
>>> str(y)
'[1. 1. 1. 1. 1.] km*(s**-1)'
>>> str(y.units)
'km*(s**-1)'
>>> y.value
array([1., 1., 1., 1., 1.])
Arithmetic¶
Any operations possible in Python with scalars or numpy arrays will also be possible with Quantity or QuantityArray objects.:
>>> x *= 5
>>> x
Quantity(5., 'cm')
>>> y / x
Quantity([20000., 20000., 20000., 20000., 20000.], 's**-1')
>>> x + 1
UnitsError: Incompatible units: '' and 'cm'
>>> x + Quantity(1, 'm')
Quantity(105., 'cm')
>>> x ** 2
Quantity(25., 'cm**2')
>>> x % 2
Quantity(1., 'cm')
Additional Methods¶
For backwards compat, units in python can also be added to numeric types (or retrieved) using several methods from the yggdrasil units submodule:
>>> from yggdrasil import units
>>> import numpy as np
>>> x = units.add_units(1.0, 'cm')
>>> x
Quantity(1., 'cm')
>>> units.get_units(x)
'cm'
>>> units.get_data(x)
1.0
>>> y = units.add_units(np.ones(5), 'km/s')
>>> y
QuantityArray([1., 1., 1., 1., 1.], 'km*(s**-1)')
>>> units.get_units(y)
'km*(s**-1)'
>>> units.get_data(y)
array([1., 1., 1., 1., 1.])
C++¶
Scalar Creation¶
#include <iostream>
#include "YggInterface.hpp"
rapidjson::units::Quantity<double> x(1.0, "cm");
std::cout << "x = " << x << std::endl;
Output:
x = 1 cm
Array Creation¶
#include <iostream>
#include "YggInterface.hpp"
double arr[5] = {1.0, 1.0, 1.0, 1.0, 1.0};
rapidjson::units::QuantityArray<double> y(arr, "km/s");
std::cout << "y = " << y << std::endl;
Output:
y = [1.0, 1.0, 1.0, 1.0, 1.0] cm
C Language¶
Units in C are inplmeented by wrapping the C++ unit classes as generic objects.
Scalar Creation¶
#include "YggInterface.h"
generic_t x;
generic_set_double(x, 1.0, "cm");
printf("x = ");
display_generic(x);
printf("\n");
Output:
x = 1 cm
Array Creation¶
#include "YggInterface.h"
generic_t y;
printf("x = ");
double arr[5] = {1.0, 1.0, 1.0, 1.0, 1.0};
generic_set_1darray_double(y, arr, 5, "cm");
display_generic(y);
printf("\n");
Output:
y = [1.0, 1.0, 1.0, 1.0, 1.0] cm
R Language¶
In R, units are represented via the units package. Details on adding units to quantites in R can be found here.
MATLAB¶
In MATLAB, units are represented via symbolic units if the YGG_MATLAB_SYMUNIT
environment variables is set to true
, othwerise the value is passed to MATLAB without the units. Details on adding units to quantaties in MATALB can be found here.
Julia¶
In Julia, units are represented via the Unitful package. Details on adding units to quantaties in Julia can be found here.