ATLAS Offline Software
Loading...
Searching...
No Matches
PileUpMergeSvc.icc
Go to the documentation of this file.
1/* -*- C++ -*- */
2
3/*
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5*/
6
7#include <algorithm> /* make_pair */
8#include <cassert>
9#include <string>
10
11#include "GaudiKernel/System.h"
12#include "GaudiKernel/StatusCode.h"
13#include "GaudiKernel/ThreadLocalContext.h"
14
15#include "AthenaKernel/ITriggerTime.h"
16#include "StoreGate/StoreGateSvc.h"
17#include "AthenaKernel/ClassID_traits.h"
18#include "AthenaBaseComps/AthMsgStreamMacros.h"
19
20namespace {
21 template <typename KEY>
22 std::string mkHSKey(const KEY& k) {
23 return "HS" + std::string(k);
24 }
25
26 template <class DATALINK, typename KEY>
27 void fillLink(DATALINK& l, const KEY& k, IProxyDict* sg = 0) {
28 l.toIdentifiedObject(k, sg);
29 if (!l.isValid()) {
30 l.toIdentifiedObject(mkHSKey(k), sg);
31 }
32 }
33
34 struct NoKey {};
35 //MsgStream& operator <<(MsgStream& os, const NoKey&) { os << "Default"; return os; }
36
37 template <class DATALINK>
38 void fillLink(DATALINK&, const NoKey&, IProxyDict*)
39 { /*leave it in default state*/ }
40
41 [[maybe_unused]] // suppress clang warning (false positive?)
42 PileUpTimeEventIndex::PileUpType getOldPileUpType(const xAOD::EventInfo_v1::PileUpType &newType) {
43 PileUpTimeEventIndex::PileUpType oldType = PileUpTimeEventIndex::Unknown;
44 switch(newType) {
45 case xAOD::EventInfo_v1::Signal :
46 oldType = PileUpTimeEventIndex::Signal;
47 break;
48 case xAOD::EventInfo_v1::MinimumBias:
49 oldType = PileUpTimeEventIndex::MinimumBias;
50 break;
51 case xAOD::EventInfo_v1::Cavern:
52 oldType = PileUpTimeEventIndex::Cavern;
53 break;
54 case xAOD::EventInfo_v1::HaloGas:
55 oldType = PileUpTimeEventIndex::HaloGas;
56 break;
57 case xAOD::EventInfo_v1::HighPtMinimumBias:
58 oldType = PileUpTimeEventIndex::HighPtMinimumBias;
59 break;
60 case xAOD::EventInfo_v1::ZeroBias:
61 oldType = PileUpTimeEventIndex::ZeroBias;
62 break;
63 default:
64 break;
65 }
66 return oldType;
67 }
68}
69
70///retrieve keyed DATA obj for the original event
71template <typename KEY, typename DATA>
72StatusCode
73PileUpMergeSvc::retrieveOriginal(const KEY& dataKey, const DATA*& data) {
74 StatusCode sc(StatusCode::FAILURE);
75 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
76 if (pEvent) {
77 // access the sub events DATA objects...
78 if( pEvent->subEvents().size() ) {
79 //here we assume that the original event is the first in pEvent list
80 sc = pEvent->subEvents()[0].ptr()->evtStore()->retrieve(data, dataKey);
81 if (!sc) {
82 sc = pEvent->subEvents()[0].ptr()->evtStore()->retrieve(data, mkHSKey(dataKey));
83 }
84 }
85 }
86 return sc;
87}
88
89/// retrieve keyed DATA objs for all sub-events and attach a time to them
90template <typename KEY, typename TIMEDDATA>
91StatusCode
92PileUpMergeSvc::retrieveSubEvtsData(const KEY &dataKey, // orig evt key
93 TIMEDDATA &timedData,
94 unsigned int &numberOfSimHits) {
95 numberOfSimHits = 0;
96 typedef typename TIMEDDATA::value_type value_type; // pair<time_t,DataLink..
97 typedef typename value_type::second_type DataLink_t;
98 typedef typename DataLink_t::value_type data_t;
99 // the tdefs above in practice check that TIMEDDATA is what we want
100 // FIXME we still have to check we are dealing with a sequence:
101 // boost::function_requires < boost::SequenceConcept<TIMEDDATA> > ();
102 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
103
104 ATH_MSG_DEBUG ( "retrieveSubEvtsData: object of type "
105 << System::typeinfoName(typeid(data_t)) << " with key "
106 << dataKey<< " ei="<<pEvent );
107
108 if (pEvent) {
109 if(pEvent->subEvents().size()==0) {
110 ATH_MSG_DEBUG ( "no subEvents for xAOD::EventInfo '"<<m_EventInfoKeyName<<"'" );
111
112 DataLink_t dLink;
113 fillLink(dLink, dataKey);
114 if (dLink.isValid()) {
115 timedData.push_back(std::make_pair(0, dLink));
116 }
117 return StatusCode::SUCCESS;
118 }
119 // access the sub events DATA objects...
120 for (const xAOD::EventInfo::SubEvent &subEv : pEvent->subEvents()) {
121 // skip if dobj not active for this xing
122 // FIXME if (!isLive<data_t>(dataKey, int(iEvt->time()))) {
123 // FIXME turning the double iEvt->time() is fraught with peril. Luckily
124 // FIXME it just works, but we should have the beam xing in iEvt
125 if (!isLive(ClassID_traits<data_t>::ID(), dataKey, int(subEv.time()))) {
126#ifndef NDEBUG
127 ATH_MSG_VERBOSE("retrieveSubEvtsData: object of type "
128 << System::typeinfoName(typeid(data_t)) << " with key "
129 << dataKey << " OUT OF XING RANGE: SKIPPING ");
130#endif
131 } else {
132 subEv.ptr()->evtStore()->makeCurrent();
133 StoreGateSvc *pSubEvtSG = subEv.ptr()->evtStore();
134 DataLink_t dLink;
135 fillLink(dLink, dataKey, pSubEvtSG);
136 double sigTime(0.0);
137 unsigned int evtIndex(0);
138 if (dLink.isValid()) {
139 if (m_returnTimedData.value()) {
140 sigTime = subEv.time();
141 if (!m_pITriggerTime.empty())
142 sigTime -= m_pITriggerTime->time();
143 evtIndex = subEv.index();
144 }
145 value_type tData(PileUpTimeEventIndex(int(sigTime), evtIndex,
146 getOldPileUpType(subEv.type())),
147 dLink);
148 numberOfSimHits += tData.second->size();
149 timedData.push_back(tData);
150 ATH_MSG_DEBUG("added entry from store "
151 << pSubEvtSG->name() << " for object of type "
152 << System::typeinfoName(typeid(data_t))
153 << "\n with key " << dataKey);
154 }
155#ifndef NDEBUG
156 if (msg().level() <= MSG::VERBOSE) {
157 msg() << MSG::VERBOSE << "SubEvt EventInfo : "
158 << " event: " << subEv.ptr()->eventNumber()
159 << " run: " << subEv.ptr()->runNumber();
160 if (m_returnTimedData.value()) {
161 msg() << " time offset: " << sigTime
162 << " event index: " << evtIndex;
163 }
164 msg() << endmsg;
165 }
166#endif
167 }
168 }
169 // reset active store pointer to default event store FIXME DANGEROUS
170 p_overStore->makeCurrent();
171 } else {
172 ATH_MSG_DEBUG("default PileUpEventInfo not found, trying any EventInfo");
173 // check for EventInfo with any key name
174 pEvent = getPileUpEvent(Gaudi::Hive::currentContext(), "");
175 if (pEvent) {
176 DataLink_t dLink;
177 fillLink(dLink, dataKey);
178 if (dLink.isValid()) {
179 timedData.push_back(std::make_pair(0, dLink));
180 }
181 } else {
182 ATH_MSG_FATAL("no EventInfo object found!");
183 return StatusCode::FAILURE;
184 }
185 }
186 return StatusCode::SUCCESS;
187}
188
189///retrieve keyed DATA objs for subset of sub-events
190template <typename KEY, typename TIMEDDATA>
191StatusCode
192PileUpMergeSvc::retrieveSubSetEvtData(const KEY& dataKey, //orig evt key
193 TIMEDDATA& timedData, int bunchXing,
194 SubEventIterator bSubEvents, SubEventIterator eSubEvents)
195{
196 typedef typename TIMEDDATA::value_type value_type; //pair<time_t,DataLink..
197 typedef typename value_type::second_type DataLink_t;
198
199 SubEventIterator iEvt = bSubEvents;
200 for (; iEvt != eSubEvents; ++iEvt) {
201
202 StoreGateSvc &seStore = *iEvt->ptr()->evtStore();
203 ATH_MSG_VERBOSE("SubEvt StoreGate " << seStore.name() << " :"
204 << " bunch crossing : " << bunchXing
205 << " time offset : " << iEvt->time()
206 << " event number : " <<
207 iEvt->ptr()->eventNumber()
208 << " run number : " <<
209 iEvt->ptr()->runNumber());
210
211 DataLink_t dLink;
212 fillLink(dLink, dataKey, iEvt->ptr()->evtStore());
213 if (dLink.isValid()) {
214
215 double sigTime(0.0);
216 unsigned int evtIndex(0);
217
218 if (m_returnTimedData.value()) {
219 sigTime=iEvt->time();
220 evtIndex = iEvt->index();
221 }
222
223 value_type tData(PileUpTimeEventIndex(int(sigTime),evtIndex), dLink);
224 timedData.push_back(tData);
225
226 } else {
227
228 ATH_MSG_FATAL("Could not retrieve hit collection from: " << seStore.name() << " with key: " << dataKey);
229 return StatusCode::FAILURE;
230
231 }
232 }
233
234 return StatusCode::SUCCESS;
235
236}
237
238///retrieve keyed DATA objs for single sub-event (un-timed)
239template <typename KEY, typename DATA>
240StatusCode
241PileUpMergeSvc::retrieveSingleSubEvtData(const KEY& dataKey, const DATA*& data, int bunchXing, SubEventIterator iEvt){
242
243 ATH_MSG_VERBOSE("In PileUpMergeSvc::retrieveSingleSubEvtData evt="<<*iEvt->ptr()<<" SG="<<iEvt->ptr()->evtStore());
244 StoreGateSvc &seStore = *iEvt->ptr()->evtStore();
245 ATH_MSG_VERBOSE("SubEvt StoreGate " << seStore.name() << " :"
246 << " bunch crossing : " << bunchXing
247 << " time offset : " << iEvt->time()
248 << " event number : " <<
249 iEvt->ptr()->eventNumber()
250 << " run number : " <<
251 iEvt->ptr()->runNumber());
252
253 StatusCode sc = seStore.retrieve(data, dataKey);
254 if (!sc) {
255 sc = seStore.retrieve(data, mkHSKey(dataKey));
256 }
257 return sc;
258
259}
260
261/// retrieve keyed DATA objs for all sub-events and attach a time to them
262template <typename KEY, typename TIMEDDATA>
263StatusCode
264PileUpMergeSvc::retrieveSubEvtsData(const KEY &dataKey, // orig evt key
265 TIMEDDATA &timedData) {
266 typedef typename TIMEDDATA::value_type value_type; // pair<time_t,DataLink..
267 typedef typename value_type::second_type DataLink_t;
268 typedef typename DataLink_t::value_type data_t;
269 // the tdefs above in practice check that TIMEDDATA is what we want
270 // FIXME we still have to check we are dealing with a sequence:
271 // boost::function_requires < boost::SequenceConcept<TIMEDDATA> > ();
272 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
273
274 ATH_MSG_DEBUG ( "retrieveSubEvtsData: object of type "
275 << System::typeinfoName(typeid(data_t)) << " with key "
276 << dataKey<< " ei="<<pEvent );
277
278 if (pEvent) {
279 if(pEvent->subEvents().size()==0) {
280 ATH_MSG_DEBUG ( "no subEvents for xAOD::EventInfo '"<<m_EventInfoKeyName<<"'" );
281
282 DataLink_t dLink;
283 fillLink(dLink, dataKey);
284 if (dLink.isValid()) {
285 timedData.push_back(std::make_pair(0, dLink));
286 }
287 return StatusCode::SUCCESS;
288 }
289
290 // access the sub events DATA objects...
291 for (const xAOD::EventInfo::SubEvent &subEv : pEvent->subEvents()) {
292 // skip if dobj not active for this xing
293 // FIXME if (!isLive<data_t>(dataKey, int(iEvt->time()))) {
294 // FIXME turning the double iEvt->time() is fraught with peril. Luckily
295 // FIXME it just works, but we should have the beam xing in iEvt
296 if (!isLive(ClassID_traits<data_t>::ID(), dataKey, int(subEv.time()))) {
297#ifndef NDEBUG
298 ATH_MSG_VERBOSE("retrieveSubEvtsData: object of type "
299 << System::typeinfoName(typeid(data_t)) << " with key "
300 << dataKey << " OUT OF XING RANGE: SKIPPING ");
301#endif
302 } else {
303 subEv.ptr()->evtStore()->makeCurrent();
304 StoreGateSvc *pSubEvtSG = subEv.ptr()->evtStore();
305 DataLink_t dLink;
306 fillLink(dLink, dataKey, pSubEvtSG);
307 double sigTime(0.0);
308 unsigned int evtIndex(0);
309 if (dLink.isValid()) {
310 if (m_returnTimedData.value()) {
311 sigTime = subEv.time();
312 if (!m_pITriggerTime.empty())
313 sigTime -= m_pITriggerTime->time();
314 evtIndex = subEv.index();
315 }
316 value_type tData(PileUpTimeEventIndex(int(sigTime), evtIndex,
317 getOldPileUpType(subEv.type())),
318 dLink);
319 timedData.push_back(tData);
320 ATH_MSG_DEBUG("added entry from store "
321 << pSubEvtSG->name() << " for object of type "
322 << System::typeinfoName(typeid(data_t))
323 << "\n with key " << dataKey);
324 }
325#ifndef NDEBUG
326 if (msg().level() <= MSG::VERBOSE) {
327 msg() << MSG::VERBOSE << "SubEvt EventInfo : "
328 << " event: " << subEv.ptr()->eventNumber()
329 << " run: " << subEv.ptr()->runNumber();
330 if (m_returnTimedData.value()) {
331 msg() << " time offset: " << sigTime
332 << " event index: " << evtIndex;
333 }
334 msg() << endmsg;
335 }
336#endif
337 }
338 }
339 // reset active store pointer to default event store FIXME DANGEROUS
340 p_overStore->makeCurrent();
341 } else {
342 ATH_MSG_DEBUG("default PileUpEventInfo not found, trying any EventInfo");
343 // check for EventInfo with any key name
344 pEvent = getPileUpEvent(Gaudi::Hive::currentContext(), "");
345 if (pEvent) {
346 DataLink_t dLink;
347 fillLink(dLink, dataKey);
348 if (dLink.isValid()) {
349 timedData.push_back(std::make_pair(0, dLink));
350 }
351 } else {
352 ATH_MSG_FATAL("no EventInfo object found!");
353 return StatusCode::FAILURE;
354 }
355 }
356 return StatusCode::SUCCESS;
357}
358
359// ///retrieve default DATA objs for all sub-events and attach a time to them
360// template <typename TIMEDDATA>
361// StatusCode
362// PileUpMergeSvc::retrieveSubEvtsData(TIMEDDATA& timedData)
363// {
364// return retrieveSubEvtsData(NoKey(), timedData);
365// }
366
367
368template <typename DATA, typename KEY>
369bool
370PileUpMergeSvc::isLive(const KEY& dataKey, int iXing) {
371 return isLive(ClassID_traits<DATA>::ID(), std::string(dataKey), iXing);
372}
373
374
375
376
377
378
379
380
381
382
383
384
385
386