4 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
7 #include <algorithm> /* make_pair */
11 #include "GaudiKernel/System.h"
12 #include "GaudiKernel/StatusCode.h"
14 #include "AthenaKernel/ITriggerTime.h"
15 #include "StoreGate/StoreGateSvc.h"
16 #include "AthenaKernel/ClassID_traits.h"
17 #include "AthenaBaseComps/AthMsgStreamMacros.h"
20 template <typename KEY>
21 std::string mkHSKey(const KEY& k) {
22 return "HS" + std::string(k);
25 template <class DATALINK, typename KEY>
26 void fillLink(DATALINK& l, const KEY& k, IProxyDict* sg = 0) {
27 l.toIdentifiedObject(k, sg);
29 l.toIdentifiedObject(mkHSKey(k), sg);
34 //MsgStream& operator <<(MsgStream& os, const NoKey&) { os << "Default"; return os; }
36 template <class DATALINK>
37 void fillLink(DATALINK&, const NoKey&, IProxyDict*)
38 { /*leave it in default state*/ }
40 [[maybe_unused]] // suppress clang warning (false positive?)
41 PileUpTimeEventIndex::PileUpType getOldPileUpType(const xAOD::EventInfo_v1::PileUpType &newType) {
42 PileUpTimeEventIndex::PileUpType oldType = PileUpTimeEventIndex::Unknown;
44 case xAOD::EventInfo_v1::Signal :
45 oldType = PileUpTimeEventIndex::Signal;
47 case xAOD::EventInfo_v1::MinimumBias:
48 oldType = PileUpTimeEventIndex::MinimumBias;
50 case xAOD::EventInfo_v1::Cavern:
51 oldType = PileUpTimeEventIndex::Cavern;
53 case xAOD::EventInfo_v1::HaloGas:
54 oldType = PileUpTimeEventIndex::HaloGas;
56 case xAOD::EventInfo_v1::HighPtMinimumBias:
57 oldType = PileUpTimeEventIndex::HighPtMinimumBias;
59 case xAOD::EventInfo_v1::ZeroBias:
60 oldType = PileUpTimeEventIndex::ZeroBias;
69 ///retrieve keyed DATA obj for the original event
70 template <typename KEY, typename DATA>
72 PileUpMergeSvc::retrieveOriginal(const KEY& dataKey, const DATA*& data) {
73 StatusCode sc(StatusCode::FAILURE);
74 const xAOD::EventInfo* pEvent = getPileUpEvent(nullptr,m_EventInfoKeyName);
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);
81 sc = pEvent->subEvents()[0].ptr()->evtStore()->retrieve(data, mkHSKey(dataKey));
88 /// retrieve keyed DATA objs for all sub-events and attach a time to them
89 template <typename KEY, typename TIMEDDATA>
91 PileUpMergeSvc::retrieveSubEvtsData(const KEY &dataKey, // orig evt key
93 unsigned int &numberOfSimHits) {
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);
103 ATH_MSG_DEBUG ( "retrieveSubEvtsData: object of type "
104 << System::typeinfoName(typeid(data_t)) << " with key "
105 << dataKey<< " ei="<<pEvent );
108 if(pEvent->subEvents().size()==0) {
109 ATH_MSG_DEBUG ( "no subEvents for xAOD::EventInfo '"<<m_EventInfoKeyName<<"'" );
112 fillLink(dLink, dataKey);
113 if (dLink.isValid()) {
114 timedData.push_back(std::make_pair(0, dLink));
116 return StatusCode::SUCCESS;
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()))) {
126 ATH_MSG_VERBOSE("retrieveSubEvtsData: object of type "
127 << System::typeinfoName(typeid(data_t)) << " with key "
128 << dataKey << " OUT OF XING RANGE: SKIPPING ");
131 subEv.ptr()->evtStore()->makeCurrent();
132 StoreGateSvc *pSubEvtSG = subEv.ptr()->evtStore();
134 fillLink(dLink, dataKey, pSubEvtSG);
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();
144 value_type tData(PileUpTimeEventIndex(int(sigTime), evtIndex,
145 getOldPileUpType(subEv.type())),
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);
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;
168 // reset active store pointer to default event store FIXME DANGEROUS
169 p_overStore->makeCurrent();
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()), "");
177 fillLink(dLink, dataKey);
178 if (dLink.isValid()) {
179 timedData.push_back(std::make_pair(0, dLink));
182 ATH_MSG_FATAL("no EventInfo object found!");
183 return StatusCode::FAILURE;
186 return StatusCode::SUCCESS;
189 ///retrieve keyed DATA objs for subset of sub-events
190 template <typename KEY, typename TIMEDDATA>
192 PileUpMergeSvc::retrieveSubSetEvtData(const KEY& dataKey, //orig evt key
193 TIMEDDATA& timedData, int bunchXing,
194 SubEventIterator bSubEvents, SubEventIterator eSubEvents)
196 typedef typename TIMEDDATA::value_type value_type; //pair<time_t,DataLink..
197 typedef typename value_type::second_type DataLink_t;
199 SubEventIterator iEvt = bSubEvents;
200 for (; iEvt != eSubEvents; ++iEvt) {
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());
212 fillLink(dLink, dataKey, iEvt->ptr()->evtStore());
213 if (dLink.isValid()) {
216 unsigned int evtIndex(0);
218 if (m_returnTimedData.value()) {
219 sigTime=iEvt->time();
220 evtIndex = iEvt->index();
223 value_type tData(PileUpTimeEventIndex(int(sigTime),evtIndex), dLink);
224 timedData.push_back(tData);
228 ATH_MSG_FATAL("Could not retrieve hit collection from: " << seStore.name() << " with key: " << dataKey);
229 return StatusCode::FAILURE;
234 return StatusCode::SUCCESS;
238 ///retrieve keyed DATA objs for single sub-event (un-timed)
239 template <typename KEY, typename DATA>
241 PileUpMergeSvc::retrieveSingleSubEvtData(const KEY& dataKey, const DATA*& data, int bunchXing, SubEventIterator iEvt){
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());
253 StatusCode sc = seStore.retrieve(data, dataKey);
255 sc = seStore.retrieve(data, mkHSKey(dataKey));
261 /// retrieve keyed DATA objs for all sub-events and attach a time to them
262 template <typename KEY, typename TIMEDDATA>
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);
274 ATH_MSG_DEBUG ( "retrieveSubEvtsData: object of type "
275 << System::typeinfoName(typeid(data_t)) << " with key "
276 << dataKey<< " ei="<<pEvent );
279 if(pEvent->subEvents().size()==0) {
280 ATH_MSG_DEBUG ( "no subEvents for xAOD::EventInfo '"<<m_EventInfoKeyName<<"'" );
283 fillLink(dLink, dataKey);
284 if (dLink.isValid()) {
285 timedData.push_back(std::make_pair(0, dLink));
287 return StatusCode::SUCCESS;
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()))) {
298 ATH_MSG_VERBOSE("retrieveSubEvtsData: object of type "
299 << System::typeinfoName(typeid(data_t)) << " with key "
300 << dataKey << " OUT OF XING RANGE: SKIPPING ");
303 subEv.ptr()->evtStore()->makeCurrent();
304 StoreGateSvc *pSubEvtSG = subEv.ptr()->evtStore();
306 fillLink(dLink, dataKey, pSubEvtSG);
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();
316 value_type tData(PileUpTimeEventIndex(int(sigTime), evtIndex,
317 getOldPileUpType(subEv.type())),
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);
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;
339 // reset active store pointer to default event store FIXME DANGEROUS
340 p_overStore->makeCurrent();
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()), "");
348 fillLink(dLink, dataKey);
349 if (dLink.isValid()) {
350 timedData.push_back(std::make_pair(0, dLink));
353 ATH_MSG_FATAL("no EventInfo object found!");
354 return StatusCode::FAILURE;
357 return StatusCode::SUCCESS;
360 // ///retrieve default DATA objs for all sub-events and attach a time to them
361 // template <typename TIMEDDATA>
363 // PileUpMergeSvc::retrieveSubEvtsData(TIMEDDATA& timedData)
365 // return retrieveSubEvtsData(NoKey(), timedData);
369 template <typename DATA, typename KEY>
371 PileUpMergeSvc::isLive(const KEY& dataKey, int iXing) {
372 return isLive(ClassID_traits<DATA>::ID(), std::string(dataKey), iXing);