12#include "GaudiKernel/PhysicalConstants.h"
13using namespace Gaudi::Units;
24 IndexKey makekey(
int signal_process_id,
int event_number,
int separator_hack=0) {
27 if(signal_process_id==0 && event_number==-1) {
28 return std::make_pair(separator_hack, event_number);
30 return std::make_pair(signal_process_id, event_number);
33 class GenEventSorter {
35 typedef std::map<IndexKey, int> PileUpBackgroundMap;
36 GenEventSorter(
const PileUpBackgroundMap& backgroundClassificationMap) : m_backgroundClassificationMap(backgroundClassificationMap) {}
40 const IndexKey key1(makekey(signal_process_id1, event_number1,separator_hack1));
41 const IndexKey key2(makekey(signal_process_id2, event_number2,separator_hack2));
42 const PileUpBackgroundMap::const_iterator event1=m_backgroundClassificationMap.find(key1);
43 const PileUpBackgroundMap::const_iterator event2=m_backgroundClassificationMap.find(key2);
44 if(event1==m_backgroundClassificationMap.end()) {
45 throw std::runtime_error(
"GenEventSorter::operator() : IndexKey 1 not found in backgroundClassificationMap");
47 if(event2==m_backgroundClassificationMap.end()) {
48 throw std::runtime_error(
"GenEventSorter::operator() : IndexKey 2 not found in backgroundClassificationMap");
52 if(event1->second==event2->second) {
53 if (is_separator(signal_process_id1, event_number1)) {
return true;}
54 if (is_separator(signal_process_id2, event_number2)) {
return false;}
56 if (signal_process_id1==signal_process_id2) {
57 return (event_number1<event_number2);
59 return (signal_process_id1<signal_process_id2);
61 return (event1->second<event2->second);
65 inline bool is_separator(
int signal_process_id,
int event_number)
const {
return (0==signal_process_id && -1==event_number); }
66 const PileUpBackgroundMap& m_backgroundClassificationMap;
71 const std::string& name,
72 const IInterface *parent) :
95 return StatusCode::SUCCESS;
107 <<
"prepareEvent: TimedTruthList with key "
110 return StatusCode::RECOVERABLE;
114 return StatusCode::SUCCESS;
121 ATH_MSG_FATAL (
"processAllSubEvents: Could not find PileUpMergeSvc" );
122 return StatusCode::FAILURE;
129 TimedTruthList truthList;
132 <<
"execute: Can not find TimedTruthList with key "
134 return StatusCode::RECOVERABLE;
144 <<
"execute: TimedTruthList with key "
147 return StatusCode::RECOVERABLE;
150 TimedTruthList::iterator timedTruthListIter(truthList.begin()), endOfTimedTruthList(truthList.end());
153 while (timedTruthListIter != endOfTimedTruthList) {
156 if (!
processEvent(pBackgroundMcEvtColl, currentPileUpTimeEventIndex.
time(), currentPileUpTimeEventIndex.
index(),
static_cast<int>(currentPileUpTimeEventIndex.
type())).isSuccess()) {
158 return StatusCode::FAILURE;
160 ++timedTruthListIter;
169 if(msgLvl(MSG::DEBUG)) {
176 ATH_MSG_FATAL(
"Signal GenEvent is not first in the list! Something has gone wrong during the GenEvent sorting!");
177 return StatusCode::FAILURE;
182 return StatusCode::SUCCESS;
192 while (iEvt != eSubEvents) {
195 bunchXing, iEvt).isSuccess()){
197 return StatusCode::FAILURE;
200 if (!
processEvent(pMEC,iEvt->time(),iEvt->index(),
static_cast<int>(iEvt->type())).isSuccess()) {
201 ATH_MSG_ERROR (
"processBunchXing: Failed to process McEventCollection." );
202 return StatusCode::FAILURE;
206 return StatusCode::SUCCESS;
213 return StatusCode::FAILURE;
230 ATH_MSG_FATAL(
"Signal GenEvent is not first in the list! Something has gone wrong during the GenEvent sorting!");
231 return StatusCode::FAILURE;
236 return StatusCode::SUCCESS;
240 ATH_MSG_INFO (
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
245 const int signal_process_id(
HepMC::signal_process_id((*outputEventItr))), event_number((*outputEventItr)->event_number()), separator_hack(
HepMC::mpi((*outputEventItr)));
246 const IndexKey key(makekey(signal_process_id,event_number,separator_hack));
249 ATH_MSG_INFO (
"GenEvent #"<<event_number<<
", signal_process_id="<<signal_process_id<<
", category="<<event->second<<
", number of Vertices="<<(*outputEventItr)->vertices_size() );
252 ATH_MSG_INFO (
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
258 StatusCode
sc(StatusCode::FAILURE);
267 ATH_MSG_DEBUG(
"execute: copied original event McEventCollection" );
275 ATH_MSG_DEBUG (
"Total Size of Output McEventCollection = " << outCollSize );
288 unsigned int currentMcEventCollectionIndex(1);
292 currentMcEventCollectionIndex += 1;
296 ATH_MSG_DEBUG (
"Placing Separator for Type: "<<
type<<
" at Posistion: " << currentMcEventCollectionIndex-1 );
308 if (currentBackgroundEvent->particles().size()!=1)
return false;
309 if (currentBackgroundEvent->particles().at(0)->pdg_id()==999)
return true;
319 return StatusCode::SUCCESS;
328 return StatusCode::SUCCESS;
331 ATH_MSG_ERROR (
"Failed to process a Truth Filtered GenEvent.");
335 if (
processUnfilteredEvent(pMcEvtColl, currentEventTime, currentBkgEventIndex, pileupType).isSuccess() ) {
337 return StatusCode::SUCCESS;
345 return StatusCode::FAILURE;
351 if (pMcEvtColl->
at(0)->heavy_ion())
357 return StatusCode::SUCCESS;
362 ATH_MSG_VERBOSE (
"processTruthFilteredEvent(): Event Type: " << pileupType );
367 const int bunchCrossingTime=
static_cast<int>(currentEventTime);
369 currentBackgroundEvent.add_attribute(
HepMCStr::PileUpType,std::make_shared<HepMC3::IntAttribute>(pileupType));
371 currentBackgroundEvent.set_event_number(currentBkgEventIndex);
373 if ( std::abs(currentEventTime)<51.0 ) {
374 currentGenEventClassification = ( std::abs(currentEventTime)<1.0 ) ?
INTIME :
OUTOFTIME;
377 currentBackgroundEvent.event_number(),
378 0, currentGenEventClassification,
true);
379 return StatusCode::SUCCESS;
383 ATH_MSG_VERBOSE (
"processUnfilteredEvent() Event Type: " << pileupType );
393 const int bunchCrossingTime=
static_cast<int>(currentEventTime);
397 evt->set_event_number(currentBkgEventIndex);
398 evt->add_vertex(pCopyOfGenVertex);
404 unsigned int nCollisionVerticesFound(0);
407 auto currentVertexIter = currentBackgroundEvent.vertices().begin();
408 auto endOfCurrentListOfVertices = currentBackgroundEvent.vertices().end();
409 for (; currentVertexIter != endOfCurrentListOfVertices; ++currentVertexIter) {
410 const auto& pCurrentVertex=*currentVertexIter;
415 bool isCollisionVertex(
false);
418 if(isCollisionVertex) ++nCollisionVerticesFound;
424 ATH_MSG_VERBOSE(
"Found a particle at location " << std::hex << currentVertexParticle << std::dec <<
" with PDG ID = " << currentVertexParticle->pdg_id() );
426 puType particleClassification(
classifyVertex(currentVertexParticle, pCurrentParticleProductionVertex,currentEventTime));
428 if(isCollisionVertex &&
NOPUTYPE==particleClassification) {
429 particleClassification=
INTIME;
433 if (!pCopyOfVertexForClassification[particleClassification]) {
434 pCopyOfVertexForClassification[particleClassification] =
HepMC::newGenVertexPtr(pCurrentVertex->position());
435 ATH_MSG_VERBOSE(
"Added bkg vertex " << pCopyOfVertexForClassification[particleClassification] <<
" at position " << pCopyOfVertexForClassification[particleClassification] <<
" for pu type = " << particleClassification );
437 pCopyOfVertexForClassification[particleClassification]->add_particle_out(std::make_shared<HepMC3::GenParticle>(currentVertexParticle->data()));
438 ATH_MSG_VERBOSE(
"Added bkg particle at location " << std::hex << currentVertexParticle << std::dec <<
" with PDG ID = " << currentVertexParticle->pdg_id() );
443 for (
const auto& currentVertexParticle: pCurrentVertex->particles_in()) {
444 pCopyOfVertexForClassification[
INTIME]->add_particle_in (std::make_shared<HepMC3::GenParticle>(currentVertexParticle->data()));
449 if (!pCopyOfVertexForClassification[
type])
continue;
450 int n_particles_out=pCopyOfVertexForClassification[
type]->particles_out_size();
457 return StatusCode::SUCCESS;
462 for (
const auto& pCurrentVertexParticle: pCurrentVertex->particles_in()) {
463 if (
MC::isBeam(pCurrentVertexParticle))
return true;
473 if ( pCurrentParticleProductionVertex ) {
477 if ( std::abs(pCurrentParticleProductionVertex->position().z()) <
m_zRange ) {
478 const float xi((pCurrentParticleProductionVertex->position()).x());
479 const float yi((pCurrentParticleProductionVertex->position()).y());
481 const double eta(pCurrentVertexParticle->momentum().pseudoRapidity());
484 if ( currentEventIsInTime ) {
486 if ( 0.0==currentEventTime ) {
487 particleClassification=
INTIME;
504 double mass(pCurrentVertexParticle->momentum().m());
505 if ( mass < 0.0 ) { mass = 0.0; }
506 const double kineticEnergy(pCurrentVertexParticle->momentum().e() - mass);
508 particleClassification=
CAVERN;
513 return particleClassification;
517 int currentClassification=int(
INTIME);
521 const int signal_process_id(
HepMC::signal_process_id((*outputEventItr))),event_number((*outputEventItr)->event_number());
523 if(signal_process_id==0 && event_number==-1) {
525 ++currentClassification;
528 if((*outputEventItr)->vertices_empty()) {
531 ATH_MSG_VERBOSE(
"compressOutputMcEventCollection() Removed Empty GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << currentClassification);
537 return StatusCode::SUCCESS;
543 ATH_MSG_ERROR(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification );
548 ATH_MSG_ERROR(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification );
549 ATH_MSG_FATAL (
"Should only ever be one signal event in the background classification map! Bailing out.");
552 IndexKey key(makekey(signal_process_id,event_number));
554 if(signal_process_id==0 && event_number==-1) {
555 key=makekey(separator_hack,event_number);
557 ATH_MSG_VERBOSE(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification <<
", key = " << key);
560 if(firstUpdateForThisEvent) {
561 ATH_MSG_ERROR(
"updateClassidificationMap: Repeated KEY! "<< key <<
". Previous category = " << event->second );
564 ATH_MSG_DEBUG(
"updateClassidificationMap: Updating category for existing key "<< key <<
". Previous category = " << event->second <<
", new category = " << classification );
567 if(event->second<=classification)
return;
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
ATLAS-specific HepMC functions.
the preferred mechanism to access information from the different event stores in a pileup job.
const T * at(size_type n) const
Access an element, as an rvalue.
DataModel_detail::iterator< DataVector > iterator
Standard iterator.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
bool empty() const noexcept
Returns true if the collection is empty.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
const std::string BunchCrossingTime
const std::string PileUpType
void set_mpi(GenEvent *e, const int i=0)
int signal_process_id(const GenEvent &evt)
HepMC3::GenHeavyIonPtr GenHeavyIonPtr
void set_signal_process_vertex(GenEvent *e, T &v)
void set_signal_process_id(GenEvent *e, const int i=0)
int mpi(const GenEvent &evt)
ConstGenVertexPtr signal_process_vertex(const GenEvent *e)
void fillBarcodesAttribute(GenEvent *e)
GenVertexPtr newGenVertexPtr(const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
HepMC3::GenVertexPtr GenVertexPtr
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
GenEvent * newGenEvent(const int signal_process_id, const int event_number)
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
HepMC3::GenEvent GenEvent
bool isBeam(const T &p)
Identify if the particle is beam particle.
double charge(const T &p)
bool isSimStable(const T &p)
Identify if the particle is considered stable at the post-detector-sim stage.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
index_type index() const
the index of the component event in PileUpEventInfo
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
time_type time() const
bunch xing time in ns