ATLAS Offline Software
Loading...
Searching...
No Matches
ISF::InputConverter Class Referencefinal

Convert simulation input collections to ISFParticles for subsequent ISF simulation. More...

#include <InputConverter.h>

Inheritance diagram for ISF::InputConverter:
Collaboration diagram for ISF::InputConverter:

Public Member Functions

 InputConverter (const std::string &name, ISvcLocator *svc)
 Constructor.
virtual ~InputConverter ()
 Destructor.
virtual StatusCode initialize () override final
 Athena algtool Hooks.
virtual StatusCode finalize () override final
 Athena algtool Hook.
virtual StatusCode convert (McEventCollection &inputGenEvents, ISF::ISFParticleContainer &simParticles) const override final
 Convert selected particles from the given McEventCollection into ISFParticles and push them into the given ISFParticleContainer.
virtual StatusCode convertHepMCToG4Event (McEventCollection &inputGenEvents, G4Event &outputG4Event, McEventCollection &shadowGenEvents) const override final
virtual StatusCode convertHepMCToG4EventLegacy (McEventCollection &inputGenEvents, G4Event &outputG4Event) const override final
void ISF_to_G4Event (G4Event &event, const std::vector< ISF::ISFParticle * > &isp, HepMC::GenEvent *genEvent, HepMC::GenEvent *shadowGenEvent=nullptr, bool useHepMC=false) const override final
 Converts vector of ISF::ISFParticles to G4Event.

Private Member Functions

const G4ParticleDefinition * getG4ParticleDefinition (int pdgcode) const
G4PrimaryParticle * getDaughterG4PrimaryParticle (HepMC::GenParticle &gp, bool makeLinkToTruth=true) const
G4PrimaryParticle * getG4PrimaryParticle (ISF::ISFParticle &isp, bool useHepMC, HepMC::GenEvent *shadowGenEvent) const
void addG4PrimaryVertex (G4Event &g4evt, ISF::ISFParticle &isp, bool useHepMC, HepMC::GenEvent *shadowGenEvent) const
void processPredefinedDecays (const HepMC::GenParticlePtr &genpart, ISF::ISFParticle &isp, G4PrimaryParticle *g4particle, bool makeLinkToTruth=true) const
bool matchedGenParticles (const HepMC::ConstGenParticlePtr &p1, const HepMC::ConstGenParticlePtr &p2) const
HepMC::GenParticlePtr findShadowParticle (const HepMC::ConstGenParticlePtr &genParticle, HepMC::GenEvent *shadowGenEvent) const
bool isInsideG4WorldVolume (const ISF::ISFParticle &isp, const G4VSolid *worldSolid) const
 Tests whether the given ISFParticle is within the Geant4 world volume.
double getParticleMass (const HepMC::GenParticle &p) const
 get right GenParticle mass
std::vector< HepMC::GenParticlePtrgetSelectedParticles (HepMC::GenEvent &evnt, bool legacyOrdering=false) const
 get all generator particles which pass filters
bool passesFilters (const HepMC::GenParticle &p) const
 check if the given particle passes all filters
ISF::ISFParticleconvertParticle (const HepMC::GenParticlePtr &genPartPtr) const
 convert GenParticle to ISFParticle

Private Attributes

ServiceHandle< IPartPropSvc > m_particlePropSvc
 ParticlePropertyService and ParticleDataTable.
const HepPDT::ParticleDataTable * m_particleDataTable
 PDT used to look up particle masses.
bool m_useGeneratedParticleMass
 use GenParticle::generated_mass() in simulation
ToolHandleArray< IGenParticleFilterm_genParticleFilters
 HepMC::GenParticle filters.
bool m_quasiStableParticlesIncluded
BooleanProperty m_useShadowEvent {this, "UseShadowEvent", false, "New approach to selecting particles for simulation" }

Detailed Description

Convert simulation input collections to ISFParticles for subsequent ISF simulation.

Author
Elmar.Ritsch -at- cern.ch

Definition at line 48 of file InputConverter.h.

Constructor & Destructor Documentation

◆ InputConverter()

ISF::InputConverter::InputConverter ( const std::string & name,
ISvcLocator * svc )

Constructor.

Definition at line 51 of file InputConverter.cxx.

52 : base_class(name, svc)
53 , m_particlePropSvc("PartPropSvc",name)
54 , m_particleDataTable(nullptr)
58{
59 // particle mass from particle data table?
60 declareProperty("UseGeneratedParticleMass",
62 "Use particle mass assigned to GenParticle.");
63 // particle filters
64 declareProperty("GenParticleFilters",
66 "Tools for filtering out GenParticles.");
67 // the particle property service
68 declareProperty("ParticlePropertyService",
70 "ParticlePropertyService to retrieve the PDT.");
71 declareProperty("QuasiStableParticlesIncluded", m_quasiStableParticlesIncluded);
72}
ServiceHandle< IPartPropSvc > m_particlePropSvc
ParticlePropertyService and ParticleDataTable.
ToolHandleArray< IGenParticleFilter > m_genParticleFilters
HepMC::GenParticle filters.
const HepPDT::ParticleDataTable * m_particleDataTable
PDT used to look up particle masses.
bool m_useGeneratedParticleMass
use GenParticle::generated_mass() in simulation

◆ ~InputConverter()

ISF::InputConverter::~InputConverter ( )
virtual

Destructor.

Definition at line 76 of file InputConverter.cxx.

77{
78}

Member Function Documentation

◆ addG4PrimaryVertex()

void ISF::InputConverter::addG4PrimaryVertex ( G4Event & g4evt,
ISF::ISFParticle & isp,
bool useHepMC,
HepMC::GenEvent * shadowGenEvent ) const
private

Definition at line 1145 of file InputConverter.cxx.

1147 {
1148 /*
1149 see conversion from PrimaryParticleInformation to TrackInformation in
1150 http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.cxx#0044
1151
1152 need to check with
1153 http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/Simulation/G4Atlas/G4AtlasAlg/src/TruthHepMCEventConverter.cxx#0151
1154
1155 that we don't miss something
1156 */
1157
1158 G4PrimaryParticle *g4particle = this->getG4PrimaryParticle( isp, useHepMC, shadowGenEvent );
1159 if (!g4particle) {
1160 ATH_MSG_ERROR("Failed to create G4PrimaryParticle for ISParticle (" << isp <<")");
1161 return;
1162 }// Already printed a warning
1163
1164 // create a new vertex
1165 G4PrimaryVertex *g4vertex = new G4PrimaryVertex(isp.position().x(),
1166 isp.position().y(),
1167 isp.position().z(),
1168 isp.timeStamp());
1169 g4vertex->SetPrimary( g4particle );
1170 ATH_MSG_VERBOSE("Print G4PrimaryVertex: ");
1171 if (msgLevel(MSG::VERBOSE)) { g4vertex->Print(); }
1172 g4evt.AddPrimaryVertex(g4vertex);
1173 return;
1174}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
double timeStamp() const
Timestamp of the ISFParticle.
const Amg::Vector3D & position() const
The current position of the ISFParticle.
G4PrimaryParticle * getG4PrimaryParticle(ISF::ISFParticle &isp, bool useHepMC, HepMC::GenEvent *shadowGenEvent) const

◆ convert()

StatusCode ISF::InputConverter::convert ( McEventCollection & inputGenEvents,
ISF::ISFParticleContainer & simParticles ) const
finaloverridevirtual

Convert selected particles from the given McEventCollection into ISFParticles and push them into the given ISFParticleContainer.

Definition at line 118 of file InputConverter.cxx.

120{
121 for ( auto eventPtr : inputGenEvents ) {
122 // skip empty events
123 if (eventPtr == nullptr) { continue; }
124
125 ATH_MSG_DEBUG("Starting conversion of GenEvent with"
126 " signal_process_id=" << HepMC::signal_process_id(eventPtr) <<
127 " and event_number=" << eventPtr->event_number() );
128
129 // new collection containing all gen particles that passed filters
130 bool legacyOrdering = true; // FIXME: this is only to keep the same order of particles
131 // as the prior 'StackFiller' implementation
132 // TODO: remove this functionality from the
133 // getSelectedParticles function once
134 // happy with the results
135 const auto passedGenParticles = getSelectedParticles(*eventPtr, legacyOrdering);
136
137 for ( auto& genPartPtr : passedGenParticles ) {
138 ATH_MSG_VERBOSE("Picking up following GenParticle for conversion to ISFParticle: " << genPartPtr);
139 auto simParticlePtr = convertParticle(genPartPtr);
140 if (!simParticlePtr) {
141 ATH_MSG_ERROR("Error while trying to convert input generator particles. Aborting.");
142 return StatusCode::FAILURE;
143 }
144 // add to collection that will be returned
145 simParticles.push_back(simParticlePtr);
146
147 } // loop over passed gen particles
148
149 } // loop over gen events
150
151 ATH_MSG_DEBUG( "Created initial simulation particle collection with size " << simParticles.size() );
152
153 return StatusCode::SUCCESS;
154}
#define ATH_MSG_DEBUG(x)
std::vector< HepMC::GenParticlePtr > getSelectedParticles(HepMC::GenEvent &evnt, bool legacyOrdering=false) const
get all generator particles which pass filters
ISF::ISFParticle * convertParticle(const HepMC::GenParticlePtr &genPartPtr) const
convert GenParticle to ISFParticle
int signal_process_id(const GenEvent &e)
Definition GenEvent.h:637

◆ convertHepMCToG4Event()

StatusCode ISF::InputConverter::convertHepMCToG4Event ( McEventCollection & inputGenEvents,
G4Event & outputG4Event,
McEventCollection & shadowGenEvents ) const
finaloverridevirtual

Definition at line 156 of file InputConverter.cxx.

158 {
159 ISF::ISFParticleContainer simParticleList{}; // particles for ISF simulation
160 ATH_CHECK(this->convert(inputGenEvents, simParticleList));
161 //Convert from ISFParticleContainer to ConstISFParticleVector
162 ISF::ISFParticleVector simParticleVector{
163 std::make_move_iterator(std::begin(simParticleList)),
164 std::make_move_iterator(std::end(simParticleList))
165 };
166 HepMC::GenEvent* shadowGenEvent =
167 !shadowGenEvents.empty()
168 ? static_cast<HepMC::GenEvent*>(shadowGenEvents.back())
169 : nullptr;
170 this->ISF_to_G4Event(outputG4Event, simParticleVector, inputGenEvents.back(),
171 shadowGenEvent);
172 return StatusCode::SUCCESS;
173}
#define ATH_CHECK
Evaluate an expression and check for errors.
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.
void ISF_to_G4Event(G4Event &event, const std::vector< ISF::ISFParticle * > &isp, HepMC::GenEvent *genEvent, HepMC::GenEvent *shadowGenEvent=nullptr, bool useHepMC=false) const override final
Converts vector of ISF::ISFParticles to G4Event.
virtual StatusCode convert(McEventCollection &inputGenEvents, ISF::ISFParticleContainer &simParticles) const override final
Convert selected particles from the given McEventCollection into ISFParticles and push them into the ...
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.

◆ convertHepMCToG4EventLegacy()

StatusCode ISF::InputConverter::convertHepMCToG4EventLegacy ( McEventCollection & inputGenEvents,
G4Event & outputG4Event ) const
finaloverridevirtual

Definition at line 175 of file InputConverter.cxx.

176 {
177 ISF::ISFParticleContainer simParticleList{}; // particles for ISF simulation
178 ATH_CHECK(this->convert(inputGenEvents, simParticleList));
179 //Convert from ISFParticleContainer to ConstISFParticleVector
180 ISF::ISFParticleVector simParticleVector{
181 std::make_move_iterator(std::begin(simParticleList)),
182 std::make_move_iterator(std::end(simParticleList))
183 };
184 this->ISF_to_G4Event(outputG4Event, simParticleVector, inputGenEvents.back(),
185 nullptr);
186 return StatusCode::SUCCESS;
187}

◆ convertParticle()

ISF::ISFParticle * ISF::InputConverter::convertParticle ( const HepMC::GenParticlePtr & genPartPtr) const
private

convert GenParticle to ISFParticle

get all generator particles which pass filters

particle origin (TODO: add proper GeoID, collision/cosmics)

Definition at line 282 of file InputConverter.cxx.

282 {
283 if (!genPartPtr) { return nullptr; }
284
285 auto pVertex = genPartPtr->production_vertex();
286 if (!pVertex) {
287 ATH_MSG_ERROR("Unable to convert following generator particle due to missing production vertex for: " << genPartPtr);
288 return nullptr;
289 }
290 auto parentEvent = genPartPtr->parent_event();
291 if (!parentEvent) {
292 ATH_MSG_ERROR("Cannot convert a GenParticle without a parent GenEvent into an ISFParticle!!!");
293 return nullptr;
294 }
295
296 const Amg::Vector3D pos(pVertex->position().x(), pVertex->position().y(), pVertex->position().z());
297 const auto& pMomentum(genPartPtr->momentum());
298 const Amg::Vector3D mom(pMomentum.px(), pMomentum.py(), pMomentum.pz());
299#ifdef HEPMC3
300 const double pMass = this->getParticleMass(genPartPtr);
301#else
302 const double pMass = this->getParticleMass(*genPartPtr);
303#endif
304 double e=pMomentum.e();
305 if (e>1) { //only test for >1 MeV in momentum
306 double px=pMomentum.px();
307 double py=pMomentum.py();
308 double pz=pMomentum.pz();
309 double teste=std::sqrt(px*px + py*py + pz*pz + pMass*pMass);
310 if (std::abs(e-teste)>0.01*e) {
311 ATH_MSG_WARNING("Difference in energy for: " << genPartPtr<<" Morg="<<pMomentum.m()<<" Mmod="<<pMass<<" Eorg="<<e<<" Emod="<<teste);
312 }
313 if (MC::isDecayed(genPartPtr) && pVertex && genPartPtr->end_vertex()) { //check for possible changes of gamma for quasi stable particles
314 const auto& prodVtx = genPartPtr->production_vertex()->position();
315 const auto& endVtx = genPartPtr->end_vertex()->position();
316 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
317
318 if (dist3D.mag()>1*Gaudi::Units::mm) {
319 CLHEP::HepLorentzVector mom( pMomentum.x(), pMomentum.y(), pMomentum.z(), pMomentum.t() );
320 double gamma_org=mom.gamma();
321 mom.setE(teste);
322 double gamma_new=mom.gamma();
323
324 if (std::abs(gamma_new-gamma_org)/(gamma_new+gamma_org)>0.001) {
325 ATH_MSG_WARNING("Difference in boost gamma for Quasi stable particle "<<genPartPtr);
326 ATH_MSG_WARNING(" gamma(m="<<mom.m()<<")="<<gamma_org<<" gamma(m="<<pMass<<")="<<gamma_new);
327 } else {
328 ATH_MSG_VERBOSE("Quasi stable particle "<<genPartPtr);
329 ATH_MSG_VERBOSE(" gamma(m="<<mom.m()<<")="<<gamma_org<<" gamma(m="<<pMass<<")="<<gamma_new);
330 }
331 }
332 }
333 }
334
335 const int pPdgId = genPartPtr->pdg_id();
336 const double charge = HepPDT::ParticleID(pPdgId).charge();
337 const double pTime = pVertex->position().t() / Gaudi::Units::c_light;
340 const auto pBarcode = HepMC::barcode(genPartPtr);
341 const auto particleID = HepMC::uniqueID(genPartPtr);
342 auto tBinding = std::make_unique<ISF::TruthBinding>(genPartPtr);
343
344 auto hmpl = std::make_unique<HepMcParticleLink>(particleID, parentEvent->event_number(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID);
345
346 auto sParticle = std::make_unique<ISF::ISFParticle>( std::move(pos),
347 std::move(mom),
348 pMass,
349 charge,
350 pPdgId,
351 genPartPtr->status(),
352 pTime,
353 origin,
354 particleID,
355 pBarcode,
356 tBinding.release(),
357 hmpl.release() );
358 return sParticle.release();
359}
#define ATH_MSG_WARNING(x)
double charge(const T &p)
Definition AtlasPID.h:997
double getParticleMass(const HepMC::GenParticle &p) const
get right GenParticle mass
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr double pMass
int barcode(const T *p)
Definition Barcode.h:16
int uniqueID(const T &p)
std::pair< AtlasDetDescr::AtlasRegion, ISF::SimSvcID > DetRegionSvcIDPair
the datatype to be used to store each individual particle hop
Definition ISFParticle.h:30
@ fEventGeneratorSimID
Definition SimSvcID.h:34
bool isDecayed(const T &p)
Identify if the particle decayed.

◆ finalize()

StatusCode ISF::InputConverter::finalize ( )
finaloverridevirtual

Athena algtool Hook.

Definition at line 108 of file InputConverter.cxx.

109{
110 ATH_MSG_DEBUG("Finalizing ...");
111 return StatusCode::SUCCESS;
112}

◆ findShadowParticle()

HepMC::GenParticlePtr ISF::InputConverter::findShadowParticle ( const HepMC::ConstGenParticlePtr & genParticle,
HepMC::GenEvent * shadowGenEvent ) const
private

Definition at line 805 of file InputConverter.cxx.

806{
807 if (!shadowGenEvent) {
808 ATH_MSG_FATAL ("Found status==2 GenParticle with no end vertex and shadow GenEvent is missing - something is wrong here!");
809 abort();
810 }
811#ifdef HEPMC3
812 // TODO in the future switch to using an Attribute which stores the shadow GenParticlePtr directly.
813 const int shadowId = genParticle->attribute<HepMC3::IntAttribute>("ShadowParticleId")->value();
814 for (auto& shadowParticle : shadowGenEvent->particles()) {
815 if (shadowParticle->id() == shadowId && matchedGenParticles(genParticle, shadowParticle) ) { return shadowParticle; }
816 }
817 return std::make_shared<HepMC::GenParticle>();
818#else
819 for (HepMC::GenEvent::particle_iterator pitr=shadowGenEvent->particles_begin(); pitr != shadowGenEvent->particles_end(); ++pitr) {
820 HepMC::GenParticlePtr shadowParticle = (*pitr);
821 if (matchedGenParticles(genParticle, shadowParticle) ) { return shadowParticle; }
822 }
823 return nullptr;
824#endif
825
826}
#define ATH_MSG_FATAL(x)
bool matchedGenParticles(const HepMC::ConstGenParticlePtr &p1, const HepMC::ConstGenParticlePtr &p2) const
GenParticle * GenParticlePtr
Definition GenParticle.h:37

◆ getDaughterG4PrimaryParticle()

G4PrimaryParticle * ISF::InputConverter::getDaughterG4PrimaryParticle ( HepMC::GenParticle & gp,
bool makeLinkToTruth = true ) const
private

Definition at line 704 of file InputConverter.cxx.

705{
706 ATH_MSG_VERBOSE("Creating G4PrimaryParticle from GenParticle.");
707
708 const G4ParticleDefinition *particleDefinition = this->getG4ParticleDefinition(genpart.pdg_id());
709
710 if (particleDefinition==nullptr) {
711 ATH_MSG_ERROR("ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << genpart.pdg_id() <<
712 "\n This usually indicates a problem with the evgen step.\n" <<
713 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
714 return nullptr;
715 }
716
717 // create new primaries and set them to the vertex
718 // G4double mass = particleDefinition->GetPDGMass();
719 auto &genpartMomentum = genpart.momentum();
720 G4double px = genpartMomentum.x();
721 G4double py = genpartMomentum.y();
722 G4double pz = genpartMomentum.z();
723
724 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
725
726 if (genpart.end_vertex()) {
727 // Set the lifetime appropriately - this is slow but rigorous, and we
728 // don't want to end up with something like vertex time that we have
729 // to validate for every generator on earth...
730 const auto& prodVtx = genpart.production_vertex()->position();
731 const auto& endVtx = genpart.end_vertex()->position();
732 //const G4LorentzVector lv0 ( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
733 //const G4LorentzVector lv1 ( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
734 //Old calculation, not taken because vertex information is not sufficiently precise
735 //g4particle->SetProperTime( (lv1-lv0).mag()/Gaudi::Units::c_light );
736
737 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
738 double tau=SetProperTimeFromDetectorFrameDecayLength(*g4particle,dist3D.mag());
739
740 if (msgLvl(MSG::VERBOSE)) {
741 double pmag2=g4particle->GetTotalMomentum(); //magnitude of particle momentum
742 pmag2*=pmag2; //magnitude of particle momentum squared
743 double e2=g4particle->GetTotalEnergy(); //energy of particle
744 e2*=e2; //energy of particle squared
745 double beta2=pmag2/e2; //beta^2=v^2/c^2 for particle
746 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_light/Gaudi::Units::c_light;
747 ATH_MSG_VERBOSE("lifetime tau(beta)="<<std::sqrt(tau2)<<" tau="<<tau);
748 }
750 ATH_MSG_VERBOSE( "Detected primary particle with end vertex." );
751 ATH_MSG_VERBOSE( "Will add the primary particle set on." );
752 ATH_MSG_VERBOSE( "Primary Particle: " << genpart );
753 ATH_MSG_VERBOSE( "Number of daughters: " << genpart.end_vertex()->particles_out_size()<<" at position "<<genpart.end_vertex());
754 }
755 else {
756 ATH_MSG_WARNING( "Detected primary particle with end vertex." );
757 ATH_MSG_WARNING( "Will add the primary particle set on." );
758 ATH_MSG_WARNING( "Primary Particle: " << genpart );
759 ATH_MSG_WARNING( "Number of daughters: " << genpart.end_vertex()->particles_out_size()<<" at position "<<genpart.end_vertex() );
760 }
761 // Add all necessary daughter particles
762 for ( auto daughterIter=genpart.end_vertex()->particles_out_const_begin();
763 daughterIter!=genpart.end_vertex()->particles_out_const_end(); ++daughterIter ) {
765 ATH_MSG_VERBOSE ( "Attempting to add daughter particle: " << **daughterIter );
766 }
767 else {
768 ATH_MSG_WARNING ( "Attempting to add daughter particle: " << **daughterIter );
769 }
770 G4PrimaryParticle *daughterG4Particle = this->getDaughterG4PrimaryParticle( **daughterIter, makeLinkToTruth );
771 if (!daughterG4Particle) {
772 ATH_MSG_ERROR("Bailing out of loop over daughters of particle due to errors - will not return G4Particle.");
773 return nullptr;
774 }
775 g4particle->SetDaughter( daughterG4Particle );
776 }
777 }
778
779 if (makeLinkToTruth) {
780 // Set the user information for this primary to point to the HepMcParticleLink...
781 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(&genpart);
782 primaryPartInfo->SetRegenerationNr(0);
783 ATH_MSG_VERBOSE("Making primary down the line with barcode " << primaryPartInfo->GetParticleUniqueID());
784 g4particle->SetUserInformation(primaryPartInfo.release());
785 }
786
787 return g4particle.release();
788}
double SetProperTimeFromDetectorFrameDecayLength(G4PrimaryParticle &g4particle, const double GeneratorDecayLength)
const G4ParticleDefinition * getG4ParticleDefinition(int pdgcode) const
G4PrimaryParticle * getDaughterG4PrimaryParticle(HepMC::GenParticle &gp, bool makeLinkToTruth=true) const
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
tuple genpart
Check that the actual generators, tune, and main PDF are consistent with the JO name.

◆ getG4ParticleDefinition()

const G4ParticleDefinition * ISF::InputConverter::getG4ParticleDefinition ( int pdgcode) const
private

Special cases for Geantinos

Standard particles

Definition at line 507 of file InputConverter.cxx.

508{
510 if (pdgcode==998) {
511 return G4ChargedGeantino::Definition();
512 }
513 if (pdgcode==999) {
514 return G4Geantino::GeantinoDefinition();
515 }
517 G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
518 if (ptable) {
519 return ptable->FindParticle(pdgcode);
520 }
521 ATH_MSG_ERROR("getG4ParticleDefinition - Failed to retrieve G4ParticleTable!");
522 return nullptr;
523}

◆ getG4PrimaryParticle()

G4PrimaryParticle * ISF::InputConverter::getG4PrimaryParticle ( ISF::ISFParticle & isp,
bool useHepMC,
HepMC::GenEvent * shadowGenEvent ) const
private

In the case that particles are being passed back to Geant4 then we may have particles which have already interacted, so we should set the regeneration number accordingly.

Definition at line 992 of file InputConverter.cxx.

993{
994 ATH_MSG_VERBOSE("Creating G4PrimaryParticle from ISFParticle.");
995
996 auto* truthBinding = isp.getTruthBinding();
997 if (!truthBinding) {
998 G4ExceptionDescription description;
999 description << G4String("getG4PrimaryParticle: ") + "No ISF::TruthBinding associated with ISParticle (" << isp <<")";
1000 G4Exception("iGeant4::TransportTool", "NoISFTruthBinding", FatalException, description);
1001 return nullptr; //The G4Exception call above should abort the job, but Coverity does not seem to pick this up.
1002 }
1003 HepMC::GenParticlePtr currentGenPart = truthBinding->getCurrentGenParticle();
1004 HepMC::GenParticlePtr primaryGenpart = truthBinding->getPrimaryGenParticle();
1005
1006 const G4ParticleDefinition *particleDefinition = this->getG4ParticleDefinition(isp.pdgCode());
1007
1008 if (particleDefinition==nullptr) {
1009 ATH_MSG_ERROR("ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << isp.pdgCode() <<
1010 "\n This usually indicates a problem with the evgen step.\n" <<
1011 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
1012 return nullptr;
1013 }
1014
1015 // create new primaries and set them to the vertex
1016 // G4double mass = particleDefinition->GetPDGMass();
1017 G4double px(0.0);
1018 G4double py(0.0);
1019 G4double pz(0.0);
1020 if (useHepMC && currentGenPart) {
1021 auto &currentGenPartMomentum = currentGenPart->momentum();
1022 px = currentGenPartMomentum.x();
1023 py = currentGenPartMomentum.y();
1024 pz = currentGenPartMomentum.z();
1025 }
1026 else {
1027 auto &ispMomentum = isp.momentum();
1028 px = ispMomentum.x();
1029 py = ispMomentum.y();
1030 pz = ispMomentum.z();
1031 }
1032
1033 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
1034 // UserInformation
1035 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(primaryGenpart,&isp);
1036
1040 const int regenerationNr = HepMC::StatusBased::generations(&isp);
1041 if (HepMC::BarcodeBased::generations(&isp) != regenerationNr) {
1042 ATH_MSG_WARNING ("StatusBased::generations() = " << regenerationNr << ", BarcodeBased::generations() = " << HepMC::BarcodeBased::generations(&isp) << ", isp: " << isp);
1043 }
1044 primaryPartInfo->SetRegenerationNr(regenerationNr);
1045
1046 if ( currentGenPart ) {
1047 if (currentGenPart->end_vertex()) {
1048 // Old approach particle had an end vertex - predefined decays taken from the main GenEvent
1049 // No longer supported
1050 ATH_MSG_ERROR ( "getG4PrimaryParticle(): GenParticle has a valid end GenVertexPtr!" );
1051 ATH_MSG_ERROR ( "getG4PrimaryParticle(): currentGenPart: " << currentGenPart << ", barcode: " << HepMC::barcode(currentGenPart) );
1052 ATH_MSG_ERROR ( "getG4PrimaryParticle(): currentGenPart->end_vertex(): " << currentGenPart->end_vertex() << ", barcode: " << HepMC::barcode(currentGenPart->end_vertex()) );
1053 ATH_MSG_FATAL ( "getG4PrimaryParticle(): Passing GenParticles with a valid end GenVertexPtr as input is no longer supported." );
1054 abort();
1055 }
1056 else if (MC::isDecayed(currentGenPart) // Some assumptions about main GenEvent here
1057 && !currentGenPart->end_vertex()) {
1058 // New approach - predefined decays taken from shadow GenEvent
1059 // Find the matching particle in the shadowGenEvent
1060#ifdef HEPMC3
1061 auto A_part = currentGenPart->attribute<HepMC::ShadowParticle>("ShadowParticle");
1062 HepMC::ConstGenParticlePtr shadowPart = (A_part) ? A_part->value() : findShadowParticle(currentGenPart, shadowGenEvent);
1063#else
1064 HepMC::GenParticlePtr shadowPart = findShadowParticle(currentGenPart, shadowGenEvent);
1065#endif
1066 if (!shadowPart) {
1067 ATH_MSG_FATAL ("Found a GenParticle with no matching GenParticle in the shadowGenEvent - something is wrong here!");
1068 abort();
1069 }
1070 if (!shadowPart->end_vertex()) {
1071 ATH_MSG_FATAL ("Found status==2 shadow GenParticle with no end vertex - something is wrong here!");
1072 abort();
1073 }
1074#ifdef HEPMC3
1075 processPredefinedDecays(shadowPart, isp, g4particle.get());
1076#else
1077 processPredefinedDecays(shadowPart, isp, g4particle.get(), false); // false to avoid truth-links to the shadow GenEvent
1078#endif
1079 }
1080
1081 double px,py,pz;
1082 const double pmass = g4particle->GetMass();
1083 CLHEP::Hep3Vector gpv = g4particle->GetMomentum();
1084 double g4px=g4particle->GetMomentum().x();
1085 double g4py=g4particle->GetMomentum().y();
1086 double g4pz=g4particle->GetMomentum().z();
1087 if (useHepMC) {
1088 //Code adapted from TruthHepMCEventConverter::TransformHepMCParticle
1089 px=g4px;
1090 py=g4py;
1091 pz=g4pz;
1092 } else {
1093 //Take mass from g4particle, put keep momentum as in currentGenPart
1094 px=currentGenPart->momentum().px();
1095 py=currentGenPart->momentum().py();
1096 pz=currentGenPart->momentum().pz();
1097 //Now a dirty hack to keep backward compatibility in the truth:
1098 //When running AtlasG4 or FullG4 between 21.0.41 and 21.0.111, the currentGenPart 3-momentum and mass was reset to the values from the g4particle
1099 //together with the mass of the g4particle after the 1st initialization of the g4particle from the genevent. This is done for a consistent mass
1100 //value in the truth record compared to the used g4 mass. Since g4particles don't store the 3-momentum directly, but rather a
1101 //unit direction vector, the mass and the kinetic energy, this reduces the numeric accuracy.
1102 //For backward compatibility, if all 3-momentum components agree to the g4particle momentum within 1 keV, we keep
1103 //this old method. This comparison is needed, since in ISF this code could be rerun after the ID or CALO simulation, where
1104 //real energy was lost in previous detectors and hence currentGenPart should NOT be changed to some g4particle values!
1105 //TODO: find a way to implement this in a backward compatible way in ISF::InputConverter::convertParticle(HepMC::GenParticlePtr genPartPtr)
1106 if (std::abs(px-g4px)<CLHEP::keV && std::abs(py-g4py)<CLHEP::keV && std::abs(pz-g4pz)<CLHEP::keV) {
1107 px=g4px;
1108 py=g4py;
1109 pz=g4pz;
1110 }
1111 }
1112 const double mag2=px*px + py*py + pz*pz;
1113 const double pe = std::sqrt(mag2 + pmass*pmass); // this does only change for boosts, etc.
1114
1115 double originalEnergy=currentGenPart->momentum().e();
1116 if (originalEnergy>0.01) { //only test for >1 MeV in momentum
1117 if ((originalEnergy-pe)/originalEnergy>0.01) {
1118 double genpx=currentGenPart->momentum().px();
1119 double genpy=currentGenPart->momentum().py();
1120 double genpz=currentGenPart->momentum().pz();
1121 double genp=sqrt(genpx*genpx + genpy*genpy + genpz*genpz);
1122 ATH_MSG_WARNING("Truth change in energy for: " << currentGenPart<<" Morg="<<currentGenPart->momentum().m()<<" Mmod="<<pmass<<" Eorg="<<originalEnergy<<" Emod="<<pe<<" porg="<<genp<<" pmod="<<gpv.mag());
1123 }
1124 }
1125
1126#ifdef HEPMC3
1127 auto& currentGenPart_nc = currentGenPart;
1128#else
1129 auto* currentGenPart_nc = currentGenPart;
1130#endif
1131 currentGenPart_nc->set_momentum(HepMC::FourVector(px,py,pz,pe));
1132 } // Truth was detected
1133
1134 ATH_MSG_VERBOSE("PrimaryParticleInformation:");
1135 ATH_MSG_VERBOSE(" GetParticleUniqueID = " << primaryPartInfo->GetParticleUniqueID());
1136 ATH_MSG_VERBOSE(" GetRegenerationNr = " << primaryPartInfo->GetRegenerationNr());
1137 ATH_MSG_VERBOSE(" GetHepMCParticle = " << primaryPartInfo->GetHepMCParticle());
1138 ATH_MSG_VERBOSE(" GetISFParticle = " << primaryPartInfo->GetISFParticle());
1139 g4particle->SetUserInformation(primaryPartInfo.release());
1140
1141 return g4particle.release();
1142}
Scalar mag2() const
mag2 method - forward to squaredNorm()
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.
int pdgCode() const
PDG value.
void processPredefinedDecays(const HepMC::GenParticlePtr &genpart, ISF::ISFParticle &isp, G4PrimaryParticle *g4particle, bool makeLinkToTruth=true) const
HepMC::GenParticlePtr findShadowParticle(const HepMC::ConstGenParticlePtr &genParticle, HepMC::GenEvent *shadowGenEvent) const
HepMC::GenParticlePtr getCurrentGenParticle()
pointer to the particle in the simulation truth
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
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...
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38

◆ getParticleMass()

double ISF::InputConverter::getParticleMass ( const HepMC::GenParticle & p) const
private

get right GenParticle mass

Definition at line 388 of file InputConverter.cxx.

389{
390 // default value: generated particle mass
391 double mass = part.generated_mass();
392 ATH_MSG_VERBOSE("part.generated_mass, mass="<<mass);
393
394 // 1. use PDT mass?
396 const int absPDG = std::abs(part.pdg_id());
397 HepPDT::ParticleData const *pData = (m_particleDataTable)
398 ? m_particleDataTable->particle(absPDG)
399 : nullptr;
400 if (pData) {
401 mass = pData->mass();
402 ATH_MSG_VERBOSE("using pData mass, mass="<<mass);
403 }
404 else {
405 ATH_MSG_WARNING( "Unable to find mass of particle with PDG ID '" << absPDG << "' in ParticleDataTable. Will set mass to generated_mass: " << mass);
406 }
407 }
408 return mass;
409}

◆ getSelectedParticles()

std::vector< HepMC::GenParticlePtr > ISF::InputConverter::getSelectedParticles ( HepMC::GenEvent & evnt,
bool legacyOrdering = false ) const
private

get all generator particles which pass filters

Definition at line 244 of file InputConverter.cxx.

244 {
245 auto allGenPartBegin = evnt.particles_begin();
246 auto allGenPartEnd = evnt.particles_end();
247
248 // reserve destination container with maximum size, i.e. number of particles in input event
249 std::vector<HepMC::GenParticlePtr> passedGenParticles{};
250 size_t maxParticles = std::distance(allGenPartBegin, allGenPartEnd);
251 passedGenParticles.reserve(maxParticles);
252
253 if (legacyOrdering) {
254 // FIXME: remove this block and the 'legacyOrdering' flag
255 // once we don't need the legacy order any longer
256 auto vtxIt = evnt.vertices_begin();
257 auto vtxItEnd = evnt.vertices_end();
258 for ( ; vtxIt != vtxItEnd; ++vtxIt ) {
259 const auto vtxPtr = *vtxIt;
260 std::copy_if (vtxPtr->particles_begin(HepMC::children),
261 vtxPtr->particles_end(HepMC::children),
262 std::back_inserter(passedGenParticles),
263 [this](HepMC::GenParticlePtr p){return this->passesFilters(*p);});
264 }
265 }
266 else {
267 std::copy_if (allGenPartBegin,
268 allGenPartEnd,
269 std::back_inserter(passedGenParticles),
270 [this](HepMC::GenParticlePtr p){return this->passesFilters(*p);});
271 }
272
273 passedGenParticles.shrink_to_fit();
274
275 return passedGenParticles;
276}
bool passesFilters(const HepMC::GenParticle &p) const
check if the given particle passes all filters
constexpr uint8_t maxParticles()

◆ initialize()

StatusCode ISF::InputConverter::initialize ( )
finaloverridevirtual

Athena algtool Hooks.

Definition at line 83 of file InputConverter.cxx.

84{
85 ATH_MSG_VERBOSE("initialize() begin");
86
87 // setup PDT if requested (to get particle masses later on)
89 ATH_CHECK(m_particlePropSvc.retrieve());
92 ATH_MSG_FATAL( "Could not get ParticleDataTable from " << m_particlePropSvc << ". Abort" );
93 return StatusCode::FAILURE;
94 }
95 }
96
97 if (!m_genParticleFilters.empty()) {
99 }
100
101 ATH_MSG_VERBOSE("initialize() successful");
102 return StatusCode::SUCCESS;
103}

◆ ISF_to_G4Event()

void ISF::InputConverter::ISF_to_G4Event ( G4Event & event,
const std::vector< ISF::ISFParticle * > & isp,
HepMC::GenEvent * genEvent,
HepMC::GenEvent * shadowGenEvent = nullptr,
bool useHepMC = false ) const
finaloverride

Converts vector of ISF::ISFParticles to G4Event.

Definition at line 468 of file InputConverter.cxx.

471 {
472 // G4Event *g4evt = new G4Event(ctx.eventID().event_number());
473
474 // retrieve world solid (volume)
475 const G4VSolid *worldSolid = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume()->GetLogicalVolume()->GetSolid();
476
477 for ( ISF::ISFParticle *ispPtr: ispVector ) {
478 ISF::ISFParticle &isp = *ispPtr;
479 if ( !isInsideG4WorldVolume(isp, worldSolid) ) {
480 ATH_MSG_WARNING("Unable to convert ISFParticle to G4PrimaryParticle!");
481 ATH_MSG_WARNING(" ISFParticle: " << isp );
482 if (worldSolid) {
483 ATH_MSG_WARNING(" is outside Geant4 world volume: ");
484 worldSolid->DumpInfo();
485 G4cout << std::flush;
486 }
487 else {
488 ATH_MSG_WARNING(" is outside Geant4 world volume.");
489 }
490 continue;
491 }
492 this->addG4PrimaryVertex(event, isp, useHepMC, shadowGenEvent);
493 }
494
495 AtlasG4EventUserInfo* atlasG4EvtUserInfo =
496 dynamic_cast<AtlasG4EventUserInfo*>(event.GetUserInformation());
497 if (!atlasG4EvtUserInfo) {
498 atlasG4EvtUserInfo = new AtlasG4EventUserInfo(Gaudi::Hive::currentContext());
499 event.SetUserInformation(atlasG4EvtUserInfo);
500 }
501 atlasG4EvtUserInfo->SetLastProcessedTrackID(0); // TODO Check if it is better to set this to -1 initially
502 atlasG4EvtUserInfo->SetLastProcessedStep(0); // TODO Check if it is better to set this to -1 initially
503 atlasG4EvtUserInfo->SetHepMCEvent(genEvent);
504}
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.
void addG4PrimaryVertex(G4Event &g4evt, ISF::ISFParticle &isp, bool useHepMC, HepMC::GenEvent *shadowGenEvent) const
bool isInsideG4WorldVolume(const ISF::ISFParticle &isp, const G4VSolid *worldSolid) const
Tests whether the given ISFParticle is within the Geant4 world volume.

◆ isInsideG4WorldVolume()

bool ISF::InputConverter::isInsideG4WorldVolume ( const ISF::ISFParticle & isp,
const G4VSolid * worldSolid ) const
private

Tests whether the given ISFParticle is within the Geant4 world volume.

Definition at line 1177 of file InputConverter.cxx.

1178{
1179
1180 const Amg::Vector3D &pos = isp.position();
1181 const G4ThreeVector g4Pos( pos.x(), pos.y(), pos.z() );
1182 EInside insideStatus = worldSolid->Inside( g4Pos );
1183
1184 bool insideWorld = insideStatus != kOutside;
1185 return insideWorld;
1186}

◆ matchedGenParticles()

bool ISF::InputConverter::matchedGenParticles ( const HepMC::ConstGenParticlePtr & p1,
const HepMC::ConstGenParticlePtr & p2 ) const
private

Definition at line 792 of file InputConverter.cxx.

794{
795 return (HepMC::barcode(p1) == HepMC::barcode(p2))
796 && (p1->status() == p2->status())
797 && (p1->pdg_id() == p2->pdg_id())
798 && ((p1->momentum().px()) == (p2->momentum().px()))
799 && ((p1->momentum().py()) == (p2->momentum().py()))
800 && ((p1->momentum().pz()) == (p2->momentum().pz()))
801 && (float(p1->momentum().m()) == float(p2->momentum().m()));
802}

◆ passesFilters()

bool ISF::InputConverter::passesFilters ( const HepMC::GenParticle & p) const
private

check if the given particle passes all filters

Definition at line 441 of file InputConverter.cxx.

442{
443 // TODO: implement this as a std::find_if with a lambda function
444 for ( const auto& filter : m_genParticleFilters ) {
445 // determine if the particle passes current filter
446 bool passFilter = filter->pass(part);
447 ATH_MSG_VERBOSE("GenParticleFilter '" << filter.typeAndName() << "' returned: "
448 << (passFilter ? "true, will keep particle."
449 : "false, will remove particle."));
450 const auto& momentum = part.momentum();
451 ATH_MSG_VERBOSE("Particle: ("
452 <<momentum.px()<<", "
453 <<momentum.py()<<", "
454 <<momentum.pz()<<"), pdgCode: "
455 <<part.pdg_id() );
456
457 if (!passFilter) {
458 return false;
459 }
460 }
461
462 return true;
463}

◆ processPredefinedDecays()

void ISF::InputConverter::processPredefinedDecays ( const HepMC::GenParticlePtr & genpart,
ISF::ISFParticle & isp,
G4PrimaryParticle * g4particle,
bool makeLinkToTruth = true ) const
private

Set the lifetime appropriately - this is slow but rigorous, and we don't want to end up with something like vertex time that we have to validate for every generator on earth...

Definition at line 910 of file InputConverter.cxx.

911{
915 const auto& prodVtx = genpart->production_vertex()->position();
916 const auto& endVtx = genpart->end_vertex()->position();
917
918 CLHEP::Hep3Vector dist3D(endVtx.x()-prodVtx.x(), endVtx.y()-prodVtx.y(), endVtx.z()-prodVtx.z());
919 double tau=SetProperTimeFromDetectorFrameDecayLength(*g4particle,dist3D.mag());
920
921 if (msgLvl(MSG::VERBOSE)) {
922 double pmag2=g4particle->GetTotalMomentum(); //magnitude of particle momentum
923 pmag2*=pmag2; //magnitude of particle momentum squared
924 double e2=g4particle->GetTotalEnergy(); //energy of particle
925 e2*=e2; //energy^2 of particle
926 double beta2=pmag2/e2; //beta^2=v^2/c^2 for particle
927 double mass2=g4particle->GetMass(); //mass of particle
928 mass2*=mass2; //mass^2 of particle
929
930 double tau2=dist3D.mag2()*(1/beta2-1)/Gaudi::Units::c_squared;
931
932 const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() );
933 const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() );
934 //Old calculation, not taken because vertex information is not sufficiently precise
935 //g4particle->SetProperTime( (lv1-lv0).mag()/Gaudi::Units::c_light );
936 G4LorentzVector dist4D(lv1);
937 dist4D-=lv0;
938
939 double dist4Dgamma=std::numeric_limits<double>::infinity();
940 if (dist4D.t()>0 && dist4D.mag2()>0) {
941 dist4Dgamma=dist4D.gamma();
942 } else {
943 ATH_MSG_VERBOSE( "dist4D t="<<dist4D.t()<<" mag2="<<dist4D.mag2());
944 }
945
946 G4LorentzVector fourmom(g4particle->GetMomentum(),g4particle->GetTotalEnergy());
947 double fourmomgamma=std::numeric_limits<double>::infinity();
948 if (fourmom.t()>0 && fourmom.mag2()>0) {
949 fourmomgamma=fourmom.gamma();
950 } else {
951 ATH_MSG_VERBOSE( "fourmom t="<<fourmom.t()<<" mag2="<<fourmom.mag2());
952 }
953
954 ATH_MSG_VERBOSE( "gammaVertex="<<dist4Dgamma<<" gammamom="<<fourmomgamma<<" gamma(beta)="<<1/std::sqrt(1-beta2)<<" lifetime tau(beta)="<<std::sqrt(tau2)<<" lifetime tau="<<tau);
955 }
957 ATH_MSG_VERBOSE( "Detected primary particle with end vertex." );
958 ATH_MSG_VERBOSE( "Will add the primary particle set on." );
959 ATH_MSG_VERBOSE( "ISF Particle: " << isp );
960 ATH_MSG_VERBOSE( "Primary Particle: " << genpart );
961 ATH_MSG_VERBOSE( "Number of daughters: " << genpart->end_vertex()->particles_out_size() << " at position "<< genpart->end_vertex() );
962 }
963 else {
964 ATH_MSG_WARNING( "Detected primary particle with end vertex. This should only be the case if" );
965 ATH_MSG_WARNING( "you are running with quasi-stable particle simulation enabled. This is not" );
966 ATH_MSG_WARNING( "yet validated - you'd better know what you're doing. Will add the primary" );
967 ATH_MSG_WARNING( "particle set on." );
968 ATH_MSG_WARNING( "ISF Particle: " << isp );
969 ATH_MSG_WARNING( "Primary Particle: " << genpart );
970 ATH_MSG_WARNING( "Number of daughters: " << genpart->end_vertex()->particles_out_size() );
971 }
972 // Add all necessary daughter particles
973 for ( auto daughter: *(genpart->end_vertex())) {
975 ATH_MSG_VERBOSE ( "Attempting to add daughter particle: " << daughter );
976 }
977 else {
978 ATH_MSG_WARNING ( "Attempting to add daughter particle: " << daughter );
979 }
980#ifdef HEPMC3
981 G4PrimaryParticle *daughterG4Particle = this->getDaughterG4PrimaryParticle( daughter, makeLinkToTruth );
982#else
983 G4PrimaryParticle *daughterG4Particle = this->getDaughterG4PrimaryParticle( *daughter, makeLinkToTruth );
984#endif
985 if (!daughterG4Particle) {
986 ATH_MSG_FATAL("Bailing out of loop over daughters due to errors.");
987 }
988 g4particle->SetDaughter( daughterG4Particle );
989 }
990}

Member Data Documentation

◆ m_genParticleFilters

ToolHandleArray<IGenParticleFilter> ISF::InputConverter::m_genParticleFilters
private

HepMC::GenParticle filters.

Definition at line 137 of file InputConverter.h.

◆ m_particleDataTable

const HepPDT::ParticleDataTable* ISF::InputConverter::m_particleDataTable
private

PDT used to look up particle masses.

Definition at line 133 of file InputConverter.h.

◆ m_particlePropSvc

ServiceHandle<IPartPropSvc> ISF::InputConverter::m_particlePropSvc
private

ParticlePropertyService and ParticleDataTable.

particle properties svc to retrieve PDT

Definition at line 132 of file InputConverter.h.

◆ m_quasiStableParticlesIncluded

bool ISF::InputConverter::m_quasiStableParticlesIncluded
private

Definition at line 139 of file InputConverter.h.

◆ m_useGeneratedParticleMass

bool ISF::InputConverter::m_useGeneratedParticleMass
private

use GenParticle::generated_mass() in simulation

Definition at line 135 of file InputConverter.h.

◆ m_useShadowEvent

BooleanProperty ISF::InputConverter::m_useShadowEvent {this, "UseShadowEvent", false, "New approach to selecting particles for simulation" }
private

Definition at line 140 of file InputConverter.h.

140{this, "UseShadowEvent", false, "New approach to selecting particles for simulation" };

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