-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add canonical unit vocabulary via mp-units #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| #pragma once | ||
|
|
||
| #include "SHiP/MCParticle.hpp" | ||
| #include "SHiP/RecParticle.hpp" | ||
| #include "SHiP/SimHit.hpp" | ||
| #include "SHiP/SimParticle.hpp" | ||
| #include "SHiP/Units.hpp" | ||
|
|
||
| /// Quantity views over the persisted data classes. | ||
| /// | ||
| /// The data classes stay plain-double PODs (ROOT streaming cannot handle | ||
| /// mp-units members); these free functions convert to and from the canonical | ||
| /// quantity types so computation code never touches an implicit unit. All | ||
| /// conversions are bitwise (the storage unit is the quantity's unit). | ||
| namespace ship::view { | ||
|
|
||
| // --- MCParticle ----------------------------------------------------------- | ||
| [[nodiscard]] inline Vec3<Length> vertex(SHiP::MCParticle const& p) { | ||
| return vecOf<Length>(p.vertex); | ||
| } | ||
| [[nodiscard]] inline Vec3<Momentum> momentum(SHiP::MCParticle const& p) { | ||
| return vecOf<Momentum>(p.momentum); | ||
| } | ||
| /// Total energy. | ||
| [[nodiscard]] inline Energy energy(SHiP::MCParticle const& p) { | ||
| return quantityOf<Energy>(p.energy); | ||
| } | ||
| [[nodiscard]] inline Time time(SHiP::MCParticle const& p) { | ||
| return quantityOf<Time>(p.time); | ||
| } | ||
| inline void setVertex(SHiP::MCParticle& p, Vec3<Length> const& v) { | ||
| p.vertex = raw(v); | ||
| } | ||
| inline void setMomentum(SHiP::MCParticle& p, Vec3<Momentum> const& v) { | ||
| p.momentum = raw(v); | ||
| } | ||
| inline void setEnergy(SHiP::MCParticle& p, Energy e) { p.energy = raw(e); } | ||
| inline void setTime(SHiP::MCParticle& p, Time t) { p.time = raw(t); } | ||
|
|
||
| // --- SimHit --------------------------------------------------------------- | ||
| [[nodiscard]] inline Vec3<Length> position(SHiP::SimHit const& h) { | ||
| return vecOf<Length>(h.position); | ||
| } | ||
| [[nodiscard]] inline Vec3<Momentum> momentum(SHiP::SimHit const& h) { | ||
| return vecOf<Momentum>(h.momentum); | ||
| } | ||
| [[nodiscard]] inline Energy energyDeposit(SHiP::SimHit const& h) { | ||
| return quantityOf<Energy>(h.energyDeposit); | ||
| } | ||
| [[nodiscard]] inline Time time(SHiP::SimHit const& h) { | ||
| return quantityOf<Time>(h.time); | ||
| } | ||
| [[nodiscard]] inline Length pathLength(SHiP::SimHit const& h) { | ||
| return quantityOf<Length>(h.pathLength); | ||
| } | ||
| inline void setPosition(SHiP::SimHit& h, Vec3<Length> const& v) { | ||
| h.position = raw(v); | ||
| } | ||
| inline void setMomentum(SHiP::SimHit& h, Vec3<Momentum> const& v) { | ||
| h.momentum = raw(v); | ||
| } | ||
| inline void setEnergyDeposit(SHiP::SimHit& h, Energy e) { | ||
| h.energyDeposit = raw(e); | ||
| } | ||
| inline void setTime(SHiP::SimHit& h, Time t) { h.time = raw(t); } | ||
| inline void setPathLength(SHiP::SimHit& h, Length l) { h.pathLength = raw(l); } | ||
|
|
||
| // --- SimParticle ---------------------------------------------------------- | ||
| [[nodiscard]] inline Vec3<Length> vertex(SHiP::SimParticle const& p) { | ||
| return vecOf<Length>(p.vertex); | ||
| } | ||
| [[nodiscard]] inline Vec3<Length> endpoint(SHiP::SimParticle const& p) { | ||
| return vecOf<Length>(p.endpoint); | ||
| } | ||
| [[nodiscard]] inline Vec3<Momentum> momentum(SHiP::SimParticle const& p) { | ||
| return vecOf<Momentum>(p.momentum); | ||
| } | ||
| /// Initial kinetic energy. | ||
| [[nodiscard]] inline Energy energy(SHiP::SimParticle const& p) { | ||
| return quantityOf<Energy>(p.energy); | ||
| } | ||
| [[nodiscard]] inline Time time(SHiP::SimParticle const& p) { | ||
| return quantityOf<Time>(p.time); | ||
| } | ||
| inline void setVertex(SHiP::SimParticle& p, Vec3<Length> const& v) { | ||
| p.vertex = raw(v); | ||
| } | ||
| inline void setEndpoint(SHiP::SimParticle& p, Vec3<Length> const& v) { | ||
| p.endpoint = raw(v); | ||
| } | ||
| inline void setMomentum(SHiP::SimParticle& p, Vec3<Momentum> const& v) { | ||
| p.momentum = raw(v); | ||
| } | ||
| inline void setEnergy(SHiP::SimParticle& p, Energy e) { p.energy = raw(e); } | ||
| inline void setTime(SHiP::SimParticle& p, Time t) { p.time = raw(t); } | ||
|
|
||
| // --- RecParticle ---------------------------------------------------------- | ||
| [[nodiscard]] inline Vec3<Length> vertex(SHiP::RecParticle const& p) { | ||
| return vecOf<Length>(p.vertex); | ||
| } | ||
| [[nodiscard]] inline Vec3<Length> endpoint(SHiP::RecParticle const& p) { | ||
| return vecOf<Length>(p.endpoint); | ||
| } | ||
| [[nodiscard]] inline Vec3<Momentum> momentum(SHiP::RecParticle const& p) { | ||
| return vecOf<Momentum>(p.momentum); | ||
| } | ||
| /// Initial kinetic energy. | ||
| [[nodiscard]] inline Energy energy(SHiP::RecParticle const& p) { | ||
| return quantityOf<Energy>(p.energy); | ||
| } | ||
| [[nodiscard]] inline Time time(SHiP::RecParticle const& p) { | ||
| return quantityOf<Time>(p.time); | ||
| } | ||
| /// Impact parameter wrt the primary vertex. | ||
| [[nodiscard]] inline Length ipPV(SHiP::RecParticle const& p) { | ||
| return quantityOf<Length>(p.ipPV); | ||
| } | ||
| inline void setVertex(SHiP::RecParticle& p, Vec3<Length> const& v) { | ||
| p.vertex = raw(v); | ||
| } | ||
| inline void setEndpoint(SHiP::RecParticle& p, Vec3<Length> const& v) { | ||
| p.endpoint = raw(v); | ||
| } | ||
| inline void setMomentum(SHiP::RecParticle& p, Vec3<Momentum> const& v) { | ||
| p.momentum = raw(v); | ||
| } | ||
| inline void setEnergy(SHiP::RecParticle& p, Energy e) { p.energy = raw(e); } | ||
| inline void setTime(SHiP::RecParticle& p, Time t) { p.time = raw(t); } | ||
| inline void setIpPV(SHiP::RecParticle& p, Length l) { p.ipPV = raw(l); } | ||
|
|
||
| } // namespace ship::view | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| #pragma once | ||
|
|
||
| #include <mp-units/systems/hep.h> // exports framework.h; includes systems/si.h | ||
|
|
||
| #include <array> | ||
|
|
||
| /// Canonical ShipSoft unit vocabulary. | ||
| /// | ||
| /// Storage convention (matches the data-class doxygen contracts and Key4hep): | ||
| /// positions and lengths [mm], momenta [GeV/c], energies [GeV], times [ns]. | ||
| /// Persisted classes keep plain doubles in these units; computation code | ||
| /// works with the quantity types below and converts at the boundaries (see | ||
| /// SHiP/QuantityView.hpp). | ||
| /// | ||
| /// NEVER `using namespace ship::units` in a translation unit that includes | ||
| /// CLHEP or Geant4 headers: G4SystemOfUnits.hh injects global `mm`, `GeV`, | ||
| /// `tesla`, ... that collide with these names. Always qualify. | ||
| namespace ship { | ||
|
|
||
| namespace units { | ||
|
|
||
| // Length | ||
| inline constexpr auto mm = mp_units::si::milli<mp_units::si::metre>; | ||
| inline constexpr auto cm = mp_units::si::centi<mp_units::si::metre>; | ||
| inline constexpr auto m = mp_units::si::metre; | ||
|
|
||
| // Time | ||
| inline constexpr auto ns = mp_units::si::nano<mp_units::si::second>; | ||
| inline constexpr auto s = mp_units::si::second; | ||
|
|
||
| // Angle | ||
| inline constexpr auto rad = mp_units::si::radian; | ||
|
|
||
| // Energy | ||
| inline constexpr auto MeV = mp_units::hep::unit_symbols::MeV; | ||
| inline constexpr auto GeV = mp_units::hep::unit_symbols::GeV; | ||
|
|
||
| // Speed of light as a named unit ("c", exact by SI definition). Building | ||
| // momentum, mass and time-of-flight units from it keeps every conversion | ||
| // factor derived rather than hand-typed. | ||
| inline constexpr auto c = mp_units::hep::speed_of_light; | ||
|
|
||
| // Momentum and mass | ||
| inline constexpr auto GeV_per_c = GeV / c; | ||
| inline constexpr auto GeV_per_c2 = GeV / mp_units::square(c); | ||
|
|
||
| // Time of flight per unit length (Pythia8 production time, lifetime cuts) | ||
| inline constexpr auto mm_per_c = mm / c; | ||
|
|
||
| // Magnetic flux density | ||
| inline constexpr auto tesla = mp_units::si::tesla; | ||
|
|
||
| } // namespace units | ||
|
|
||
| /// Canonical quantity types: double representation, storage unit baked in. | ||
| using Length = mp_units::quantity<units::mm, double>; | ||
| using Time = mp_units::quantity<units::ns, double>; | ||
| using Energy = mp_units::quantity<units::GeV, double>; | ||
| using Momentum = mp_units::quantity<units::GeV_per_c, double>; | ||
| using Mass = mp_units::quantity<units::GeV_per_c2, double>; | ||
| using Angle = mp_units::quantity<units::rad, double>; | ||
| using MagneticField = mp_units::quantity<units::tesla, double>; | ||
|
|
||
| template <typename Q> | ||
| using Vec3 = std::array<Q, 3>; | ||
|
|
||
| /// Wrap a raw scalar, interpreting it in Q's canonical unit (bitwise). | ||
| template <typename Q> | ||
| [[nodiscard]] constexpr Q quantityOf(double v) { | ||
| return v * Q::reference; | ||
| } | ||
|
|
||
| /// Unwrap a scalar quantity to a raw double in Q's canonical unit (bitwise). | ||
| template <typename Q> | ||
| [[nodiscard]] constexpr double raw(Q q) { | ||
| return q.numerical_value_in(Q::unit); | ||
| } | ||
|
|
||
| /// Wrap a raw 3-vector, interpreting it in Q's canonical unit (bitwise). | ||
| template <typename Q> | ||
| [[nodiscard]] constexpr Vec3<Q> vecOf(std::array<double, 3> const& v) { | ||
| return {v[0] * Q::reference, v[1] * Q::reference, v[2] * Q::reference}; | ||
| } | ||
|
|
||
| /// Unwrap a quantity 3-vector to raw doubles in Q's canonical unit (bitwise). | ||
| template <typename Q> | ||
| [[nodiscard]] constexpr std::array<double, 3> raw(Vec3<Q> const& v) { | ||
| return {v[0].numerical_value_in(Q::unit), v[1].numerical_value_in(Q::unit), | ||
| v[2].numerical_value_in(Q::unit)}; | ||
| } | ||
|
|
||
| } // namespace ship |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.