34 const auto flavor = curSimTool->simFlavor();
38 ATH_MSG_FATAL(
"Two ISimulatorTool instances (" << itr->second->name() <<
"," << curSimTool->name() <<
") with the same flavor in this job!\n Check your configuration!");
39 return StatusCode::FAILURE;
50 ATH_MSG_FATAL(
"No fallback ParticleKiller Simulator Tool provided in SimulationTools, the job will bail out now.");
51 return StatusCode::FAILURE;
58 ATH_CHECK( selectorsToolHandleArray.retrieve() );
62 ATH_MSG_INFO(
"The following routing chains are defined:" );
68 for (
auto& selector : localSelectors )
70 const auto flavor = selector->simFlavor();
77 ATH_MSG_WARNING(
"SimulationFlavor: " << entry.first <<
", SimulatorTool Name: " << entry.second->name() );
79 ATH_MSG_FATAL(
"No SimulationTool with flavor " << flavor <<
" expected by " << selector->name() <<
" found in this job!\n Check your configuration!" );
80 return StatusCode::FAILURE;
111 return StatusCode::SUCCESS;
117 const EventContext& ctx = Gaudi::Hive::currentContext();
118 auto hitCollections = std::make_shared<HitCollectionMap>();
124 ATH_CHECK(g4sim->setupEvent(ctx, *hitCollections));
128 ATH_MSG_DEBUG(
"Event setup done for " << curSimTool->name() );
134 ATH_MSG_FATAL(
"Unable to read input GenEvent collection '" << inputEvgen.
key() <<
"'");
135 return StatusCode::FAILURE;
140 std::unique_ptr<McEventCollection> shadowTruth{};
142 outputTruth = std::make_unique<McEventCollection>();
144 shadowTruth = std::make_unique<McEventCollection>(*inputEvgen);
145 for (HepMC::GenEvent* currentGenEvent : *shadowTruth ) {
152 outputTruth->push_back(outputEvent.release());
157 outputTruth = std::make_unique<McEventCollection>(*inputEvgen);
160 for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
175 caloEntryLayer = std::make_unique<TrackRecordCollection>(caloEntryLayer.
name());
178 muonEntryLayer = std::make_unique<TrackRecordCollection>(muonEntryLayer.
name());
181 muonExitLayer = std::make_unique<TrackRecordCollection>(muonExitLayer.
name());
190 for (
auto& particle : simParticles ) {
194 particle->setOrder( -particleQueue.size() );
199 particleQueue.push( particle );
202 unsigned int loopCounter{0};
207 while ( particleQueue.size() ) {
210 ATH_MSG_VERBOSE(
"Queue starts with " << particleQueue.size() <<
" particles.");
213 while ( particleQueue.size() ) {
214 auto particlePtr = particleQueue.top();
220 m_geoIDSvc->identifyAndRegNextGeoID( curParticle );
227 if ( particles.empty() ) {
229 particles.push_back(particlePtr);
230 lastSimulator=&simTool;
234 tempQueue.push(particlePtr);
237 particles.push_back(particlePtr);
240 particleQueue = std::move(tempQueue);
242 if (loopCounter>100 && particles.size()<3) {
244 ATH_MSG_INFO(
"Selected " << particles.size() <<
" particles to be processed by " << lastSimulator->name());
251 ATH_MSG_VERBOSE(
"Selected " << particles.size() <<
" particles to be processed by " << lastSimulator->name());
254 ATH_CHECK(g4sim->simulateVector(ctx, particles, newSecondaries,
255 outputTruth.
ptr(), hitCollections,
263 ATH_MSG_VERBOSE(lastSimulator->name() <<
" returned " << newSecondaries.size() <<
" new particles to be added to the queue." );
265 for (
auto* secondary : newSecondaries ) {
270 m_geoIDSvc->identifyAndRegNextGeoID( *secondary );
275 secondary->setOrder( -particleQueue.size() );
280 particleQueue.push( secondary );
282 newSecondaries.clear();
285 for (
auto usedParticle : particles ) {
290 ATH_MSG_VERBOSE(
"Final status: queue contains " << particleQueue.size() <<
" particles.");
297 ATH_CHECK(g4sim->releaseEvent(ctx, *hitCollections));
299 ATH_CHECK(curSimTool->releaseEvent(ctx));
301 ATH_MSG_DEBUG(
"releaseEvent() completed for " << curSimTool->name() );
307 for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
312 return StatusCode::SUCCESS;
317 return StatusCode::SUCCESS;
326 for (
auto& selector: localSelectors) {
327 bool selected = selector->selfSelect(particle);
333 ATH_MSG_WARNING(
"No simulator found for particle (" << particle <<
")."
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool validAtlasRegion(AtlasDetDescr::AtlasRegion region)
Check a given AtlasRegion for its validity.
static const char * getName(int region)
The generic ISF particle definition,.
AtlasDetDescr::AtlasRegion nextGeoID() const
next geoID the particle will be simulated in
SG::WriteHandleKey< McEventCollection > m_outputTruthKey
Output Simulation Truth collection.
ToolHandleArray< ISimulatorTool > m_simulationTools
Simulation Tools.
SG::ReadHandleKey< McEventCollection > m_inputEvgenKey
Input Generator Truth collection.
BooleanProperty m_useShadowEvent
SG::WriteHandleKey< TrackRecordCollection > m_muonEntryLayerKey
std::map< ISF::SimulationFlavor, ISimulatorTool * > m_simToolMap
Map of the simulation flavours used in this job to the corresponding Simulation Services.
ToolHandle< IGenEventFilter > m_truthPreselectionTool
ToolHandle< IParticleOrderingTool > m_orderingTool
Tool to set particle ordering.
Gaudi::Property< size_t > m_maxParticleVectorSize
Number of particles simultaneously sent to simulator.
ISimulatorTool & identifySimulator(const ISF::ISFParticle &particle)
Returns the simulator to use for the given particle.
ServiceHandle< IGeoIDSvc > m_geoIDSvc
Service to set particle GeoIDs.
SG::WriteHandleKey< TrackRecordCollection > m_caloEntryLayerKey
Output TrackRecordCollections.
ServiceHandle< Simulation::IZeroLifetimePatcher > m_qspatcher
Quasi-Stable Particle Simulation Patcher.
StatusCode execute() override
Check the validity of the MC truth event in the current Athena event.
ServiceHandle< IInputConverter > m_inputConverter
Input converter service (from Generator->ISF particle types)
ISimulatorTool * m_particleKillerTool
When no appropriate simulator can be found for a given particle, the particle is sent to this "partic...
std::array< PublicToolHandleArray< ISimulationSelector >, AtlasDetDescr::fNumAtlasRegions > m_simSelectors
The simulation selectors defining the "routing chain".
SG::WriteHandleKey< TrackRecordCollection > m_muonExitLayerKey
Gaudi::Property< bool > m_forceGeoIDSvc
Force geoID recalculation for each particle.
PublicToolHandle< IEntryLayerTool > m_entryLayerTool
AthenaTool responsible for writing Calo/Muon Entry/Exit Layer collection.
StatusCode initialize() override
Check user configuration and configure the algorithm state accordingly.
ServiceHandle< ITruthSvc > m_truthRecordSvc
Central truth service.
StatusCode finalize() override
Implements empty finalize (implementation required by AthAlgorithm)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
const std::string & name() const
Return the StoreGate ID for the referenced object.
pointer_type ptr()
Dereference the pointer.
AtlasRegion
A simple enum of ATLAS regions and sub-detectors.
int maxGeneratedVertexBarcode(const HepMC::GenEvent *genEvent)
Get the maximal absolute value of barcode of vertex present in the event. Returns a negative number.
constexpr int UNDEFINED_ID
int maxGeneratedParticleBarcode(const HepMC::GenEvent *genEvent)
Get the maximal value of barcode of particle present in the event.
std::priority_queue< ISF::ISFParticle *, ISF::ISFParticleVector, ISF::ISFParticleOrdering > ISFParticleOrderedQueue
the actual particle priority_queue
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.