File indexing completed on 2026-09-27 09:14:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef LAGER_CORE_EVENT_LOADED
0021 #define LAGER_CORE_EVENT_LOADED
0022
0023 #include <lager/core/assert.hh>
0024 #include <lager/core/event.hh>
0025 #include <lager/core/generator.hh>
0026 #include <lager/core/particle.hh>
0027
0028 #include <TClonesArray.h>
0029 #include <TFile.h>
0030 #include <TParticle.h>
0031 #include <TTree.h>
0032
0033 #include <HepMC3/WriterAscii.h>
0034
0035 #include <fstream>
0036 #include <memory>
0037 #include <string>
0038 #include <vector>
0039
0040 namespace lager {
0041
0042
0043
0044
0045
0046
0047
0048 class event : public generator_data {
0049 public:
0050 event(const event&) = default;
0051 event& operator=(const event&) = default;
0052 explicit event(const double xs = 1., const double w = 1.)
0053 : generator_data{xs}, weight_{w} {}
0054
0055
0056
0057
0058
0059
0060 size_t evgen() const { return evgen_; }
0061 double total_cross_section() const { return total_cross_section_; }
0062 double process_cross_section() const { return process_cross_section_; }
0063 double weight() const { return weight_; }
0064 int process() const { return process_; }
0065
0066
0067 double s() const;
0068
0069
0070
0071
0072
0073 void update_stat(const size_t evgen, const double txs);
0074 void update_process(const int proc);
0075
0076 void update_weight(const double w) { weight_ *= w; }
0077 void reset_weight(const double w = 1.) { weight_ = w; }
0078
0079
0080 size_t count_status(const particle::status_code stat) const {
0081 return std::count_if(part_.begin(), part_.end(),
0082 [=](const particle& p) { return p.status() == stat; });
0083 }
0084 size_t count_stable() const {
0085 return std::count_if(part_.begin(), part_.end(),
0086 [](const particle& p) { return p.stable(); });
0087 }
0088 size_t count_final_state() const {
0089 return std::count_if(part_.begin(), part_.end(),
0090 [](const particle& p) { return p.final_state(); });
0091 }
0092
0093
0094
0095
0096
0097 particle& operator[](const int index) { return part_[index]; }
0098 const particle& operator[](const int index) const { return part_[index]; }
0099 std::vector<particle>& part() { return part_; }
0100 const std::vector<particle>& part() const { return part_; }
0101 particle& part(const int index) { return part_[index]; }
0102 const particle& part(const int index) const { return part_[index]; }
0103
0104
0105 size_t size() const { return part_.size(); }
0106
0107
0108 std::vector<particle>::iterator begin() { return part_.begin(); }
0109 std::vector<particle>::const_iterator begin() const { return part_.begin(); }
0110 std::vector<particle>::iterator end() { return part_.end(); }
0111 std::vector<particle>::const_iterator end() const { return part_.end(); }
0112
0113
0114 int add_particle(const particle& p);
0115 int add_particle(const std::pair<particle, particle>& p);
0116
0117
0118
0119 int add_daughter(particle daughter, const int parent1,
0120 const int parent2 = -1);
0121 int add_daughter(const std::pair<particle, particle>& daughters,
0122 const int parent1, const int parent2 = -1);
0123
0124
0125
0126 int add_ibeam(const particle& p);
0127 int add_tbeam(const particle& p);
0128
0129
0130 particle& ibeam();
0131 const particle& ibeam() const;
0132 particle& tbeam();
0133 const particle& tbeam() const;
0134 int ibeam_index() const { return ibeam_index_; }
0135 int tbeam_index() const { return tbeam_index_; }
0136
0137
0138
0139
0140
0141 std::vector<detected_particle>& detected() { return detected_; }
0142 const std::vector<detected_particle>& detected() const { return detected_; }
0143 detected_particle& detected(const int index) { return detected_[index]; }
0144 const detected_particle& detected(const int index) const;
0145
0146 int add_detected(const detected_particle& dp);
0147
0148 private:
0149 size_t evgen_{1};
0150 double total_cross_section_{0.};
0151 double process_cross_section_{0.};
0152 double weight_{1.};
0153 int process_{0};
0154
0155 double s_;
0156
0157 int ibeam_index_{-1};
0158 int tbeam_index_{-1};
0159
0160
0161 std::vector<particle> part_;
0162 std::vector<detected_particle> detected_;
0163 };
0164 }
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 namespace lager {
0183 class event_out {
0184 public:
0185 constexpr static const int32_t PARTICLE_BUFFER_SIZE{1000};
0186
0187 event_out(std::shared_ptr<TFile> f,
0188 std::unique_ptr<HepMC3::WriterAscii> ohepmc,
0189 std::unique_ptr<std::ofstream> ogemc,
0190 std::unique_ptr<std::ofstream> osimc, const std::string& name);
0191 ~event_out() { tree_->AutoSave(); }
0192
0193
0194 event_out() = delete;
0195 event_out(const event_out&) = delete;
0196 event_out& operator=(const event_out&) = delete;
0197
0198
0199 void push(const event& e);
0200 void push(const std::vector<event>& e);
0201
0202 TTree* tree() { return tree_; }
0203
0204 private:
0205 void write_hepmc(const event& e);
0206 void write_gemc(const event& e);
0207 void write_simc(const event& e);
0208
0209
0210 void clear();
0211
0212 void add(const particle& part);
0213
0214 void add_detected(const detected_particle& dp);
0215
0216 void create_branches();
0217
0218 private:
0219
0220 std::shared_ptr<TFile> file_;
0221 TTree* tree_;
0222 std::unique_ptr<HepMC3::WriterAscii> ohepmc_;
0223 std::unique_ptr<std::ofstream> ogemc_;
0224 std::unique_ptr<std::ofstream> osimc_;
0225
0226
0227 int32_t index_{0};
0228 int32_t evgen_;
0229 float cross_section_;
0230 float total_cross_section_;
0231 float process_cross_section_;
0232 float weight_;
0233 int32_t process_;
0234 float s_;
0235 int16_t ibeam_index_;
0236 int16_t tbeam_index_;
0237
0238
0239 int16_t n_part_{0};
0240 TClonesArray parts_;
0241 int16_t rc_n_part_{0};
0242 TClonesArray rc_parts_;
0243 };
0244 }
0245
0246
0247
0248
0249 namespace lager {
0250 inline int event::add_particle(const particle& p) {
0251 const int index = part_.size();
0252 part_.push_back(p);
0253 part_[index].update_index(index);
0254 return index;
0255 }
0256 inline int event::add_particle(const std::pair<particle, particle>& p) {
0257 int first = add_particle(p.first);
0258 add_particle(p.second);
0259 return first;
0260 }
0261
0262 inline int event::add_daughter(particle daughter, const int parent1,
0263 const int parent2) {
0264 daughter.add_parent(parent1);
0265 daughter.add_parent(parent2);
0266 int index = add_particle(daughter);
0267 part_[parent1].add_daughter(index);
0268 if (parent2 >= 0) {
0269 part_[parent2].add_daughter(index);
0270 }
0271 return index;
0272 }
0273 inline int event::add_daughter(const std::pair<particle, particle>& daughters,
0274 const int parent1, const int parent2) {
0275 int first = add_daughter(daughters.first, parent1, parent2);
0276 add_daughter(daughters.second, parent1, parent2);
0277 return first;
0278 }
0279
0280 inline void event::update_stat(const size_t evgen, const double txs) {
0281 evgen_ = evgen;
0282 total_cross_section_ = txs;
0283 update_cross_section(jacobian());
0284 process_cross_section_ = 0.;
0285 }
0286 inline void event::update_process(const int proc) { process_ = proc; }
0287 inline const detected_particle& event::detected(const int index) const {
0288 return detected_[index];
0289 }
0290
0291 inline int event::add_detected(const detected_particle& dp) {
0292 detected_.push_back(dp);
0293 return detected_.size() - 1;
0294 }
0295 inline int event::add_ibeam(const particle& p) {
0296 ibeam_index_ = add_particle(p);
0297 return ibeam_index_;
0298 }
0299 inline int event::add_tbeam(const particle& p) {
0300 tbeam_index_ = add_particle(p);
0301 return tbeam_index_;
0302 }
0303 inline particle& event::ibeam() {
0304 tassert(ibeam_index_ >= 0, "trying to access beam data, but no beam "
0305 "data present in the event.");
0306 return part_[ibeam_index_];
0307 }
0308 inline const particle& event::ibeam() const {
0309 tassert(ibeam_index_ >= 0, "trying to access beam data, but no beam "
0310 "data present in the event.");
0311 return part_[ibeam_index_];
0312 }
0313 inline particle& event::tbeam() {
0314 tassert(tbeam_index_ >= 0, "trying to access target data, but no target "
0315 "data present in the event.");
0316 return part_[tbeam_index_];
0317 }
0318 inline const particle& event::tbeam() const {
0319 tassert(tbeam_index_ >= 0, "trying to access target data, but no target "
0320 "data present in the event.");
0321 return part_[tbeam_index_];
0322 }
0323 inline double event::s() const {
0324
0325 if (ibeam_index_ < 0 || tbeam_index_ < 0) {
0326 return 0.;
0327 }
0328 return (ibeam().p() + tbeam().p()).M2();
0329 }
0330
0331 }
0332
0333 #endif