46 ATH_CHECK( m_simulationTools.retrieve() );
47 for (
auto& curSimTool : m_simulationTools )
51 const auto flavor = curSimTool->simFlavor();
52 auto itr = m_simToolMap.find(flavor);
53 if (itr != m_simToolMap.end() )
55 ATH_MSG_FATAL(
"Two ISimulatorTool instances (" << itr->second->name() <<
"," << curSimTool->name() <<
") with the same flavor in this job!\n Check your configuration!");
56 return StatusCode::FAILURE;
59 m_simToolMap[flavor] = &*curSimTool;
61 m_particleKillerTool = &*curSimTool;
66 if (!m_particleKillerTool) {
67 ATH_MSG_FATAL(
"No fallback ParticleKiller Simulator Tool provided in SimulationTools, the job will bail out now.");
68 return StatusCode::FAILURE;
71 ATH_MSG_INFO(
"The following Simulators will be used in this job: \t" << m_simulationTools);
73 for (
auto& selectorsToolHandleArray: m_simSelectors )
75 ATH_CHECK( selectorsToolHandleArray.retrieve() );
79 ATH_MSG_INFO(
"The following routing chains are defined:" );
82 auto& localSelectors = m_simSelectors[geoID];
85 for (
auto&
selector : localSelectors )
87 const auto flavor =
selector->simFlavor();
88 auto itr = m_simToolMap.find(flavor);
89 if (itr == m_simToolMap.end() )
92 for (
auto&
entry : m_simToolMap )
96 ATH_MSG_FATAL(
"No SimulationTool with flavor " << flavor <<
" expected by " <<
selector->name() <<
" found in this job!\n Check your configuration!" );
97 return StatusCode::FAILURE;
102 ATH_CHECK( m_entryLayerTool.retrieve() );
104 if ( not m_orderingTool.empty() ) {
108 ATH_CHECK( m_inputEvgenKey.initialize() );
109 ATH_CHECK( m_outputTruthKey.initialize() );
111 ATH_CHECK( m_caloEntryLayerKey.initialize() );
112 ATH_CHECK( m_muonEntryLayerKey.initialize() );
113 ATH_CHECK( m_muonExitLayerKey.initialize() );
115 ATH_CHECK( m_inputConverter.retrieve() );
116 if ( not m_truthPreselectionTool.empty() ) {
117 ATH_CHECK(m_truthPreselectionTool.retrieve());
120 ATH_CHECK ( m_truthRecordSvc.retrieve() );
122 if ( not m_qspatcher.empty() ) {
128 return StatusCode::SUCCESS;
134 const EventContext& ctx = Gaudi::Hive::currentContext();
136 for (
auto& curSimTool: m_simulationTools) {
139 ATH_MSG_DEBUG(
"Event setup done for " << curSimTool->name() );
145 ATH_MSG_FATAL(
"Unable to read input GenEvent collection '" << inputEvgen.
key() <<
"'");
146 return StatusCode::FAILURE;
151 std::unique_ptr<McEventCollection> shadowTruth{};
152 if (m_useShadowEvent) {
153 outputTruth = std::make_unique<McEventCollection>();
155 shadowTruth = std::make_unique<McEventCollection>(*inputEvgen);
156 for (HepMC::GenEvent* currentGenEvent : *shadowTruth ) {
158 if ( not m_qspatcher.empty() ) {
159 ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
162 std::unique_ptr<HepMC::GenEvent> outputEvent = m_truthPreselectionTool->filterGenEvent(*currentGenEvent);
163 outputTruth->
push_back(outputEvent.release());
168 outputTruth = std::make_unique<McEventCollection>(*inputEvgen);
170 if ( not m_qspatcher.empty() ) {
171 for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
172 ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
182 ATH_CHECK( m_truthRecordSvc->initializeTruthCollection(largestGeneratedParticleBC, largestGeneratedVertexBC) );
186 caloEntryLayer = std::make_unique<TrackRecordCollection>(caloEntryLayer.
name());
189 muonEntryLayer = std::make_unique<TrackRecordCollection>(muonEntryLayer.
name());
192 muonExitLayer = std::make_unique<TrackRecordCollection>(muonExitLayer.
name());
197 ATH_CHECK( m_inputConverter->convert(*outputTruth, simParticles) );
201 for (
auto&
particle : simParticles ) {
203 if ( m_orderingTool.empty() ) {
205 particle->setOrder( -particleQueue.size() );
207 m_orderingTool->setOrder( *
particle );
213 unsigned int loopCounter{0};
218 while ( particleQueue.size() ) {
221 ATH_MSG_VERBOSE(
"Queue starts with " << particleQueue.size() <<
" particles.");
224 while ( particleQueue.size() ) {
225 auto particlePtr = particleQueue.top();
231 m_geoIDSvc->identifyAndRegNextGeoID( curParticle );
235 auto& simTool = identifySimulator(curParticle);
241 lastSimulator=&simTool;
243 else if (&simTool!=lastSimulator ||
particles.size() >= m_maxParticleVectorSize ) {
245 tempQueue.push(particlePtr);
251 particleQueue = std::move(tempQueue);
253 if (loopCounter>100 &&
particles.size()<3) {
255 ATH_MSG_INFO(
"Selected " <<
particles.size() <<
" particles to be processed by " << lastSimulator->name());
265 ATH_MSG_VERBOSE(lastSimulator->name() <<
" returned " << newSecondaries.size() <<
" new particles to be added to the queue." );
267 for (
auto* secondary : newSecondaries ) {
270 m_entryLayerTool->registerParticle( *secondary );
272 m_geoIDSvc->identifyAndRegNextGeoID( *secondary );
275 if ( m_orderingTool.empty() ) {
277 secondary->setOrder( -particleQueue.size() );
279 m_orderingTool->setOrder( *secondary );
282 particleQueue.push( secondary );
284 newSecondaries.clear();
292 ATH_MSG_VERBOSE(
"Final status: queue contains " << particleQueue.size() <<
" particles.");
295 for (
auto& curSimTool: m_simulationTools) {
297 ATH_CHECK(curSimTool->releaseEvent(ctx));
298 ATH_MSG_DEBUG(
"releaseEvent() completed for " << curSimTool->name() );
303 if(!m_qspatcher.empty()) {
304 for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
305 ATH_CHECK(m_qspatcher->removeWorkaround(*currentGenEvent));
309 return StatusCode::SUCCESS;
314 return StatusCode::SUCCESS;
322 auto& localSelectors = m_simSelectors[geoID];
323 for (
auto&
selector: localSelectors) {
326 return *m_simToolMap.at(
selector->simFlavor());
331 <<
" Will send it to " << m_particleKillerTool->name());
332 return *m_particleKillerTool;