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