LDMX Software
PrimaryGeneratorAction.cxx
Go to the documentation of this file.
1
8
9/*~~~~~~~~~~~~*/
10/* Geant4 */
11/*~~~~~~~~~~~~*/
12#include "G4Event.hh"
13#include "G4RunManager.hh" // Needed for CLHEP
14
15/*~~~~~~~~~~~~~*/
16/* SimCore */
17/*~~~~~~~~~~~~~*/
18#include "SimCore/G4User/UserEventInformation.h"
21
22/*~~~~~~~~~~*/
23/* ROOT */
24/*~~~~~~~~~~*/
25#include "TRandom3.h"
26
27namespace simcore::g4user {
28
29PrimaryGeneratorAction::PrimaryGeneratorAction(
30 const framework::config::Parameters& parameters)
31 : G4VUserPrimaryGeneratorAction() {
32 // Check whether a beamspot should be used or not.
33 auto beam_spot{parameters.get<std::vector<double> >("beamSpotSmear", {})};
34 if (!beam_spot.empty()) {
35 use_beamspot_ = true;
36 beamspot_x_size_ = beam_spot[0];
37 beamspot_y_size_ = beam_spot[1];
38 beamspot_z_size_ = beam_spot[2];
39 }
40
41 time_shift_primaries_ = parameters.get<bool>("time_shift_primaries");
42
43 auto generators{parameters.get<std::vector<framework::config::Parameters> >(
44 "generators", {})};
45 if (generators.empty()) {
46 EXCEPTION_RAISE("MissingGenerator",
47 "Need to define some generator of primaries.");
48 }
49
50 for (auto& generator : generators) {
51 if (not PrimaryGenerator::Factory::get().make(
52 generator.get<std::string>("class_name"),
53 generator.get<std::string>("instance_name"), generator)) {
54 EXCEPTION_RAISE("UnableToCreate",
55 "Unable to create a PrimaryGenerator of type " +
56 generator.get<std::string>("class_name"));
57 }
58 }
59}
60
61void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event) {
62 /*
63 * Create our Event information first so that it
64 * can be accessed by everyone from now on.
65 */
66 // Make sure we aren't overwriting a different information container
67 if (event->GetUserInformation()) {
68 EXCEPTION_RAISE(
69 "Misconfig",
70 "There was a UserEventInformation attached before beginning event."
71 "\nI don't know how this happend!!");
72 }
73
74 // Make our information container and give it to geant4
75 // G4Event owns the event information and will delete it
76 auto event_info = new UserEventInformation;
77 event->SetUserInformation(event_info);
78
79 PrimaryGenerator::Factory::get().apply([event](const auto& generator) {
80 generator->GeneratePrimaryVertex(event);
81 });
82
83 // smear all primary vertices (if activated)
84 int n_pv = event->GetNumberOfPrimaryVertex();
85 if (n_pv > 0) {
86 // loop over all vertices generated
87 for (int i_pv = 0; i_pv < n_pv; ++i_pv) {
88 G4PrimaryVertex* primary_vertex = event->GetPrimaryVertex(i_pv);
89
90 if (not primary_vertex) {
91 EXCEPTION_RAISE(
92 "BadGen",
93 "One of the primary generators created a NULL primary vertex.");
94 }
95
96 // Loop over all particle associated with the primary vertex and
97 // set the generator status to 1.
98 for (int iparticle = 0; iparticle < primary_vertex->GetNumberOfParticle();
99 ++iparticle) {
100 G4PrimaryParticle* primary = primary_vertex->GetPrimary(iparticle);
101
102 if (not primary) {
103 EXCEPTION_RAISE(
104 "BadGen",
105 "One of the primary generators created a NULL primary particle.");
106 }
107
108 auto primary_info{dynamic_cast<UserPrimaryParticleInformation*>(
109 primary->GetUserInformation())};
110 if (not primary_info) {
111 // no user info defined
112 // ==> make a new one
113 primary_info = new UserPrimaryParticleInformation;
114 primary->SetUserInformation(primary_info);
115 } // check if primaryinfo is defined
116
117 int hep_status = primary_info->getHepEvtStatus();
118 if (hep_status <= 0) {
119 // undefined hepStatus ==> set to 1
120 primary_info->setHepEvtStatus(1);
121 } // check if hepStatus defined
122
123 } // iparticle - loop over primary particles from this vertex
124
125 // include the weight of this primary vertex in the event weight
126 event_info->incWeight(primary_vertex->GetWeight());
127
128 // smear beamspot if it is turned on
129 if (use_beamspot_) {
130 double x0_i = primary_vertex->GetX0();
131 double y0_i = primary_vertex->GetY0();
132 double z0_i = primary_vertex->GetZ0();
133 /*
134 * G4UniformRand returns a number in [0,1]
135 * - we shift this range so that it is [-0.5,0.5]
136 * - multiply by the width to get [-0.5*size,0.5*size]
137 * - add the initial point (in case its off center) to get
138 * [init-0.5*size, init+0.5*size]
139 */
140 double x0_f = beamspot_x_size_ * (G4UniformRand() - 0.5) + x0_i;
141 double y0_f = beamspot_y_size_ * (G4UniformRand() - 0.5) + y0_i;
142 double z0_f = beamspot_z_size_ * (G4UniformRand() - 0.5) + z0_i;
143 primary_vertex->SetPosition(x0_f, y0_f, z0_f);
144 }
145
146 // shift so that t=0 coincides with primaries arriving at (or coming from)
147 // the target
148 if (time_shift_primaries_) {
149 primary_vertex->SetT0(primary_vertex->GetT0() +
150 primary_vertex->GetZ0() / 299.702547);
151 }
152
153 } // iPV - loop over primary vertices
154 } else {
155 EXCEPTION_RAISE(
156 "NoPrimaries",
157 "No primary vertices were produced by any of the generators.");
158 }
159}
160} // namespace simcore::g4user
Class implementing the Geant4 primary generator action.
Header file for PrimaryGenerator.
Class that provides extra information for Geant4 primary particles.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
Encapsulates user defined information associated with a Geant4 event.
Defines extra information attached to a Geant4 primary particle.