LDMX Software
BertiniEventTopologyProcess.h
1#ifndef SIMCORE_BERTINI_EVENTTOPOLOGY_PROCESS_H
2#define SIMCORE_BERTINI_EVENTTOPOLOGY_PROCESS_H
3
4#include <G4CascadeInterface.hh>
5#include <G4EventManager.hh>
6#include <G4HadFinalState.hh>
7#include <G4HadProjectile.hh>
8#include <G4Nucleus.hh>
9
10#include "SimCore/G4User/UserEventInformation.h"
11
12namespace simcore {
13
14/*
15** A wrapper interface around the Bertini cascade process (G4CascadeInterface)
16** which reruns the event generator until a particular condition is met for the
17** products. The decision of whether or not to rerun the event generator is
18** handled by the acceptEvent virtual function.
19**
20** For example of a derived class, see
21** SimCore/include/SimCore/PhotoNuclearModels/BertiniNothingHardModel.h
22**
23** Note: You almost certainly want to use these types of models together with a
24** photonuclear topology filter.
25**
26** Note: When performing N attempts, this will increment the event weight in the
27** UserEventInformation by 1/N. To change this behaviour, override the
28** incrementEventWeight function.
29*/
30
31class BertiniEventTopologyProcess : public G4CascadeInterface {
32 public:
33 BertiniEventTopologyProcess(bool count_light_ions = true)
34 : G4CascadeInterface{}, count_light_ions_{count_light_ions} {}
35
36 /*
37 * The primary function for derived classes to customize. After each call to
38 * the Bertini cascade, this function will be called to see whether or not to
39 * keep the event. The products can be accessed from the `theParticleChange`
40 * member inherited from G4CascadeInterface (i.e. the Bertini cascade).
41 */
42 virtual bool acceptEvent() const = 0;
43
44 /*
45 * Is the projectile of interest?
46 *
47 * If false, the cascade will only run once. Example use includes only
48 * applying repeated simulations for particular energy ranges. Is called
49 * automatically during `ApplyYourself`.
50 *
51 **/
52 virtual bool acceptProjectile(const G4HadProjectile& projectile) const = 0;
53
54 /*
55 * Is the target nucleus of interest?
56 *
57 * If false, the cascade will only run once. Example use includes only
58 * applying repeated simulations for high Z materials. Is called
59 * automatically during `ApplyYourself`.
60 *
61 **/
62 virtual bool acceptTarget(const G4Nucleus& targetNucleus) const = 0;
63
64 /*
65 * Run the Bertini cascade until the condition given by `acceptEvent` is
66 * matched by the reaction products. Increments the event weight by 1/n where
67 * n is the number of attempts needed to produce a match.
68 *
69 **/
70 G4HadFinalState* ApplyYourself(const G4HadProjectile& projectile,
71 G4Nucleus& targetNucleus) override;
72
73 /*
74 * Geant4 assumes that secondaries produced from the bertini cascade are owned
75 * by some other part of the code. Since we are re-running the cascade until
76 * we get something matching our condition in `acceptEvent`, we have to make
77 * sure to clean up any secondaries from failed attempts.
78 *
79 */
80 void cleanupSecondaries();
81
90 constexpr bool isLightIon(const int pdgCode) const {
91 //
92 if (pdgCode > 1000000000) {
93 // Check if the atomic number is less than or equal to 4
94 return ((pdgCode / 10) % 1000) <= 4;
95 }
96 return false;
97 }
98
111 constexpr bool skipCountingParticle(const int pdgcode) const {
112 return !(pdgcode < 10000 || (count_light_ions_ && isLightIon(pdgcode)));
113 }
114
115 /*
116 * Update the event weight depending on the number of attempts made.
117 *
118 * @param N The number of attempts used for a successful topology
119 * production.
120 *
121 **/
122
123 virtual void incrementEventWeight(int N) {
124 auto event_info{static_cast<UserEventInformation*>(
125 G4EventManager::GetEventManager()->GetUserInformation())};
126 event_info->incWeight(1. / N);
127 }
128
129 private:
130 bool count_light_ions_;
131};
132} // namespace simcore
133
134#endif /* SIMCORE_BERTINI_EVENTTOPOLOGY_PROCESS_H */
constexpr bool skipCountingParticle(const int pdgcode) const
Whether or not to include a particular particle type in any counting.
constexpr bool isLightIon(const int pdgCode) const
Check if the PDG code corresponds to a light ion nucleus.
Encapsulates user defined information associated with a Geant4 event.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...