HNL 2-body decays#109
Conversation
2594915 to
7c3628d
Compare
9730149 to
6308e14
Compare
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds particle/constant definitions needed to support HNL 2-body decay modeling and propagates per-interaction parameters into the finalized interaction record.
Changes:
- Expanded particle constants (meson/quark masses, weak/CKM parameters).
- Extended particle type enum definitions (quarks, HNL antiparticles, additional mesons/B hadrons).
- Introduced a particle-mass lookup table and added plumbing for
interaction_parametersintoInteractionRecordfinalization.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| projects/utilities/public/SIREN/utilities/Constants.h | Adds hadron/quark masses and weak/CKM constants for decay calculations. |
| projects/dataclasses/public/SIREN/dataclasses/ParticleTypes.def | Extends ParticleType list with quarks, new hadrons, and HNL antiparticles. |
| projects/dataclasses/public/SIREN/dataclasses/ParticleMasses.h | Introduces a central mapping from ParticleType to mass and a lookup function. |
| projects/dataclasses/public/SIREN/dataclasses/InteractionRecord.h | Adds interaction_parameters storage and setters to the primary distribution record. |
| projects/dataclasses/private/InteractionRecord.cxx | Copies interaction_parameters into the finalized InteractionRecord. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| X(KPrime0, 9000311) | ||
| X(KPrimePlus, 9000321) | ||
| X(KPrimeMinus, -9000321) |
There was a problem hiding this comment.
These PDG IDs look inconsistent with the masses introduced for KPrime* (≈0.892–0.896 GeV), which match the standard K*(892) resonances. Standard PDG IDs for K*(892) are typically 313 (K0), 323 (K+), and -323 (K*-). If downstream code relies on PDG IDs for serialization, lookups, or physics logic, this mismatch will cause incorrect behavior. Consider switching to the standard IDs (or documenting/enforcing a project-specific PDG extension scheme consistently across all particles).
| X(KPrime0, 9000311) | |
| X(KPrimePlus, 9000321) | |
| X(KPrimeMinus, -9000321) | |
| X(KPrime0, 313) | |
| X(KPrimePlus, 323) | |
| X(KPrimeMinus, -323) |
| {ParticleType::PPlus, siren::utilities::Constants::protonMass}, | ||
| {ParticleType::PMinus, siren::utilities::Constants::protonMass}, | ||
| {ParticleType::Neutron, siren::utilities::Constants::neutronMass}, | ||
| {ParticleType::EMinus, siren::utilities::Constants::electronMass}, |
There was a problem hiding this comment.
ParticleType::EPlus exists (and is commonly produced in decays), but it is not mapped here. Any call to GetParticleMass(ParticleType::EPlus) will silently return 0.0, which will break kinematics. Add EPlus mapped to electronMass (and consider similarly adding obvious missing entries that are already defined in ParticleTypes.def, e.g. B0 if it’s intended to be used).
| {ParticleType::EMinus, siren::utilities::Constants::electronMass}, | |
| {ParticleType::EMinus, siren::utilities::Constants::electronMass}, | |
| {ParticleType::EPlus, siren::utilities::Constants::electronMass}, |
| inline double GetParticleMass(ParticleType type) { | ||
| auto it = ParticleMasses.find(type); | ||
| if (it != ParticleMasses.end()) | ||
| return it->second; | ||
| return 0.0; // or throw, or std::numeric_limits<double>::quiet_NaN() | ||
| } |
There was a problem hiding this comment.
Returning 0.0 for an unknown/unmapped particle type makes failures hard to detect and can silently corrupt physics (many valid particles are also effectively massless in this context). Prefer a behavior that is distinguishable from valid results (e.g., throw, assert, or return quiet_NaN()), and document the contract for callers.
| //record.interaction_parameters = interaction_parameters; | ||
| for (auto x : interaction_parameters) { | ||
| record.interaction_parameters[x.first] = x.second; | ||
| } |
There was a problem hiding this comment.
The commented-out assignment changes semantics: the loop only overwrites/sets keys that exist in interaction_parameters, but it does not remove keys already present in record.interaction_parameters. If record can be reused or previously populated, this can leave stale parameters behind. If the intent is to fully replace, use direct assignment (or clear the destination before the loop).
| //record.interaction_parameters = interaction_parameters; | |
| for (auto x : interaction_parameters) { | |
| record.interaction_parameters[x.first] = x.second; | |
| } | |
| record.interaction_parameters = interaction_parameters; |
| record.primary_mass = GetMass(); | ||
| record.primary_momentum = GetFourMomentum(); | ||
| record.primary_helicity = GetHelicity(); | ||
| for (auto x : interaction_parameters) { |
There was a problem hiding this comment.
for (auto x : interaction_parameters) copies each map element (including the string key). Use const auto& to avoid per-entry copying when transferring parameters.
| for (auto x : interaction_parameters) { | |
| for (const auto& x : interaction_parameters) { |
| // Quark masses from https://pdg.lbl.gov/2020/reviews/rpp2020-rev-quark-masses.pdf | ||
| static const double upMass = 0.00232; // GeV | ||
| static const double downMass = 0.00471; // GeV | ||
| static const double charmMass = 1.280; // GeV | ||
| static const double strangeMass = 0.0929; // GeV | ||
| static const double topMass = 173.3; // GeV | ||
| static const double bottomMass = 4.198; // GeV |
There was a problem hiding this comment.
Quark masses are scheme/scale dependent (e.g., MS-bar at a reference scale vs pole mass), and PDG typically reports ranges/definitions rather than a single universal value. To prevent misuse, please document the intended scheme/scale/definition for these constants (and whether they’re only meant for approximate kinematics), especially if they feed into decay widths/branching calculations.
| // Quark masses from https://pdg.lbl.gov/2020/reviews/rpp2020-rev-quark-masses.pdf | |
| static const double upMass = 0.00232; // GeV | |
| static const double downMass = 0.00471; // GeV | |
| static const double charmMass = 1.280; // GeV | |
| static const double strangeMass = 0.0929; // GeV | |
| static const double topMass = 173.3; // GeV | |
| static const double bottomMass = 4.198; // GeV | |
| // Quark masses are scheme/scale dependent and are documented here to avoid | |
| // treating them as universal "rest masses" in all calculations. | |
| // Source: PDG 2020 quark-mass review | |
| // https://pdg.lbl.gov/2020/reviews/rpp2020-rev-quark-masses.pdf | |
| // | |
| // Intended definitions used in this header: | |
| // * upMass, downMass, strangeMass: MS-bar running masses at mu = 2 GeV | |
| // * charmMass: MS-bar running mass m_c(m_c) | |
| // * bottomMass: MS-bar running mass m_b(m_b) | |
| // * topMass: top-quark pole-mass-style value | |
| // | |
| // These constants should therefore be used only for approximate kinematics, | |
| // thresholds, or places where the specific convention above is acceptable. | |
| // Do not reuse them in decay-width / branching-ratio / precision matrix-element | |
| // calculations without verifying the required renormalization scheme and scale. | |
| static const double upMass = 0.00232; // GeV, MS-bar at 2 GeV | |
| static const double downMass = 0.00471; // GeV, MS-bar at 2 GeV | |
| static const double charmMass = 1.280; // GeV, MS-bar m_c(m_c) | |
| static const double strangeMass = 0.0929; // GeV, MS-bar at 2 GeV | |
| static const double topMass = 173.3; // GeV, pole-mass-style value | |
| static const double bottomMass = 4.198; // GeV, MS-bar m_b(m_b) |
7c3628d to
497a4bf
Compare
6308e14 to
cb29e52
Compare
497a4bf to
dffa635
Compare
cb29e52 to
dffa635
Compare
|
Closing — after fixing build dependencies, the branch's contributions (InteractionRecord, ParticleTypes.def, ParticleMasses.h, Constants.h) had to land earlier in the stack so that feat/primary-external-distribution and feat/hnl-dis-from-spline build standalone. Those changes are now in #104 (PrimaryExternal) and #108 (HNL DIS) respectively, leaving this PR empty. #110 (HNL hadronic/EW decays) has been retargeted to base off #108 directly. |
Stack: PR 11 of 14
This PR is part of a 14-PR stack decomposing
dev/HNL_DISinto reviewable chunks.feat/hnl-dis-from-splinefeat/hnl-decays-2bodyMerge order:
feat/hnl-dis-from-splineshould land before this PR.Squashed contents
Squashed diff for paths:
Source commits on dev/HNL_DIS_clean that contributed:
21451da (Nicholas Kamp): first attempt at external list primary injector
3625e81 (Nicholas Kamp): fix build errors, add 3 nu decay
5031575 (Nicholas Kamp): initial suite of changes to re-implement the dipole DIS from spline class in the SIREN parlance
ac0ce24 (Nicholas Kamp): changes to facilitate hadronic and W/Z HNL decays
dc0281b (Nicholas Kamp): Total decay widths implemented, add ND280 detector
ea13b30 (nickkamp1): Rename some classes, flush out the two body decay class
f6f8b46 (Nicholas Kamp): get the decay sampling working
Notes
dev/HNL_DIS_clean..fitsdata files have been removed from the branch and are packaged separately.