Unit definitions and conversions
-
namespace UnitConstants
Constants and helper literals for physical units.
All physical quantities have both a numerical value and a unit. For the computations we always choose a particular unit for a given physical quantity so we only need to consider the numerical values as such. The chosen base unit for a particular physical dimension, e.g. length, time, or energy, within this code base is called the native unit. The base units should be chosen such that they are internally consistent, require the least amount of explicit conversion factors (ideally none at all), and have typical numerical values close to unity to reduce numerical issues.
Here, the following native units are used:
Length is expressed in mm.
Time is expressed in [speed-of-light * time] == mm. A consequence of this choice is that the speed-of-light expressed in native units is 1.
Angles are expressed in radian.
Energy, mass, and momentum are all expressed in GeV (consistent with speed-of-light == 1).
Electric charge is expressed in e, i.e. units of the elementary charge.
The magnetic field is expressed in GeV/(e*mm). The magnetic field connects momentum to length, e.g. in SI units the radius of a charged particle trajectory in a constant magnetic field is given by
\( \text{radius} = - \frac{\text{momentum} }{ \text{charge} } / \text{field} \)
With the chosen magnetic field unit the expression above stays the same and no additional conversion factors are necessary.
Depending on the context a physical quantity might not be given in the native units. In this case we need to convert to the native unit first before the value can be used. The necessary conversion factors are defined in Acts::UnitConstants. Multiplying a value with the unit constant produces the equivalent value in the native unit, e.g.
To further simplify the usage, physical quantities can also be expressed via C++ user literals defined in Acts::UnitLiterals. This allows us to express quantities in a concise way:// Define input values using unit constants double length = 1 * Acts::UnitConstants::m; // length == 1000.0 double momentum = 100 * Acts::UnitConstants::MeV; // momentum == 0.1 // Convert output values from native units to specific units double lengthInMm = length / Acts::UnitConstants::mm; // == 1000.0 double lengthInM = length / Acts::UnitConstants::m; // == 1.0
To ensure consistent computations and results the following guidelines must be followed when handling physical quantities with units:using namespace Acts::UnitLiterals; // Define input values using user-defined literals double length = 1_m; // == 1000.0 (native units: mm) double momentum = 1.25_TeV; // == 1250.0 (native units: GeV) // Convert output values to specific units double lengthInUm = length / 1_um; // == 1000000.0 double momentumInMeV = momentum / 1_MeV; // == 1250000.0
Here’s a comprehensive example showing various ways to work with units:using namespace Acts::UnitLiterals; // GOOD: All input values explicitly specify units double momentum = 100 * Acts::UnitConstants::GeV; // or 100_GeV double distance = 5 * Acts::UnitConstants::m; // or 5_m // GOOD: Variable names indicate non-native units double momentumInMeV = 10.0; // would be 0.01 in native units (GeV) // GOOD: Unqualified values are in native units double energyGeV = 100.0; // native unit GeV, clear from context // Output conversion double output_in_meters = distance / 1_m;
Converting output values from native units:using namespace Acts::UnitLiterals; // Define input values with units (via unit constants) double width = 12 * Acts::UnitConstants::mm; double mmuon = 105.7 * Acts::UnitConstants::MeV; // Define input values with units (via user literals) double length = 23_cm; double time = 1214.2_ns; double angle = 123_degree; double particleMomentum = 2.5_TeV; double mass = 511_keV; double velocity = 345_m / 1_s; double bfield = 3.9_T; // All values are now in native units and can be used in calculations // Native units: mm, GeV, radian, GeV/(e*mm), etc.
using namespace Acts::UnitLiterals; // Assume trackPars is a track parameter object with methods // that return values in native units // Convert output values (via unit constants) double t_in_ns = trackPars.time() / Acts::UnitConstants::ns; // Convert output values (via user literals) double x_in_mm = trackPars.position(gctx)[Acts::eBoundLoc0] / 1_mm; double p_in_TeV = trackPars.absoluteMomentum() / 1_TeV;
Warning
Since using user-defined literals requires a namespace import of Acts::UnitLiterals it should not be used in headers since it would (accidentally) modify the namespace wherever the header is included.
Note
A helper script is available in
Core/scripts/print_units_physical_constants.pyto validate some of the numerical values.Variables
-
constexpr double e = 1.0
Charge, native unit e (elementary charge)
-
constexpr double g = 1.0 / 1.782662e-24
Gram in GeV/c²
Note
1eV/c² == 1.782662e-36kg 1GeV/c² == 1.782662e-27kg -> 1kg == (1/1.782662e-27)GeV/c² -> 1g == (1/(1e3*1.782662e-27))GeV/c²
-
constexpr double GeV = 1.0
Gigaelectronvolt - native unit for energy/mass/momentum.
-
constexpr double kg = 1.0 / 1.782662e-27
Kilogram in GeV/c²
-
constexpr double mm = 1.0
Millimeter - native unit for length.
-
constexpr double mol = 1.0
Amount of substance, native unit mol.
-
constexpr double mrad = 1e-3
Milliradian - 1e-3 radian.
-
constexpr double rad = 1.0
Radian - native unit for angle.
-
constexpr double s = 299792458000.0
Note
Depends on speed of light in SI units
-
constexpr double T = 0.000299792458
Magnetic field, native unit (eV*s)/(e*m²)
Note
Depends on speed of light in SI units
-
constexpr double u = 0.93149410242
atomic mass unit u