ATLAS Offline Software
Loading...
Searching...
No Matches
PileUpMergeSvc.icc
Go to the documentation of this file.
1/* -*- C++ -*- */
2
3/*
4 Copyright (C) 2002-2023 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
14#include "AthenaKernel/ITriggerTime.h"
15#include "StoreGate/StoreGateSvc.h"
16#include "AthenaKernel/ClassID_traits.h"
17#include "AthenaBaseComps/AthMsgStreamMacros.h"
18
19namespace {
20 template <typename KEY>
21 std::string mkHSKey(const KEY& k) {
22 return "HS" + std::string(k);
23 }
24
25 template <class DATALINK, typename KEY>
26 void fillLink(DATALINK& l, const KEY& k, IProxyDict* sg = 0) {
27 l.toIdentifiedObject(k, sg);
28 if (!l.isValid()) {
29 l.toIdentifiedObject(mkHSKey(k), sg);
30 }
31 }
32
33 struct NoKey {};
34 //MsgStream& operator <<(MsgStream& os, const NoKey&) { os << "Default"; return os; }
35
36 template <class DATALINK>
37 void fillLink(DATALINK&, const NoKey&, IProxyDict*)
38 { /*leave it in default state*/ }
39
40 [[maybe_unused]] // suppress clang warning (false positive?)
41 PileUpTimeEventIndex::PileUpType getOldPileUpType(const xAOD::EventInfo_v1::PileUpType &newType) {
42 PileUpTimeEventIndex::PileUpType oldType = PileUpTimeEventIndex::Unknown;
43 switch(newType) {
44 case xAOD::EventInfo_v1::Signal :
45 oldType = PileUpTimeEventIndex::Signal;
46 break;
47 case xAOD::EventInfo_v1::MinimumBias:
48 oldType = PileUpTimeEventIndex::MinimumBias;
49 break;
50 case xAOD::EventInfo_v1::Cavern:
51 oldType = PileUpTimeEventIndex::Cavern;
52 break;
53 case xAOD::EventInfo_v1::HaloGas:
54 oldType = PileUpTimeEventIndex::HaloGas;
55 break;
56 case xAOD::EventInfo_v1::HighPtMinimumBias:
57 oldType = PileUpTimeEventIndex::HighPtMinimumBias;
58 break;
59 case xAOD::EventInfo_v1::ZeroBias:
60 oldType = PileUpTimeEventIndex::ZeroBias;
61 break;
62 default:
63 break;
64 }
65 return oldType;
66 }
67}
68
69///retrieve keyed DATA obj for the original event
70template <typename KEY, typename DATA>
71StatusCode
72PileUpMergeSvc::retrieveOriginal(const KEY& dataKey, const DATA*& data) {
73 StatusCode sc(StatusCode::FAILURE);
74 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
75 if (pEvent) {
76 // access the sub events DATA objects...
77 if( pEvent->subEvents().size() ) {
78 //here we assume that the original event is the first in pEvent list
79 sc = pEvent->subEvents()[0].ptr()->evtStore()->retrieve(data, dataKey);
80 if (!sc) {
81 sc = pEvent->subEvents()[0].ptr()->evtStore()->retrieve(data, mkHSKey(dataKey));
82 }
83 }
84 }
85 return sc;
86}
87
88/// retrieve keyed DATA objs for all sub-events and attach a time to them
89template <typename KEY, typename TIMEDDATA>
90StatusCode
91PileUpMergeSvc::retrieveSubEvtsData(const KEY &dataKey, // orig evt key
92 TIMEDDATA &timedData,
93 unsigned int &numberOfSimHits) {
94 numberOfSimHits = 0;
95 typedef typename TIMEDDATA::value_type value_type; // pair<time_t,DataLink..
96 typedef typename value_type::second_type DataLink_t;
97 typedef typename DataLink_t::value_type data_t;
98 // the tdefs above in practice check that TIMEDDATA is what we want
99 // FIXME we still have to check we are dealing with a sequence:
100 // boost::function_requires < boost::SequenceConcept<TIMEDDATA> > ();
101 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
102
103 ATH_MSG_DEBUG ( "retrieveSubEvtsData: object of type "
104 << System::typeinfoName(typeid(data_t)) << " with key "
105 << dataKey<< " ei="<<pEvent );
106
107 if (pEvent) {
108 if(pEvent->subEvents().size()==0) {
109 ATH_MSG_DEBUG ( "no subEvents for xAOD::EventInfo '"<<m_EventInfoKeyName<<"'" );
110
111 DataLink_t dLink;
112 fillLink(dLink, dataKey);
113 if (dLink.isValid()) {
114 timedData.push_back(std::make_pair(0, dLink));
115 }
116 return StatusCode::SUCCESS;
117 }
118 // access the sub events DATA objects...
119 for (const xAOD::EventInfo::SubEvent &subEv : pEvent->subEvents()) {
120 // skip if dobj not active for this xing
121 // FIXME if (!isLive<data_t>(dataKey, int(iEvt->time()))) {
122 // FIXME turning the double iEvt->time() is fraught with peril. Luckily
123 // FIXME it just works, but we should have the beam xing in iEvt
124 if (!isLive(ClassID_traits<data_t>::ID(), dataKey, int(subEv.time()))) {
125#ifndef NDEBUG
126 ATH_MSG_VERBOSE("retrieveSubEvtsData: object of type "
127 << System::typeinfoName(typeid(data_t)) << " with key "
128 << dataKey << " OUT OF XING RANGE: SKIPPING ");
129#endif
130 } else {
131 subEv.ptr()->evtStore()->makeCurrent();
132 StoreGateSvc *pSubEvtSG = subEv.ptr()->evtStore();
133 DataLink_t dLink;
134 fillLink(dLink, dataKey, pSubEvtSG);
135 double sigTime(0.0);
136 unsigned int evtIndex(0);
137 if (dLink.isValid()) {
138 if (m_returnTimedData.value()) {
139 sigTime = subEv.time();
140 if (!m_pITriggerTime.empty())
141 sigTime -= m_pITriggerTime->time();
142 evtIndex = subEv.index();
143 }
144 value_type tData(PileUpTimeEventIndex(int(sigTime), evtIndex,
145 getOldPileUpType(subEv.type())),
146 dLink);
147 numberOfSimHits += tData.second->size();
148 timedData.push_back(tData);
149 ATH_MSG_DEBUG("added entry from store "
150 << pSubEvtSG->name() << " for object of type "
151 << System::typeinfoName(typeid(data_t))
152 << "\n with key " << dataKey);
153 }
154#ifndef NDEBUG
155 if (msg().level() <= MSG::VERBOSE) {
156 msg() << MSG::VERBOSE << "SubEvt EventInfo : "
157 << " event: " << subEv.ptr()->eventNumber()
158 << " run: " << subEv.ptr()->runNumber();
159 if (m_returnTimedData.value()) {
160 msg() << " time offset: " << sigTime
161 << " event index: " << evtIndex;
162 }
163 msg() << endmsg;
164 }
165#endif
166 }
167 }
168 // reset active store pointer to default event store FIXME DANGEROUS
169 p_overStore->makeCurrent();
170 } else {
171 ATH_MSG_DEBUG("default PileUpEventInfo not found, trying any EventInfo");
172 // check for EventInfo with any key name
173 pEvent = getPileUpEvent(
174 dynamic_cast<StoreGateSvc *>(SG::CurrentEventStore::store()), "");
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(
345 dynamic_cast<StoreGateSvc *>(SG::CurrentEventStore::store()), "");
346 if (pEvent) {
347 DataLink_t dLink;
348 fillLink(dLink, dataKey);
349 if (dLink.isValid()) {
350 timedData.push_back(std::make_pair(0, dLink));
351 }
352 } else {
353 ATH_MSG_FATAL("no EventInfo object found!");
354 return StatusCode::FAILURE;
355 }
356 }
357 return StatusCode::SUCCESS;
358}
359
360// ///retrieve default DATA objs for all sub-events and attach a time to them
361// template <typename TIMEDDATA>
362// StatusCode
363// PileUpMergeSvc::retrieveSubEvtsData(TIMEDDATA& timedData)
364// {
365// return retrieveSubEvtsData(NoKey(), timedData);
366// }
367
368
369template <typename DATA, typename KEY>
370bool
371PileUpMergeSvc::isLive(const KEY& dataKey, int iXing) {
372 return isLive(ClassID_traits<DATA>::ID(), std::string(dataKey), iXing);
373}
374
375
376
377
378
379
380
381
382
383
384
385
386
387