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