ATLAS Offline Software
SimKernel.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // ISF_Algs includes
6 #include "SimKernel.h"
7 // ISF_Event includes
9 // ISF_Interfaces includes
15 // FrameWork includes
16 #include "Gaudi/Property.h"
17 // ATLAS cxx utils
19 // ROOT includes
20 #include "TTree.h"
21 // DetectorDescription
23 // GeneratorObjects
26 
27 #undef ISFDEBUG
28 
30 // Public methods:
32 
33 // Constructors
35 ISF::SimKernel::SimKernel( const std::string& name, ISvcLocator* pSvcLocator ) :
36  ::AthAlgorithm( name, pSvcLocator ),
37  m_inputHardScatterEvgen(),
38  m_inputPileupEvgen(),
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),
45  m_doMemMon(true),
46  m_memMon("MemMonitoringTool"),
47  m_memUsageEvts(1000),
48  m_simSvcs(ISF::fMaxNumAtlasSimIDs),
49  m_simSvcNames(ISF::fMaxNumAtlasSimIDs),
50  m_numSimSvcs(ISF::fFirstAtlasSimID), // ==1 since UndefinedSimID is always there
51  m_numISFEvents(0),
52  m_doCPUMon(true),
53  //m_benchPDGCode(0), TODO: implement this if feasible
54  //m_benchGeoID(0), TODO: implement this if feasible
55  m_benchSimID(0),
56  m_numParticles(0),
57  m_maxParticleVectorSize(10240)
58 {
59  declareProperty("InputHardScatterCollection",
61  "Input Hard Scatter EVGEN collection.");
62  declareProperty("InputPileupCollection",
64  "Input Pileup EVGEN collection.");
65  declareProperty("OutputHardScatterTruthCollection",
67  "Output Hard Scatter Truth collection.");
68  declareProperty("OutputPileupTruthCollection",
70  "Output Pileup Truth collection.");
71  declareProperty("InputConverter",
73  "Input McEventCollection->ISFParticleContainer conversion service.");
74 
75  // the general services and tools needed
76  declareProperty("ParticleBroker" , m_particleBroker );
77  declareProperty("TruthRecordService" , m_truthRecordSvc );
78  declareProperty("DoCPUMonitoring" , m_doCPUMon );
79  declareProperty("DoMemoryMonitoring" , m_doMemMon );
80  declareProperty("MemoryMonitoringTool" , m_memMon );
81  declareProperty("SummarizeMemUsageEveryNEvts", m_memUsageEvts );
82  // routing tool
83  declareProperty("BeamPipeSimulationSelectors", m_simSelectors[AtlasDetDescr::fAtlasForward] );
84  declareProperty("IDSimulationSelectors" , m_simSelectors[AtlasDetDescr::fAtlasID] );
85  declareProperty("CaloSimulationSelectors" , m_simSelectors[AtlasDetDescr::fAtlasCalo] );
86  declareProperty("MSSimulationSelectors" , m_simSelectors[AtlasDetDescr::fAtlasMS] );
87  declareProperty("CavernSimulationSelectors" , m_simSelectors[AtlasDetDescr::fAtlasCavern] );
88  // Quasi-stable particle sim
89  declareProperty("QuasiStablePatcher", m_qspatcher);
90  // event filter
91  declareProperty("EventFilterTools" , m_eventFilters );
92  // tuning parameters
93  declareProperty("MaximumParticleVectorSize" , m_maxParticleVectorSize );
94 }
95 
96 // Destructor
99 {}
100 
101 // Athena Algorithm's Hooks
104 {
105 
106  ATH_MSG_VERBOSE ( "--------------------------------------------------------" );
107  ATH_MSG_INFO( "Initializing the ISF KERNEL " );
108 
109  // setup memory monitoring Tool
110  if ( m_doMemMon) {
111  // memory monitoring tool given -> do memory monitoring
112  ATH_CHECK( m_memMon.retrieve() );
113  ATH_MSG_INFO( "- MemoryMonitoring : " << m_memMon.typeAndName() );
114  // record current memory usage
115  m_memMon->recordCurrent("at beginning of SimKernel initialize()");
116  }
117 
118 
119  // setup CPU Benchmarks
120  if (m_doCPUMon) {
121  //if (!m_benchPDGCode)
122  // m_benchPDGCode = new PMonUtils::CustomBenchmark(ISF::fMaxBenchmarkPDGCode);
123  //if (!m_benchGeoID)
124  // m_benchGeoID = new PMonUtils::CustomBenchmark(AtlasDetDescr::fNumAtlasRegions );
125  if (!m_benchSimID)
127  }
128 
129  // retrieve the stack service
130  ATH_CHECK ( m_particleBroker.retrieve() );
131  ATH_MSG_INFO( "- ParticleBroker : " << m_particleBroker.typeAndName() );
132 
133  // the truth service
134  ATH_CHECK ( m_truthRecordSvc.retrieve() );
135  ATH_MSG_INFO( "- TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
136 
137  // initialize all SimulationServices
138  //
139  for ( short geoID=AtlasDetDescr::fFirstAtlasRegion; geoID<AtlasDetDescr::fNumAtlasRegions ; ++geoID) {
140  ATH_CHECK ( initSimSvcs(m_simSelectors[geoID]) );
141  }
142 
143  ATH_CHECK( m_inputConverter.retrieve() );
144  if ( not m_truthPreselectionTool.empty() ) {
145  ATH_CHECK(m_truthPreselectionTool.retrieve());
146  }
147 
148  if(!m_qspatcher.empty()) {
149  ATH_CHECK(m_qspatcher.retrieve());
150  }
151 
152  // initialize all the EventFilterTools
153  ATH_CHECK ( m_eventFilters.retrieve() );
154  ATH_MSG_INFO( "The following Event Filters are defined:");
155  ATH_MSG_INFO( m_eventFilters );
156 
157  // free unused space
158  m_simSvcs.resize( m_numSimSvcs);
159  m_simSvcNames.resize( m_numSimSvcs);
160  // some screen output
161  ATH_MSG_INFO ( "The following SimulationSvc are registered to ISF:");
162  for (SimSvcID id=ISF::fFirstAtlasSimID; id<m_numSimSvcs; id++)
163  ATH_MSG_INFO ( "ID: " << id << "\t Name: '" << m_simSvcNames[id]
164  << "'");
165 
166  // setup the simulation selectors
167  //
168  for ( short geoID=AtlasDetDescr::fFirstAtlasRegion; geoID<AtlasDetDescr::fNumAtlasRegions ; ++geoID) {
169  ATH_CHECK ( m_particleBroker->registerSimSelector( m_simSelectors[geoID], (AtlasDetDescr::AtlasRegion)geoID) );
170  }
171  // screen output
172  ATH_MSG_INFO( "The following routing chains are defined:");
173  for ( short geoID = 0; geoID<AtlasDetDescr::fNumAtlasRegions ; ++geoID) {
175  << " (GeoID=" << geoID << "): \t" << m_simSelectors[geoID]);
176  }
177 
178  // record current memory usage
179  if (m_doMemMon) m_memMon->recordCurrent("at end of ISF SimKernel initialize()");
180 
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() ) );
185 
186  // intialziation successful
187  return StatusCode::SUCCESS;
188 }
189 
190 
192 {
193  ATH_MSG_INFO ( "Finalizing ..." );
194 
195  // record current memory usage
196  if (m_doMemMon) m_memMon->recordCurrent("at beginning of ISF SimKernel finalize()");
197 
198  // statistics: number of particles handled
199  ATH_MSG_INFO(" Number of particles handled by the ISF SimKernel: " << m_numParticles );
200 
201  ATH_MSG_INFO(" ========================= ISF Timing Stats =========================");
202  // Benchmarking: by SimID
203  if (m_benchSimID) {
204  ATH_MSG_INFO("Breakdown of simulation loop by SimulatorID:");
205  //TODO: for (unsigned simID=0;simID<m_benchSimID->size();++simID) {
206  for (unsigned simID=0;simID<ISF::fMaxNumAtlasSimIDs;++simID) {
207  uint64_t count;
208  double time_ms;
209  m_benchSimID->getData(simID, count, time_ms);
210  if (count>0)
211  ATH_MSG_INFO(" "<<std::setprecision(4)
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) );
215  }
216 
217  delete m_benchSimID;
218  m_benchSimID=0;
219  }
220 
221  //TODO: implement this if feasible
222  // Benchmarking: by GeoID
223  //if (m_benchGeoID) {
224  // ATH_MSG_INFO("Breakdown of simulation loop by GeoID:");
225  // //TODO: for (unsigned geoID=0;geoID<m_benchGeoID->size();++simID) {
226  // for (unsigned geoID=AtlasDetDescr::fFirstAtlasRegion;geoID<AtlasDetDescr::fNumAtlasRegions;++geoID) {
227  // uint64_t count;
228  // double time_ms;
229  // m_benchGeoID->getData(geoID, count, time_ms);
230  // if (count>0)
231  // ATH_MSG_INFO(" "<<std::setprecision(4)
232  // <<AtlasDetDescr::AtlasRegionHelper::getName(geoID)<<" (id="<<geoID<<")"
233  // <<"\t\tn="<<count<<"\t\tt=" <<time_ms<<" ms\t\tt/n="<<time_ms/count<<" ms"
234  // <<std::setprecision(-1) );
235  // }
236 
237  // delete m_benchGeoID;
238  // m_benchGeoID=0;
239  //}
240 
241  //TODO: implement this if feasible
242  // Benchmarking: by PDGCode
243  //if (m_benchPDGCode) {
244  // ATH_MSG_INFO("Breakdown of simulation loop by PDG Particle Code:");
245  // //TODO: for (unsigned geoID=0;geoID<m_benchGeoID->size();++simID) {
246  // for (int pdgCode=ISF::fUndefinedPDGCode;pdgCode<ISF::fMaxBenchmarkPDGCode;++pdgCode) {
247  // uint64_t count;
248  // double time_ms;
249  // m_benchPDGCode->getData(pdgCode, count, time_ms);
250  // if (count>0)
251  // ATH_MSG_INFO( std::setprecision(4)
252  // << " |PDGCode|="<<pdgCode<<", n="
253  // <<count<<", t="<<time_ms<<" ms, t/n="<<time_ms/count<<" ms"
254  // <<std::setprecision(-1) );
255  // }
256 
257  // delete m_benchPDGCode;
258  // m_benchPDGCode=0;
259  //}
260 
261  // call the memory monitoring tool to print some memory stats
262  if (m_doMemMon) {
263  ATH_MSG_INFO(" ====================== ISF Memory Usage Stats =======================");
264  m_memMon->dumpSummary("end of ISF event");
265  }
266 
267  ATH_MSG_INFO(" =====================================================================");
268 
269  return StatusCode::SUCCESS;
270 }
271 
272 
274 {
275  // (1.) retrieve all SimulationSelector tools in the array
276  if ( simSelectorTools.retrieve().isFailure() ) {
277  ATH_MSG_FATAL( "Could not retrieve SimulatorSelector Tool Array. Abort." );
278  return StatusCode::FAILURE;
279  }
280 
281  // (2.) loop over SimulationSelector tool array and retrieve simulators
282  SimSelectorToolArray::iterator fSimSelectorIter = simSelectorTools.begin();
283  SimSelectorToolArray::iterator fSimSelectorIterEnd = simSelectorTools.end();
284  for ( ; fSimSelectorIter != fSimSelectorIterEnd; ++fSimSelectorIter ) {
285 
286  // take the simulator from the current SimulationSelector
287  ServiceHandle<ISimulationSvc> *curSimulator = (*fSimSelectorIter)->simulator();
288 
289  if ( (*curSimulator).retrieve().isFailure() ){
290  ATH_MSG_FATAL( "Could not retrieve SimulatorSelector Tool. Abort." );
291  return StatusCode::FAILURE;
292  } else
293  ATH_MSG_INFO( "- SimulationSelector : " << fSimSelectorIter->typeAndName() );
294 
295  // hand over particle broker to simulator
296  if ( (*curSimulator)->setParticleBroker( &*m_particleBroker).isFailure() ){
297  ATH_MSG_FATAL( "Unable to register ParticleService to SimulationService "
298  << *curSimulator );
299  return StatusCode::FAILURE;
300  }
301 
302  // get the unique ID assigned to the Simulation Service
303  SimSvcID curID = (*curSimulator)->simSvcID();
304  // if no ID assigned yet -> new simulator
305  if ( curID == ISF::fUndefinedSimID) {
306  // assign a new new ID to the simulator
307  (*curSimulator)->assignSimSvcID( m_numSimSvcs);
308  // register current simulator to the simulatorArray
309  m_simSvcs[m_numSimSvcs] = (&**curSimulator);
310  m_simSvcNames[m_numSimSvcs] = (*curSimulator)->simSvcDescriptor();
311  ATH_MSG_DEBUG( "Assigned SimSvcID=" << m_numSimSvcs
312  << " to simulator '" << m_simSvcNames[m_numSimSvcs]
313  << "'");
314  // increment the total number of simulators registered (=used as IDs)
315  ++m_numSimSvcs;
316  }
317 
318  } // loop over simulation Selectors
319 
320 
321  return StatusCode::SUCCESS;
322 }
323 
324 
326 {
327 
328  ATH_MSG_DEBUG ("Executing ...");
329 
330  // dump and record current memory stats
331  if ( m_doMemMon && (m_numISFEvents==0) ) {
332  m_memMon->dumpCurrent( "before 1st event", false );
333  m_memMon->recordCurrent("before 1st event");
334  }
335 
336  // read and convert input
337  // a. hard-scatter
338  ISFParticleContainer simParticles{}; // particles for ISF simulation
339  std::unique_ptr<McEventCollection> shadowTruth{};
340  std::unique_ptr<McEventCollection> shadowPileUpTruth{};
341  ATH_CHECK( prepareInput(m_inputHardScatterEvgen, m_outputHardScatterTruth, shadowTruth, simParticles) );
342  // b. pileup
343  if (!m_inputPileupEvgen.key().empty()) {
344  ATH_CHECK( prepareInput(m_inputPileupEvgen, m_outputPileupTruth, shadowPileUpTruth, simParticles) );
345  }
346 
347  // -----------------------------------------------------------------------------------------------
348  // Step 1: Initialize the particle stack and the TruthManager, ABORT if failure
349  ATH_CHECK ( m_particleBroker->initializeEvent( std::move(simParticles) ) );
350 
351  const int largestGeneratedParticleBC = (m_outputHardScatterTruth->empty()) ? HepMC::UNDEFINED_ID
352  : HepMC::maxGeneratedParticleBarcode(m_outputHardScatterTruth->at(0)); // TODO make this more robust
353  const int largestGeneratedVertexBC = (m_outputHardScatterTruth->empty()) ? HepMC::UNDEFINED_ID
354  : HepMC::maxGeneratedVertexBarcode(m_outputHardScatterTruth->at(0)); // TODO make this more robust
355  // tell TruthService we're starting a new event
356  ATH_CHECK( m_truthRecordSvc->initializeTruthCollection(largestGeneratedParticleBC, largestGeneratedVertexBC) );
357  // -----------------------------------------------------------------------------------------------
358 
359 
360  // -----------------------------------------------------------------------------------------------
361  // Step 2: Initialize the Event
362  {
363  std::vector<ISimulationSvc*>::iterator fSimSvcIter = m_simSvcs.begin();
364  std::vector<ISimulationSvc*>::iterator fSimSvcIterEnd = m_simSvcs.end();
365  for ( ; fSimSvcIter != fSimSvcIterEnd; ++fSimSvcIter ){
366  ISimulationSvc *curSimSvc = (*fSimSvcIter);
367  // if simulation with current flavour is registered
368  // -> setupEvent
369  if ( curSimSvc){
370  if( curSimSvc->setupEvent().isFailure() ) {
371  ATH_MSG_WARNING( "Event setup failed for "
372  << curSimSvc->simSvcDescriptor() );
373  } else {
374  ATH_MSG_DEBUG ( "Event setup done for "
375  << curSimSvc->simSvcDescriptor() );
376  }
377  }
378  }
379  }
380  // -----------------------------------------------------------------------------------------------
381 
382 
383 
384  // -----------------------------------------------------------------------------------------------
385  // Step 3: ISimulation KERNEL : loop over particle stack, until empty
386  unsigned int loopCounter{0};
387  ATH_MSG_DEBUG( "Starting simulation loop, initial particle stack size: " << m_particleBroker->numParticles());
388  while ( m_particleBroker->numParticles() ) {
389  ++loopCounter;
390  ATH_MSG_VERBOSE("Main Loop pass no. " << loopCounter);
391  ATH_MSG_VERBOSE("Queue starts with " << m_particleBroker->numParticles() << " particles.");
392  // get next vector of particles for simulation
393  const ISF::ISFParticleVector &particles = m_particleBroker->popVector(m_maxParticleVectorSize);
394  const unsigned int numParticlesLeftInBroker = m_particleBroker->numParticles();
395  int numParticles = particles.size();
396 
397  // particle vector empty -> end simulation
398  if (numParticles==0) break;
399 
400  // for job statistics
401  m_numParticles += numParticles;
402 
403  // retrieve the particle destination simulator (and geoID)
404  const ISFParticle *firstP = particles.front();
405  ISF::SimSvcID simID = firstP->nextSimID();
406  //AtlasDetDescr::AtlasRegion geoID = firstP->nextGeoID();
407 
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 << ")" );
410 
411  #ifdef ISFDEBUG
412  if (loopCounter>100 && numParticles<3) {
413  ATH_MSG_INFO("Main Loop pass no. " << loopCounter);
414  ATH_MSG_INFO("Selected " << numParticles << " particles to be processed by " << m_simSvcNames[simID]);
415  for ( const ISFParticle *particle : particles ) {
417  }
418  }
419  #endif // ISFDEBUG
420 
421  // ensure that all particles in the vector have the same SimID
422  for ( const ISFParticle *particle : particles ) {
423  if ( particle->nextSimID() != simID ) {
424  ATH_MSG_WARNING( "Particle with SimID " << particle->nextSimID() << " found in vector with expected ID " << simID );
425  }
426  }
427 
428  // block defines scope for Benchmarks
429  // -> benchmarks will be stared/stopped automatically via the CustomBenchmarkGuard
430  // constructor and destructor, respectively
431  {
432  // setup sim svc benchmarks
433  PMonUtils::CustomBenchmarkGuard benchSimID( m_benchSimID , simID , numParticles );
434 
435  // ===> simulate particle
436  // NB Passing only the hard-scatter McEventCollection is not
437  // correct if Geant4 simulation were to be used for pile-up Hits
438  // in Fast Chain.
439  ATH_MSG_VERBOSE("Selected " << particles.size() << " particles to be processed by " << m_simSvcNames[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]);
442  }
443  ATH_MSG_VERBOSE(m_simSvcNames[simID] << " returned " << m_particleBroker->numParticles()-numParticlesLeftInBroker << " new particles to be added to the queue." );
444  }
445 
446  }
447  ATH_MSG_VERBOSE("Final status: queue contains " << m_particleBroker->numParticles() << " particles.");
448  // -----------------------------------------------------------------------------------------------
449 
450 
451 
452  // Step 4: Finalize the Event
453  // -> stack service
454  if ( m_particleBroker->finalizeEvent().isFailure()) {
455  ATH_MSG_WARNING( "ParticleBroker returned with an error in event finalization." );
456  }
457  // -> simulator services
458  {
459  std::vector<ISimulationSvc*>::iterator fSimSvcIter = m_simSvcs.begin();
460  std::vector<ISimulationSvc*>::iterator fSimSvcIterEnd = m_simSvcs.end();
461  for ( ; fSimSvcIter != fSimSvcIterEnd; ++fSimSvcIter ){
462  ISimulationSvc *curSimSvc = (*fSimSvcIter);
463  // if simulation with current flavour is registered
464  // -> releaseEvent()
465  if ( curSimSvc){
466  if( curSimSvc->releaseEvent().isFailure() ) {
467  ATH_MSG_WARNING( "Event release failed for "
468  << curSimSvc->simSvcDescriptor() );
469  } else {
470  ATH_MSG_DEBUG ( "Event release done for "
471  << curSimSvc->simSvcDescriptor() );
472  }
473  }
474  } // -> loop over SimSvcs
475  }
476 
477  if ( m_truthRecordSvc->releaseEvent().isFailure() ){
478  ATH_MSG_FATAL( "Event finalize failed for TruthService. Abort." );
479  return StatusCode::FAILURE;
480  }
481 
482  // Step 4a: Remove QS patch if required
483  if(!m_qspatcher.empty()) {
484  for (HepMC::GenEvent* currentGenEvent : *m_outputHardScatterTruth ) {
485  ATH_CHECK(m_qspatcher->removeWorkaround(*currentGenEvent));
486  }
487  }
488 
489  // Step 5: Check Any Filters
490  ToolHandleArray<IEventFilterTool>::iterator eventFilter(m_eventFilters.begin());
491  const ToolHandleArray<IEventFilterTool>::iterator endOfEventFilters(m_eventFilters.end());
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.");
496  break;
497  }
498  ++eventFilter;
499  }
500 
501 
502  // -----------------------------------------------------------------------------------------------
503 
504  // dump current memory monitoring information
505  if (m_doMemMon) {
506  std::string evtStr = std::to_string( m_numISFEvents );
507  std::string descr("after event " + evtStr);
508  m_memMon->dumpCurrent( descr.c_str(), true);
509 
510  // ISF internal event counting
511  m_numISFEvents++;
512 
513  // memory monitoring records for the final summary
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");
519  }
520 
521  return StatusCode::SUCCESS;
522 }
523 
524 
529  std::unique_ptr<McEventCollection>& shadowTruth,
530  ISFParticleContainer& simParticles) const {
531 
532  if (!inputTruth.isValid()) {
533  ATH_MSG_FATAL("Unable to read input GenEvent collection '" << inputTruth.key() << "'");
534  return StatusCode::FAILURE;
535  }
536 
537  if (m_useShadowEvent) {
538  outputTruth = std::make_unique<McEventCollection>();
539  // copy input Evgen collection to shadow Truth collection
540  shadowTruth = std::make_unique<McEventCollection>(*inputTruth);
541  for (HepMC::GenEvent* currentGenEvent : *shadowTruth ) {
542  // Apply QS patch if required
543  if ( not m_qspatcher.empty() ) {
544  ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
545  }
546  // Copy GenEvent and remove daughters of quasi-stable particles to be simulated
547  std::unique_ptr<HepMC::GenEvent> outputEvent = m_truthPreselectionTool->filterGenEvent(*currentGenEvent);
548  outputTruth->push_back(outputEvent.release());
549  }
550  }
551  else {
552  // copy input Evgen collection to output Truth collection
553  outputTruth = std::make_unique<McEventCollection>(*inputTruth);
554 
555  // Apply QS patch if required
556  if(!m_qspatcher.empty()) {
557  for (HepMC::GenEvent* currentGenEvent : *outputTruth ) {
558  ATH_CHECK(m_qspatcher->applyWorkaround(*currentGenEvent));
559  }
560  }
561  }
562  ATH_CHECK( m_inputConverter->convert(*outputTruth, simParticles) );
563 
564  return StatusCode::SUCCESS;
565 }
ISF::SimKernel::m_qspatcher
ServiceHandle< Simulation::IZeroLifetimePatcher > m_qspatcher
Quasi-Stable Particle Simulation Patcher.
Definition: SimKernel.h:115
ISF::ISFParticleContainer
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
Definition: ISFParticleContainer.h:23
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
AtlasDetDescr::fNumAtlasRegions
@ fNumAtlasRegions
Definition: AtlasRegion.h:39
ISF::SimKernel::m_outputPileupTruth
SG::WriteHandle< McEventCollection > m_outputPileupTruth
output pileup truth collection
Definition: SimKernel.h:99
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
ISF::SimKernel::m_truthRecordSvc
ServiceHandle< ITruthSvc > m_truthRecordSvc
Central truth service.
Definition: SimKernel.h:109
AtlasDetDescr::fAtlasForward
@ fAtlasForward
Definition: AtlasRegion.h:34
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ISF::ISimulationSvc::simSvcDescriptor
virtual const std::string & simSvcDescriptor()=0
Return the simulation service descriptor.
SG::ReadHandle< McEventCollection >
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
ISF::SimKernel::SimKernel
SimKernel(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters.
Definition: SimKernel.cxx:35
AtlasDetDescr::AtlasRegion
AtlasRegion
Definition: AtlasRegion.h:27
IParticleBroker.h
SimKernel.h
ISF::SimKernel::m_doCPUMon
bool m_doCPUMon
CPU Benchmarking.
Definition: SimKernel.h:134
ISF::ISFParticle
Definition: ISFParticle.h:42
HepMC::maxGeneratedVertexBarcode
int maxGeneratedVertexBarcode(const HepMC::GenEvent *genEvent)
Get the maximal absolute value of barcode of vertex present in the event. Returns a negative number.
Definition: MagicNumbers.h:445
ISF::SimKernel::execute
StatusCode execute()
Athena algorithm's interface method execute()
Definition: SimKernel.cxx:325
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ISF::SimKernel::m_inputHardScatterEvgen
SG::ReadHandle< McEventCollection > m_inputHardScatterEvgen
Input/output truth collections and input conversion.
Definition: SimKernel.h:96
AtlasDetDescr::AtlasRegionHelper::getName
static const char * getName(int region)
Definition: AtlasRegionHelper.cxx:13
ISF::SimSelectorToolArray
ToolHandleArray< ISimulationSelector > SimSelectorToolArray
typedef for better readable code
Definition: ISimulationSelector.h:76
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
ISF::SimKernel::m_simSelectors
ToolHandleArray< ISimulationSelector > m_simSelectors[AtlasDetDescr::fNumAtlasRegions]
The Simulation Selector Chains.
Definition: SimKernel.h:112
IEventFilterTool.h
ISFParticle.h
ISF::SimKernel::m_memUsageEvts
unsigned int m_memUsageEvts
Definition: SimKernel.h:123
AtlasDetDescr::fAtlasMS
@ fAtlasMS
Definition: AtlasRegion.h:36
McEventCollection.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
CustomBenchmark.h
IMonitoringTool.h
ISF::ISimulationSvc
@ class ISimulationSvc
Definition: ISimulationSvc.h:37
ISF::ISimulationSvc::releaseEvent
virtual StatusCode releaseEvent()=0
Release Event chain - in case of an end-of event action is needed, to be called by simulation kernel
ISF::ISFParticleVector
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.
Definition: ISFParticleContainer.h:26
AtlasRegionHelper.h
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
python.TransformConfig.descr
descr
print "%s.properties()" % self.__name__
Definition: TransformConfig.py:360
ISF::SimKernel::finalize
StatusCode finalize()
Athena algorithm's interface method finalize()
Definition: SimKernel.cxx:191
PMonUtils::CustomBenchmarkGuard
Definition: CustomBenchmark.h:118
ISF::SimKernel::prepareInput
StatusCode prepareInput(SG::ReadHandle< McEventCollection > &inputTruth, SG::WriteHandle< McEventCollection > &outputTruth, std::unique_ptr< McEventCollection > &shadowTruth, ISFParticleContainer &simParticles) const
Convert input generator particles to ISFParticles and copy input generator truth collection into outp...
Definition: SimKernel.cxx:527
AthAlgorithm
Definition: AthAlgorithm.h:47
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
HepMC::UNDEFINED_ID
constexpr int UNDEFINED_ID
Definition: MagicNumbers.h:56
ISF::SimKernel::m_inputPileupEvgen
SG::ReadHandle< McEventCollection > m_inputPileupEvgen
input pileup collection
Definition: SimKernel.h:97
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
AtlasDetDescr::fAtlasCavern
@ fAtlasCavern
Definition: AtlasRegion.h:37
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
ISF::SimKernel::initialize
StatusCode initialize()
Athena algorithm's interface method initialize()
Definition: SimKernel.cxx:103
AtlasDetDescr::fAtlasID
@ fAtlasID
Definition: AtlasRegion.h:33
ISF::SimKernel::m_memMon
ToolHandle< IMonitoringTool > m_memMon
Definition: SimKernel.h:122
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::VarHandleBase::key
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:64
AtlasDetDescr::fAtlasCalo
@ fAtlasCalo
Definition: AtlasRegion.h:35
SG::WriteHandle< McEventCollection >
ISF::SimKernel::~SimKernel
virtual ~SimKernel()
Destructor.
Definition: SimKernel.cxx:98
ISF::ISFParticle::nextSimID
SimSvcID nextSimID() const
the next simulation service the particle will be sent to
HepMC::maxGeneratedParticleBarcode
int maxGeneratedParticleBarcode(const HepMC::GenEvent *genEvent)
Get the maximal value of barcode of particle present in the event.
Definition: MagicNumbers.h:428
ISF::SimSvcID
uint8_t SimSvcID
Simulation service ID datatype.
Definition: SimSvcID.h:28
ISF
ISFParticleOrderedQueue.
Definition: PrimaryParticleInformation.h:13
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LArG4FSStartPointFilter.particles
list particles
Definition: LArG4FSStartPointFilter.py:84
ISF::SimKernel::m_maxParticleVectorSize
size_t m_maxParticleVectorSize
tuning
Definition: SimKernel.h:143
ISimulationSvc.h
ISF::SimKernel::m_outputHardScatterTruth
SG::WriteHandle< McEventCollection > m_outputHardScatterTruth
output hard scatter truth collection
Definition: SimKernel.h:98
ISF::ISimulationSvc::setupEvent
virtual StatusCode setupEvent()=0
Setup Event chain - in case of a begin-of event action is needed, to be called by simulation kernel.
ISF::SimKernel::m_eventFilters
ToolHandleArray< IEventFilterTool > m_eventFilters
The Event Filters.
Definition: SimKernel.h:118
ISF::SimKernel::m_particleBroker
ServiceHandle< IParticleBroker > m_particleBroker
Central particle broker service.
Definition: SimKernel.h:107
ITruthSvc.h
ISF::SimKernel::m_inputConverter
ServiceHandle< IInputConverter > m_inputConverter
input->ISFParticle converter
Definition: SimKernel.h:100
ISF::SimKernel::initSimSvcs
StatusCode initSimSvcs(SimSelectorToolArray &simSelectorTools)
Definition: SimKernel.cxx:273
ISF::fUndefinedSimID
@ fUndefinedSimID
Definition: SimSvcID.h:32
ISF::fMaxNumAtlasSimIDs
@ fMaxNumAtlasSimIDs
Definition: SimSvcID.h:39
ISF::SimKernel::m_doMemMon
bool m_doMemMon
The Memory Info Tool.
Definition: SimKernel.h:121
AtlasDetDescr::fFirstAtlasRegion
@ fFirstAtlasRegion
Definition: AtlasRegion.h:31
PMonUtils::CustomBenchmark
Definition: CustomBenchmark.h:30
ISF::fFirstAtlasSimID
@ fFirstAtlasSimID
Definition: SimSvcID.h:36
ServiceHandle
Definition: ClusterMakerTool.h:37