@@ -29,6 +29,17 @@ The **mp-units** HEP system implements:
2929 hand-maintained unit constants across multiple HEP frameworks while maintaining compatibility
3030 during migration.
3131
32+ ### Historical Context
33+
34+ The need for compile-time dimensional analysis in HEP was recognized early. Walter Brown
35+ presented [ "SI Library of Unit-Based Computation"] ( https://digital.library.unt.edu/ark:/67531/metadc668099 )
36+ at CHEP '98 (International Conference in High Energy Physics, Chicago, IL, August 31 -
37+ September 4, 1998) — the first systematic approach to compile-time dimensional analysis
38+ in C++. Nearly three decades later, most HEP code still uses raw ` double ` values, making
39+ dimensional errors invisible to the compiler. The ** mp-units** HEP system builds on this
40+ foundation with modern C++20 features to finally bring compile-time safety to production
41+ HEP codebases.
42+
3243
3344## System of Quantities
3445
@@ -83,9 +94,6 @@ quantity proton_m = m_p; // ≈ 938.3 MeV/c²
8394// Calculate rest energies from mass (dimension: E)
8495quantity electron_rest_energy = m_e * c2; // E = mc² ≈ 0.511 MeV
8596quantity proton_rest_energy = m_p * c2; // E = mc² ≈ 938.3 MeV
86-
87- // In natural units where c=1, physicists often say "electron mass = 0.511 MeV"
88- // but in HEP system with explicit units, we distinguish mass from rest energy
8997```
9098
9199**_Electric Charge_ instead of _Electric Current_:**
@@ -119,13 +127,14 @@ analysis:
119127This dimensional structure ensures dimensional consistency while using quantities
120128natural to particle physics calculations.
121129
122- ## System of Units (Base Units)
130+ ## Commonly Used Units in HEP
123131
124- The HEP System of Units provides concrete measurement scales for the base
125- quantities. Unlike SI (which uses metre, second, kilogram, ampere), the HEP
126- system uses units natural to particle physics:
132+ The HEP system provides units that are conventional in particle physics practice.
133+ ** Unlike some libraries, mp-units does not force conversion to privileged "base units"** —
134+ quantities can natively store values in any unit without automatic conversion. The units
135+ listed below simply reflect common HEP conventions for numerical convenience:
127136
128- | Quantity | Unit | Symbol | Why? |
137+ | Quantity | Typical Unit | Symbol | Why commonly used? |
129138| -----------------------| -------------------| :------:| -----------------------------------------------------------------------------------|
130139| ** _ Length_ ** | millimetre | mm | Detector geometries are typically millimetre-scale; avoids frequent powers of 10³ |
131140| ** _ Time_ ** | nanosecond | ns | Particle lifetimes and detector timing naturally in nanoseconds |
@@ -136,17 +145,43 @@ system uses units natural to particle physics:
136145| ** _ Luminosity_ ** | candela | cd | Same as SI (for detector calibration) |
137146| ** _ Angle_ ** | radian | rad | Same as SI (for angular measurements) |
138147
148+ You're free to use any units you prefer — for example, ` quantity<hep::length[hep::metre]> `
149+ and ` quantity<hep::length[hep::millimetre]> ` are both valid, and conversions happen
150+ automatically when needed without forcing storage in a particular unit.
151+
139152## Specialized Quantities of the Same Kind
140153
141154Beyond the basic dimensional safety, the HEP system provides ** specialized quantities**
142155to distinguish physically distinct concepts that share the same dimension. This
143156addresses real problems in particle physics code where mixing conceptually different
144157values is physically meaningless but dimensionally valid.
145158
159+ ### Motivation: The "Argument Soup" Problem
160+
161+ Consider the Geant4 ` G4Trap ` constructor, which takes 12 ` G4double ` parameters —
162+ some _ lengths_ , some _ angles_ :
163+
164+ ``` cpp
165+ G4Trap (const G4String& name,
166+ G4double pDz, G4double pTheta, G4double pPhi,
167+ G4double pDy1, G4double pDx1, G4double pDx2, G4double pAlp1,
168+ G4double pDy2, G4double pDx3, G4double pDx4, G4double pAlp2);
169+ ```
170+
171+ Swapping `pDx2` (a _length_) with `pAlp1` (an _angle_) compiles without warning because
172+ both are `G4double`. Even worse, swapping two _length_ parameters that represent
173+ different geometric axes (e.g., `pDx1` with `pDy1`) also compiles, despite being
174+ physically meaningless for the geometry.
175+
176+ Specialized quantities solve this by giving each conceptually distinct quantity
177+ its own type, making such errors impossible.
178+
146179The HEP system provides specialized quantities for:
147180
148- - ** Energy** : ` total_energy ` , ` kinetic_energy ` , ` rest_mass_energy ` , ` binding_energy ` ,
149- ` excitation_energy ` , ` ionization_energy ` , ` threshold_energy ` , ` Q_value ` , and more
181+ - **Energy**: `total_energy`, `kinetic_energy`, `rest_mass_energy`,
182+ `center_of_mass_energy`, `binding_energy`, `separation_energy`, `excitation_energy`,
183+ `ionization_energy`, `threshold_energy`, `Q_value`, `transverse_energy`,
184+ `missing_energy`, and more
150185- **Length**: `path_length`, `displacement`, `decay_length`, `radiation_length`,
151186 `interaction_length`, `impact_parameter`, `wavelength`, `range`, and more
152187- **Time**: `proper_time`, `coordinate_time`, `mean_lifetime`, `half_life`,
@@ -162,7 +197,7 @@ For complete hierarchy trees and all available specialized quantities, see the
162197
163198## Distinct Quantity Subkinds
164199
165- Some HEP quantities share the same dimension, unit, and even the same parent quantity,
200+ Some HEP quantities share the same dimension, unit, and even the same parent quantity,
166201yet represent fundamentally **incompatible physical concepts** that should never be added
167202to or compared with each other. The HEP system uses the `is_kind` specifier to enforce
168203this at compile time. See
@@ -172,52 +207,56 @@ for the general mechanism.
172207### Relativistic Time: `proper_time` and `coordinate_time`
173208
174209Both are sub-quantities of `duration`, but they live in different reference frames and
175- are related by the Lorentz factor , not by addition:
210+ are related by the _Lorentz factor_ , not by addition:
176211
177212$$\tau = \frac{t}{\gamma}$$
178213
179- Adding a proper time to a coordinate time is a classic special-relativity mistake —
214+ Adding a _proper time_ to a _coordinate time_ is a classic special-relativity mistake —
180215one is Lorentz-invariant, the other is frame-dependent:
181216
182217```cpp
183- quantity tau = 10 . * hep::ns * proper_time; // particle rest frame
184- quantity t = 25 . * hep::ns * coordinate_time; // lab frame
218+ using namespace mp_units::hep::unit_symbols;
185219
186- // auto wrong = tau + t; // Compile error — different kinds ✓
220+ quantity tau = hep::proper_time(0.385 * ns); // B⁰ meson rest-frame lifetime
221+ quantity t_lab = hep::coordinate_time(4.2 * ns); // observed lab time of flight
222+
223+ // auto wrong = tau + t_lab; // Compile error — different kinds ✓
187224```
188225
189226To convert between them, the Lorentz factor must be applied explicitly:
190227
191228``` cpp
192- quantity gamma = 2.5 * lorentz_factor;
193- quantity t_lab = coordinate_time(tau * gamma); // explicit physics conversion
229+ quantity gamma = hep::lorentz_factor(t_lab / tau); // γ ≈ 10.9
230+ quantity tau_from_t = proper_time(t_lab / gamma); // explicit physics conversion
194231```
195232
196233### Material Characteristic Lengths: ` radiation_length ` and ` interaction_length `
197234
198- These are properties of a material, not distances travelled by a particle. They appear
235+ These are properties of a material, not distances traveled by a particle. They appear
199236as ** denominators** in physics expressions (number of radiation lengths traversed = path
200237/ X₀), never as addends.
201238
202- - ** ` radiation_length ` (X₀)** : mean distance over which an electron loses 1/e of its
203- energy through Bremsstrahlung — an electromagnetic material property.
204- - ** ` interaction_length ` (λ_I)** : mean free path before a hadronic nuclear interaction —
239+ - ** ` radiation_length ` (X₀)** : _ mean distance _ over which an electron loses 1/e of its
240+ _ energy _ through Bremsstrahlung — an electromagnetic material property.
241+ - ** ` interaction_length ` (λ_I)** : _ mean free path _ before a hadronic nuclear interaction —
205242 a nuclear material property.
206243- ** ` nuclear_interaction_length ` ** : a specialization of ` interaction_length ` for nuclear
207244 (as opposed to hadronic-elastic) interactions.
208245
209- All three are distinct from each other and from geometric lengths :
246+ All three are distinct from each other and from geometric _ lengths _ :
210247
211248``` cpp
212- quantity X0 = 88.97 * hep::mm * radiation_length; // lead X₀
213- quantity lambda_I = 194.4 * hep::mm * interaction_length; // lead λ_I
214- quantity path = 50 . * hep::mm * path_length;
249+ using namespace mp_units ::hep::unit_symbols;
250+
251+ quantity X0 = hep::radiation_length(88.97 * mm); // lead X₀
252+ quantity lambda_I = hep::interaction_length(194.4 * mm); // lead λ_I
253+ quantity path = hep::path_length(50. * mm);
215254
216- // auto wrong1 = X0 + lambda_I; // Compile error — different kinds ✓
217- // auto wrong2 = X0 + path; // Compile error — different kinds ✓
255+ // auto bad1 = X0 + lambda_I; // Compile error — different kinds ✓
256+ // auto bad2 = X0 + path; // Compile error — different kinds ✓
218257
219258// Correct usage: use as a denominator
220- quantity n_X0 = path / X0; // dimensionless: number of X₀ traversed
259+ quantity n_X0 = path / X0; // dimensionless: number of radiation lengths traversed ✓
221260```
222261
223262### Dimensionless Relativistic Quantities
@@ -226,24 +265,24 @@ quantity n_X0 = path / X0; // dimensionless: number
226265specific physical meaning that must not be mixed with generic dimensionless values or
227266with each other:
228267
229- - ** ` lorentz_factor ` (γ = E/E₀)** : characterises relativistic time dilation and length
230- contraction ; ranges from 1 (at rest) to ∞.
231- - ** ` relativistic_beta ` (β = v/c)** : velocity expressed as a fraction of the speed of
232- light ; ranges from 0 to 1. Related to γ by $\beta = \sqrt{1 - 1/\gamma^2}$.
233- - ** ` phase ` ** : quantum mechanical phase angle — a cyclic, dimensionless quantity
268+ - **`lorentz_factor` (γ = E/E₀)**: characterizes _relativistic time dilation_ and
269+ _length contraction_ ; ranges from 1 (at rest) to ∞.
270+ - **`relativistic_beta` (β = v/c)**: _velocity_ expressed as a fraction of the
271+ _speed of light_ ; ranges from 0 to 1. Related to γ by $\beta = \sqrt{1 - 1/\gamma^2}$.
272+ - **`phase`**: quantum mechanical _phase angle_ — a cyclic, dimensionless quantity
234273 incompatible with both γ and β and with the angular `angle` kind.
235274
236275```cpp
237- quantity gamma = 10 . * lorentz_factor ;
238- quantity beta = 0.995 * relativistic_beta ;
239- quantity phi = 1.57 * phase ;
276+ quantity gamma = hep::lorentz_factor( 10. * one) ;
277+ quantity beta = hep::relativistic_beta( 0.995 * one) ;
278+ quantity phi = hep::phase( 1.57 * one) ;
240279
241- // auto wrong1 = gamma + beta; // Compile error — different kinds ✓
242- // auto wrong2 = gamma + phi; // Compile error — different kinds ✓
243- // auto wrong3 = gamma + 1.; // Compile error — not a plain dimensionless ✓
280+ // auto bad1 = gamma + beta; // Compile error — different kinds ✓
281+ // auto bad2 = gamma + phi; // Compile error — different kinds ✓
282+ // auto bad3 = gamma + 1.; // Compile error — not a plain dimensionless ✓
244283
245- // Physics: recover beta from gamma
246- quantity beta_from_gamma = relativistic_beta(sqrt(1 . - 1 . / pow<2 >(gamma / lorentz_factor)));
284+ // Physics: convert between gamma and beta
285+ quantity beta_from_gamma = hep:: relativistic_beta(sqrt(1. - 1. / pow<2>(gamma / hep:: lorentz_factor)));
247286```
248287
249288
0 commit comments