12#include "GaudiKernel/PhysicalConstants.h"
28#include "G4PrimaryParticle.hh"
30#include "G4Geantino.hh"
31#include "G4ChargedGeantino.hh"
32#include "G4ParticleTable.hh"
33#include "G4LorentzVector.hh"
34#include "G4TransportationManager.hh"
40#include "CLHEP/Geometry/Point3D.h"
41#include "CLHEP/Geometry/Vector3D.h"
42#include "CLHEP/Units/SystemOfUnits.h"
48 : base_class(name, svc)
54 declareProperty(
"UseGeneratedParticleMass",
56 "Use particle mass assigned to GenParticle.");
58 declareProperty(
"GenParticleFilters",
60 "Tools for filtering out GenParticles.");
86 return StatusCode::SUCCESS;
95 return StatusCode::SUCCESS;
105 for (
auto eventPtr : inputGenEvents ) {
107 if (eventPtr ==
nullptr) {
continue; }
111 " and event_number=" << eventPtr->event_number() );
114 bool legacyOrdering =
true;
121 for (
auto& genPartPtr : passedGenParticles ) {
122 ATH_MSG_VERBOSE(
"Picking up following GenParticle for conversion to ISFParticle: " << genPartPtr);
124 if (!simParticlePtr) {
125 ATH_MSG_ERROR(
"Error while trying to convert input generator particles. Aborting.");
126 return StatusCode::FAILURE;
129 simParticles.push_back(simParticlePtr);
135 ATH_MSG_DEBUG(
"Created initial simulation particle collection with size " << simParticles.size() );
137 return StatusCode::SUCCESS;
147 std::make_move_iterator(std::begin(simParticleList)),
148 std::make_move_iterator(std::end(simParticleList))
151 !shadowGenEvents.
empty()
156 return StatusCode::SUCCESS;
165 std::make_move_iterator(std::begin(simParticleList)),
166 std::make_move_iterator(std::end(simParticleList))
170 return StatusCode::SUCCESS;
174std::vector<HepMC::GenParticlePtr>
176 auto allGenPartBegin = evnt.particles().begin();
177 auto allGenPartEnd = evnt.particles().end();
180 std::vector<HepMC::GenParticlePtr> passedGenParticles{};
181 size_t maxParticles = std::distance(allGenPartBegin, allGenPartEnd);
182 passedGenParticles.reserve(maxParticles);
185 if (legacyOrdering) {
188 for (
auto vtx: evnt.vertices() ) {
189 std::copy_if (vtx->particles_out().begin(),
190 vtx->particles_out().end(),
191 std::back_inserter(passedGenParticles),
192 [](
HepMC::GenParticlePtr p){return p->attribute<HepMC3::IntAttribute>(HepMCStr::ShadowParticleId);});
196 std::copy_if (allGenPartBegin,
198 std::back_inserter(passedGenParticles),
199 [](
HepMC::GenParticlePtr p){
return p->attribute<HepMC3::IntAttribute>(HepMCStr::ShadowParticleId);});
203 if (legacyOrdering) {
206 for (
auto vtx: evnt.vertices() ) {
207 std::copy_if (vtx->particles_out().begin(),
208 vtx->particles_out().end(),
209 std::back_inserter(passedGenParticles),
210 [
this](
HepMC::GenParticlePtr p){return this->passesFilters(std::const_pointer_cast<const HepMC3::GenParticle>(p));});
214 std::copy_if (allGenPartBegin,
216 std::back_inserter(passedGenParticles),
221 passedGenParticles.shrink_to_fit();
223 return passedGenParticles;
230 if (!genPartPtr) {
return nullptr; }
232 auto pVertex = genPartPtr->production_vertex();
234 ATH_MSG_ERROR(
"Unable to convert following generator particle due to missing production vertex for: " << genPartPtr);
237 auto parentEvent = genPartPtr->parent_event();
239 ATH_MSG_ERROR(
"Cannot convert a GenParticle without a parent GenEvent into an ISFParticle!!!");
243 const Amg::Vector3D pos(pVertex->position().x(), pVertex->position().y(), pVertex->position().z());
244 const auto& pMomentum(genPartPtr->momentum());
245 const Amg::Vector3D mom(pMomentum.px(), pMomentum.py(), pMomentum.pz());
247 double e=pMomentum.e();
249 double px=pMomentum.px();
250 double py=pMomentum.py();
251 double pz=pMomentum.pz();
252 double teste=std::sqrt(px*px + py*py + pz*pz + pMass*pMass);
253 if (std::abs(e-teste)>0.01*e) {
254 ATH_MSG_WARNING(
"Difference in energy for: " << genPartPtr<<
" Morg="<<pMomentum.m()<<
" Mmod="<<pMass<<
" Eorg="<<e<<
" Emod="<<teste);
256 if (
MC::isDecayed(genPartPtr) && pVertex && genPartPtr->end_vertex()) {
257 const auto& prodVtx = genPartPtr->production_vertex()->position();
258 const auto& endVtx = genPartPtr->end_vertex()->position();
259 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
261 if (dist3D.mag()>1*Gaudi::Units::mm) {
262 CLHEP::HepLorentzVector mom( pMomentum.x(), pMomentum.y(), pMomentum.z(), pMomentum.t() );
263 double gamma_org=mom.gamma();
265 double gamma_new=mom.gamma();
267 if (std::abs(gamma_new-gamma_org)/(gamma_new+gamma_org)>0.001) {
268 ATH_MSG_WARNING(
"Difference in boost gamma for Quasi stable particle "<<genPartPtr);
269 ATH_MSG_WARNING(
" gamma(m="<<mom.m()<<
")="<<gamma_org<<
" gamma(m="<<pMass<<
")="<<gamma_new);
272 ATH_MSG_VERBOSE(
" gamma(m="<<mom.m()<<
")="<<gamma_org<<
" gamma(m="<<pMass<<
")="<<gamma_new);
278 const int pPdgId = genPartPtr->pdg_id();
280 const double pTime = pVertex->position().t() / Gaudi::Units::c_light;
285 auto tBinding = std::make_unique<ISF::TruthBinding>(genPartPtr);
289 auto sParticle = std::make_unique<ISF::ISFParticle>( std::move(pos),
294 genPartPtr->status(),
301 return sParticle.release();
309 double mass = part->generated_mass();
314 const int absPDG = std::abs(part->pdg_id());
315 auto pData =
m_gendata->particleMass(absPDG);
317 mass = pData.value();
321 ATH_MSG_WARNING(
"Unable to find mass of particle with PDG ID '" << absPDG <<
"' in ParticleDataTable. Will set mass to generated_mass: " << mass);
336 bool passFilter = filter->pass(part);
337 ATH_MSG_VERBOSE(
"GenParticleFilter '" << filter.typeAndName() <<
"' returned: "
338 << (passFilter ?
"true, will keep particle."
339 :
"false, will remove particle."));
340 const auto& momentum = part->momentum();
342 <<momentum.px()<<
", "
343 <<momentum.py()<<
", "
344 <<momentum.pz()<<
"), pdgCode: "
361 bool useHepMC)
const {
365 const G4VSolid *worldSolid = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume()->GetLogicalVolume()->GetSolid();
370 ATH_MSG_WARNING(
"Unable to convert ISFParticle to G4PrimaryParticle!");
374 worldSolid->DumpInfo();
375 G4cout << std::flush;
387 if (!atlasG4EvtUserInfo) {
389 event.SetUserInformation(atlasG4EvtUserInfo);
401 return G4ChargedGeantino::Definition();
404 return G4Geantino::GeantinoDefinition();
407 G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
409 return ptable->FindParticle(pdgcode);
411 ATH_MSG_ERROR(
"getG4ParticleDefinition - Failed to retrieve G4ParticleTable!");
421 const double p2=std::pow(g4particle.GetTotalMomentum(),2);
422 const double m2=std::pow(g4particle.GetMass(),2);
423 const double l2=std::pow(GeneratorDecayLength,2);
424 const double tau2=l2*m2/p2/CLHEP::c_squared;
425 const double tau=std::sqrt(tau2);
426 g4particle.SetProperTime( tau );
436 if (particleDefinition==
nullptr) {
437 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << genpart->pdg_id() <<
438 "\n This usually indicates a problem with the evgen step.\n" <<
439 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
445 auto &genpartMomentum = genpart->momentum();
446 G4double px = genpartMomentum.x();
447 G4double py = genpartMomentum.y();
448 G4double pz = genpartMomentum.z();
450 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
452 if (genpart->end_vertex()) {
456 const auto& prodVtx = genpart->production_vertex()->position();
457 const auto& endVtx = genpart->end_vertex()->position();
463 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
466 if (msgLvl(MSG::VERBOSE)) {
467 double pmag2=g4particle->GetTotalMomentum();
469 double e2=g4particle->GetTotalEnergy();
471 double beta2=pmag2/e2;
472 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_light/Gaudi::Units::c_light;
479 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
485 ATH_MSG_WARNING(
"Number of daughters : " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
488 for (
auto daughter: genpart->end_vertex()->particles_out() ) {
490 ATH_MSG_VERBOSE (
"Attempting to add daughter particle : " << daughter );
493 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
496 if (!daughterG4Particle) {
497 ATH_MSG_ERROR(
"Bailing out of loop over daughters of particle: "<<
498 " due to errors - will not return G4Particle.");
501 g4particle->SetDaughter( daughterG4Particle );
505 if (makeLinkToTruth) {
507 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(genpart);
508 primaryPartInfo->SetRegenerationNr(0);
509 ATH_MSG_VERBOSE(
"Making primary down the line with barcode " << primaryPartInfo->GetParticleUniqueID());
510 g4particle->SetUserInformation(primaryPartInfo.release());
513 return g4particle.release();
522 if (particleDefinition==
nullptr) {
523 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << genpart->pdg_id() <<
524 "\n This usually indicates a problem with the evgen step.\n" <<
525 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
531 auto &genpartMomentum = genpart->momentum();
532 G4double px = genpartMomentum.x();
533 G4double py = genpartMomentum.y();
534 G4double pz = genpartMomentum.z();
536 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
538 if (genpart->end_vertex()) {
542 const auto& prodVtx = genpart->production_vertex()->position();
543 const auto& endVtx = genpart->end_vertex()->position();
549 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
552 if (msgLvl(MSG::VERBOSE)) {
553 double pmag2=g4particle->GetTotalMomentum();
555 double e2=g4particle->GetTotalEnergy();
557 double beta2=pmag2/e2;
558 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_light/Gaudi::Units::c_light;
565 ATH_MSG_VERBOSE(
"Number of daughters : " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
571 ATH_MSG_WARNING(
"Number of daughters: " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
574 for (
auto daughter: genpart->end_vertex()->particles_out() ) {
576 ATH_MSG_VERBOSE (
"Attempting to add daughter particle: " << daughter );
579 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
582 if (!daughterG4Particle) {
583 ATH_MSG_ERROR(
"Bailing out of loop over daughters of particle due to errors - will not return G4Particle.");
586 g4particle->SetDaughter( daughterG4Particle );
590 return g4particle.release();
598 && (p1->status() == p2->status())
599 && (p1->pdg_id() == p2->pdg_id())
600 && ((p1->momentum().px()) == (p2->momentum().px()))
601 && ((p1->momentum().py()) == (p2->momentum().py()))
602 && ((p1->momentum().pz()) == (p2->momentum().pz()))
603 && (float(p1->momentum().m()) == float(p2->momentum().m()));
609 if (!shadowGenEvent) {
610 ATH_MSG_FATAL (
"Found status==2 GenParticle with no end vertex and shadow GenEvent is missing - something is wrong here!");
614 const int shadowId = genParticle->attribute<HepMC3::IntAttribute>(HepMCStr::ShadowParticleId)->value();
615 for (
auto& shadowParticle : shadowGenEvent->particles()) {
616 if (shadowParticle->id() == shadowId &&
matchedGenParticles(genParticle, shadowParticle) ) {
return shadowParticle; }
618 return std::make_shared<HepMC::GenParticle>();
627 const auto& prodVtx = genpart->production_vertex()->position();
628 const auto& endVtx = genpart->end_vertex()->position();
630 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
633 if (msgLvl(MSG::VERBOSE)) {
634 double pmag2=g4particle->GetTotalMomentum();
636 double e2=g4particle->GetTotalEnergy();
638 double beta2=pmag2/e2;
639 double mass2=g4particle->GetMass();
642 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_squared;
644 const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
645 const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
648 G4LorentzVector dist4D(lv1);
651 double dist4Dgamma=std::numeric_limits<double>::infinity();
652 if (dist4D.t()>0 && dist4D.mag2()>0) {
653 dist4Dgamma=dist4D.gamma();
658 G4LorentzVector fourmom(g4particle->GetMomentum(),g4particle->GetTotalEnergy());
659 double fourmomgamma=std::numeric_limits<double>::infinity();
660 if (fourmom.t()>0 && fourmom.mag2()>0) {
661 fourmomgamma=fourmom.gamma();
666 ATH_MSG_VERBOSE(
"gammaVertex="<<dist4Dgamma<<
" gammamom="<<fourmomgamma<<
" gamma(beta)="<<1/std::sqrt(1-beta2)<<
" lifetime tau(beta)="<<std::sqrt(tau2)<<
" lifetime tau="<<tau);
673 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size() <<
" at position "<< genpart->end_vertex() );
676 ATH_MSG_WARNING(
"Detected primary particle with end vertex. This should only be the case if" );
677 ATH_MSG_WARNING(
"you are running with quasi-stable particle simulation enabled. This is not" );
678 ATH_MSG_WARNING(
"yet validated - you'd better know what you're doing. Will add the primary" );
682 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size() );
685 for (
auto daughter: *(genpart->end_vertex())) {
690 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
693 if (!daughterG4Particle) {
694 ATH_MSG_FATAL(
"Bailing out of loop over daughters due to errors.");
696 g4particle->SetDaughter( daughterG4Particle );
706 const auto& prodVtx = genpart->production_vertex()->position();
707 const auto& endVtx = genpart->end_vertex()->position();
709 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
712 if (msgLvl(MSG::VERBOSE)) {
713 double pmag2=g4particle->GetTotalMomentum();
715 double e2=g4particle->GetTotalEnergy();
717 double beta2=pmag2/e2;
718 double mass2=g4particle->GetMass();
721 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_squared;
723 const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
724 const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
727 G4LorentzVector dist4D(lv1);
730 double dist4Dgamma=std::numeric_limits<double>::infinity();
731 if (dist4D.t()>0 && dist4D.mag2()>0) {
732 dist4Dgamma=dist4D.gamma();
737 G4LorentzVector fourmom(g4particle->GetMomentum(),g4particle->GetTotalEnergy());
738 double fourmomgamma=std::numeric_limits<double>::infinity();
739 if (fourmom.t()>0 && fourmom.mag2()>0) {
740 fourmomgamma=fourmom.gamma();
745 ATH_MSG_VERBOSE(
"gammaVertex="<<dist4Dgamma<<
" gammamom="<<fourmomgamma<<
" gamma(beta)="<<1/std::sqrt(1-beta2)<<
" lifetime tau(beta)="<<std::sqrt(tau2)<<
" lifetime tau="<<tau);
752 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out_size() <<
" at position "<< genpart->end_vertex() );
755 ATH_MSG_WARNING(
"Detected primary particle with end vertex. This should only be the case if" );
756 ATH_MSG_WARNING(
"you are running with quasi-stable particle simulation enabled. This is not" );
757 ATH_MSG_WARNING(
"yet validated - you'd better know what you're doing. Will add the primary" );
761 ATH_MSG_WARNING(
"Number of daughters: " << genpart->end_vertex()->particles_out_size() );
764 for (
auto daughter: *(genpart->end_vertex())) {
766 ATH_MSG_VERBOSE (
"Attempting to add daughter particle: " << daughter );
769 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
772 if (!daughterG4Particle) {
773 ATH_MSG_FATAL(
"Bailing out of loop over daughters due to errors.");
775 g4particle->SetDaughter( daughterG4Particle );
786 description << G4String(
"getG4PrimaryParticle: ") +
"No ISF::TruthBinding associated with ISParticle (" << isp <<
")";
787 G4Exception(
"iGeant4::TransportTool",
"NoISFTruthBinding", FatalException,
description);
795 if (particleDefinition==
nullptr) {
796 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << isp.
pdgCode() <<
797 "\n This usually indicates a problem with the evgen step.\n" <<
798 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
807 if (useHepMC && currentGenPart) {
808 auto ¤tGenPartMomentum = currentGenPart->momentum();
809 px = currentGenPartMomentum.x();
810 py = currentGenPartMomentum.y();
811 pz = currentGenPartMomentum.z();
815 px = ispMomentum.x();
816 py = ispMomentum.y();
817 pz = ispMomentum.z();
820 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
822 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(primaryGenpart,&isp);
831 primaryPartInfo->SetRegenerationNr(regenerationNr);
833 if ( currentGenPart ) {
834 if (currentGenPart->end_vertex()) {
837 ATH_MSG_ERROR (
"getG4PrimaryParticle(): GenParticle has a valid end GenVertexPtr!" );
839 ATH_MSG_ERROR (
"getG4PrimaryParticle(): currentGenPart->end_vertex(): " << currentGenPart->end_vertex() <<
", barcode: " <<
HepMC::barcode(currentGenPart->end_vertex()) );
840 ATH_MSG_FATAL (
"getG4PrimaryParticle(): Passing GenParticles with a valid end GenVertexPtr as input is no longer supported." );
844 && !currentGenPart->end_vertex()) {
850 ATH_MSG_FATAL (
"Found a GenParticle with no matching GenParticle in the shadowGenEvent - something is wrong here!");
853 if (!shadowPart->end_vertex()) {
854 ATH_MSG_FATAL (
"Found status==2 shadow GenParticle with no end vertex - something is wrong here!");
861 const double pmass = g4particle->GetMass();
862 CLHEP::Hep3Vector gpv = g4particle->GetMomentum();
863 double g4px=g4particle->GetMomentum().x();
864 double g4py=g4particle->GetMomentum().y();
865 double g4pz=g4particle->GetMomentum().z();
873 px=currentGenPart->momentum().px();
874 py=currentGenPart->momentum().py();
875 pz=currentGenPart->momentum().pz();
885 if (std::abs(px-g4px)<CLHEP::keV && std::abs(py-g4py)<CLHEP::keV && std::abs(pz-g4pz)<CLHEP::keV) {
891 const double mag2=px*px + py*py + pz*pz;
892 const double pe = std::sqrt(
mag2 + pmass*pmass);
894 double originalEnergy=currentGenPart->momentum().e();
895 if (originalEnergy>0.01) {
896 if ((originalEnergy-pe)/originalEnergy>0.01) {
897 double genpx=currentGenPart->momentum().px();
898 double genpy=currentGenPart->momentum().py();
899 double genpz=currentGenPart->momentum().pz();
900 double genp=sqrt(genpx*genpx + genpy*genpy + genpz*genpz);
901 ATH_MSG_WARNING(
"Truth change in energy for: " << currentGenPart<<
" Morg="<<currentGenPart->momentum().m()<<
" Mmod="<<pmass<<
" Eorg="<<originalEnergy<<
" Emod="<<pe<<
" porg="<<genp<<
" pmod="<<gpv.mag());
905 auto& currentGenPart_nc = currentGenPart;
910 ATH_MSG_VERBOSE(
" GetParticleUniqueID = " << primaryPartInfo->GetParticleUniqueID());
911 ATH_MSG_VERBOSE(
" GetRegenerationNr = " << primaryPartInfo->GetRegenerationNr());
912 ATH_MSG_VERBOSE(
" GetHepMCParticle = " << primaryPartInfo->GetHepMCParticle());
913 ATH_MSG_VERBOSE(
" GetISFParticle = " << primaryPartInfo->GetISFParticle());
914 g4particle->SetUserInformation(primaryPartInfo.release());
916 return g4particle.release();
935 ATH_MSG_ERROR(
"Failed to create G4PrimaryParticle for ISParticle (" << isp <<
")");
940 G4PrimaryVertex *g4vertex =
new G4PrimaryVertex(isp.
position().x(),
944 g4vertex->SetPrimary( g4particle );
946 if (msgLevel(MSG::VERBOSE)) { g4vertex->Print(); }
947 g4evt.AddPrimaryVertex(g4vertex);
956 const G4ThreeVector g4Pos( pos.x(), pos.y(), pos.z() );
957 EInside insideStatus = worldSolid->Inside( g4Pos );
959 bool insideWorld = insideStatus != kOutside;
Scalar mag2() const
mag2 method - forward to squaredNorm()
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
ATLAS-specific HepMC functions.
This class is attached to G4Event objects as UserInformation.
void SetHepMCEvent(HepMC::GenEvent *)
set m_theEvent, the pointer to the HepMC::GenEvent used to create the G4Event.
void SetLastProcessedStep(int stepNumber)
record value of the G4Track::GetCurrentStepNumber() for the current G4Step.
void SetLastProcessedTrackID(int trackID)
record the value of G4Track::GetTrackID() for the current G4Step.
const T * back() const
Access the last element in the collection as an rvalue.
bool empty() const noexcept
Returns true if the collection is empty.
Attribute for linking GenParticles between GenEvents.
The generic ISF particle definition,.
const TruthBinding * getTruthBinding() const
pointer to the simulation truth - optional, can be 0
const Amg::Vector3D & momentum() const
The current momentum vector of the ISFParticle.
double timeStamp() const
Timestamp of the ISFParticle.
const Amg::Vector3D & position() const
The current position of the ISFParticle.
int pdgCode() const
PDG value.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
std::string description
glabal timer - how long have I taken so far?
Eigen::Matrix< double, 3, 1 > Vector3D
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (only to be used in...
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation based on the status...
int signal_process_id(const GenEvent &evt)
HepMC3::FourVector FourVector
HepMC3::GenParticlePtr GenParticlePtr
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
HepMC3::GenEvent GenEvent
std::pair< AtlasDetDescr::AtlasRegion, ISF::SimSvcID > DetRegionSvcIDPair
the datatype to be used to store each individual particle hop
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.
bool isDecayed(const T &p)
Identify if the particle decayed.
double charge(const T &p)