12#include "GaudiKernel/IPartPropSvc.h"
13#include "GaudiKernel/PhysicalConstants.h"
29#include "G4PrimaryParticle.hh"
31#include "G4Geantino.hh"
32#include "G4ChargedGeantino.hh"
33#include "G4ParticleTable.hh"
34#include "G4LorentzVector.hh"
35#include "G4TransportationManager.hh"
41#include "CLHEP/Geometry/Point3D.h"
42#include "CLHEP/Geometry/Vector3D.h"
43#include "CLHEP/Units/SystemOfUnits.h"
45#include "HepPDT/ParticleID.hh"
46#include "HepPDT/DecayData.hh"
47#include "HepPDT/ParticleDataTable.hh"
52 : base_class(name, svc)
60 declareProperty(
"UseGeneratedParticleMass",
62 "Use particle mass assigned to GenParticle.");
64 declareProperty(
"GenParticleFilters",
66 "Tools for filtering out GenParticles.");
68 declareProperty(
"ParticlePropertyService",
70 "ParticlePropertyService to retrieve the PDT.");
93 return StatusCode::FAILURE;
102 return StatusCode::SUCCESS;
111 return StatusCode::SUCCESS;
121 for (
auto eventPtr : inputGenEvents ) {
123 if (eventPtr ==
nullptr) {
continue; }
127 " and event_number=" << eventPtr->event_number() );
130 bool legacyOrdering =
true;
137 for (
auto& genPartPtr : passedGenParticles ) {
138 ATH_MSG_VERBOSE(
"Picking up following GenParticle for conversion to ISFParticle: " << genPartPtr);
140 if (!simParticlePtr) {
141 ATH_MSG_ERROR(
"Error while trying to convert input generator particles. Aborting.");
142 return StatusCode::FAILURE;
145 simParticles.push_back(simParticlePtr);
151 ATH_MSG_DEBUG(
"Created initial simulation particle collection with size " << simParticles.size() );
153 return StatusCode::SUCCESS;
163 std::make_move_iterator(std::begin(simParticleList)),
164 std::make_move_iterator(std::end(simParticleList))
167 !shadowGenEvents.
empty()
172 return StatusCode::SUCCESS;
181 std::make_move_iterator(std::begin(simParticleList)),
182 std::make_move_iterator(std::end(simParticleList))
186 return StatusCode::SUCCESS;
190std::vector<HepMC::GenParticlePtr>
192 auto allGenPartBegin = evnt.particles().begin();
193 auto allGenPartEnd = evnt.particles().end();
196 std::vector<HepMC::GenParticlePtr> passedGenParticles{};
197 size_t maxParticles = std::distance(allGenPartBegin, allGenPartEnd);
198 passedGenParticles.reserve(maxParticles);
201 if (legacyOrdering) {
204 for (
auto vtx: evnt.vertices() ) {
205 std::copy_if (vtx->particles_out().begin(),
206 vtx->particles_out().end(),
207 std::back_inserter(passedGenParticles),
208 [](
HepMC::GenParticlePtr p){return p->attribute<HepMC3::IntAttribute>(HepMCStr::ShadowParticleId);});
212 std::copy_if (allGenPartBegin,
214 std::back_inserter(passedGenParticles),
219 if (legacyOrdering) {
222 for (
auto vtx: evnt.vertices() ) {
223 std::copy_if (vtx->particles_out().begin(),
224 vtx->particles_out().end(),
225 std::back_inserter(passedGenParticles),
226 [
this](
HepMC::GenParticlePtr p){return this->passesFilters(std::const_pointer_cast<const HepMC3::GenParticle>(p));});
230 std::copy_if (allGenPartBegin,
232 std::back_inserter(passedGenParticles),
237 passedGenParticles.shrink_to_fit();
239 return passedGenParticles;
246 if (!genPartPtr) {
return nullptr; }
248 auto pVertex = genPartPtr->production_vertex();
250 ATH_MSG_ERROR(
"Unable to convert following generator particle due to missing production vertex for: " << genPartPtr);
253 auto parentEvent = genPartPtr->parent_event();
255 ATH_MSG_ERROR(
"Cannot convert a GenParticle without a parent GenEvent into an ISFParticle!!!");
259 const Amg::Vector3D pos(pVertex->position().x(), pVertex->position().y(), pVertex->position().z());
260 const auto& pMomentum(genPartPtr->momentum());
261 const Amg::Vector3D mom(pMomentum.px(), pMomentum.py(), pMomentum.pz());
263 double e=pMomentum.e();
265 double px=pMomentum.px();
266 double py=pMomentum.py();
267 double pz=pMomentum.pz();
268 double teste=std::sqrt(px*px + py*py + pz*pz + pMass*pMass);
269 if (std::abs(e-teste)>0.01*e) {
270 ATH_MSG_WARNING(
"Difference in energy for: " << genPartPtr<<
" Morg="<<pMomentum.m()<<
" Mmod="<<pMass<<
" Eorg="<<e<<
" Emod="<<teste);
272 if (
MC::isDecayed(genPartPtr) && pVertex && genPartPtr->end_vertex()) {
273 const auto& prodVtx = genPartPtr->production_vertex()->position();
274 const auto& endVtx = genPartPtr->end_vertex()->position();
275 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
277 if (dist3D.mag()>1*Gaudi::Units::mm) {
278 CLHEP::HepLorentzVector mom( pMomentum.x(), pMomentum.y(), pMomentum.z(), pMomentum.t() );
279 double gamma_org=mom.gamma();
281 double gamma_new=mom.gamma();
283 if (std::abs(gamma_new-gamma_org)/(gamma_new+gamma_org)>0.001) {
284 ATH_MSG_WARNING(
"Difference in boost gamma for Quasi stable particle "<<genPartPtr);
285 ATH_MSG_WARNING(
" gamma(m="<<mom.m()<<
")="<<gamma_org<<
" gamma(m="<<pMass<<
")="<<gamma_new);
288 ATH_MSG_VERBOSE(
" gamma(m="<<mom.m()<<
")="<<gamma_org<<
" gamma(m="<<pMass<<
")="<<gamma_new);
294 const int pPdgId = genPartPtr->pdg_id();
296 const double pTime = pVertex->position().t() / Gaudi::Units::c_light;
301 auto tBinding = std::make_unique<ISF::TruthBinding>(genPartPtr);
305 auto sParticle = std::make_unique<ISF::ISFParticle>( std::move(pos),
310 genPartPtr->status(),
317 return sParticle.release();
325 double mass = part->generated_mass();
330 const int absPDG = std::abs(part->pdg_id());
335 mass = pData->mass();
339 ATH_MSG_WARNING(
"Unable to find mass of particle with PDG ID '" << absPDG <<
"' in ParticleDataTable. Will set mass to generated_mass: " << mass);
354 bool passFilter = filter->pass(part);
355 ATH_MSG_VERBOSE(
"GenParticleFilter '" << filter.typeAndName() <<
"' returned: "
356 << (passFilter ?
"true, will keep particle."
357 :
"false, will remove particle."));
358 const auto& momentum = part->momentum();
360 <<momentum.px()<<
", "
361 <<momentum.py()<<
", "
362 <<momentum.pz()<<
"), pdgCode: "
379 bool useHepMC)
const {
383 const G4VSolid *worldSolid = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume()->GetLogicalVolume()->GetSolid();
388 ATH_MSG_WARNING(
"Unable to convert ISFParticle to G4PrimaryParticle!");
392 worldSolid->DumpInfo();
393 G4cout << std::flush;
405 if (!atlasG4EvtUserInfo) {
407 event.SetUserInformation(atlasG4EvtUserInfo);
419 return G4ChargedGeantino::Definition();
422 return G4Geantino::GeantinoDefinition();
425 G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
427 return ptable->FindParticle(pdgcode);
429 ATH_MSG_ERROR(
"getG4ParticleDefinition - Failed to retrieve G4ParticleTable!");
439 const double p2=std::pow(g4particle.GetTotalMomentum(),2);
440 const double m2=std::pow(g4particle.GetMass(),2);
441 const double l2=std::pow(GeneratorDecayLength,2);
442 const double tau2=l2*m2/p2/CLHEP::c_squared;
443 const double tau=std::sqrt(tau2);
444 g4particle.SetProperTime( tau );
454 if (particleDefinition==
nullptr) {
455 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << genpart->pdg_id() <<
456 "\n This usually indicates a problem with the evgen step.\n" <<
457 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
463 auto &genpartMomentum = genpart->momentum();
464 G4double px = genpartMomentum.x();
465 G4double py = genpartMomentum.y();
466 G4double pz = genpartMomentum.z();
468 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
470 if (genpart->end_vertex()) {
474 const auto& prodVtx = genpart->production_vertex()->position();
475 const auto& endVtx = genpart->end_vertex()->position();
481 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
484 if (msgLvl(MSG::VERBOSE)) {
485 double pmag2=g4particle->GetTotalMomentum();
487 double e2=g4particle->GetTotalEnergy();
489 double beta2=pmag2/e2;
490 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_light/Gaudi::Units::c_light;
497 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
503 ATH_MSG_WARNING(
"Number of daughters : " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
506 for (
auto daughter: genpart->end_vertex()->particles_out() ) {
508 ATH_MSG_VERBOSE (
"Attempting to add daughter particle : " << daughter );
511 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
514 if (!daughterG4Particle) {
515 ATH_MSG_ERROR(
"Bailing out of loop over daughters of particle: "<<
516 " due to errors - will not return G4Particle.");
519 g4particle->SetDaughter( daughterG4Particle );
523 if (makeLinkToTruth) {
525 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(genpart);
526 primaryPartInfo->SetRegenerationNr(0);
527 ATH_MSG_VERBOSE(
"Making primary down the line with barcode " << primaryPartInfo->GetParticleUniqueID());
528 g4particle->SetUserInformation(primaryPartInfo.release());
531 return g4particle.release();
540 if (particleDefinition==
nullptr) {
541 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << genpart->pdg_id() <<
542 "\n This usually indicates a problem with the evgen step.\n" <<
543 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
549 auto &genpartMomentum = genpart->momentum();
550 G4double px = genpartMomentum.x();
551 G4double py = genpartMomentum.y();
552 G4double pz = genpartMomentum.z();
554 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
556 if (genpart->end_vertex()) {
560 const auto& prodVtx = genpart->production_vertex()->position();
561 const auto& endVtx = genpart->end_vertex()->position();
567 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
570 if (msgLvl(MSG::VERBOSE)) {
571 double pmag2=g4particle->GetTotalMomentum();
573 double e2=g4particle->GetTotalEnergy();
575 double beta2=pmag2/e2;
576 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_light/Gaudi::Units::c_light;
583 ATH_MSG_VERBOSE(
"Number of daughters : " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
589 ATH_MSG_WARNING(
"Number of daughters: " << genpart->end_vertex()->particles_out().size()<<
" at position "<<genpart->end_vertex() );
592 for (
auto daughter: genpart->end_vertex()->particles_out() ) {
594 ATH_MSG_VERBOSE (
"Attempting to add daughter particle: " << daughter );
597 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
600 if (!daughterG4Particle) {
601 ATH_MSG_ERROR(
"Bailing out of loop over daughters of particle due to errors - will not return G4Particle.");
604 g4particle->SetDaughter( daughterG4Particle );
608 return g4particle.release();
616 && (p1->status() == p2->status())
617 && (p1->pdg_id() == p2->pdg_id())
618 && ((p1->momentum().px()) == (p2->momentum().px()))
619 && ((p1->momentum().py()) == (p2->momentum().py()))
620 && ((p1->momentum().pz()) == (p2->momentum().pz()))
621 && (float(p1->momentum().m()) == float(p2->momentum().m()));
627 if (!shadowGenEvent) {
628 ATH_MSG_FATAL (
"Found status==2 GenParticle with no end vertex and shadow GenEvent is missing - something is wrong here!");
633 for (
auto& shadowParticle : shadowGenEvent->particles()) {
634 if (shadowParticle->id() == shadowId &&
matchedGenParticles(genParticle, shadowParticle) ) {
return shadowParticle; }
636 return std::make_shared<HepMC::GenParticle>();
645 const auto& prodVtx = genpart->production_vertex()->position();
646 const auto& endVtx = genpart->end_vertex()->position();
648 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
651 if (msgLvl(MSG::VERBOSE)) {
652 double pmag2=g4particle->GetTotalMomentum();
654 double e2=g4particle->GetTotalEnergy();
656 double beta2=pmag2/e2;
657 double mass2=g4particle->GetMass();
660 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_squared;
662 const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
663 const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
666 G4LorentzVector dist4D(lv1);
669 double dist4Dgamma=std::numeric_limits<double>::infinity();
670 if (dist4D.t()>0 && dist4D.mag2()>0) {
671 dist4Dgamma=dist4D.gamma();
676 G4LorentzVector fourmom(g4particle->GetMomentum(),g4particle->GetTotalEnergy());
677 double fourmomgamma=std::numeric_limits<double>::infinity();
678 if (fourmom.t()>0 && fourmom.mag2()>0) {
679 fourmomgamma=fourmom.gamma();
684 ATH_MSG_VERBOSE(
"gammaVertex="<<dist4Dgamma<<
" gammamom="<<fourmomgamma<<
" gamma(beta)="<<1/std::sqrt(1-beta2)<<
" lifetime tau(beta)="<<std::sqrt(tau2)<<
" lifetime tau="<<tau);
691 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size() <<
" at position "<< genpart->end_vertex() );
694 ATH_MSG_WARNING(
"Detected primary particle with end vertex. This should only be the case if" );
695 ATH_MSG_WARNING(
"you are running with quasi-stable particle simulation enabled. This is not" );
696 ATH_MSG_WARNING(
"yet validated - you'd better know what you're doing. Will add the primary" );
700 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out().size() );
703 for (
auto daughter: *(genpart->end_vertex())) {
708 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
711 if (!daughterG4Particle) {
712 ATH_MSG_FATAL(
"Bailing out of loop over daughters due to errors.");
714 g4particle->SetDaughter( daughterG4Particle );
724 const auto& prodVtx = genpart->production_vertex()->position();
725 const auto& endVtx = genpart->end_vertex()->position();
727 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
730 if (msgLvl(MSG::VERBOSE)) {
731 double pmag2=g4particle->GetTotalMomentum();
733 double e2=g4particle->GetTotalEnergy();
735 double beta2=pmag2/e2;
736 double mass2=g4particle->GetMass();
739 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_squared;
741 const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
742 const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
745 G4LorentzVector dist4D(lv1);
748 double dist4Dgamma=std::numeric_limits<double>::infinity();
749 if (dist4D.t()>0 && dist4D.mag2()>0) {
750 dist4Dgamma=dist4D.gamma();
755 G4LorentzVector fourmom(g4particle->GetMomentum(),g4particle->GetTotalEnergy());
756 double fourmomgamma=std::numeric_limits<double>::infinity();
757 if (fourmom.t()>0 && fourmom.mag2()>0) {
758 fourmomgamma=fourmom.gamma();
763 ATH_MSG_VERBOSE(
"gammaVertex="<<dist4Dgamma<<
" gammamom="<<fourmomgamma<<
" gamma(beta)="<<1/std::sqrt(1-beta2)<<
" lifetime tau(beta)="<<std::sqrt(tau2)<<
" lifetime tau="<<tau);
770 ATH_MSG_VERBOSE(
"Number of daughters: " << genpart->end_vertex()->particles_out_size() <<
" at position "<< genpart->end_vertex() );
773 ATH_MSG_WARNING(
"Detected primary particle with end vertex. This should only be the case if" );
774 ATH_MSG_WARNING(
"you are running with quasi-stable particle simulation enabled. This is not" );
775 ATH_MSG_WARNING(
"yet validated - you'd better know what you're doing. Will add the primary" );
779 ATH_MSG_WARNING(
"Number of daughters: " << genpart->end_vertex()->particles_out_size() );
782 for (
auto daughter: *(genpart->end_vertex())) {
784 ATH_MSG_VERBOSE (
"Attempting to add daughter particle: " << daughter );
787 ATH_MSG_WARNING (
"Attempting to add daughter particle: " << daughter );
790 if (!daughterG4Particle) {
791 ATH_MSG_FATAL(
"Bailing out of loop over daughters due to errors.");
793 g4particle->SetDaughter( daughterG4Particle );
804 description << G4String(
"getG4PrimaryParticle: ") +
"No ISF::TruthBinding associated with ISParticle (" << isp <<
")";
805 G4Exception(
"iGeant4::TransportTool",
"NoISFTruthBinding", FatalException,
description);
813 if (particleDefinition==
nullptr) {
814 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << isp.
pdgCode() <<
815 "\n This usually indicates a problem with the evgen step.\n" <<
816 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
825 if (useHepMC && currentGenPart) {
826 auto ¤tGenPartMomentum = currentGenPart->momentum();
827 px = currentGenPartMomentum.x();
828 py = currentGenPartMomentum.y();
829 pz = currentGenPartMomentum.z();
833 px = ispMomentum.x();
834 py = ispMomentum.y();
835 pz = ispMomentum.z();
838 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
840 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(primaryGenpart,&isp);
849 primaryPartInfo->SetRegenerationNr(regenerationNr);
851 if ( currentGenPart ) {
852 if (currentGenPart->end_vertex()) {
855 ATH_MSG_ERROR (
"getG4PrimaryParticle(): GenParticle has a valid end GenVertexPtr!" );
857 ATH_MSG_ERROR (
"getG4PrimaryParticle(): currentGenPart->end_vertex(): " << currentGenPart->end_vertex() <<
", barcode: " <<
HepMC::barcode(currentGenPart->end_vertex()) );
858 ATH_MSG_FATAL (
"getG4PrimaryParticle(): Passing GenParticles with a valid end GenVertexPtr as input is no longer supported." );
862 && !currentGenPart->end_vertex()) {
868 ATH_MSG_FATAL (
"Found a GenParticle with no matching GenParticle in the shadowGenEvent - something is wrong here!");
871 if (!shadowPart->end_vertex()) {
872 ATH_MSG_FATAL (
"Found status==2 shadow GenParticle with no end vertex - something is wrong here!");
879 const double pmass = g4particle->GetMass();
880 CLHEP::Hep3Vector gpv = g4particle->GetMomentum();
881 double g4px=g4particle->GetMomentum().x();
882 double g4py=g4particle->GetMomentum().y();
883 double g4pz=g4particle->GetMomentum().z();
891 px=currentGenPart->momentum().px();
892 py=currentGenPart->momentum().py();
893 pz=currentGenPart->momentum().pz();
903 if (std::abs(px-g4px)<CLHEP::keV && std::abs(py-g4py)<CLHEP::keV && std::abs(pz-g4pz)<CLHEP::keV) {
909 const double mag2=px*px + py*py + pz*pz;
910 const double pe = std::sqrt(
mag2 + pmass*pmass);
912 double originalEnergy=currentGenPart->momentum().e();
913 if (originalEnergy>0.01) {
914 if ((originalEnergy-pe)/originalEnergy>0.01) {
915 double genpx=currentGenPart->momentum().px();
916 double genpy=currentGenPart->momentum().py();
917 double genpz=currentGenPart->momentum().pz();
918 double genp=sqrt(genpx*genpx + genpy*genpy + genpz*genpz);
919 ATH_MSG_WARNING(
"Truth change in energy for: " << currentGenPart<<
" Morg="<<currentGenPart->momentum().m()<<
" Mmod="<<pmass<<
" Eorg="<<originalEnergy<<
" Emod="<<pe<<
" porg="<<genp<<
" pmod="<<gpv.mag());
923 auto& currentGenPart_nc = currentGenPart;
928 ATH_MSG_VERBOSE(
" GetParticleUniqueID = " << primaryPartInfo->GetParticleUniqueID());
929 ATH_MSG_VERBOSE(
" GetRegenerationNr = " << primaryPartInfo->GetRegenerationNr());
930 ATH_MSG_VERBOSE(
" GetHepMCParticle = " << primaryPartInfo->GetHepMCParticle());
931 ATH_MSG_VERBOSE(
" GetISFParticle = " << primaryPartInfo->GetISFParticle());
932 g4particle->SetUserInformation(primaryPartInfo.release());
934 return g4particle.release();
953 ATH_MSG_ERROR(
"Failed to create G4PrimaryParticle for ISParticle (" << isp <<
")");
958 G4PrimaryVertex *g4vertex =
new G4PrimaryVertex(isp.
position().x(),
962 g4vertex->SetPrimary( g4particle );
964 if (msgLevel(MSG::VERBOSE)) { g4vertex->Print(); }
965 g4evt.AddPrimaryVertex(g4vertex);
974 const G4ThreeVector g4Pos( pos.x(), pos.y(), pos.z() );
975 EInside insideStatus = worldSolid->Inside( g4Pos );
977 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
const std::string ShadowParticleId
const std::string ShadowParticle
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)