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