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 useBeamspot_ {false}
 Flag denoting whether the vertex position of a particle should be smeared.
 
double beamspotXSize_ {0}
 Extent of the beamspot in x.
 
double beamspotYSize_ {0}
 Extent of the beamspot in y.
 
double beamspotZSize_ {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 beamSpot{
34 parameters.getParameter<std::vector<double> >("beamSpotSmear", {})};
35 if (!beamSpot.empty()) {
36 useBeamspot_ = true;
37 beamspotXSize_ = beamSpot[0];
38 beamspotYSize_ = beamSpot[1];
39 beamspotZSize_ = beamSpot[2];
40 }
41
42 time_shift_primaries_ = parameters.getParameter<bool>("time_shift_primaries");
43
44 auto generators{
45 parameters.getParameter<std::vector<framework::config::Parameters> >(
46 "generators", {})};
47 if (generators.empty()) {
48 EXCEPTION_RAISE("MissingGenerator",
49 "Need to define some generator of primaries.");
50 }
51
52 for (auto& generator : generators) {
54 generator.getParameter<std::string>("class_name"),
55 generator.getParameter<std::string>("instance_name"), generator);
56 }
57}
static Factory & get()
get the factory instance
Definition Factory.h:217
PrototypePtr make(const std::string &full_name, PrototypeConstructorArgs... maker_args)
make a new object by name
Definition Factory.h:265
double beamspotXSize_
Extent of the beamspot in x.
double beamspotYSize_
Extent of the beamspot in y.
double beamspotZSize_
Extent of the beamspot in y.
bool useBeamspot_
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 59 of file PrimaryGeneratorAction.cxx.

59 {
60 /*
61 * Create our Event information first so that it
62 * can be accessed by everyone from now on.
63 */
64 // Make sure we aren't overwriting a different information container
65 if (event->GetUserInformation()) {
66 EXCEPTION_RAISE(
67 "Misconfig",
68 "There was a UserEventInformation attached before beginning event."
69 "\nI don't know how this happend!!");
70 }
71
72 // Make our information container and give it to geant4
73 // G4Event owns the event information and will delete it
74 auto event_info = new UserEventInformation;
75 event->SetUserInformation(event_info);
76
77 PrimaryGenerator::Factory::get().apply([event](const auto& generator) {
78 generator->GeneratePrimaryVertex(event);
79 });
80
81 // smear all primary vertices (if activated)
82 int nPV = event->GetNumberOfPrimaryVertex();
83 if (nPV > 0) {
84 // loop over all vertices generated
85 for (int iPV = 0; iPV < nPV; ++iPV) {
86 G4PrimaryVertex* primary_vertex = event->GetPrimaryVertex(iPV);
87
88 if (not primary_vertex) {
89 EXCEPTION_RAISE(
90 "BadGen",
91 "One of the primary generators created a NULL primary vertex.");
92 }
93
94 // Loop over all particle associated with the primary vertex and
95 // set the generator status to 1.
96 for (int iparticle = 0; iparticle < primary_vertex->GetNumberOfParticle();
97 ++iparticle) {
98 G4PrimaryParticle* primary = primary_vertex->GetPrimary(iparticle);
99
100 if (not primary) {
101 EXCEPTION_RAISE(
102 "BadGen",
103 "One of the primary generators created a NULL primary particle.");
104 }
105
106 auto primary_info{dynamic_cast<UserPrimaryParticleInformation*>(
107 primary->GetUserInformation())};
108 if (not primary_info) {
109 // no user info defined
110 // ==> make a new one
111 primary_info = new UserPrimaryParticleInformation;
112 primary->SetUserInformation(primary_info);
113 } // check if primaryinfo is defined
114
115 int hepStatus = primary_info->getHepEvtStatus();
116 if (hepStatus <= 0) {
117 // undefined hepStatus ==> set to 1
118 primary_info->setHepEvtStatus(1);
119 } // check if hepStatus defined
120
121 } // iparticle - loop over primary particles from this vertex
122
123 // include the weight of this primary vertex in the event weight
124 event_info->incWeight(primary_vertex->GetWeight());
125
126 // smear beamspot if it is turned on
127 if (useBeamspot_) {
128 double x0_i = primary_vertex->GetX0();
129 double y0_i = primary_vertex->GetY0();
130 double z0_i = primary_vertex->GetZ0();
131 /*
132 * G4UniformRand returns a number in [0,1]
133 * - we shift this range so that it is [-0.5,0.5]
134 * - multiply by the width to get [-0.5*size,0.5*size]
135 * - add the initial point (in case its off center) to get
136 * [init-0.5*size, init+0.5*size]
137 */
138 double x0_f = beamspotXSize_ * (G4UniformRand() - 0.5) + x0_i;
139 double y0_f = beamspotYSize_ * (G4UniformRand() - 0.5) + y0_i;
140 double z0_f = beamspotZSize_ * (G4UniformRand() - 0.5) + z0_i;
141 primary_vertex->SetPosition(x0_f, y0_f, z0_f);
142 }
143
144 // shift so that t=0 coincides with primaries arriving at (or coming from)
145 // the target
147 primary_vertex->SetT0(primary_vertex->GetT0() +
148 primary_vertex->GetZ0() / 299.702547);
149 }
150
151 } // iPV - loop over primary vertices
152 } else {
153 EXCEPTION_RAISE(
154 "NoPrimaries",
155 "No primary vertices were produced by any of the generators.");
156 }
157}
void apply(UnaryFunction f) const
Apply the input UnaryFunction to each entry in the inventory.
Definition Factory.h:283

Member Data Documentation

◆ beamspotXSize_

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

Extent of the beamspot in x.

Definition at line 91 of file PrimaryGeneratorAction.h.

91{0};

◆ beamspotYSize_

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

Extent of the beamspot in y.

Definition at line 94 of file PrimaryGeneratorAction.h.

94{0};

◆ beamspotZSize_

double simcore::g4user::PrimaryGeneratorAction::beamspotZSize_ {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};

◆ useBeamspot_

bool simcore::g4user::PrimaryGeneratorAction::useBeamspot_ {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: