ATLAS Offline Software
Loading...
Searching...
No Matches
LArPileUpTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// +==========================================================================+
6// + +
7// + Authors .......: G.Unal +
8// + migrate LAr digitization to PileUpTool framework +
9// +==========================================================================+
10//
11
12#include "LArPileUpTool.h"
13
15
17#include "CLHEP/Random/RandGaussZiggurat.h"
25#include "LArSimEvent/LArHit.h"
28
30#include "CLHEP/Random/RandomEngine.h"
31
32#include <CLHEP/Random/Randomize.h>
33
34#include <utility>
35
36using CLHEP::RandFlat;
37using CLHEP::RandGaussZiggurat;
38
39LArPileUpTool::LArPileUpTool(const std::string& type, const std::string& name, const IInterface* parent) :
40 PileUpToolBase(type, name, parent) {
41}
42
43
45
47
48 //
49 // ........ Check for inconsistent configuration
50 //
52 ATH_MSG_FATAL("Adding noise to hard-scatter Hits is not supported for Data Overlay! Fix your configuration. Bailing out.");
53 return StatusCode::FAILURE;
54 }
56 ATH_MSG_FATAL("MC overlay. Need to switch back on noise only to emulate extra noise for cells with different gains! Fix your configuration. Bailing out.");
57 return StatusCode::FAILURE;
58 }
59 if (m_RndmEvtOverlay && !m_PileUp) {
60 ATH_MSG_FATAL("If RndmEvtOverlay==True then PileUp must also be True. Fix your configuration. Bailing out.");
61 return StatusCode::FAILURE;
62 }
64 ATH_MSG_FATAL("If PileUp==False then OnlyUserContainerName must also be False. Fix your configuration. Bailing out.");
65 return StatusCode::FAILURE;
66 }
67 //
68 // ........ print random event overlay flag
69 //
70 if (m_RndmEvtOverlay) {
71 ATH_MSG_INFO(" pileup and/or noise added by overlaying digits of random events");
72 if (m_isMcOverlay) {
73 ATH_MSG_INFO(" random events are from MC ");
74 } else {
75 ATH_MSG_INFO(" random events are from data ");
76 }
77 } else {
78 ATH_MSG_INFO(" No overlay of random events");
79 }
80
82 ATH_CHECK(m_mergeSvc.retrieve());
83 ATH_MSG_INFO("PileUpMergeSvc successfully initialized");
84 }
85
86 //
87 // ......... print the noise flag
88 //
89 if (m_NoiseOnOff) {
90 ATH_MSG_INFO(" Electronic noise will be added in each cell ");
91 } else {
92 ATH_MSG_INFO(" No electronic noise added.");
93
94 // not useful (see MakeDigit), but in case of...
95 m_NoiseInEMB = false;
96 m_NoiseInEMEC = false;
97 m_NoiseInHEC = false;
98 m_NoiseInFCAL = false;
99 }
100 //
101 // ............ print cross-talk configuration
102 //
103 if (m_CrossTalk) {
104 ATH_MSG_INFO(" Cross-talk in EM barrel will be taken into account : ");
105 ATH_MSG_INFO(" Cross talk strip strip included ");
107 ATH_MSG_INFO(" Cross talk strip-2nd strip included ");
108 ATH_MSG_INFO(" Cross talk strip middle included ");
110 ATH_MSG_INFO(" Cross talk strip middle included ");
112 ATH_MSG_INFO(" Cross talk middle middle included");
113 } else {
114 ATH_MSG_INFO(" no Cross-Talk simulated");
115 }
116
119 } else {
120 if (m_useLArHitFloat) {
122 } else {
124 }
125 }
126 ATH_MSG_DEBUG("Input objects in these containers : '" << m_hitContainerNames << "'");
127
128 // Initialize ReadHandleKey
132
134 ATH_CHECK(m_mcEventColl.initialize(m_Windows));
135
136
137 ATH_CHECK(m_caloMgrKey.initialize());
138
139 // retrieve ID helpers
140 ATH_CHECK(detStore()->retrieve(m_calocell_id, "CaloCell_ID"));
141
142 const CaloIdManager* caloIdMgr = nullptr;
143 StatusCode sc = detStore()->retrieve(caloIdMgr);
144 if (sc.isFailure()) {
145 ATH_MSG_ERROR(" Unable to retrieve CaloIdManager from DetectoreStore");
146 return StatusCode::FAILURE;
147 }
148 m_larem_id = caloIdMgr->getEM_ID();
149 m_larhec_id = caloIdMgr->getHEC_ID();
150 m_larfcal_id = caloIdMgr->getFCAL_ID();
151
152 sc = detStore()->retrieve(m_laronline_id);
153 if (sc.isFailure()) {
154 ATH_MSG_ERROR(" Unable to retrieve LArOnlineId from DetectoreStore");
155 return StatusCode::FAILURE;
156 }
157
158 ATH_CHECK(m_rndmGenSvc.retrieve());
159
160 // register data handle for conditions data
161
162 ATH_CHECK(m_xtalkKey.initialize());
163
164 ATH_CHECK(m_cablingKey.initialize());
165
166 ATH_CHECK(m_hitMapKey.initialize());
168
169 ATH_MSG_DEBUG("Initialization completed successfully");
170
171 return StatusCode::SUCCESS;
172}
173// ----------------------------------------------------------------------------------------------------------------------------------
174
175StatusCode LArPileUpTool::prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents */)
176{
177
178 //Clear per-event data:
179 m_data.m_energySum.clear();
180 m_data.m_energySum_DigiHSTruth.clear();
181 m_data.m_hitmap=nullptr;
182 m_data.m_hitmap_DigiHSTruth=nullptr;
183 m_data.m_trigtime=0;
184 m_data.m_weights=nullptr;
185
187 auto* cabling=*cablingHdl;
188 if(!cabling) {
189 ATH_MSG_ERROR("Failed to retrieve LAr Cabling map with key " << m_cablingKey.key() );
190 return StatusCode::FAILURE;
191 }
193 const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
194 auto hitmap=SG::makeHandle(m_hitMapKey, ctx);
195 auto hitMapPtr=std::make_unique<LArHitEMap>(cabling,m_calocell_id,caloDDMgr,m_RndmEvtOverlay);
196 ATH_CHECK(hitmap.record(std::move(hitMapPtr)));
197 m_data.m_hitmap=hitmap.ptr();
198 ATH_MSG_DEBUG(" Number of created cells in Map " << hitmap->GetNbCells());
199 if (!m_useMBTime) m_data.m_energySum.assign(m_data.m_hitmap->GetNbCells(),0.);
200
201
202 if (m_doDigiTruth) {
203 auto hitmap_DigiHSTruth=SG::makeHandle(m_hitMapKey_DigiHSTruth, ctx);
204 auto hitMapPtr=std::make_unique<LArHitEMap>(cabling,m_calocell_id,caloDDMgr,m_RndmEvtOverlay);
205 ATH_CHECK(hitmap_DigiHSTruth.record(std::move(hitMapPtr)));
206 m_data.m_hitmap_DigiHSTruth=hitmap_DigiHSTruth.ptr();
207 if (!m_useMBTime) m_data.m_energySum_DigiHSTruth.assign(m_data.m_hitmap_DigiHSTruth->GetNbCells(),0.);
208 }
209 // get the trigger time if requested
210 m_data.m_trigtime=0;
211 if (m_useTriggerTime) {
213 m_data.m_trigtime = cosTimeHdl->time();
214 ATH_MSG_DEBUG(" Trigger time used : " << m_data.m_trigtime);
215 }
216
217 ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this, m_randomStreamName);
219 rngWrapper->setSeedLegacy( m_randomStreamName, ctx, m_randomSeedOffset, seedingmode );
220 // add random phase (i.e subtract it from trigtime)
221 if (m_addPhase) {
222 m_data.m_trigtime -= (m_phaseMin + (m_phaseMax-m_phaseMin)*RandFlat::shoot(rngWrapper->getEngine(ctx)) );
223 }
224
225 if (m_Windows) {
226 ATH_MSG_DEBUG(" redefine windows list ");
228 const McEventCollection* mcCollptr=mcColl.cptr();
229 if ( evtStore()->retrieve(mcCollptr).isFailure() ) {
230 ATH_MSG_WARNING ("LArHitEMap:cannot retrieve McEventCollection (keyless)");
231 }
232
233 m_data.m_hitmap->BuildWindows(mcCollptr, m_WindowsEtaSize, m_WindowsPhiSize, m_WindowsPtCut);
234 if (m_doDigiTruth) {
235 m_data.m_hitmap_DigiHSTruth->BuildWindows(mcCollptr, m_WindowsEtaSize, m_WindowsPhiSize, m_WindowsPtCut);
236 }
237 }
238
239 return StatusCode::SUCCESS;
240}
241
242
243//----------------------------------------------------------------------------------------------------------------------------
244
245StatusCode LArPileUpTool::processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) {
246
247 ATH_MSG_VERBOSE("processBunchXing()");
248 float tbunch = (float)(bunchXing);
249 const EventContext& ctx = Gaudi::Hive::currentContext();
251 m_data.m_weights = *weightHdl;
252
253 SubEventIterator iEvt(bSubEvents);
254 while (iEvt != eSubEvents) {
255
256 // do we deal with the MC signal event ?
257 bool isSignal = ((iEvt->type() == xAOD::EventInfo_v1::PileUpType::Signal) || m_RndmEvtOverlay);
258
259 // fill LArHits in map
260 if (this->fillMapFromHit(iEvt, tbunch, isSignal, m_data).isFailure()) {
261
262 ATH_MSG_ERROR(" cannot fill map from hits ");
263 return StatusCode::FAILURE;
264 }
265
266 // store digits from randoms for overlay
267 if (m_RndmEvtOverlay) {
268 const LArDigitContainer* rndm_digit_container;
269 if (m_mergeSvc->retrieveSingleSubEvtData(m_inputDigitContainerKey.key(), rndm_digit_container, bunchXing, iEvt).isSuccess()) {
270 int ndigit = 0;
271 for (const LArDigit* digit : *rndm_digit_container) {
272 if (m_data.m_hitmap->AddDigit(digit))
273 ndigit++;
274 }
275 ATH_MSG_INFO(" Number of digits stored for RndmEvt Overlay " << ndigit);
276 }
277 }
278
279 ++iEvt;
280 }
281
282 if (!m_useMBTime) {
283 if (!this->fillMapfromSum(tbunch, m_data)) {
284 ATH_MSG_ERROR(" error in FillMapFromSum ");
285 return StatusCode::FAILURE;
286 }
287 }
288
289 return StatusCode::SUCCESS;
290}
291
292// ---------------------------------------------------------------------------------------------------------------------------------
293
294StatusCode LArPileUpTool::processAllSubEvents(const EventContext& ctx) {
295 return const_cast<const LArPileUpTool*>(this)->processAllSubEvents(ctx); //refer to const-version
296}
297
298StatusCode LArPileUpTool::processAllSubEvents(const EventContext& ctx) const {
299
300
302
304 if(!cablingHdl.isValid()) {
305 ATH_MSG_ERROR("Failed to retrieve LAr Cabling map with key " << m_cablingKey.key() );
306 return StatusCode::FAILURE;
307 }
308 const LArOnOffIdMapping* cabling=*cablingHdl;
310 const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
311
312
314 auto hitMapPtr=std::make_unique<LArHitEMap>(cabling,m_calocell_id,caloDDMgr,m_RndmEvtOverlay);
315 ATH_CHECK(hitmap.record(std::move(hitMapPtr)));
316 data.m_hitmap=hitmap.ptr();
317 ATH_MSG_DEBUG(" Number of created cells in Map " << hitmap->GetNbCells());
318
319 if (!m_useMBTime) data.m_energySum.assign(hitmap->GetNbCells(),0.);
320
321
322 if (m_doDigiTruth) {
323 SG::WriteHandle<LArHitEMap> hitmap_DigiHSTruth;
324 hitmap_DigiHSTruth=SG::makeHandle(m_hitMapKey_DigiHSTruth, ctx);
325 auto hitMapPtr=std::make_unique<LArHitEMap>(cabling,m_calocell_id,caloDDMgr,m_RndmEvtOverlay);
326 ATH_CHECK(hitmap_DigiHSTruth.record(std::move(hitMapPtr)));
327 if (!m_useMBTime) data.m_energySum_DigiHSTruth.assign(hitmap_DigiHSTruth->GetNbCells(),0.);
328 data.m_hitmap_DigiHSTruth=hitmap_DigiHSTruth.ptr();
329 }
330
331 // get the trigger time if requested
332
333 data.m_trigtime=0;
334 if (m_useTriggerTime) {
336 data.m_trigtime = cosTimeHdl->time();
337 ATH_MSG_DEBUG(" Trigger time used : " << m_data.m_trigtime);
338 }
339
340 ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this, m_randomStreamName);
342 rngWrapper->setSeedLegacy( m_randomStreamName, ctx, m_randomSeedOffset, seedingmode );
343
344 // add random phase (i.e subtract it from trigtime)
345 if (m_addPhase) {
346 data.m_trigtime -= (m_phaseMin + (m_phaseMax-m_phaseMin)*RandFlat::shoot(rngWrapper->getEngine(ctx)) );
347 }
348
349 if (m_Windows) {
350 ATH_MSG_DEBUG(" redefine windows list ");
352 const McEventCollection* mcCollptr=mcColl.cptr();
353 data.m_hitmap->BuildWindows(mcCollptr,
356 if(m_doDigiTruth) {
357 data.m_hitmap_DigiHSTruth->BuildWindows(mcCollptr,
359 }
360
361 }
362
363 //
364 // ....... create the LAr Digit Container
365 //
366
367 if (m_CrossTalk) {
369 data.m_weights=weightHdl.cptr();
370 }
371
373 auto hitVectorHandles = m_hitContainerKeys.makeHandles(ctx);
374 for (auto & inputHits : hitVectorHandles) {
375 if (!inputHits.isValid()) {
376 ATH_MSG_ERROR("Input LAr hit container is missing!");
377 return StatusCode::FAILURE;
378 }
379 bool isSignal(true);
380 double SubEvtTimOffset(0.0);
381 double timeCurrBunch=-9999999.;
382 for (const LArHit* hit : *inputHits) {
383 float energy = (float) (hit->energy());
384 float time;
385 if (m_ignoreTime && isSignal) time=0.;
386 else time = (float) (SubEvtTimOffset+ hit->time() - data.m_trigtime);
387 Identifier cellId = hit->cellID();
388 if (!m_useMBTime) {
389 if (std::fabs(SubEvtTimOffset-timeCurrBunch)>1.) {
390 if (timeCurrBunch>-9999.) {
391 if (!this->fillMapfromSum(timeCurrBunch,data)) {
392 ATH_MSG_ERROR(" error in FillMapFromSum ");
393 return(StatusCode::FAILURE);
394 }
395 }
396 timeCurrBunch = SubEvtTimOffset;
397 }
398 }
399 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
400 } // End of loop over LArHitContainer
401 } // End of loop over SG::ReadHandles
402 }
403
404 if (!m_PileUp) {
405 float time=0.;
406 if (this->fillMapFromHit(ctx, time,true,data).isFailure()) {
407 ATH_MSG_ERROR("error in fillMapFromHit");
408 return StatusCode::FAILURE;
409 }
410 }
411
412 else {
413
414 for (const std::string& containerName : m_hitContainerNames) {
415
416 ATH_MSG_DEBUG(" pileUpOld asking for: " << containerName);
417
418 double timeCurrBunch=-9999999.;
419
420 if (!m_useLArHitFloat) {
422 TimedHitContList hitContList;
423 //
424 // retrieve list of pairs (time,container) from PileUp service
425
426 if (!(m_mergeSvc->retrieveSubEvtsData(containerName
427 ,hitContList).isSuccess()) && hitContList.empty()) {
428 ATH_MSG_ERROR("Could not fill TimedHitContList");
429 return StatusCode::FAILURE;
430 }
431
432 // loop over this list
433 TimedHitContList::iterator iFirstCont(hitContList.begin());
434 TimedHitContList::iterator iEndCont(hitContList.end());
435 if(m_RndmEvtOverlay) {
436 iEndCont = iFirstCont ;
437 ATH_MSG_DEBUG(" random event overlay mode : only time 0 read ");
438 ++iEndCont ;
439 }
440 double SubEvtTimOffset;
441 while (iFirstCont != iEndCont) {
442 // get time for this subevent
443 // new coding of time information (January 05)
444 bool isSignal = ( iFirstCont == hitContList.begin());
445 const PileUpTimeEventIndex* time_evt = &(iFirstCont->first);
446 SubEvtTimOffset = time_evt->time();
447 // get LArHitContainer for this subevent
448 const LArHitContainer& firstCont = *(iFirstCont->second);
449 // Loop over cells in this LArHitContainer
450 for (const LArHit* hit : firstCont) {
451 float energy = (float) (hit->energy());
452 float time;
453 if (m_ignoreTime && isSignal) time=0.;
454 else time = (float) (SubEvtTimOffset+ hit->time() - data.m_trigtime);
455 Identifier cellId = hit->cellID();
456
457 if (!m_useMBTime) {
458 if (std::fabs(SubEvtTimOffset-timeCurrBunch)>1.) {
459 if (timeCurrBunch>-9999.) {
460 if (!this->fillMapfromSum(timeCurrBunch,data)) {
461 ATH_MSG_ERROR(" error in FillMapFromSum ");
462 return(StatusCode::FAILURE);
463 }
464 }
465 timeCurrBunch = SubEvtTimOffset;
466 }
467 }
468 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
469 } // loop over hits
470 ++iFirstCont;
471 } // loop over subevent list
472 }
473
474 else {
475
477 TimedHitContList hitContList;
478 //
479 // retrieve list of pairs (time,container) from PileUp service
480
481 if (!(m_mergeSvc->retrieveSubEvtsData(containerName
482 ,hitContList).isSuccess()) && hitContList.empty()) {
483 ATH_MSG_ERROR("Could not fill TimedHitContList");
484 return StatusCode::FAILURE;
485 }
486
487 // loop over this list
488 TimedHitContList::iterator iFirstCont(hitContList.begin());
489 TimedHitContList::iterator iEndCont(hitContList.end());
490 if(m_RndmEvtOverlay) {
491 iEndCont = iFirstCont ;
492 ATH_MSG_DEBUG("random event overlay mode : only time 0 read ");
493 ++iEndCont ;
494 }
495 double SubEvtTimOffset;
496 while (iFirstCont != iEndCont) {
497 bool isSignal = ( iFirstCont == hitContList.begin());
498 // get time for this subevent
499 // new coding of time information (January 05)
500 const PileUpTimeEventIndex* time_evt = &(iFirstCont->first);
501 SubEvtTimOffset = time_evt->time();
502 // get LArHitContainer for this subevent
503 const LArHitFloatContainer& firstCont = *(iFirstCont->second);
504 // Loop over cells in this LArHitContainer
505 for (const LArHitFloat& hit : firstCont) {
506 float energy = (float)( hit.energy());
507 float time;
508 if (m_ignoreTime && isSignal) time=0.;
509 else time = (float) (SubEvtTimOffset+ hit.time() - data.m_trigtime);
510 Identifier cellId = hit.cellID();
511
512 if (!m_useMBTime) {
513 if (std::fabs(SubEvtTimOffset-timeCurrBunch)>1.) {
514 if (timeCurrBunch>-9999.) {
515 if (!this->fillMapfromSum(timeCurrBunch,data)) {
516 ATH_MSG_ERROR(" error in FillMapFromSum ");
517 return(StatusCode::FAILURE);
518 }
519 }
520 timeCurrBunch = SubEvtTimOffset;
521 }
522 }
523 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
524 } // loop over hits
525 ++iFirstCont;
526 } // loop over subevent list
527
528 } // LArHitFloat vs LArHit useage
529
530 if (!m_useMBTime) {
531 if (!this->fillMapfromSum(timeCurrBunch,data)) {
532 ATH_MSG_ERROR(" error in FillMapFromSum ");
533 return(StatusCode::FAILURE);
534 }
535 }
536
537 } // loop over containers
538
539 // get digits for random overlay
541 {
543 {
544 if (m_inputDigitContainerKey.empty()) {
545 return StatusCode::SUCCESS;
546 }
547
549 if (!digitCollection.isValid()) {
550 ATH_MSG_ERROR("Could not get LArDigitContainer container " << digitCollection.name() << " from store " << digitCollection.store());
551 return StatusCode::FAILURE;
552 }
553
554 ATH_MSG_DEBUG("LArDigitContainer found with " << digitCollection->size() << " digits");
555
556 size_t ndigit{};
557 for (const LArDigit* digit : *digitCollection) {
558 if (hitmap->AddDigit(digit)) ndigit++;
559 }
560 ATH_MSG_DEBUG(" Number of digits stored for RndmEvt Overlay " << ndigit);
561 }
562 else
563 {
564 typedef PileUpMergeSvc::TimedList<LArDigitContainer>::type TimedDigitContList ;
565 LArDigitContainer::const_iterator rndm_digititer_begin ;
566 LArDigitContainer::const_iterator rndm_digititer_end ;
567 LArDigitContainer::const_iterator rndm_digititer ;
568
569
570 TimedDigitContList digitContList;
571 if (!(m_mergeSvc->retrieveSubEvtsData(m_inputDigitContainerKey.key(),
572 digitContList).isSuccess()) || digitContList.empty())
573 {
574 ATH_MSG_ERROR("Cannot retrieve LArDigitContainer for random event overlay or empty Container");
575 ATH_MSG_ERROR("Random Digit Key= " << m_inputDigitContainerKey.key() << ",size=" << digitContList.size());
576 return StatusCode::FAILURE ;
577 }
578 TimedDigitContList::iterator iTzeroDigitCont(digitContList.begin()) ;
579 double SubEvtTimOffset;
580 // get time for this subevent
581 const PileUpTimeEventIndex* time_evt = &(iTzeroDigitCont->first);
582 SubEvtTimOffset = time_evt->time();
583 ATH_MSG_DEBUG(" Subevt time : " << SubEvtTimOffset);
584 const LArDigitContainer& rndm_digit_container = *(iTzeroDigitCont->second);
585 int ndigit=0;
586 for (const LArDigit* digit : rndm_digit_container) {
587 if (hitmap->AddDigit(digit)) ndigit++;
588 }
589 ATH_MSG_INFO(" Number of digits stored for RndmEvt Overlay " << ndigit);
590 }
591 }
592
593 } // if pileup
594
595 return StatusCode::SUCCESS;
596
597}
598
599// ============================================================================================
600
601StatusCode LArPileUpTool::fillMapFromHit(const EventContext& ctx, float bunchTime, bool isSignal, perEventData_t& data) const
602{
603 if (m_useLArHitFloat) {
604 auto hitVectorHandles = m_hitFloatContainerKeys.makeHandles(ctx);
605 for (auto & hit_container : hitVectorHandles) {
606 if (hit_container.isValid()) {
607 for (const LArHitFloat& hit : *hit_container)
608 {
609 Identifier cellId = hit.cellID();
610 float energy = (float) hit.energy();
611 float time;
612 if (m_ignoreTime) time=0.;
613 else time = (float) (hit.time() - data.m_trigtime);
614 time = time + bunchTime;
615 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
616 }
617 }
618 else {
619 if (isSignal) {
620 ATH_MSG_WARNING(" LAr HitFloat container not found for signal event key " << hit_container.key());
621 }
622 }
623 }
624 }
625 else {
626 auto hitVectorHandles = m_hitContainerKeys.makeHandles(ctx);
627 for (auto & hit_container : hitVectorHandles) {
628 if (hit_container.isValid()) {
629 for (const LArHit* hit : *hit_container)
630 {
631 Identifier cellId = hit->cellID();
632 float energy = (float) hit->energy();
633 float time;
634 if (m_ignoreTime) time=0.;
635 else time = (float) (hit->time() - data.m_trigtime);
636 time = time + bunchTime;
637 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
638 }
639 }
640 else {
641 if (isSignal) {
642 ATH_MSG_WARNING(" LAr Hit container not found for signal event key " << hit_container.key());
643 }
644 }
645 }
646 } // end loop over containers
647
648 return StatusCode::SUCCESS;
649}
650
651// ============================================================================================
652StatusCode LArPileUpTool::fillMapFromHit(SubEventIterator iEvt, float bunchTime, bool isSignal, perEventData_t& data) const
653{
654 for (const std::string& containerName : m_hitContainerNames) {
655
656 //
657 // ..... Get the pointer to the Hit Container from StoreGate through the merge service
658 //
659
660 ATH_MSG_DEBUG(" fillMapFromHit: asking for: " << containerName);
661
662 if (m_useLArHitFloat) {
663
664 const LArHitFloatContainer * hit_container;
665
666 if (!(m_mergeSvc->retrieveSingleSubEvtData(containerName, hit_container, bunchTime,
667 iEvt).isSuccess())){
668 ATH_MSG_ERROR(" LAr Hit container not found for event key " << containerName);
669 return StatusCode::FAILURE;
670 }
671
672 for (const LArHitFloat& hit : *hit_container){
673
674 Identifier cellId = hit.cellID();
675 float energy = (float) hit.energy();
676 float time;
677 if (m_ignoreTime) time=0.;
678 else time = (float) (hit.time() - data.m_trigtime);
679 time = time + bunchTime;
680
681 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
682 }
683 }
684 else {
685
686 const LArHitContainer * hit_container;
687
688 if (!(m_mergeSvc->retrieveSingleSubEvtData(containerName, hit_container, bunchTime,
689 iEvt).isSuccess())){
690 ATH_MSG_ERROR(" LAr Hit container not found for event key " << containerName);
691 return StatusCode::FAILURE;
692 }
693
695 for(hititer=hit_container->begin();
696 hititer != hit_container->end();++hititer)
697 {
698 Identifier cellId = (*hititer)->cellID();
699 float energy = (float) (*hititer)->energy();
700 float time;
701 if (m_ignoreTime) time=0.;
702 else time = (float) ((*hititer)->time() - data.m_trigtime);
703 time = time + bunchTime;
704
705 if (this->AddHit(cellId,energy,time,isSignal,data).isFailure()) return StatusCode::FAILURE;
706 }
707 }
708 } // end loop over containers
709
710 return StatusCode::SUCCESS;
711}
712
713// ----------------------------------------------------------------------------------------------------------------------
714
715StatusCode LArPileUpTool::AddHit(const Identifier cellId, const float energy, const float time, const bool isSignal, perEventData_t& data) const
716{
717
718 // remove pathological energies...
719 if (std::fabs(energy)>1e+9) {
720 ATH_MSG_WARNING(" Pathological energy ignored Id= "<< m_larem_id->show_to_string(cellId) << " energy= " << energy );
721 return StatusCode::SUCCESS;
722 }
723
724#ifndef NDEBUG
725 ATH_MSG_DEBUG(" Found hit Id= "<< m_larem_id->show_to_string(cellId)<< " energy= " << energy << "(MeV) time= " << time << "(ns)");
726#endif
727
728 IdentifierHash idHash=m_calocell_id->calo_cell_hash(cellId);
729
730// simulation of cross talk if requested (EM barrel + EndCap)
731 if (m_CrossTalk && isSignal && m_calocell_id->is_em(cellId))
732 {
733 std::vector<IdentifierHash> neighbourList;
734 std::vector<float> energyList;
735 //bool dump=false;
736 //if (energy>200. || m_larem_id->sampling(cellId)==3) dump=true;
737 //if(dump) std::cout << " Input cell energy " << m_larem_id->show_to_string(cellId) << " " << energy << std::endl;
738 this->cross_talk(idHash,cellId,energy, //FIXME -> Needs to work with full hash!
739 neighbourList,energyList, *data.m_weights);
740 //if(dump) std::cout <<" After cross-talk " ;
741 for (unsigned int icell=0;icell<neighbourList.size();icell++)
742 {
743 //unsigned int index=neighbourList[icell];
744 //Turn sub-calo hash in neighbour list into global calo-cell hash:
745 const auto subCalo = m_calocell_id->sub_calo(cellId);
746 if (subCalo == CaloCell_Base_ID::NOT_VALID){
747 ATH_MSG_ERROR("subCalo value is invalid in LArPileUpTool::AddHit");
748 return StatusCode::FAILURE;
749 }
750 const IdentifierHash index=m_calocell_id->calo_cell_hash(subCalo,neighbourList[icell]);
751 float e = energyList[icell];
752 //Identifier id2=m_larem_id->channel_id(neighbourList[icell]);
753 //if(dump) std::cout << "Cell/E " << m_larem_id->show_to_string(id2) << " " << e << " ";
754 if ( !data.m_hitmap->AddEnergy(index,e,time) )
755 {
756 ATH_MSG_ERROR(" Cell " << m_larem_id->show_to_string(cellId) << " could not add the energy= " << energy << " (GeV)");
757 return(StatusCode::FAILURE);
758 }
759 if ( m_doDigiTruth){
760 if(!data.m_hitmap_DigiHSTruth->AddEnergy(index,e,time) ) {
761 ATH_MSG_ERROR(" Cell " << m_larem_id->show_to_string(cellId) << " could not add the energy= " << energy << " (GeV)");
762 return(StatusCode::FAILURE);
763 }
764 }
765 }
766 //if (dump) std::cout << std::endl;
767 }
768 else // no cross-talk simulated
769 {
770 if (isSignal || m_useMBTime)
771 {
772 if ( !data.m_hitmap->AddEnergy(idHash,energy,time) )
773 {
774 ATH_MSG_ERROR(" Cell " << m_larem_id->show_to_string(cellId) << " could not add the energy= " << energy << " (GeV)");
775 return(StatusCode::FAILURE);
776 }
777 if ( m_doDigiTruth){
778 if(!data.m_hitmap_DigiHSTruth->AddEnergy(idHash,energy,time) ) {
779 ATH_MSG_ERROR(" Cell " << m_larem_id->show_to_string(cellId) << " could not add the energy= " << energy << " (GeV)");
780 return(StatusCode::FAILURE);
781 }
782 }
783 }
784 else
785 {
786 if (idHash<data.m_energySum.size()) data.m_energySum[idHash] += energy;
787 }
788 } // end if cross-talk
789 return StatusCode::SUCCESS;
790}
791
792// -------------------------------------------------------------------------------------------------------------------------------------
793
795 const Identifier& cellId,
796 const float& energy,
797 std::vector<IdentifierHash>& neighbourList,
798 std::vector<float>& energyList,
799 const LArXTalkWeightGlobal& weights) const
800{
801 neighbourList.clear();
802 energyList.clear();
803 int result=0;
804 neighbourList.reserve(8);
805 energyList.reserve(8);
806
807
808 int ibec = abs(m_larem_id->barrel_ec(cellId)); // 1 barrel 2 EC OW 3 EC IW
809 int sampling = m_larem_id->sampling(cellId);
810 int eta = m_larem_id->eta(cellId);
811 int region = m_larem_id->region(cellId);
812 float fcr=0,e,er;
813 float fcr2=0.;
814 std::vector<IdentifierHash> tmpList;
815
816 er=energy; // total energy of hit to be spread among channels
817
818// cross-talk in strips
819 if ((ibec==1 && sampling == 1 && region == 0)
820 || (ibec==2 && sampling ==1) )
821 {
822
823 if (ibec==1) fcr2 = weights.get_xtalk(LArXTalkWeightGlobal::TWOSTRIP,eta);
824 if (ibec==2) fcr2 = weights.get_xtalk(LArXTalkWeightGlobal::TWOSTRIP_EC,region,eta);
825
826// next in eta
827 if ( (ibec==1 && eta !=447) || (ibec==2 && (eta!=3 || region !=5)) )
828 {
829 result=m_larem_id->get_neighbours(hashId,
831 if(ibec==1) fcr = weights.get_xtalk(LArXTalkWeightGlobal::STRIP,eta+1)*m_scaleStripXtalk;
832 if(ibec==2) fcr = weights.get_xtalk(LArXTalkWeightGlobal::STRIP_EC,region,eta+1)*m_scaleStripXtalk;
833
834 if (result==0) {
835 if (tmpList.size() == 1) {
836 e=energy*fcr;
837 er=er-e;
838 neighbourList.push_back(tmpList[0]);
839 energyList.push_back(e);
840
841// second neighbor cross-talk
842 if (( (ibec==1 && eta !=446)
843 ||(ibec==2 && (eta!=2 || region !=5)) ) && m_CrossTalk2Strip) {
844 std::vector<IdentifierHash> tmpList2;
845 result = m_larem_id->get_neighbours(tmpList[0],LArNeighbours::nextInEta,tmpList2);
846 if (result==0) {
847 if (tmpList2.size()==1) {
848 e=energy*fcr2;
849 er=er-e;
850 neighbourList.push_back(tmpList2[0]);
851 energyList.push_back(e);
852 }
853 }
854 }
855
856 }
857 }
858 }
859// prev in eta (if possible)
860 if ( (ibec==1 && eta >1) || (ibec==2 && (eta !=0 || region !=0)) )
861 {
862 result=m_larem_id->get_neighbours(hashId,
864 if(ibec==1) fcr = weights.get_xtalk(LArXTalkWeightGlobal::STRIP,eta)*m_scaleStripXtalk;
865 if(ibec==2) fcr = weights.get_xtalk(LArXTalkWeightGlobal::STRIP_EC,region,eta)*m_scaleStripXtalk;
866 if (result==0 ) {
867 if (tmpList.size() == 1) {
868 e=energy*fcr;
869 er=er-e;
870 neighbourList.push_back(tmpList[0]);
871 energyList.push_back(e);
872
873// second neighbor cross-talk
874 if (( (ibec==1 && eta !=2)
875 ||(ibec==2 && (eta!=1 || region !=0)) ) && m_CrossTalk2Strip) {
876 std::vector<IdentifierHash> tmpList2;
877 result = m_larem_id->get_neighbours(tmpList[0],LArNeighbours::prevInEta,tmpList2);
878 if (result==0) {
879 if (tmpList2.size()==1) {
880 e=energy*fcr2;
881 er=er-e;
882 neighbourList.push_back(tmpList2[0]);
883 energyList.push_back(e);
884 }
885 }
886 }
887
888 }
889 }
890 }
891 }
892
893// cross-talk strip to middle
895 if ((ibec==1 && sampling==1 && region==0)
896 || (ibec==2 && sampling==1) )
897 {
899 if (ibec==2) fcr = weights.get_xtalk(LArXTalkWeightGlobal::STRIPMIDDLE_EC,region,eta)*m_scaleStripMiddle;
900
901 if (ibec==1) fcr = fcr*2.; // 8 strips for 4 middle cells
902 if (ibec==2) {
903 if (region==0) fcr=fcr/4.; // 1 strip for 4 middle cells
904 if (region==1) fcr=fcr/4.; // 1 strip for 4 middle cells
905 if (region==2) fcr=fcr*2.; // 8 strips for 4 middle cells
906 if (region==3) fcr=fcr*1.5; // 6 strips for 4 middle cells
907 // (region 4: 4strips for 4 middle cells)
908 if (region==5) fcr=fcr/4.; // 1 strip for 4 middle cells
909 }
910
911 // next sampling (should have only one cell)
912 result = m_larem_id->get_neighbours(hashId, LArNeighbours::nextInSamp,tmpList);
913 if (result==0) {
914 e=energy*fcr;
915 for (unsigned int ii=0;ii<tmpList.size();ii++) {
916 er = er-e;
917 neighbourList.push_back(tmpList[ii]);
918 energyList.push_back(e);
919 }
920 }
921 }
922
923// cross-talk middle to strip
924 if ((ibec==1 && sampling==2 && region==0)
925 || (ibec==2 && sampling==2) )
926 {
927 // previous sampling, expect 8 channels in middle for barrel, varing number in end-cap
928 result = m_larem_id->get_neighbours(hashId,
930 if (result==0) {
931 for (unsigned int ii=0;ii<tmpList.size();ii++) {
932 Identifier stripId = m_larem_id->channel_id(tmpList[ii]);
933 if (m_larem_id->sampling(stripId)==1) {
934 neighbourList.push_back(tmpList[ii]);
935 int eta2 = m_larem_id->eta(stripId);
936 int region2 = m_larem_id->region(stripId);
937 if (ibec==1) fcr=weights.get_xtalk(LArXTalkWeightGlobal::STRIPMIDDLE,eta2)*m_scaleStripMiddle;
938 if (ibec==2) fcr=weights.get_xtalk(LArXTalkWeightGlobal::STRIPMIDDLE_EC,region2,eta2)*m_scaleStripMiddle;
939 e=energy*fcr;
940 er=er-e;
941 energyList.push_back(e);
942 }
943 }
944 }
945 }
946 } // strip middle crosstalk
947
948// cross-talk middle to middle
949 if (m_CrossTalkMiddle) {
950 if ((ibec==1 && sampling==2 && region==0 ) ||
951 (ibec==2 && sampling==2 && region==1)) {
952
953 // fmiddle1 crosstalk to eta-1
954 // fmiddle2 crosstalk to eta+1
955 float fmiddle1=0.;
956 float fmiddle2=0.;
957 if (ibec==1) {
960 }
961 if (ibec==2) {
964 }
965
966 // next in eta
967 if ( (ibec==1 && eta<55) || (ibec==2 && eta <42) ) {
968 result=m_larem_id->get_neighbours(hashId,
970 if (result==0) {
971 if (tmpList.size() == 1) {
972 e=energy*fmiddle2;
973 er=er-e;
974 neighbourList.push_back(tmpList[0]);
975 energyList.push_back(e);
976 }
977 }
978 }
979 // previous in eta
980 if ( (ibec==1 && eta>0) || (ibec==2 && eta >0) ) {
981 result=m_larem_id->get_neighbours(hashId,
983 if (result==0) {
984 if (tmpList.size() == 1) {
985 e=energy*fmiddle1;
986 er=er-e;
987 neighbourList.push_back(tmpList[0]);
988 energyList.push_back(e);
989 }
990 }
991 }
992 }
993 }
994
995// cross-talk in middle to back
996 if ( (ibec==1 && sampling ==2 && region == 0 )
997 || (ibec==2 && sampling ==2 && region ==1 && eta > 2) // no sampling 3 before 1.5
998 || (ibec==3 && sampling ==1) ) // inner wheel
999 {
1000 if (ibec==1) {
1002 } else if(ibec==2) {
1004 } else if(ibec==3) {
1005 fcr = weights.get_xtalk(LArXTalkWeightGlobal::MIDDLEBACK_ECIW,eta); // same size of middle and back in IW
1006 }
1007// next sampling
1008 result=m_larem_id->get_neighbours(hashId,
1010 if (result==0) {
1011 if (tmpList.size() == 1) {
1012 e=energy*fcr;
1013 er=er-e;
1014 neighbourList.push_back(tmpList[0]);
1015 energyList.push_back(e);
1016 }
1017 }
1018 }
1019
1020// cross-talk back to middle
1021 if ( (ibec==1 && sampling == 3 && region == 0 )
1022 ||(ibec==2 && sampling ==3)
1023 ||(ibec==3 && sampling ==2) )
1024 {
1025 if (ibec==1) {
1026 // eta2 = eta for middle layer cells
1027 int eta2=2*eta;
1028 fcr=0.5*(weights.get_xtalk(LArXTalkWeightGlobal::MIDDLEBACK,eta2)+weights.get_xtalk(LArXTalkWeightGlobal::MIDDLEBACK,eta2+1));
1029 } else if(ibec==2) {
1030 int eta2=3+2*eta;
1032 } else if(ibec==3) {
1034 }
1035// previous sampling, expect two channels in middle for barrel + OW, one for IW
1036 result = m_larem_id->get_neighbours(hashId,
1038 if (result==0) {
1039 if ((ibec==1 || ibec==2) && tmpList.size() == 2) {
1040 fcr=fcr/2.;
1041 e=energy*fcr;
1042 er=er-2.*e;
1043 neighbourList.push_back(tmpList[0]);
1044 neighbourList.push_back(tmpList[1]);
1045 energyList.push_back(e);
1046 energyList.push_back(e);
1047 }
1048 if (ibec==1 && tmpList.size()==1) {
1049 e=energy*fcr;
1050 er=er-e;
1051 neighbourList.push_back(tmpList[0]);
1052 energyList.push_back(e);
1053 }
1054 if (ibec==3 && tmpList.size() ==1) {
1055 e=energy*fcr;
1056 er=er-e;
1057 neighbourList.push_back(tmpList[0]);
1058 energyList.push_back(e);
1059 }
1060 }
1061 }
1062
1063// remaining energy in original cell
1064 neighbourList.push_back(hashId);
1065 energyList.push_back(er);
1066
1067}
1068
1069// ----------------------------------------------------------------------------------------------------------------------------------
1070
1071
1072//
1073// take accumulated energy in cell vector for a given bunch time and push that in the hit map
1074
1076
1077 for (unsigned int i=0;i<data.m_energySum.size();i++) {
1078 float e = data.m_energySum[i];
1079 if (e>1e-6) {
1080 if (!data.m_hitmap->AddEnergy(i,e,bunchTime)) return false;
1081 }
1082 data.m_energySum[i]=0.;
1083 }
1084 if(m_doDigiTruth){
1085 for (unsigned int i=0;i<data.m_energySum_DigiHSTruth.size();i++) {
1086 float e = data.m_energySum_DigiHSTruth[i];
1087 if (e>1e-6) {
1088 if (!data.m_hitmap_DigiHSTruth->AddEnergy(i,e,bunchTime)) return false;
1089 }
1090 data.m_energySum_DigiHSTruth[i]=0.;
1091 }
1092 }
1093
1094 return true;
1095}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
interface to a tool that returns the time offset of the current trigger.
static Double_t sc
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
SeedingOptionType
Options for seeding option=0 is setSeed as in MC20 option=1 is setSeedLegacy as in MC16 option=2 is s...
Definition RNGWrapper.h:97
void setSeedLegacy(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, uint64_t offset, SeedingOptionType seeding, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
boost::transform_iterator< make_const, typename CONT::const_iterator > const_iterator
const_iterator end() const
const_iterator begin() const
This class provides the client interface for accessing the detector description information common to...
This class initializes the Calo (LAr and Tile) offline identifiers.
const LArHEC_ID * getHEC_ID(void) const
const LArFCAL_ID * getFCAL_ID(void) const
const LArEM_ID * getEM_ID(void) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
This is a "hash" representation of an Identifier.
Container class for LArDigit.
Liquid Argon digit base class.
Definition LArDigit.h:25
Hit collection.
Container for LArHitFloat.
Class to store hit energy and time in LAr cell from G4 simulation.
Definition LArHitFloat.h:18
Class to store hit energy and time in LAr cell from G4 simulation.
Definition LArHit.h:25
Gaudi::Property< bool > m_NoiseOnOff
Gaudi::Property< bool > m_useLArHitFloat
Gaudi::Property< bool > m_CrossTalkMiddle
Gaudi::Property< float > m_scaleStripMiddle
Gaudi::Property< bool > m_useMBTime
Gaudi::Property< float > m_WindowsPhiSize
Gaudi::Property< bool > m_CrossTalk2Strip
const CaloCell_ID * m_calocell_id
virtual StatusCode initialize() override final
const LArFCAL_ID * m_larfcal_id
std::vector< std::string > m_hitContainerNames
Gaudi::Property< bool > m_ignoreTime
Gaudi::Property< float > m_phaseMin
SG::ReadHandleKey< CosTrigTime > m_timeKey
SG::WriteHandleKey< LArHitEMap > m_hitMapKey_DigiHSTruth
Gaudi::Property< bool > m_isMcOverlay
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Gaudi::Property< bool > m_NoiseInEMB
Gaudi::Property< bool > m_CrossTalkStripMiddle
Gaudi::Property< bool > m_NoiseInEMEC
Gaudi::Property< float > m_WindowsEtaSize
Gaudi::Property< bool > m_doDigiTruth
bool fillMapfromSum(float bunchTime, perEventData_t &data) const
SG::ReadHandleKeyArray< LArHitFloatContainer > m_hitFloatContainerKeys
Gaudi::Property< bool > m_NoiseInFCAL
Gaudi::Property< float > m_scaleStripXtalk
Gaudi::Property< float > m_WindowsPtCut
Gaudi::Property< bool > m_RndmEvtOverlay
LArPileUpTool(const std::string &type, const std::string &name, const IInterface *parent)
SG::ReadHandleKey< LArDigitContainer > m_inputDigitContainerKey
StringArrayProperty m_inputKeys
Gaudi::Property< float > m_phaseMax
StatusCode fillMapFromHit(const EventContext &ctx, float tbunch, bool isSignal, perEventData_t &data) const
SG::ReadHandleKey< McEventCollection > m_mcEventColl
ServiceHandle< PileUpMergeSvc > m_mergeSvc
Gaudi::Property< bool > m_addPhase
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Gaudi::Property< uint32_t > m_randomSeedOffset
virtual StatusCode prepareEvent(const EventContext &ctx, unsigned int nInputEvents) override final
Gaudi::Property< bool > m_useLegacyRandomSeeds
const LArOnlineID * m_laronline_id
SG::ReadCondHandleKey< LArXTalkWeightGlobal > m_xtalkKey
StatusCode AddHit(const Identifier cellId, const float energy, const float time, const bool iSignal, perEventData_t &data) const
void cross_talk(const IdentifierHash &idHash, const Identifier &cellId, const float &energy, std::vector< IdentifierHash > &neighbourList, std::vector< float > &energyList, const LArXTalkWeightGlobal &weights) const
Gaudi::Property< bool > m_onlyUseContainerName
Gaudi::Property< bool > m_useTriggerTime
const LArEM_ID * m_larem_id
Gaudi::Property< bool > m_PileUp
SG::WriteHandleKey< LArHitEMap > m_hitMapKey
Gaudi::Property< bool > m_NoiseInHEC
Gaudi::Property< float > m_scaleMiddleXtalk
const LArHEC_ID * m_larhec_id
SG::ReadHandleKeyArray< LArHitContainer > m_hitContainerKeys
ServiceHandle< IAthRNGSvc > m_rndmGenSvc
virtual StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
perEventData_t m_data
Gaudi::Property< bool > m_Windows
Gaudi::Property< bool > m_CrossTalk
Gaudi::Property< std::string > m_randomStreamName
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)
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
@ Signal
The signal event.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
time_type time() const
bunch xing time in ns