LDMX Software
HepMCPrimaryGenerator.cxx
2
3#include <algorithm>
4
5#include "G4RunManager.hh"
7
8namespace simcore {
9namespace generators {
10
12 const std::string& name, const framework::config::Parameters& parameters)
13 : PrimaryGenerator(name, parameters),
14 file_path_{parameters.get<std::string>("file_path")},
15 reader_{file_path_},
16 vertex_{parameters.get<std::vector<double>>("vertex")} {}
17
19 std::unique_ptr<simcore::hepmc::HepMCEvent> hepmc_event =
21
22 if (hepmc_event != nullptr) {
23 // One G4 vertex per HepMC production vertex, in order of first use
24 std::vector<std::pair<int, G4PrimaryVertex*>> vertices;
25
26 const auto& particles = hepmc_event->getParticles();
27 for (const auto& particle : particles) {
28 const int vtx_id = particle->getProductionVertexId();
29 auto it =
30 std::find_if(vertices.begin(), vertices.end(),
31 [vtx_id](const auto& v) { return v.first == vtx_id; });
32 G4PrimaryVertex* vertex{nullptr};
33 if (it == vertices.end()) {
34 // HepMC3 lengths are mm after the reader converts units
35 const HepMC3::FourVector pos = particle->getProductionPosition();
36 // This is a raw pointer, and GEANT4 will delete it
37 vertex = new G4PrimaryVertex(pos.x() + vertex_[0], pos.y() + vertex_[1],
38 pos.z() + vertex_[2], pos.t() / c_light);
39 // vertex weights multiply, so only the first carries the event weight
40 if (vertices.empty()) vertex->SetWeight(hepmc_event->getEventWeight());
41 vertices.emplace_back(vtx_id, vertex);
42 } else {
43 vertex = it->second;
44 }
45
46 // Create a primary particle for Geant4
47 // This is a raw pointer, and GEANT4 will delete it
48 G4PrimaryParticle* primary = new G4PrimaryParticle();
49
50 primary->SetPDGcode(particle->getPdgId());
51
52 // Set the primary particle's momentum
53 // HepMC3 uses GeV by default, which is what Geant4 expects
54 primary->Set4Momentum(particle->getMomentum(0) * GeV, // px
55 particle->getMomentum(1) * GeV, // py
56 particle->getMomentum(2) * GeV, // pz
57 particle->getMomentum(3) * GeV // E
58 );
59
60 auto primary_info = std::make_unique<UserPrimaryParticleInformation>();
61 primary_info->setHepEvtStatus(particle->getStatus());
62 primary->SetUserInformation(primary_info.release());
63
64 vertex->SetPrimary(primary);
65 }
66
67 // Apply beam spot smearing if configured, same shift for all vertices
68 if (useBeamspot() && !vertices.empty()) {
69 G4PrimaryVertex* first = vertices.front().second;
70 const G4ThreeVector before = first->GetPosition();
71 smearBeamspot(first);
72 const G4ThreeVector shift = first->GetPosition() - before;
73 for (std::size_t i = 1; i < vertices.size(); ++i) {
74 auto* vertex = vertices[i].second;
75 vertex->SetPosition(vertex->GetX0() + shift.x(),
76 vertex->GetY0() + shift.y(),
77 vertex->GetZ0() + shift.z());
78 }
79 }
80
81 for (auto& [vtx_id, vertex] : vertices) anEvent->AddPrimaryVertex(vertex);
82
83 } else {
84 ldmx_log(error) << "Ran out of input events so run will be aborted!";
85 G4RunManager::GetRunManager()->AbortRun(true);
86 anEvent->SetEventAborted();
87 }
88}
89
90void HepMCPrimaryGenerator::RecordConfig(const std::string& id,
91 ldmx::RunHeader& rh) {
92 rh.setStringParameter(id + " Class",
93 "simcore::generators::HepMCPrimaryGenerator");
94 rh.setStringParameter(id + " HepMC File", file_path_);
95}
96
97} // namespace generators
98} // namespace simcore
99
Class for generating a Geant4 event from HepMC event data.
#define DECLARE_GENERATOR(CLASS)
@macro DECLARE_GENERATOR
Class that provides extra information for Geant4 primary particles.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:68
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:261
Interface that defines a simulation primary generator.
bool useBeamspot() const
Check if beam spot smearing is enabled for this generator.
void smearBeamspot(G4PrimaryVertex *primary_vertex)
Apply beam spot smearing to a primary vertex.
Generates a Geant4 event from a HepMCEvent.
std::vector< double > vertex_
The vertex offset to apply to the HepMC event vertex.
hepmc::HepMCReader reader_
The HepMC reader with the event data.
std::string file_path_
The file path to the HepMC file.
HepMCPrimaryGenerator(const std::string &name, const framework::config::Parameters &parameters)
Class constructor.
void GeneratePrimaryVertex(G4Event *anEvent) override
Generate vertices in the Geant4 event.
void RecordConfig(const std::string &id, ldmx::RunHeader &rh) override
Record configuration information.
std::unique_ptr< HepMCEvent > readNextEvent()
Read the next event.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...