21#include "BDSBunchEventGenerator.hh"
23#include "BDSEventGeneratorFileType.hh"
24#include "BDSException.hh"
25#include "BDSHepMC3Reader.hh"
26#include "BDSParticleCoords.hh"
27#include "BDSParticleCoordsFull.hh"
28#include "BDSParticleCoordsFullGlobal.hh"
29#include "BDSPhysicalConstants.hh"
30#include "BDSPrimaryVertexInformation.hh"
31#include "BDSPrimaryVertexInformationV.hh"
32#include "BDSUtilities.hh"
35#include "G4LorentzVector.hh"
36#include "G4PrimaryParticle.hh"
37#include "G4PrimaryVertex.hh"
38#include "G4RunManager.hh"
39#include "G4TransportationManager.hh"
42#include "HepMC3/Attribute.h"
43#include "HepMC3/GenParticle.h"
44#include "HepMC3/GenVertex.h"
45#include "HepMC3/Reader.h"
46#include "HepMC3/ReaderAscii.h"
47#include "HepMC3/ReaderAsciiHepMC2.h"
48#include "HepMC3/ReaderHEPEVT.h"
49#include "HepMC3/ReaderLHEF.h"
50#ifdef USE_HEPMC3_ROOTIO
51#include "HepMC3/ReaderRoot.h"
52#include "HepMC3/ReaderRootTree.h"
55#include "CLHEP/Units/SystemOfUnits.h"
63 const G4String& fileNameIn,
65 G4bool removeUnstableWithoutDecayIn,
66 G4bool warnAboutSkippedParticlesIn):
71 removeUnstableWithoutDecay(removeUnstableWithoutDecayIn),
72 warnAboutSkippedParticles(warnAboutSkippedParticlesIn),
77 G4cout << __METHOD_NAME__ <<
"event generator file format to be " << fileType.ToString() << G4endl;
82BDSHepMC3Reader::~BDSHepMC3Reader()
88void BDSHepMC3Reader::GeneratePrimaryVertex(G4Event* anEvent)
91 {
throw BDSException(__METHOD_NAME__,
"no file reader available");}
99 G4cout <<
"BDSHepMC3Reader::RecreateAdvanceToEvent> Advancing file to event: " << eventOffset << G4endl;
100 for (G4int i = 0; i < eventOffset; i++)
106 G4cout << __METHOD_NAME__ <<
"Opening file: " << fileName << G4endl;
109 case BDSEventGeneratorFileType::hepmc2:
110 {reader =
new HepMC3::ReaderAsciiHepMC2(fileName);
break;}
111 case BDSEventGeneratorFileType::hepmc3:
112 {reader =
new HepMC3::ReaderAscii(fileName);
break;}
113 case BDSEventGeneratorFileType::hpe:
114 {reader =
new HepMC3::ReaderHEPEVT(fileName);
break;}
115#ifdef USE_HEPMC3_ROOTIO
116 case BDSEventGeneratorFileType::root:
117 {reader =
new HepMC3::ReaderRoot(fileName);
break;}
118 case BDSEventGeneratorFileType::treeroot:
119 {reader =
new HepMC3::ReaderRootTree(fileName);
break;}
121 case BDSEventGeneratorFileType::root:
122 case BDSEventGeneratorFileType::treeroot:
124 throw BDSException(__METHOD_NAME__,
"HEPMC3 installation not compiled with ROOT support so can't load root file.");
128 case BDSEventGeneratorFileType::lhef:
129 {reader =
new HepMC3::ReaderLHEF(fileName);
break;}
145 hepmcEvent =
new HepMC3::GenEvent();
147 bool readEventOK = reader->read_event(*hepmcEvent);
149 {
throw BDSException(__METHOD_NAME__,
"problem with event generator file \"" + fileName +
"\"");}
150 if (reader->failed())
152 G4cout << __METHOD_NAME__ <<
"End of file reached. Return to beginning of file for next event." << G4endl;
156 hepmcEvent =
new HepMC3::GenEvent();
157 readEventOK = reader->read_event(*hepmcEvent);
159 {
throw BDSException(__METHOD_NAME__,
"cannot read file \"" + fileName +
"\".");}
169 G4PrimaryVertex* g4vtx =
new G4PrimaryVertex(centralCoordsGlobal.global.x,
170 centralCoordsGlobal.global.y,
171 centralCoordsGlobal.global.z,
172 centralCoordsGlobal.global.T);
174 double overallWeight = 1.0;
175 if (!(hepmcevt->weights().empty()))
176 {overallWeight = hepmcevt->weight();}
177 std::vector<BDSPrimaryVertexInformation> vertexInfos;
178 G4int nParticlesSkipped = 0;
179 for (
const auto& particlePtr : hepmcevt->particles())
181 const HepMC3::GenParticle* particle = particlePtr.get();
182 if (!particle->children().empty())
185 int pdgcode = particle->pdg_id();
186 const HepMC3::FourVector& fv = particle->momentum();
187 G4LorentzVector p(fv.px(), fv.py(), fv.pz(), fv.e());
188 G4double px = p.x() * CLHEP::GeV;
189 G4double py = p.y() * CLHEP::GeV;
190 G4double pz = p.z() * CLHEP::GeV;
191 G4ThreeVector originalUnitMomentum(px,py,pz);
192 originalUnitMomentum = originalUnitMomentum.unit();
193 G4double rp = std::hypot(originalUnitMomentum.x(), originalUnitMomentum.y());
196 G4ThreeVector unitMomentum = originalUnitMomentum;
197 unitMomentum.transform(referenceBeamMomentumOffset);
200 G4PrimaryParticle* g4prim =
new G4PrimaryParticle(pdgcode, px, py, pz);
205 const G4ParticleDefinition* pd = g4prim->GetParticleDefinition();
206 G4bool deleteIt = !pd;
207 if (pd && removeUnstableWithoutDecay)
208 {deleteIt = !(pd->GetPDGStable()) && !pd->GetDecayTable();}
213 G4cout << __METHOD_NAME__ <<
"skipping particle with PDG ID: " << pdgcode << G4endl;
228 g4prim->GetTotalEnergy(),
231 if (!bunch->
AcceptParticle(local, rp, g4prim->GetKineticEnergy(), pdgcode))
240 if (!VertexInsideWorld(fullCoords.global.Position()))
248 G4double charge = g4prim->GetCharge();
249 G4double momentum = g4prim->GetTotalMomentum();
253 brho *= CLHEP::tesla*CLHEP::m;
256 g4prim->GetTotalMomentum(),
261 vertexInfos.emplace_back(vertexInfo);
264 g4prim->SetMomentumDirection(G4ThreeVector(fullCoords.global.xp,
265 fullCoords.global.yp,
266 fullCoords.global.zp));
267 g4vtx->SetPrimary(g4prim);
270 if (nParticlesSkipped > 0 && warnAboutSkippedParticles)
271 {G4cout << __METHOD_NAME__ << nParticlesSkipped <<
" particles skipped" << G4endl;}
274 g4event->AddPrimaryVertex(g4vtx);
277G4bool BDSHepMC3Reader::VertexInsideWorld(
const G4ThreeVector& pos)
const
281 G4Navigator* navigator = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
282 G4VPhysicalVolume* world = navigator->GetWorldVolume();
283 worldSolid = world->GetLogicalVolume()->GetSolid();
285 EInside qinside = worldSolid->Inside(pos);
286 return qinside == kInside;
291void _SymbolToPreventWarningHEPMC3Reader(){;}
A wrapper of BDSBunch to include a filter for the events loaded by an event generator.
G4RotationMatrix ReferenceBeamMomentumOffset() const
Get a rotation matrix according to Xp0 and Yp0.
G4bool AcceptParticle(const BDSParticleCoordsFull &coords, G4double rpOriginal, G4double kineticEnergy, G4int pdgID)
BDSParticleCoordsFullGlobal ApplyTransform(const BDSParticleCoordsFull &localIn) const
virtual BDSParticleCoordsFull GetNextParticleLocal()
General exception with possible name of object and message.
BDSHepMC3Reader()=delete
Do not require default constructor.
virtual void RecreateAdvanceToEvent(G4int eventOffset)
Advance to the correct event number in the file for recreation.
void OpenFile()
Construct the member "reader" and open the file for reading.
void ReadSingleEvent()
Clear the hepmcEvent object, reallocate and read a single event and fill that member.
void HepMC2G4(const HepMC3::GenEvent *hepmcevt, G4Event *g4event)
Conversion from HepMC::GenEvent to G4Event.
A set of particle coordinates in both local and global.
A set of particle coordinates including energy and weight.
G4double s
TODO - remove this. Unused. S (global) is calculated from S0 + z.
type underlying() const
return underlying value (can be used in switch statement)
std::pair< G4String, G4String > SplitOnColon(const G4String &formatAndPath)
static const G4double cOverGeV
speed of light / 1 GeV, used for scaling in brho calculation
BDSEventGeneratorFileType DetermineEventGeneratorFileType(G4String distrType)
Function that gives corresponding enum value for string (case-insensitive).
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())