LDMX Software
Public Member Functions | Private Attributes | List of all members
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}
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
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 // Loop over all particle associated with the primary vertex and
89 // set the generator status to 1.
90 for (int iparticle = 0; iparticle < primary_vertex->GetNumberOfParticle();
91 ++iparticle) {
92 G4PrimaryParticle* primary = primary_vertex->GetPrimary(iparticle);
93
94 auto primary_info{dynamic_cast<UserPrimaryParticleInformation*>(
95 primary->GetUserInformation())};
96 if (not primary_info) {
97 // no user info defined
98 // ==> make a new one
99 primary_info = new UserPrimaryParticleInformation;
100 primary->SetUserInformation(primary_info);
101 } // check if primaryinfo is defined
102
103 int hepStatus = primary_info->getHepEvtStatus();
104 if (hepStatus <= 0) {
105 // undefined hepStatus ==> set to 1
106 primary_info->setHepEvtStatus(1);
107 } // check if hepStatus defined
108
109 } // iparticle - loop over primary particles from this vertex
110
111 // include the weight of this primary vertex in the event weight
112 event_info->incWeight(primary_vertex->GetWeight());
113
114 // smear beamspot if it is turned on
115 if (useBeamspot_) {
116 double x0_i = primary_vertex->GetX0();
117 double y0_i = primary_vertex->GetY0();
118 double z0_i = primary_vertex->GetZ0();
119 /*
120 * G4UniformRand returns a number in [0,1]
121 * - we shift this range so that it is [-0.5,0.5]
122 * - multiply by the width to get [-0.5*size,0.5*size]
123 * - add the initial point (in case its off center) to get
124 * [init-0.5*size, init+0.5*size]
125 */
126 double x0_f = beamspotXSize_ * (G4UniformRand() - 0.5) + x0_i;
127 double y0_f = beamspotYSize_ * (G4UniformRand() - 0.5) + y0_i;
128 double z0_f = beamspotZSize_ * (G4UniformRand() - 0.5) + z0_i;
129 primary_vertex->SetPosition(x0_f, y0_f, z0_f);
130 }
131
132 // shift so that t=0 coincides with primaries arriving at (or coming from)
133 // the target
135 primary_vertex->SetT0(primary_vertex->GetT0() +
136 primary_vertex->GetZ0() / 299.702547);
137 }
138
139 } // iPV - loop over primary vertices
140 } else {
141 EXCEPTION_RAISE(
142 "NoPrimaries",
143 "No primary vertices were produced by any of the generators.");
144 }
145}
void apply(UnaryFunction f) const
Apply the input UnaryFunction to each entry in the inventory.
Definition Factory.h:283

References simcore::UserPrimaryParticleInformation::getHepEvtStatus().

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: