LDMX Software
simcore::g4user::PrimaryGeneratorAction Class Reference

Implementation of Geant4 primary generator action. More...

#include <PrimaryGeneratorAction.h>

Public Member Functions

 PrimaryGeneratorAction (const framework::config::Parameters &parameters)
 
virtual ~PrimaryGeneratorAction ()=default
 Class destructor.
 
void GeneratePrimaries (G4Event *event) override
 Generate primaries for the event.
 

Private Attributes

bool use_beamspot_ {false}
 Flag denoting whether the vertex position of a particle should be smeared.
 
double beamspot_x_size_ {0}
 Extent of the beamspot in x_.
 
double beamspot_y_size_ {0}
 Extent of the beamspot in y_.
 
double beamspot_z_size_ {0.}
 Extent of the beamspot in y_.
 
bool time_shift_primaries_ {true}
 Should we time-shift so that the primary vertices arrive (or originate) at t=0ns at z_=0mm?
 

Detailed Description

Implementation of Geant4 primary generator action.

Definition at line 35 of file PrimaryGeneratorAction.h.

Constructor & Destructor Documentation

◆ PrimaryGeneratorAction()

simcore::g4user::PrimaryGeneratorAction::PrimaryGeneratorAction ( const framework::config::Parameters & parameters)

Definition at line 29 of file PrimaryGeneratorAction.cxx.

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}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
double beamspot_y_size_
Extent of the beamspot in y_.
double beamspot_x_size_
Extent of the beamspot in x_.
double beamspot_z_size_
Extent of the beamspot in y_.
bool use_beamspot_
Flag denoting whether the vertex position of a particle should be smeared.
bool time_shift_primaries_
Should we time-shift so that the primary vertices arrive (or originate) at t=0ns at z_=0mm?

Member Function Documentation

◆ GeneratePrimaries()

void simcore::g4user::PrimaryGeneratorAction::GeneratePrimaries ( G4Event * event)
override

Generate primaries for the event.

This is called by the RunManager before being given to the EventManager to process. This means we must create the UserEventInformation here so that it is accessible for including the weights imported by the primary generators.

See also
G4RunManager::GenerateEvent for where this method is called
G4RunManager::ProcessOneEvent for where G4RunManager::GenerateEvent is called

Set UserInformation for primary vertices if they haven't been set before.

Some features downstream of the primaries require certain user info to function properly. This ensures that it happens.

Makes sure that each particle on each primary vertex has

  1. A defined UserPrimaryParticleInformation member
  2. The HepEvtStatus for this primary info is non-zero

If we are passed configuration to smear the beam spot, we smear the beam spot around the spot generated by the primary generator.

If we are configured to time-shift the primaries, we shift them so that t=0 coincides with primaries arriving at (or coming from) the target.

Parameters
eventThe Geant4 event.

Definition at line 61 of file PrimaryGeneratorAction.cxx.

61 {
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
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}

Member Data Documentation

◆ beamspot_x_size_

double simcore::g4user::PrimaryGeneratorAction::beamspot_x_size_ {0}
private

Extent of the beamspot in x_.

Definition at line 91 of file PrimaryGeneratorAction.h.

91{0};

◆ beamspot_y_size_

double simcore::g4user::PrimaryGeneratorAction::beamspot_y_size_ {0}
private

Extent of the beamspot in y_.

Definition at line 94 of file PrimaryGeneratorAction.h.

94{0};

◆ beamspot_z_size_

double simcore::g4user::PrimaryGeneratorAction::beamspot_z_size_ {0.}
private

Extent of the beamspot in y_.

Definition at line 97 of file PrimaryGeneratorAction.h.

97{0.};

◆ time_shift_primaries_

bool simcore::g4user::PrimaryGeneratorAction::time_shift_primaries_ {true}
private

Should we time-shift so that the primary vertices arrive (or originate) at t=0ns at z_=0mm?

Note
This should remain true unless the user knows what they are doing!

Definition at line 105 of file PrimaryGeneratorAction.h.

105{true};

◆ use_beamspot_

bool simcore::g4user::PrimaryGeneratorAction::use_beamspot_ {false}
private

Flag denoting whether the vertex position of a particle should be smeared.

Definition at line 88 of file PrimaryGeneratorAction.h.

88{false};

The documentation for this class was generated from the following files: