16 #include "Gaudi/Property.h"
37 m_inputHardScatterEvgen(),
39 m_outputHardScatterTruth(),
40 m_outputPileupTruth(),
41 m_inputConverter(
"",
name),
42 m_particleBroker(
"ISF_ParticleBroker",
name),
43 m_truthRecordSvc(
"ISF_TruthRecordSvc",
name),
44 m_qspatcher(
"",
name),
46 m_memMon(
"MemMonitoringTool"),
57 m_maxParticleVectorSize(10240)
61 "Input Hard Scatter EVGEN collection.");
64 "Input Pileup EVGEN collection.");
67 "Output Hard Scatter Truth collection.");
70 "Output Pileup Truth collection.");
73 "Input McEventCollection->ISFParticleContainer conversion service.");
106 ATH_MSG_VERBOSE (
"--------------------------------------------------------" );
113 ATH_MSG_INFO(
"- MemoryMonitoring : " << m_memMon.typeAndName() );
115 m_memMon->recordCurrent(
"at beginning of SimKernel initialize()");
130 ATH_CHECK ( m_particleBroker.retrieve() );
131 ATH_MSG_INFO(
"- ParticleBroker : " << m_particleBroker.typeAndName() );
134 ATH_CHECK ( m_truthRecordSvc.retrieve() );
135 ATH_MSG_INFO(
"- TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
140 ATH_CHECK ( initSimSvcs(m_simSelectors[geoID]) );
143 ATH_CHECK( m_inputConverter.retrieve() );
144 if ( not m_truthPreselectionTool.empty() ) {
145 ATH_CHECK(m_truthPreselectionTool.retrieve());
148 if(!m_qspatcher.empty()) {
154 ATH_MSG_INFO(
"The following Event Filters are defined:");
158 m_simSvcs.resize( m_numSimSvcs);
159 m_simSvcNames.resize( m_numSimSvcs);
161 ATH_MSG_INFO (
"The following SimulationSvc are registered to ISF:");
163 ATH_MSG_INFO (
"ID: " <<
id <<
"\t Name: '" << m_simSvcNames[
id]
172 ATH_MSG_INFO(
"The following routing chains are defined:");
175 <<
" (GeoID=" << geoID <<
"): \t" << m_simSelectors[geoID]);
179 if (m_doMemMon) m_memMon->recordCurrent(
"at end of ISF SimKernel initialize()");
181 ATH_CHECK ( m_inputHardScatterEvgen.initialize() );
182 ATH_CHECK ( m_inputPileupEvgen.initialize( !m_inputPileupEvgen.key().empty() ) );
183 ATH_CHECK ( m_outputHardScatterTruth.initialize() );
184 ATH_CHECK ( m_outputPileupTruth.initialize( !m_outputPileupTruth.key().empty() ) );
187 return StatusCode::SUCCESS;
196 if (m_doMemMon) m_memMon->recordCurrent(
"at beginning of ISF SimKernel finalize()");
199 ATH_MSG_INFO(
" Number of particles handled by the ISF SimKernel: " << m_numParticles );
201 ATH_MSG_INFO(
" ========================= ISF Timing Stats =========================");
204 ATH_MSG_INFO(
"Breakdown of simulation loop by SimulatorID:");
209 m_benchSimID->getData(simID,
count, time_ms);
212 <<m_simSvcNames[simID]<<
" (id="<<simID<<
")"
213 <<
"\t\tn="<<
count<<
"\t\tt=" <<time_ms<<
" ms\t\tt/n="<<time_ms/
count<<
" ms"
214 <<std::setprecision(-1) );
263 ATH_MSG_INFO(
" ====================== ISF Memory Usage Stats =======================");
264 m_memMon->dumpSummary(
"end of ISF event");
267 ATH_MSG_INFO(
" =====================================================================");
269 return StatusCode::SUCCESS;
276 if ( simSelectorTools.retrieve().isFailure() ) {
277 ATH_MSG_FATAL(
"Could not retrieve SimulatorSelector Tool Array. Abort." );
278 return StatusCode::FAILURE;
284 for ( ; fSimSelectorIter != fSimSelectorIterEnd; ++fSimSelectorIter ) {
289 if ( (*curSimulator).retrieve().isFailure() ){
290 ATH_MSG_FATAL(
"Could not retrieve SimulatorSelector Tool. Abort." );
291 return StatusCode::FAILURE;
293 ATH_MSG_INFO(
"- SimulationSelector : " << fSimSelectorIter->typeAndName() );
296 if ( (*curSimulator)->setParticleBroker( &*m_particleBroker).isFailure() ){
297 ATH_MSG_FATAL(
"Unable to register ParticleService to SimulationService "
299 return StatusCode::FAILURE;
303 SimSvcID curID = (*curSimulator)->simSvcID();
307 (*curSimulator)->assignSimSvcID( m_numSimSvcs);
309 m_simSvcs[m_numSimSvcs] = (&**curSimulator);
310 m_simSvcNames[m_numSimSvcs] = (*curSimulator)->simSvcDescriptor();
312 <<
" to simulator '" << m_simSvcNames[m_numSimSvcs]
321 return StatusCode::SUCCESS;
331 if ( m_doMemMon && (m_numISFEvents==0) ) {
332 m_memMon->dumpCurrent(
"before 1st event",
false );
333 m_memMon->recordCurrent(
"before 1st event");
339 std::unique_ptr<McEventCollection> shadowTruth{};
340 std::unique_ptr<McEventCollection> shadowPileUpTruth{};
341 ATH_CHECK( prepareInput(m_inputHardScatterEvgen, m_outputHardScatterTruth, shadowTruth, simParticles) );
343 if (!m_inputPileupEvgen.key().empty()) {
344 ATH_CHECK( prepareInput(m_inputPileupEvgen, m_outputPileupTruth, shadowPileUpTruth, simParticles) );
349 ATH_CHECK ( m_particleBroker->initializeEvent( std::move(simParticles) ) );
351 const int largestGeneratedParticleBC = (m_outputHardScatterTruth->empty()) ?
HepMC::UNDEFINED_ID
353 const int largestGeneratedVertexBC = (m_outputHardScatterTruth->empty()) ?
HepMC::UNDEFINED_ID
356 ATH_CHECK( m_truthRecordSvc->initializeTruthCollection(largestGeneratedParticleBC, largestGeneratedVertexBC) );
365 for ( ; fSimSvcIter != fSimSvcIterEnd; ++fSimSvcIter ){
386 unsigned int loopCounter{0};
387 ATH_MSG_DEBUG(
"Starting simulation loop, initial particle stack size: " << m_particleBroker->numParticles());
388 while ( m_particleBroker->numParticles() ) {
391 ATH_MSG_VERBOSE(
"Queue starts with " << m_particleBroker->numParticles() <<
" particles.");
394 const unsigned int numParticlesLeftInBroker = m_particleBroker->numParticles();
398 if (numParticles==0)
break;
401 m_numParticles += numParticles;
408 ATH_MSG_DEBUG (
"Took " << numParticles <<
" particles from queue (remaining: " << m_particleBroker->numParticles() <<
")" );
409 ATH_MSG_VERBOSE(
" -> All particles will be sent to '" << m_simSvcNames[simID] <<
"' simulator (SimSvcID=" << simID <<
")" );
412 if (loopCounter>100 && numParticles<3) {
414 ATH_MSG_INFO(
"Selected " << numParticles <<
" particles to be processed by " << m_simSvcNames[simID]);
423 if (
particle->nextSimID() != simID ) {
424 ATH_MSG_WARNING(
"Particle with SimID " <<
particle->nextSimID() <<
" found in vector with expected ID " << simID );
440 if (m_simSvcs[simID]->simulateVector(
particles, m_outputHardScatterTruth.ptr(), shadowTruth.get()).isFailure()) {
441 ATH_MSG_WARNING(
"Simulation of particles failed in Simulator: " << m_simSvcNames[simID]);
443 ATH_MSG_VERBOSE(m_simSvcNames[simID] <<
" returned " << m_particleBroker->numParticles()-numParticlesLeftInBroker <<
" new particles to be added to the queue." );
447 ATH_MSG_VERBOSE(
"Final status: queue contains " << m_particleBroker->numParticles() <<
" particles.");
454 if ( m_particleBroker->finalizeEvent().isFailure()) {
455 ATH_MSG_WARNING(
"ParticleBroker returned with an error in event finalization." );
461 for ( ; fSimSvcIter != fSimSvcIterEnd; ++fSimSvcIter ){
477 if ( m_truthRecordSvc->releaseEvent().isFailure() ){
478 ATH_MSG_FATAL(
"Event finalize failed for TruthService. Abort." );
479 return StatusCode::FAILURE;
483 if(!m_qspatcher.empty()) {
484 for (HepMC::GenEvent* currentGenEvent : *m_outputHardScatterTruth ) {
485 ATH_CHECK(m_qspatcher->removeWorkaround(*currentGenEvent));
492 while (eventFilter != endOfEventFilters) {
493 if (!((**eventFilter).eventPassesFilter())) {
494 setFilterPassed(
false);
495 ATH_MSG_INFO(
"This event failed the " << (**eventFilter).name() <<
" Filter. Therefore it will not be recorded.");
507 std::string
descr(
"after event " + evtStr);
508 m_memMon->dumpCurrent(
descr.c_str(),
true);
514 if ( !(m_numISFEvents%m_memUsageEvts) ) m_memMon->recordCurrent(
descr.c_str() );
515 else if ( m_numISFEvents==1) m_memMon->recordCurrent(
"after 1st event");
516 else if ( m_numISFEvents==2) m_memMon->recordCurrent(
"after 2nd event");
517 else if ( m_numISFEvents==10) m_memMon->recordCurrent(
"after 10th event");
518 else if ( m_numISFEvents==100) m_memMon->recordCurrent(
"after 100th event");
521 return StatusCode::SUCCESS;
529 std::unique_ptr<McEventCollection>& shadowTruth,
533 ATH_MSG_FATAL(
"Unable to read input GenEvent collection '" << inputTruth.
key() <<
"'");
534 return StatusCode::FAILURE;
537 if (m_useShadowEvent) {
538 outputTruth = std::make_unique<McEventCollection>();
540 shadowTruth = std::make_unique<McEventCollection>(*inputTruth);
541 for (HepMC::GenEvent* currentGenEvent : *shadowTruth ) {
543 if ( not m_qspatcher.empty() ) {
544 ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
547 std::unique_ptr<HepMC::GenEvent> outputEvent = m_truthPreselectionTool->filterGenEvent(*currentGenEvent);
548 outputTruth->
push_back(outputEvent.release());
553 outputTruth = std::make_unique<McEventCollection>(*inputTruth);
556 if(!m_qspatcher.empty()) {
557 for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
558 ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
562 ATH_CHECK( m_inputConverter->convert(*outputTruth, simParticles) );
564 return StatusCode::SUCCESS;