ATLAS Offline Software
Loading...
Searching...
No Matches
SimpleMergeMcEventCollTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include <fstream>
11
13 const std::string& name,
14 const IInterface *parent) :
15 PileUpToolBase(type, name, parent)
16{
17}
18
20{
21 if(!m_pMergeSvc.empty())
22 {
23 ATH_CHECK(m_pMergeSvc.retrieve());
24 }
25 return StatusCode::SUCCESS;
26}
27
29StatusCode SimpleMergeMcEventCollTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
30{
31 ATH_MSG_VERBOSE ( "prepareEvent()" );
33 m_newevent = true;
34
35 //Check we are getting at least one event
36 m_nInputMcEventColls = nInputEvents;
37 if (0 == m_nInputMcEventColls)
38 {
39 ATH_MSG_ERROR("prepareEvent: TimedTruthList with key "
40 << m_truthCollInputKey << " is empty");
41 return StatusCode::RECOVERABLE;
42 }
43 ATH_MSG_DEBUG( "prepareEvent: there are " << m_nInputMcEventColls << " subevents in this event.");
44
46 return StatusCode::SUCCESS;
47}
48
50 SubEventIterator bSubEvents,
51 SubEventIterator eSubEvents)
52{
53 SubEventIterator iEvt(bSubEvents);
54 //loop over the McEventCollections (each one assumed to containing exactly one GenEvent) of the various input events
55 while (iEvt != eSubEvents)
56 {
57 StoreGateSvc& seStore(*iEvt->ptr()->evtStore());
58 const McEventCollection *pMEC(nullptr);
60 ATH_MSG_DEBUG ("processBunchXing: SubEvt McEventCollection from StoreGate " << seStore.name() );
64 }
66 pMEC,
68 iEvt->index(),
69 static_cast<int>(iEvt->time()),
70 static_cast<int>(iEvt->type())
71 ));
72 ++iEvt;
73 }
74 return StatusCode::SUCCESS;
75}
76
77StatusCode SimpleMergeMcEventCollTool::mergeEvent(const EventContext& /*ctx*/)
78{
79 ATH_MSG_DEBUG( "mergeEvent()" );
81 {
82 ATH_MSG_WARNING( "mergeEvent: Expected " << m_nInputMcEventColls << " subevents, but only saw " << m_nBkgEventsReadSoFar+1 << "! The job will probably crash now..." );
83 return StatusCode::FAILURE;
84 }
85 if(msgLvl(MSG::VERBOSE)) { this->printDetailsOfMergedMcEventCollection(m_outputMcEventCollection); }
86 return StatusCode::SUCCESS;
87}
88
90StatusCode SimpleMergeMcEventCollTool::processAllSubEvents(const EventContext& /*ctx*/)
91{
92 ATH_MSG_VERBOSE ( "processAllSubEvents()" );
93 SG::WriteHandle<McEventCollection> outputMcEventCollection(m_truthCollOutputKey.value());
94 ATH_CHECK(outputMcEventCollection.record(std::make_unique<McEventCollection>()));
95
96 //first get the list of McEventCollections
98 TimedTruthList truthList;
99 ATH_CHECK(m_pMergeSvc->retrieveSubEvtsData(m_truthCollInputKey.value(), truthList));
100
102 m_newevent = true;
103
104 //Check we are getting at least one event
105 m_nInputMcEventColls=truthList.size();
106 if (0 == m_nInputMcEventColls)
107 {
108 ATH_MSG_ERROR("TimedTruthList with key " << m_truthCollInputKey << " is empty.");
109 return StatusCode::RECOVERABLE;
110 }
111
112 ATH_MSG_DEBUG( "execute: there are " << m_nInputMcEventColls << " subevents in this event.");
113 //TODO can we make this into an auto for loop?
114 TimedTruthList::iterator timedTruthListIter(truthList.begin()), endOfTimedTruthList(truthList.end());
115 //loop over the McEventCollections (each one assumed to containing exactly one GenEvent) of the various input events
116 while (timedTruthListIter != endOfTimedTruthList)
117 {
118 const PileUpTimeEventIndex& currentPileUpTimeEventIndex(timedTruthListIter->first); //time() , type()
119 const McEventCollection *pBackgroundMcEvtColl(&*(timedTruthListIter->second));
121 pBackgroundMcEvtColl,
122 outputMcEventCollection.ptr(),
123 currentPileUpTimeEventIndex.index(),
124 static_cast<int>(currentPileUpTimeEventIndex.time()),
125 static_cast<int>(currentPileUpTimeEventIndex.type())
126 ));
127 ++timedTruthListIter;
128 } //timed colls
129
130 if(msgLvl(MSG::VERBOSE)) { this->printDetailsOfMergedMcEventCollection(outputMcEventCollection.ptr()); }
131 return StatusCode::SUCCESS;
132}
133
135
136StatusCode SimpleMergeMcEventCollTool::saveHeavyIonInfo(const McEventCollection *pMcEvtColl, McEventCollection *outputMcEventCollection)
137{
138 if (outputMcEventCollection->at(0)->heavy_ion()) return StatusCode::SUCCESS;
139 if (pMcEvtColl->at(0)->heavy_ion())
140 {
141//It should be clarified if we want to get a copy or the content
142 HepMC::GenHeavyIonPtr hinew=std::make_shared<HepMC::GenHeavyIon>(*(pMcEvtColl->at(0)->heavy_ion()));
143 outputMcEventCollection->at(0)->set_heavy_ion(std::move(hinew));
144 }
145 return StatusCode::SUCCESS;
146}
147
148StatusCode SimpleMergeMcEventCollTool::processEvent(const McEventCollection *pMcEvtColl, McEventCollection *outputMcEventCollection, const int currentBkgEventIndex, int bunchCrossingTime, int pileupType)
149{
150 ATH_MSG_VERBOSE ( "processEvent() Event Type: " << pileupType << ", BunchCrossingTime: " << bunchCrossingTime );
151 if (!outputMcEventCollection) {
152 ATH_MSG_ERROR( this->name()<<"::processEvent() was passed an null output McEventCollection pointer." );
153 return StatusCode::FAILURE;
154 }
155 if (!pMcEvtColl) {
156 ATH_MSG_ERROR( this->name()<<"::processEvent() was passed an null input McEventCollection pointer." );
157 return StatusCode::FAILURE;
158 }
159
160 if ( pMcEvtColl->empty() || (m_onlySaveSignalTruth && !m_newevent) ) {
162 return StatusCode::SUCCESS;
163 }
164
165 //GenEvt is there
166
167 const HepMC::GenEvent& currentBackgroundEvent(**(pMcEvtColl->begin()));
168 // FIXME no protection against multiple GenEvents having the same event number
169 HepMC::GenEvent* copiedEvent = new HepMC::GenEvent(currentBackgroundEvent);
171 copiedEvent->set_event_number(currentBkgEventIndex);
172 }
173 HepMC::fillBarcodesAttribute(copiedEvent);
174 copiedEvent->add_attribute(HepMCStr::BunchCrossingTime,std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime));
175 copiedEvent->add_attribute(HepMCStr::PileUpType,std::make_shared<HepMC3::IntAttribute>(pileupType));
176 outputMcEventCollection->push_back(copiedEvent);
177 ATH_CHECK(this->saveHeavyIonInfo(pMcEvtColl, outputMcEventCollection));
178 m_newevent = false;
180 return StatusCode::SUCCESS;
181}
182
184{
185 if (outputMcEventCollection->empty()) { return; }
186 DataVector<HepMC::GenEvent>::const_iterator outputEventItr(outputMcEventCollection->begin());
187 const DataVector<HepMC::GenEvent>::const_iterator endOfEvents(outputMcEventCollection->end());
188 ATH_MSG_INFO ( "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
189 ATH_MSG_INFO ( "Current OUTPUT GenEvent: " );
190 while(outputEventItr!=endOfEvents)
191 {
192 const int signal_process_id=HepMC::signal_process_id(*outputEventItr);
193 const int event_number((*outputEventItr)->event_number());
194 ATH_MSG_INFO ( "GenEvent #"<<event_number<<", signal_process_id="<<signal_process_id<</*", category="<<event->second<<*/", number of Vertices="<<(*outputEventItr)->vertices_size() );
195 char fname[80];
196 sprintf(fname,"%s.event%d.txt",m_truthCollInputKey.value().c_str(),event_number);
197 std::ofstream of(fname);
198 HepMC::Print::line(of,*(*outputEventItr)); // verbose output
199 of.close();
200 ++outputEventItr;
201 }
202 ATH_MSG_INFO ( "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
203 return;
204}
205
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
the preferred mechanism to access information from the different event stores in a pileup job.
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const T * at(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
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...
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
ServiceHandle< PileUpMergeSvc > m_pMergeSvc
virtual StatusCode initialize() override final
virtual StatusCode mergeEvent(const EventContext &ctx) override final
called at the end of the subevts loop.
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
return false if not interested in certain xing times (in ns) implemented by default in PileUpToolBase...
virtual StatusCode prepareEvent(const EventContext &ctx, unsigned int nInputEvents) override final
called before the subevts loop.
SimpleMergeMcEventCollTool(const std::string &type, const std::string &name, const IInterface *parent)
McEventCollection * m_outputMcEventCollection
StatusCode saveHeavyIonInfo(const McEventCollection *pMcEvtColl, McEventCollection *outputMcEventCollection)
Common methods.
StatusCode processEvent(const McEventCollection *pMcEvtColl, McEventCollection *outputMcEventCollection, const int currentBkgEventIndex, int bunchCrossingTime, int pileupType)
virtual StatusCode processBunchXing(int, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
called for each active bunch-crossing to process current SubEvents bunchXing is in ns
void printDetailsOfMergedMcEventCollection(McEventCollection *outputMcEventCollection) const
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
const std::string BunchCrossingTime
const std::string PileUpType
int signal_process_id(const GenEvent &evt)
Definition GenEvent.h:572
HepMC3::GenHeavyIonPtr GenHeavyIonPtr
Definition HeavyIon.h:11
void fillBarcodesAttribute(GenEvent *e)
Definition GenEvent.h:393
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39
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