aegir-genie
GENIE neutrino event generation for the SHiP experiment's aegir framework.
Loading...
Searching...
No Matches
ship_flux_driver.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 CERN for the benefit of the SHiP Collaboration
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5// ship_flux_driver.hpp — GENIE flux driver reading SHiP neutrino flux files
6//
7// Implements genie::GFluxI (and the GFluxExposureI extension for POT
8// accounting) on top of the SHiP neutrino-flux ntuple, schema version 1
9// (see docs/neutrino_flux.md in aegir): an RNTuple `nu_flux` with one entry
10// per neutrino ray (production vertex in mm/ns, momentum in GeV, statistical
11// weight) plus an `flux_meta` RNTuple carrying the POT-equivalent of the
12// file and the maximum neutrino energy.
13//
14// Each entry defines one flux ray exactly — energy, direction and production
15// point stay correlated, unlike the histogram-based FairShip flux files.
16// Positions are converted mm -> m and ns -> s for GENIE (SI units), the
17// 4-momentum is completed with E = |p| (massless neutrinos).
18
19#pragma once
20
21#include <TLorentzVector.h>
22
23#include <cstdint>
24#include <memory>
25#include <string>
26
27#include "Framework/EventGen/GFluxI.h"
28#include "Framework/ParticleData/PDGCodeList.h"
29#include "Tools/Flux/GFluxExposureI.h"
30
31namespace aegir {
32
33class ShipFluxDriver : public genie::GFluxI,
34 public genie::flux::GFluxExposureI {
35 public:
36 // Opens the flux file and reads its metadata; throws std::runtime_error
37 // with a descriptive message if the file is missing, has no nu_flux /
38 // flux_meta ntuples, or declares an unsupported schema version.
39 // With cycle = true the driver restarts from the first entry when the file
40 // is exhausted (exposure keeps accumulating); with cycle = false End()
41 // becomes true instead.
42 explicit ShipFluxDriver(std::string const& path, bool cycle = false);
43 ~ShipFluxDriver() override;
44
45 // GFluxI interface
46 genie::PDGCodeList const& FluxParticles() override;
47 double MaxEnergy() override { return max_energy_; }
48 bool GenerateNext() override;
49 int PdgCode() override { return pdg_; }
50 double Weight() override { return weight_; }
51 TLorentzVector const& Momentum() override { return p4_; }
52 TLorentzVector const& Position() override { return x4_; }
53 bool End() override { return end_; }
54 long int Index() override { return index_; }
55 void Clear(Option_t* opt) override;
56 void GenerateWeighted(bool gen_weighted) override;
57
58 // GFluxExposureI interface (kPOTs): the file represents pot() protons on
59 // target; the exposure delivered so far scales with the fraction of the
60 // total statistical weight consumed (cycling accumulates across passes).
61 // NFluxNeutrinos() is the raw ray count, not weight-corrected.
62 double GetTotalExposure() const override;
63 long int NFluxNeutrinos() const override { return n_used_; }
64
65 // SHiP-specific accessors
66 double pot() const { return pot_; }
67 std::uint64_t entries() const { return n_entries_; }
68
69 // First ray of the file (SI units, like Position()/Momentum()), read
70 // without disturbing the sequential driver state — for startup
71 // frame-sanity logging.
72 struct Ray {
73 int pdg;
74 TLorentzVector position; // m, s
75 TLorentzVector momentum; // GeV
76 };
78
79 private:
80 struct Reader; // hides ROOT RNTuple types from this header
81 std::unique_ptr<Reader> reader_;
82
83 std::string path_;
84 bool cycle_ = false;
85 bool gen_weighted_ = true; // rays carry their weight either way
86
87 // file metadata (flux_meta)
88 double pot_ = 0.0;
89 double max_energy_ = 0.0;
90 std::uint64_t n_entries_ = 0;
91 double total_weight_ = 0.0; // Σ weight over the file (> 0, checked)
92
93 // current ray
94 long int index_ = -1; // entry number of the current ray
95 int pdg_ = 0;
96 double weight_ = 0.0;
97 TLorentzVector p4_; // GeV
98 TLorentzVector x4_; // SI: m, s
99 bool end_ = false;
100 long int n_used_ = 0; // rays generated so far (across cycles)
101 double used_weight_ = 0.0; // Σ weight of the rays generated so far
102
103 genie::PDGCodeList pdg_list_;
104 bool pdg_list_built_ = false;
105};
106
107} // namespace aegir
Definition ship_flux_driver.hpp:34
std::uint64_t entries() const
Definition ship_flux_driver.hpp:67
double GetTotalExposure() const override
Definition ship_flux_driver.cpp:213
bool End() override
Definition ship_flux_driver.hpp:53
bool GenerateNext() override
Definition ship_flux_driver.cpp:152
void GenerateWeighted(bool gen_weighted) override
Definition ship_flux_driver.cpp:204
TLorentzVector const & Position() override
Definition ship_flux_driver.hpp:52
long int NFluxNeutrinos() const override
Definition ship_flux_driver.hpp:63
double pot() const
Definition ship_flux_driver.hpp:66
genie::PDGCodeList const & FluxParticles() override
Definition ship_flux_driver.cpp:127
void Clear(Option_t *opt) override
Definition ship_flux_driver.cpp:193
TLorentzVector const & Momentum() override
Definition ship_flux_driver.hpp:51
double MaxEnergy() override
Definition ship_flux_driver.hpp:47
int PdgCode() override
Definition ship_flux_driver.hpp:49
double Weight() override
Definition ship_flux_driver.hpp:50
Ray peek_first_ray()
Definition ship_flux_driver.cpp:180
~ShipFluxDriver() override
long int Index() override
Definition ship_flux_driver.hpp:54
Definition genie_config.hpp:22
Definition ship_flux_driver.hpp:72
int pdg
Definition ship_flux_driver.hpp:73
TLorentzVector position
Definition ship_flux_driver.hpp:74
TLorentzVector momentum
Definition ship_flux_driver.hpp:75
Definition ship_flux_driver.cpp:33