All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
larg4::MCTruthEventActionService Class Reference

#include <MCTruthEventAction_service.h>

Inheritance diagram for larg4::MCTruthEventActionService:

Public Member Functions

 MCTruthEventActionService (fhicl::ParameterSet const &)
 
 ~MCTruthEventActionService ()
 
void setInputCollections (std::vector< art::Handle< std::vector< simb::MCTruth >>> const &mclists)
 

Private Member Functions

void generatePrimaries (G4Event *anEvent) override
 

Private Attributes

std::vector< art::Handle
< std::vector< simb::MCTruth >
> > const * 
fMCLists
 MCTruthCollection input lists. More...
 
std::map< G4int, G4int > fUnknownPDG
 map of unknown PDG codes to instances More...
 
std::map< G4int, G4int > fNon1StatusPDG
 PDG codes skipped because not status 1. More...
 
std::map< G4int, G4int > fProcessedPDG
 PDG codes processed. More...
 

Static Private Attributes

static G4ParticleTable * fParticleTable = nullptr
 Geant4's table of particle definitions. More...
 

Detailed Description

Definition at line 40 of file MCTruthEventAction_service.h.

Constructor & Destructor Documentation

larg4::MCTruthEventActionService::MCTruthEventActionService ( fhicl::ParameterSet const &  p)

Definition at line 43 of file MCTruthEventAction.cc.

44  : PrimaryGeneratorActionBase(p.get<string>("name", "MCTruthEventActionService"))
45 {}
pdgs p
Definition: selectors.fcl:22
larg4::MCTruthEventActionService::~MCTruthEventActionService ( )

Definition at line 47 of file MCTruthEventAction.cc.

48 {
49  // Print out a list of "unknown" PDG codes we saw in the input.
50  if (!fUnknownPDG.empty()) {
51  std::ostringstream badtxt;
52  for (auto const [pdg, n] : fUnknownPDG) {
53  badtxt << "\n Unknown PDG code = " << pdg << ", seen " << n << " times.";
54  if (genie_specific(pdg)) { badtxt << " (GENIE specific)"; }
55  }
56 
57  mf::LogWarning("MCTruthEventAction") << "The following unknown PDG codes were present in the "
58  << "simb::MCTruth input.\n"
59  << "They were not processed by Geant4." << badtxt.str();
60  }
61 
62  // Print out a list of PDG codes we saw in the input that weren't status=1
63  if (!fNon1StatusPDG.empty()) {
64  std::ostringstream non1txt;
65  for (auto const [pdg, n] : fNon1StatusPDG) {
66  non1txt << "\n PDG code = " << pdg << ", seen " << n << " times.";
67  if (genie_specific(pdg)) { non1txt << " (GENIE specific)"; }
68  }
69 
70  mf::LogDebug("MCTruthEventAction") << "The following PDG codes were present in the "
71  << "simb::MCTruth input with Status != 1.\n"
72  << "They were not processed by Geant4." << non1txt.str();
73  }
74 
75  // Print out a list of PDG codes that were processed
76  if (!fProcessedPDG.empty()) {
77  std::ostringstream goodtxt;
78  for (auto const [pdg, n] : fProcessedPDG) {
79  goodtxt << "\n PDG code = " << pdg << ", seen " << n << " times.";
80  }
81  mf::LogDebug("MCTruthEventAction") << "The following PDG codes were present in the "
82  << "simb::MCTruth input with Status = 1 "
83  << "and were processed by Geant4" << goodtxt.str();
84  }
85 }
var pdg
Definition: selectors.fcl:14
std::map< G4int, G4int > fProcessedPDG
PDG codes processed.
std::map< G4int, G4int > fNon1StatusPDG
PDG codes skipped because not status 1.
std::map< G4int, G4int > fUnknownPDG
map of unknown PDG codes to instances

Member Function Documentation

void larg4::MCTruthEventActionService::generatePrimaries ( G4Event *  anEvent)
overrideprivate

Definition at line 90 of file MCTruthEventAction.cc.

91 {
92  // For each MCTruth (probably only one, but you never know):
93  // index keeps track of which MCTruth object you are using
94  auto const& mclistHandles = *fMCLists;
95 
96  size_t mclSize = mclistHandles.size(); // -- should match the number of generators
97  mf::LogDebug("generatePrimaries") << "MCTruth Handles Size: " << mclSize;
98 
99  // -- Loop over MCTruth Handle List
100  size_t index = 0;
101  std::map<CLHEP::HepLorentzVector, G4PrimaryVertex*> vertexMap;
102  for (size_t mcl = 0; mcl < mclSize; ++mcl) {
103  mf::LogDebug("generatePrimaries")
104  << "MCTruth Handle Number: " << (mcl + 1) << " of " << mclSize;
105  art::Handle<std::vector<simb::MCTruth>> mclistHandle = mclistHandles[mcl];
106  // Loop over all MCTruth handle entries for a given generator,
107  // usually only one, but you never know
108  for (size_t i = 0; i < mclistHandle->size(); ++i) {
109  art::Ptr<simb::MCTruth> mclist(mclistHandle, i);
110 
111  mf::LogDebug("generatePrimaries")
112  << "art::Ptr number " << (i + 1) << " of " << mclistHandle->size() << ", Ptr: " << mclist;
113  int nPart = mclist->NParticles();
114  MF_LOG_INFO("generatePrimaries") << "Generating " << nPart << " particles";
115 
116  // -- Loop over all particles in MCTruth Object
117  for (int m = 0; m != nPart; ++m) {
118  simb::MCParticle const& particle = mclist->GetParticle(m);
119  G4int const pdgCode = particle.PdgCode();
120 
121  if (particle.StatusCode() != 1) {
122  MF_LOG_DEBUG("generatePrimaries")
123  << "Status code != 1, skipping particle number with MCTruth index = "
124  << "(" << mcl << "," << i << ")"
125  << " and particle index = " << m;
126  fNon1StatusPDG[pdgCode] += 1;
127  continue;
128  }
129 
130  if (((m + 1) % nPart) < 2) // -- only first and last will satisfy this
131  {
132  mf::LogDebug("generatePrimaries") << "Particle Number: " << (m + 1) << " of " << nPart;
133  mf::LogDebug("generatePrimaries") << "TrackID: " << particle.TrackId();
134  mf::LogDebug("generatePrimaries") << "index: " << index;
135  }
136 
137  G4double x = particle.Vx() * CLHEP::cm;
138  G4double y = particle.Vy() * CLHEP::cm;
139  G4double z = particle.Vz() * CLHEP::cm;
140  G4double t = particle.T() * CLHEP::ns;
141 
142  // Create a CLHEP four-vector from the particle's vertex.
143  CLHEP::HepLorentzVector fourpos(x, y, z, t);
144 
145  // Is this vertex already in our map?
146  G4PrimaryVertex* vertex = nullptr;
147  auto result = vertexMap.find(fourpos);
148  if (result == vertexMap.end()) {
149  // No, it's not, so create a new vertex and add it to the map.
150  vertex = new G4PrimaryVertex(x, y, z, t);
151  vertexMap[fourpos] = vertex;
152 
153  // Add the vertex to the G4Event.
154  anEvent->AddPrimaryVertex(vertex);
155  }
156  else {
157  // Yes, it is, so use the existing vertex.
158  vertex = result->second;
159  }
160 
161  // Get additional particle information.
162  TLorentzVector const& momentum = particle.Momentum(); // (px,py,pz,E)
163  TVector3 const& polarization = particle.Polarization();
164 
165  // Get the particle table if necessary. (Note: we're doing
166  // this "late" because I'm not sure at what point the G4
167  // particle table is initialized in the loading process.)
168  if (fParticleTable == nullptr) { fParticleTable = G4ParticleTable::GetParticleTable(); }
169 
170  // Get Geant4's definition of the particle.
171  G4ParticleDefinition* particleDefinition = nullptr;
172 
173  if (pdgCode == 0) { particleDefinition = fParticleTable->FindParticle("opticalphoton"); }
174  else {
175  particleDefinition = fParticleTable->FindParticle(pdgCode);
176  }
177 
178  if (pdgCode >= 2'000'000'000) { // If the particle is generator-specific
179  mf::LogDebug("ConvertPrimaryToGeant4")
180  << ": %%% Will skip particle with generator-specific PDG code = " << pdgCode;
181  fUnknownPDG[pdgCode] += 1;
182  continue;
183  }
184  if (pdgCode > 1'000'000'000) { // If the particle is a nucleus
185  mf::LogDebug("ConvertPrimaryToGeant4")
186  << ": %%% Nuclear PDG code = " << pdgCode << " (x,y,z,t)=(" << x << "," << y << "," << z
187  << "," << t << ")"
188  << " P=" << momentum.P() << ", E=" << momentum.E();
189  // If the particle table doesn't have a definition yet, ask
190  // the ion table for one. This will create a new ion
191  // definition as needed.
192  if (!particleDefinition) {
193  int const Z = (pdgCode % 10'000'000) / 10'000; // atomic number
194  int const A = (pdgCode % 10'000) / 10; // mass number
195  particleDefinition = fParticleTable->GetIonTable()->GetIon(Z, A, 0.);
196  }
197  }
198 
199  // What if the PDG code is unknown? This has been a known
200  // issue with GENIE.
201  if (particleDefinition == nullptr) {
202  mf::LogDebug("ConvertPrimaryToGeant4") << ": %%% Code not found = " << pdgCode;
203  fUnknownPDG[pdgCode] += 1;
204  continue;
205  }
206 
207  fProcessedPDG[pdgCode] += 1;
208 
209  // Create a Geant4 particle to add to the vertex.
210  auto* g4particle = new G4PrimaryParticle(particleDefinition,
211  momentum.Px() * CLHEP::GeV,
212  momentum.Py() * CLHEP::GeV,
213  momentum.Pz() * CLHEP::GeV);
214 
215  // Add more particle information the Geant4 particle.
216  g4particle->SetCharge(particleDefinition->GetPDGCharge());
217  g4particle->SetPolarization(polarization.x(), polarization.y(), polarization.z());
218 
219  // Add the particle to the vertex.
220  vertex->SetPrimary(g4particle);
221 
222  // Create a PrimaryParticleInformation object, and save the
223  // MCTruth pointer in it. This will allow the
224  // ParticleActionList class to access MCTruth information
225  // during Geant4's tracking.
226 
227  auto* primaryParticleInfo = new g4b::PrimaryParticleInformation;
228  primaryParticleInfo->SetMCTruth(mclist.get(), index, m);
229 
230  // Save the PrimaryParticleInformation in the
231  // G4PrimaryParticle for access during tracking.
232  g4particle->SetUserInformation(primaryParticleInfo);
233  } // -- for each particle in MCTruth
234  ++index;
235  } // -- for each MCTruth entry
236  } // -- for each MCTruth handle
237 } // -- generatePrimaries()
process_name vertex
Definition: cheaterreco.fcl:51
util::quantities::gigaelectronvolt GeV
process_name opflash particleana ie ie ie z
static G4ParticleTable * fParticleTable
Geant4&#39;s table of particle definitions.
process_name opflash particleana ie x
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::vector< art::Handle< std::vector< simb::MCTruth > > > const * fMCLists
MCTruthCollection input lists.
process_name opflash particleana ie ie y
std::map< G4int, G4int > fProcessedPDG
PDG codes processed.
std::map< G4int, G4int > fNon1StatusPDG
PDG codes skipped because not status 1.
std::map< G4int, G4int > fUnknownPDG
map of unknown PDG codes to instances
float A
Definition: dedx.py:137
void larg4::MCTruthEventActionService::setInputCollections ( std::vector< art::Handle< std::vector< simb::MCTruth >>> const &  mclists)
inline

Definition at line 46 of file MCTruthEventAction_service.h.

47  {
48  fMCLists = &mclists;
49  }
std::vector< art::Handle< std::vector< simb::MCTruth > > > const * fMCLists
MCTruthCollection input lists.

Member Data Documentation

std::vector<art::Handle<std::vector<simb::MCTruth> > > const* larg4::MCTruthEventActionService::fMCLists
private

MCTruthCollection input lists.

Definition at line 59 of file MCTruthEventAction_service.h.

std::map<G4int, G4int> larg4::MCTruthEventActionService::fNon1StatusPDG
private

PDG codes skipped because not status 1.

Definition at line 61 of file MCTruthEventAction_service.h.

G4ParticleTable * larg4::MCTruthEventActionService::fParticleTable = nullptr
staticprivate

Geant4's table of particle definitions.

Definition at line 57 of file MCTruthEventAction_service.h.

std::map<G4int, G4int> larg4::MCTruthEventActionService::fProcessedPDG
private

PDG codes processed.

Definition at line 62 of file MCTruthEventAction_service.h.

std::map<G4int, G4int> larg4::MCTruthEventActionService::fUnknownPDG
private

map of unknown PDG codes to instances

Definition at line 60 of file MCTruthEventAction_service.h.


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