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#ifdef HEPMC3
143 HepMC::GenHeavyIonPtr hinew=std::make_shared<HepMC::GenHeavyIon>(*(pMcEvtColl->at(0)->heavy_ion()));
144 outputMcEventCollection->at(0)->set_heavy_ion(std::move(hinew));
145#else
146 outputMcEventCollection->at(0)->set_heavy_ion(*(pMcEvtColl->at(0)->heavy_ion()));
147#endif
148 }
149 return StatusCode::SUCCESS;
150}
151
152StatusCode SimpleMergeMcEventCollTool::processEvent(const McEventCollection *pMcEvtColl, McEventCollection *outputMcEventCollection, const int currentBkgEventIndex, int bunchCrossingTime, int pileupType)
153{
154 ATH_MSG_VERBOSE ( "processEvent() Event Type: " << pileupType << ", BunchCrossingTime: " << bunchCrossingTime );
155 if (!outputMcEventCollection) {
156 ATH_MSG_ERROR( this->name()<<"::processEvent() was passed an null output McEventCollection pointer." );
157 return StatusCode::FAILURE;
158 }
159 if (!pMcEvtColl) {
160 ATH_MSG_ERROR( this->name()<<"::processEvent() was passed an null input McEventCollection pointer." );
161 return StatusCode::FAILURE;
162 }
163
164 if ( pMcEvtColl->empty() || (m_onlySaveSignalTruth && !m_newevent) ) {
166 return StatusCode::SUCCESS;
167 }
168
169 //GenEvt is there
170
171 const HepMC::GenEvent& currentBackgroundEvent(**(pMcEvtColl->begin()));
172 // FIXME no protection against multiple GenEvents having the same event number
173 HepMC::GenEvent* copiedEvent = new HepMC::GenEvent(currentBackgroundEvent);
175 copiedEvent->set_event_number(currentBkgEventIndex);
176 }
177 HepMC::fillBarcodesAttribute(copiedEvent);
178#ifdef HEPMC3
179 copiedEvent->add_attribute("BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime));
180 copiedEvent->add_attribute("PileUpType",std::make_shared<HepMC3::IntAttribute>(pileupType));
181#endif
182 outputMcEventCollection->push_back(copiedEvent);
183 ATH_CHECK(this->saveHeavyIonInfo(pMcEvtColl, outputMcEventCollection));
184 m_newevent = false;
186 return StatusCode::SUCCESS;
187}
188
190{
191 if (outputMcEventCollection->empty()) { return; }
192 DataVector<HepMC::GenEvent>::const_iterator outputEventItr(outputMcEventCollection->begin());
193 const DataVector<HepMC::GenEvent>::const_iterator endOfEvents(outputMcEventCollection->end());
194 ATH_MSG_INFO ( "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
195 ATH_MSG_INFO ( "Current OUTPUT GenEvent: " );
196 while(outputEventItr!=endOfEvents)
197 {
198 const int signal_process_id=HepMC::signal_process_id(*outputEventItr);
199 const int event_number((*outputEventItr)->event_number());
200 ATH_MSG_INFO ( "GenEvent #"<<event_number<<", signal_process_id="<<signal_process_id<</*", category="<<event->second<<*/", number of Vertices="<<(*outputEventItr)->vertices_size() );
201 char fname[80];
202 sprintf(fname,"%s.event%d.txt",m_truthCollInputKey.value().c_str(),event_number);
203 std::ofstream of(fname);
204 HepMC::Print::line(of,*(*outputEventItr)); // verbose output
205 of.close();
206 ++outputEventItr;
207 }
208 ATH_MSG_INFO ( "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" );
209 return;
210}
211
#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*.
void line(std::ostream &os, const GenEvent &e)
Definition GenEvent.h:678
int signal_process_id(const GenEvent &e)
Definition GenEvent.h:637
void fillBarcodesAttribute(GenEvent *)
Definition GenEvent.h:628
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