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) {}
37 bool operator() (
const HepMC::GenEvent *pGenEvent1,
const HepMC::GenEvent *pGenEvent2) {
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);
264 m_pOvrlMcEvColl->at(0)->add_attribute(
"BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(0));
265 m_pOvrlMcEvColl->at(0)->add_attribute(
"PileUpType",std::make_shared<HepMC3::IntAttribute>(0));
269 ATH_MSG_DEBUG(
"execute: copied original event McEventCollection" );
277 ATH_MSG_DEBUG (
"Total Size of Output McEventCollection = " << outCollSize );
290 unsigned int currentMcEventCollectionIndex(1);
294 currentMcEventCollectionIndex += 1;
298 ATH_MSG_DEBUG (
"Placing Separator for Type: "<<
type<<
" at Posistion: " << currentMcEventCollectionIndex-1 );
309 const HepMC::GenEvent* currentBackgroundEvent = *(pMcEvtColl->
begin());
311 if (currentBackgroundEvent->particles().size()!=1)
return false;
312 if (currentBackgroundEvent->particles().at(0)->pdg_id()==999)
return true;
314 if (currentBackgroundEvent->particles_size()!=1)
return false;
315 if ((*(currentBackgroundEvent->particles_begin()))->pdg_id()==999)
return true;
326 return StatusCode::SUCCESS;
335 return StatusCode::SUCCESS;
338 ATH_MSG_ERROR (
"Failed to process a Truth Filtered GenEvent.");
342 if (
processUnfilteredEvent(pMcEvtColl, currentEventTime, currentBkgEventIndex, pileupType).isSuccess() ) {
344 return StatusCode::SUCCESS;
352 return StatusCode::FAILURE;
358 if (pMcEvtColl->
at(0)->heavy_ion())
362 HepMC::GenHeavyIonPtr hinew=std::make_shared<HepMC::GenHeavyIon>(*(pMcEvtColl->
at(0)->heavy_ion()));
368 return StatusCode::SUCCESS;
373 ATH_MSG_VERBOSE (
"processTruthFilteredEvent(): Event Type: " << pileupType );
379 const int bunchCrossingTime=
static_cast<int>(currentEventTime);
380 currentBackgroundEvent.add_attribute(
"BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime));
381 currentBackgroundEvent.add_attribute(
"PileUpType",std::make_shared<HepMC3::IntAttribute>(pileupType));
384 currentBackgroundEvent.set_event_number(currentBkgEventIndex);
386 if ( std::abs(currentEventTime)<51.0 ) {
387 currentGenEventClassification = ( std::abs(currentEventTime)<1.0 ) ?
INTIME :
OUTOFTIME;
390 currentBackgroundEvent.event_number(),
391 0, currentGenEventClassification,
true);
392 return StatusCode::SUCCESS;
396 ATH_MSG_VERBOSE (
"processUnfilteredEvent() Event Type: " << pileupType );
398 const HepMC::GenEvent& currentBackgroundEvent(**(pMcEvtColl->
begin()));
406 HepMC::GenEvent* evt =
m_onlySaveSignalTruth ?
new HepMC::GenEvent() :
new HepMC::GenEvent(currentBackgroundEvent);
407 const int bunchCrossingTime=
static_cast<int>(currentEventTime);
408 evt->add_attribute(
"BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime));
409 evt->add_attribute(
"PileUpType",std::make_shared<HepMC3::IntAttribute>(pileupType));
411 evt->set_event_number(currentBkgEventIndex);
412 evt->add_vertex(pCopyOfGenVertex);
418 unsigned int nCollisionVerticesFound(0);
421 auto currentVertexIter = currentBackgroundEvent.vertices().begin();
422 auto endOfCurrentListOfVertices = currentBackgroundEvent.vertices().end();
424 if (
HepMC::signal_process_vertex(¤tBackgroundEvent) ) pCopyOfGenVertex =
new HepMC::GenVertex ( *currentBackgroundEvent.signal_process_vertex() );
429 unsigned int nCollisionVerticesFound(0);
432 auto currentVertexIter = currentBackgroundEvent.vertices_begin();
433 auto endOfCurrentListOfVertices = currentBackgroundEvent.vertices_end();
435 for (; currentVertexIter != endOfCurrentListOfVertices; ++currentVertexIter) {
436 const auto& pCurrentVertex=*currentVertexIter;
441 bool isCollisionVertex(
false);
444 if(isCollisionVertex) ++nCollisionVerticesFound;
450 ATH_MSG_VERBOSE(
"Found a particle at location " << std::hex << currentVertexParticle << std::dec <<
" with PDG ID = " << currentVertexParticle->pdg_id() );
452 puType particleClassification(
classifyVertex(currentVertexParticle, pCurrentParticleProductionVertex,currentEventTime));
454 if(isCollisionVertex &&
NOPUTYPE==particleClassification) {
455 particleClassification=
INTIME;
459 if (!pCopyOfVertexForClassification[particleClassification]) {
460 pCopyOfVertexForClassification[particleClassification] =
HepMC::newGenVertexPtr(pCurrentVertex->position());
461 ATH_MSG_VERBOSE(
"Added bkg vertex " << pCopyOfVertexForClassification[particleClassification] <<
" at position " << pCopyOfVertexForClassification[particleClassification] <<
" for pu type = " << particleClassification );
464 pCopyOfVertexForClassification[particleClassification]->add_particle_out(std::make_shared<HepMC3::GenParticle>(currentVertexParticle->data()));
466 pCopyOfVertexForClassification[particleClassification]->add_particle_out(
new HepMC::GenParticle(*currentVertexParticle) );
468 ATH_MSG_VERBOSE(
"Added bkg particle at location " << std::hex << currentVertexParticle << std::dec <<
" with PDG ID = " << currentVertexParticle->pdg_id() );
474 for (
const auto& currentVertexParticle: pCurrentVertex->particles_in()) {
475 pCopyOfVertexForClassification[
INTIME]->add_particle_in (std::make_shared<HepMC3::GenParticle>(currentVertexParticle->data()));
478 HepMC::GenVertex::particles_in_const_iterator currentVertexParticleIter(pCurrentVertex->particles_in_const_begin());
479 const HepMC::GenVertex::particles_in_const_iterator endOfListOfParticlesFromCurrentVertex(pCurrentVertex->particles_in_const_end());
480 for (; currentVertexParticleIter != endOfListOfParticlesFromCurrentVertex; ++currentVertexParticleIter) {
481 pCopyOfVertexForClassification[
INTIME]->add_particle_in (
new HepMC::GenParticle(**currentVertexParticleIter) );
487 if (!pCopyOfVertexForClassification[
type])
continue;
488 int n_particles_out=pCopyOfVertexForClassification[
type]->particles_out_size();
495 return StatusCode::SUCCESS;
501 for (
const auto& pCurrentVertexParticle: pCurrentVertex->particles_in()) {
503 auto currentVertexParticleIter = pCurrentVertex->particles_in_const_begin();
504 auto endOfListOfParticlesFromCurrentVertex = pCurrentVertex->particles_in_const_end();
505 for( ;currentVertexParticleIter != endOfListOfParticlesFromCurrentVertex; ++currentVertexParticleIter ) {
506 auto pCurrentVertexParticle = *currentVertexParticleIter;
508 if (
MC::isBeam(pCurrentVertexParticle))
return true;
518 if ( pCurrentParticleProductionVertex ) {
522 if ( std::abs(pCurrentParticleProductionVertex->position().z()) <
m_zRange ) {
523 const float xi((pCurrentParticleProductionVertex->position()).x());
524 const float yi((pCurrentParticleProductionVertex->position()).y());
526 const double eta(pCurrentVertexParticle->momentum().pseudoRapidity());
529 if ( currentEventIsInTime ) {
531 if ( 0.0==currentEventTime ) {
532 particleClassification=
INTIME;
549 double mass(pCurrentVertexParticle->momentum().m());
550 if ( mass < 0.0 ) { mass = 0.0; }
551 const double kineticEnergy(pCurrentVertexParticle->momentum().e() - mass);
553 particleClassification=
CAVERN;
558 return particleClassification;
562 int currentClassification=int(
INTIME);
566 const int signal_process_id(
HepMC::signal_process_id((*outputEventItr))),event_number((*outputEventItr)->event_number());
568 if(signal_process_id==0 && event_number==-1) {
570 ++currentClassification;
573 if((*outputEventItr)->vertices_empty()) {
576 ATH_MSG_VERBOSE(
"compressOutputMcEventCollection() Removed Empty GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << currentClassification);
582 return StatusCode::SUCCESS;
588 ATH_MSG_ERROR(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification );
593 ATH_MSG_ERROR(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification );
594 ATH_MSG_FATAL (
"Should only ever be one signal event in the background classification map! Bailing out.");
597 IndexKey key(makekey(signal_process_id,event_number));
599 if(signal_process_id==0 && event_number==-1) {
600 key=makekey(separator_hack,event_number);
602 ATH_MSG_VERBOSE(
"updateClassidificationMap: GenEvent #" << event_number <<
", signal_process_id(" << signal_process_id <<
"), category = " << classification <<
", key = " << key);
605 if(firstUpdateForThisEvent) {
606 ATH_MSG_ERROR(
"updateClassidificationMap: Repeated KEY! "<< key <<
". Previous category = " << event->second );
609 ATH_MSG_DEBUG(
"updateClassidificationMap: Updating category for existing key "<< key <<
". Previous category = " << event->second <<
", new category = " << classification );
612 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.
char data[hepevt_bytes_allocation_ATLAS]
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...
int signal_process_id(const GenEvent &e)
void set_mpi(GenEvent *e, const int i)
void set_signal_process_vertex(GenEvent *e, T v)
HepMC::GenVertex * GenVertexPtr
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
void set_signal_process_id(GenEvent *e, const int i)
void fillBarcodesAttribute(GenEvent *)
const GenParticle * ConstGenParticlePtr
GenVertex * signal_process_vertex(const GenEvent *e)
int mpi(const GenEvent &e)
const HepMC::GenVertex * ConstGenVertexPtr
GenEvent * newGenEvent(const int a, const int b)
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