12 #include "GaudiKernel/PhysicalConstants.h" 
   13 using namespace Gaudi::Units;
 
   28       return std::make_pair(separator_hack, 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);
 
   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;
 
  153   while (timedTruthListIter != endOfTimedTruthList) {
 
  156     if (!
processEvent(pBackgroundMcEvtColl, currentPileUpTimeEventIndex.
time(), currentPileUpTimeEventIndex.
index(), 
static_cast<int>(currentPileUpTimeEventIndex.
type())).isSuccess()) {
 
  158       return StatusCode::FAILURE;
 
  160     ++timedTruthListIter;
 
  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 ( 
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
 
  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 ( 
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
 
  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()));
 
  365       m_pOvrlMcEvColl->at(0)->set_heavy_ion(*(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()));         
 
  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) {
 
  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());
 
  551         const double kineticEnergy(pCurrentVertexParticle->momentum().e() - 
mass);
 
  553           particleClassification=
CAVERN;
 
  558   return particleClassification;
 
  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.");
 
  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;