ATLAS Offline Software
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 
19 namespace {
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
70 template <typename KEY, typename DATA>
71 StatusCode
72 PileUpMergeSvc::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
89 template <typename KEY, typename TIMEDDATA>
90 StatusCode
91 PileUpMergeSvc::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
190 template <typename KEY, typename TIMEDDATA>
191 StatusCode
192 PileUpMergeSvc::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)
239 template <typename KEY, typename DATA>
240 StatusCode
241 PileUpMergeSvc::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
262 template <typename KEY, typename TIMEDDATA>
263 StatusCode
264 PileUpMergeSvc::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 
369 template <typename DATA, typename KEY>
370 bool
371 PileUpMergeSvc::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