ATLAS Offline Software
Loading...
Searching...
No Matches
TRTDigitizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TRTDigitizationTool.cxx
7//
8// Implementation file for class TRTDigitizationTool
9//
11
12#include "TRTDigitizationTool.h"
17
18#include "TRTDigCondBase.h"
19#include "TRTDigCondFakeMap.h"
20
21#include "TRTNoise.h"
22#include "TRTDigiHelper.h"
23#include "TRTElectronicsNoise.h"
24
25#include "Identifier/Identifier.h"
28
30
31// Det descr includes:
34#include "TRTDigSettings.h"
35
38
39// Gaudi includes
40#include "GaudiKernel/EventContext.h"
41
42//CondDB
44
45// Random Number Generation
47#include "CLHEP/Random/RandomEngine.h"
48#include "CLHEP/Random/RandGaussZiggurat.h"
49
50
51//_____________________________________________________________________________
53 const std::string& name,
54 const IInterface* parent)
55: PileUpToolBase(type, name, parent)
56{
58 m_settings->addPropertiesForOverrideableParameters(static_cast<AlgTool*>(this));
59}
60
61//_____________________________________________________________________________
63
64 ATH_MSG_VERBOSE ( "Begin TRTDigitizationTool::Destructor");
67 delete m_pDigConditions;
68 delete m_pNoise;
69 delete m_settings;
70 ATH_MSG_VERBOSE ( "End TRTDigitizationTool::Destructor");
71
72}
73
74//_____________________________________________________________________________
76{
77
78 ATH_MSG_DEBUG ( name()<<"::initialize() begin" );
79
80 // Get the TRT Detector Manager
81 ATH_CHECK(detStore()->retrieve(m_manager,"TRT"));
82 ATH_MSG_DEBUG ( "Retrieved TRT_DetectorManager with version " << m_manager->getVersion().majorNum() );
83
84 ATH_CHECK(detStore()->retrieve(m_trt_id, "TRT_ID"));
85
86 // Fill setting defaults and process joboption overrides:
87 m_settings->initialize(m_manager);
88
90 m_settings->printFlagsForOverrideableParameters("TRTDigSettings Overrideables : ");
91 }
92
94
95 ATH_CHECK(m_TRTpaiToolXe.retrieve());
96 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Xe straws" );
97
98 ATH_CHECK(m_TRTpaiToolAr.retrieve());
99 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Ar straws" );
100
101 ATH_CHECK(m_TRTpaiToolKr.retrieve());
102 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Kr straws" );
103
106 ATH_MSG_DEBUG ( "Retrieved the Sim. Drifttime Tool" );
107
108 // Check data object name
109 if (m_hitsContainerKey.key().empty()) {
110 ATH_MSG_FATAL ( "Property DataObjectName not set!" );
111 return StatusCode::FAILURE;
112 }
114 ATH_MSG_DEBUG ( "Input hits: " << m_dataObjectName );
115
116 // Initialize ReadHandleKey
117 ATH_CHECK(m_hitsContainerKey.initialize(true));
118
119 // Initialize data handle keys
120 ATH_CHECK(m_outputRDOCollName.initialize());
121 ATH_CHECK(m_outputSDOCollName.initialize());
122
123 // Get Random Service
124 ATH_CHECK(m_rndmSvc.retrieve());
125
126 //locate the PileUpMergeSvc and initialize our local ptr
128 ATH_CHECK(m_mergeSvc.retrieve());
129 }
130
131 //Retrieve TRT_StrawNeighbourService.
133
134 //Retrieve TRT_CalDbTool
135 if (m_settings->getT0FromData()) {
136 ATH_CHECK(m_calDbTool.retrieve());
137 }
138 else {
139 m_calDbTool.disable();
140 }
141
142 m_minpileuptruthEkin = m_settings->pileUpSDOsMinEkin();
143
144 // Set SDO readout range
145 const double intervalBetweenCrossings(m_settings->timeInterval() / 3.);
146
147 switch ( (m_settings->storeSDO() )) {
148 case 0: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = -1.*CLHEP::ns; break;
149 case 1: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
150 case 2: m_minCrossingTimeSDO = -(intervalBetweenCrossings * 2. + 1.*CLHEP::ns); m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
151 default:
152 ATH_MSG_ERROR ( "storeSDO is out of range:"<<m_settings->storeSDO()<<"allowed values are: 0,1,2. Setting storeSDO = 2 " );
153 m_minCrossingTimeSDO = -51.*CLHEP::ns; m_maxCrossingTimeSDO = 51.*CLHEP::ns;
154 break;
155 }
156
159 ATH_CHECK( m_trtDetElementsInputKey.initialize() );
161
162 return StatusCode::SUCCESS;
163}
164
165//_____________________________________________________________________________
166StatusCode TRTDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
167{
168 m_vDigits.clear();
169 m_trtHitCollList.clear();
172 return StatusCode::SUCCESS;
173}
174
175//_____________________________________________________________________________
177 SubEventIterator bSubEvents,
178 SubEventIterator eSubEvents) {
179
180 m_seen.emplace_back(std::distance(bSubEvents,eSubEvents), bunchXing);
181 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
182 if (m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
183 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
185
186
187 //TRTUncompressedHit
188
190 TimedHitCollList hitCollList;
191
192 if (!(m_mergeSvc->retrieveSubSetEvtData(m_dataObjectName, hitCollList, bunchXing,
193 bSubEvents, eSubEvents).isSuccess()) &&
194 hitCollList.empty()) {
195 ATH_MSG_ERROR("Could not fill TimedHitCollList");
196 return StatusCode::FAILURE;
197 } else {
198 ATH_MSG_VERBOSE(hitCollList.size() << " TRTUncompressedHitCollection with key " <<
199 m_dataObjectName << " found");
200 }
201
202 TimedHitCollList::iterator iColl(hitCollList.begin());
203 TimedHitCollList::iterator endColl(hitCollList.end());
204
205 for( ; iColl != endColl; ++iColl){
206 TRTUncompressedHitCollection *hitCollPtr = new TRTUncompressedHitCollection(*iColl->second);
207 PileUpTimeEventIndex timeIndex(iColl->first);
208 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollPtr->size() <<
209 " hits");
210 ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
211 << " index: " << timeIndex.index()
212 << " type: " << timeIndex.type());
213 m_thpctrt->insert(timeIndex, hitCollPtr);
214 m_trtHitCollList.push_back(hitCollPtr);
215 }
216
217 return StatusCode::SUCCESS;
218}
219
220//_____________________________________________________________________________
221StatusCode TRTDigitizationTool::lateInitialize(const EventContext& ctx) {
222
223 // setup the RNGs which are only used in the first event
224 CLHEP::HepRandomEngine *fakeCondRndmEngine = getRandomEngine("TRT_FakeConditions", m_randomSeedOffset, ctx);
225 CLHEP::HepRandomEngine *noiseInitRndmEngine = getRandomEngine("TRT_Noise", m_randomSeedOffset, ctx);
226 CLHEP::HepRandomEngine *noiseElecRndmEngine = getRandomEngine("TRT_Noise_Electronics", m_randomSeedOffset, ctx);
227 CLHEP::HepRandomEngine *noiseThreshRndmEngine = getRandomEngine("TRT_Noise_ThresholdFluctuations", m_randomSeedOffset, ctx);
228 CLHEP::HepRandomEngine *noiseElecResetRndmEngine = getRandomEngine("TRT_ElectronicsNoiseReset", m_randomSeedOffset, ctx);
229 m_first_event=false;
230
231 //Resuming initialiazation. Section below had to be moved into event loop due to dependence on conditions data
232
233 TRTElectronicsNoise *electronicsNoise(nullptr);
234 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
235 electronicsNoise = new TRTElectronicsNoise(m_settings, noiseElecRndmEngine);
236 }
237 // ElectronicsProcessing is needed for the regular straw processing,
238 // but also for the noise (it assumes ownership of electronicsnoise )
240
242 m_manager,
243 m_trt_id,
245 m_sumTool);
246
247 m_pDigConditions->initialize(fakeCondRndmEngine);
248
249 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
250
251 // In short this next constructor does 3 things;
252 // i) tunes the amplitude of the electronics noise,
253 // ii) creates a pool of noise digits,
254 // iii) figures out exact low thresholds needed to reproduce actual
255 // straw noise-frequencies:
257 m_manager,
258 noiseInitRndmEngine,
259 noiseElecRndmEngine,
260 noiseThreshRndmEngine,
261 noiseElecResetRndmEngine,
264 electronicsNoise,
265 m_trt_id,
267 m_sumTool);
268
269 ATH_MSG_DEBUG ( "Average straw noise level is " << m_pDigConditions->strawAverageNoiseLevel() );
270
271 } else {
272 m_pNoise = nullptr;
273 }
274
275 ITRT_PAITool *TRTpaiToolXe = &(* m_TRTpaiToolXe);
276 ITRT_PAITool *TRTpaiToolAr = &(* m_TRTpaiToolAr);
277 ITRT_PAITool *TRTpaiToolKr = &(* m_TRTpaiToolKr);
278
279 ITRT_SimDriftTimeTool *pTRTsimdrifttimetool = &(*m_TRTsimdrifttimetool);
280
281 const ITRT_CalDbTool* calDbTool = nullptr;
282 if (m_settings->getT0FromData()) {
283 calDbTool = m_calDbTool.get();
284 }
287 m_manager,
288 TRTpaiToolXe,
289 pTRTsimdrifttimetool,
291 m_pNoise,
293 m_trt_id,
294 TRTpaiToolAr,
295 TRTpaiToolKr,
296 calDbTool);
297
298 ATH_MSG_INFO ( "Gas Property: UseGasMix is " << m_UseGasMix );
299
300 return StatusCode::SUCCESS;
301}
302
303//_____________________________________________________________________________
304StatusCode TRTDigitizationTool::processStraws(const EventContext& ctx,
306 std::set<int>& sim_hitids, std::set<Identifier>& simhitsIdentifiers,
307 CLHEP::HepRandomEngine *rndmEngine,
308 CLHEP::HepRandomEngine *strawRndmEngine,
309 CLHEP::HepRandomEngine *elecProcRndmEngine,
310 CLHEP::HepRandomEngine *elecNoiseRndmEngine,
311 CLHEP::HepRandomEngine *paiRndmEngine) {
312
313 // Create a map for the SDO
315
317 // Access to Conditions objects
318 MagField::AtlasFieldCache fieldCache;
319 if (m_settings->useMagneticFieldMap()) {
320
321 // Get field cache object
323 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
324
325 if (fieldCondObj == nullptr) {
326 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
327 return StatusCode::FAILURE;
328 }
329 fieldCondObj->getInitializedCache (fieldCache);
330 }
331
333 const InDetDD::TRT_DetElementContainer* trtDetElements{*trtDetElementsHandle};
334 if(!trtDetElements) {
335 ATH_MSG_ERROR("Failed to retrieve TRT_DetElementContainer with key " << m_trtDetElementsInputKey.key());
336 return StatusCode::FAILURE;
337 }
339
340
341 ATH_CHECK(simDataMap.record(std::make_unique<InDetSimDataCollection>() ));
342
343 // Register the map into StoreGate
344 if (not simDataMap.isValid()) {
345 ATH_MSG_FATAL ( "InDetSimData map " << m_outputSDOCollName.key() << " could not be registered in StoreGate !" );
346 return StatusCode::FAILURE;
347 } else {
348 ATH_MSG_DEBUG ( "InDetSimData map " << m_outputSDOCollName.key() << " registered in StoreGate" );
349 }
350
351 m_cosmicEventPhase = 0.0;
352 if (m_settings->doCosmicTimingPit()) {
354 };
355
356 // Create a vector of deposits
357 std::vector<InDetSimData::Deposit> depositVector(100);
358
359 // loop over all straws
361 while (thpctrt.nextDetectorElement(i, e)) {
362
363 int hitID((*i)->GetHitID()); // Get hitID
364
365 // evtIndex should be 0 for main event and 1,2,3,... for pileup events:
366 // (event Id is a property of the TimedHitPtr)
367 HepMcParticleLink::index_type evtIndex(i->eventId());
368
369 if ( m_settings->noiseInUnhitStraws() ) {
370 sim_hitids.insert(hitID);
371 }
372 //Safeguard against a rare case of hitID corruption found by Davide:
373 if ( hitID & 0xc0000000 ) {
374 ATH_MSG_ERROR ( "Hit ID not Valid (" << MSG::hex << hitID << ")" << MSG::dec );
375 continue;
376 }
377
378 // Convert hitID to Identifier
379 IdentifierHash IdHash;
380 Identifier idLayer;
381 bool identifierOK;
382 Identifier idStraw(getIdentifier(hitID, IdHash, idLayer, identifierOK));
383 if ( !identifierOK ) {
384 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (1)" );
385 continue;
386 }
387
388 //For crosstalk sim
389 simhitsIdentifiers.insert(idStraw);
390
392 // Fill a vector of deposits
393 depositVector.clear();
394 depositVector.reserve(std::distance(i,e));
395 for (TimedHitCollection<TRTUncompressedHit>::const_iterator hit_iter(i); hit_iter != e; ++hit_iter ) {
396 // create a new deposit
397 InDetSimData::Deposit deposit( HepMcParticleLink::getRedirectedLink((*hit_iter)->particleLink(), hit_iter->eventId(), ctx), // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
398 (*hit_iter)->GetEnergyDeposit() );
400 continue;
401 }
402 ATH_MSG_VERBOSE ( "Deposit: trackID " << deposit.first << " energyDeposit " << deposit.second );
403 depositVector.emplace_back(std::move(deposit));
404 }
405
406 const TimedHitPtr<TRTUncompressedHit>& theHit(*i);
407 const double bunchCrossingTime(hitTime(theHit) - static_cast<double>(theHit->GetGlobalTime()));
408
409 // Add the simdata object to the map.
410 if ( !depositVector.empty() &&
411 (evtIndex == 0 || ((*i)->GetKineticEnergy()>m_minpileuptruthEkin)) &&
412 (bunchCrossingTime < m_maxCrossingTimeSDO) && (bunchCrossingTime > m_minCrossingTimeSDO) ) {
413 simDataMap->try_emplace(idStraw, std::move(depositVector));
414 }
416
417 // Digitization for the given straw
418 TRTDigit digit_straw;
419
421 //if (m_settings->doCosmicTimingPit()) {
422 // if ( StatusCode::SUCCESS == evtStore()->retrieve(m_ComTime,"ComTime")) {
423 // ATH_MSG_VERBOSE ( "Found tool for cosmic timing: ComTime" );
424 // } else {
425 // ATH_MSG_ERROR ( "Did not find tool needed for cosmic timing: ComTime" );
426 // }
427 //}
428
429 // if StatusHT == 6 thats emulate argon, ==7 that's emulate krypton
430 bool emulateArFlag = m_sumTool->getStatusHT(idStraw, ctx) == 6;
431 bool emulateKrFlag = m_sumTool->getStatusHT(idStraw, ctx) == 7;
432 const int statusHT = m_sumTool->getStatusHT(idStraw, ctx);
433 m_pProcessingOfStraw->ProcessStraw(fieldCache, trtDetElements, i, e, digit_straw,
435 m_cosmicEventPhase, //m_ComTime,
437 emulateArFlag,
438 emulateKrFlag,
439 strawRndmEngine,
440 elecProcRndmEngine,
441 elecNoiseRndmEngine,
442 paiRndmEngine);
443
444 // Print out the digits etc (for debugging)
445 //int mstrw = digit_straw.GetStrawID();
446 //unsigned int mword = digit_straw.GetDigit();
447 //std::cout << "AJB " << mstrw << ":" << mword << std::endl;
448 //print_mword_properties(mword);
449 //std::cout << "AJB "; bits24(mword);
450 //std::cout << "AJB "; bits27(mword);
451
452 // finally push back the output digit.
453 if ( digit_straw.GetDigit() ) {
454 m_vDigits.push_back(digit_straw);
455 }
456
457 } // end of straw loop
458
459 return StatusCode::SUCCESS;
460}
461
462//_____________________________________________________________________________
463StatusCode TRTDigitizationTool::processAllSubEvents(const EventContext& ctx) {
464
465 // Set the RNGs to use for this event.
466 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
467 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
468 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
469 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
470 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
471 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
472
473 if (m_first_event) {
474 if(this->lateInitialize(ctx).isFailure()) {
475 ATH_MSG_FATAL ( "lateInitialize method failed!" );
476 return StatusCode::FAILURE;
477 }
478 }
479
481
482 ATH_MSG_DEBUG ( "TRTDigitizationTool::processAllSubEvents()" );
483
485 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
486 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
487
488 if (not m_trtrdo_container.isValid()) {
489 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
490 return StatusCode::FAILURE;
491 }else {
492 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
493 }
494
495 m_vDigits.clear();
496
497 // get the container(s)
500 // In case of single hits container just load the collection using read handles
503 if (!hitCollection.isValid()) {
504 ATH_MSG_ERROR("Could not get TRTUncompressedHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
505 return StatusCode::FAILURE;
506 }
507
508 // Define Hit Collection
509 thpctrt.reserve(1);
510
511 // create a new hits collection
512 thpctrt.insert(0, hitCollection.cptr());
513 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollection->size() << " hits");
514 }
515 else {
516 TimedHitCollList hitCollList; // this is a list<pair<time_t, DataLink<TRTUncompressedHitCollection> > >
517 unsigned int numberOfSimHits(0);
518 if ( !(m_mergeSvc->retrieveSubEvtsData(m_dataObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
519 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
520 return StatusCode::FAILURE;
521 } else {
522 ATH_MSG_DEBUG ( hitCollList.size() << " TRTUncompressedHitCollections with key " << m_dataObjectName << " found" );
523 }
524
525 // Define Hit Collection
526 thpctrt.reserve(numberOfSimHits);
527
528 //now merge all collections into one
529 TimedHitCollList::iterator iColl(hitCollList.begin());
530 TimedHitCollList::iterator endColl(hitCollList.end() );
532 // loop on the hit collections
533 while ( iColl != endColl ) {
534 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
536 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
538 const TRTUncompressedHitCollection* p_collection(iColl->second);
539 thpctrt.insert(iColl->first, p_collection);
540 ATH_MSG_DEBUG ( "TRTUncompressedHitCollection found with " << p_collection->size() << " hits" );
541 ++iColl;
542 }
543 }
544
545 //Set of all hitid's with simhits (used for noise simulation).
546 std::set<int> sim_hitids;
547 std::set<Identifier> simhitsIdentifiers;
548
549 // Process the Hits straw by straw: get the iterator pairs for given straw
550 ATH_CHECK(this->processStraws(ctx, thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
551
552 // no more hits
553
554 //Noise in straws without simhits:
555 if (m_settings->noiseInUnhitStraws()) {
556 const int numberOfDigitsBeforeNoise(m_vDigits.size());
557
558 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
559 if (m_settings->doCrosstalk()) {
560 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
561 }
562
563 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
564
566
567 } else {
568 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
569 }
570
571 // All digits are ready.
572 // We just need to convert to relevant identifiers and output to storegate.
573
574 if (createAndStoreRDOs().isFailure()) {
575 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
576 return StatusCode::FAILURE;
577 }
578 else {
579 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
580 }
581
582 return StatusCode::SUCCESS;
583}
584
585CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName,
586 const EventContext& ctx) const
587{
588 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
589 std::string rngName = name()+streamName;
590 rngWrapper->setSeed( rngName, ctx );
591 return rngWrapper->getEngine(ctx);
592}
593
594//_____________________________________________________________________________
595CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset,
596 const EventContext& ctx) const
597{
598 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
599 rngWrapper->setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
600 return rngWrapper->getEngine(ctx);
601}
602
603//_____________________________________________________________________________
604StatusCode TRTDigitizationTool::mergeEvent(const EventContext& ctx) {
605 std::vector<std::pair<unsigned int, int> >::iterator ii(m_seen.begin());
606 std::vector<std::pair<unsigned int, int> >::iterator ee(m_seen.end());
607 while (ii != ee) {
608 ATH_MSG_DEBUG( "mergeEvent: there are " << ii->first << " events in bunch xing " << ii->second );
609 ++ii;
610 }
611
612 // Set the RNGs to use for this event.
613 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
614 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
615 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
616 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
617 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
618 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
619
620 if (m_first_event) {
621 if(this->lateInitialize(ctx).isFailure()) {
622 ATH_MSG_FATAL ( "lateInitialize method failed!" );
623 return StatusCode::FAILURE;
624 }
625 }
626
628
629 ATH_MSG_DEBUG ( "TRTDigitization::execute()" );
630
632 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
633 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
634 if (not m_trtrdo_container.isValid()) {
635 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
636 return StatusCode::FAILURE;
637 } else {
638 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
639 }
640
641 //Set of all hitid's with simhits (used for noise simulation).
642 std::set<int> sim_hitids;
643 std::set<Identifier> simhitsIdentifiers;
644
645 // Process the Hits straw by straw:
646 // get the iterator pairs for given straw
647 ATH_CHECK(this->processStraws(ctx, *m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
648
649 delete m_thpctrt;
650 for(TRTUncompressedHitCollection* ptr : m_trtHitCollList) delete ptr;
651 m_trtHitCollList.clear();
652 // no more hits
653
654 //Noise in straws without simhits:
655 if (m_settings->noiseInUnhitStraws()) {
656 const unsigned int numberOfDigitsBeforeNoise(m_vDigits.size());
657
658 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
659 if (m_settings->doCrosstalk()) {
660 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
661 }
662
663 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
664
666
667 } else {
668 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
669 };
670
671 // All digits are ready.
672 // We just need to convert to relevant identifiers and output to storegate.
673
674 if (createAndStoreRDOs().isFailure()) {
675 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
676 return StatusCode::FAILURE;
677 }
678 else {
679 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
680 }
681
682 return StatusCode::SUCCESS;
683}
684
685//_____________________________________________________________________________
687{
688
689 std::vector<TRTDigit>::const_iterator TRTDigitIter(m_vDigits.begin());
690 std::vector<TRTDigit>::const_iterator endOfTRTDigits(m_vDigits.end());
691
692 // for testing
693 IdentifierHash IdHash; // default value is 0xFFFFFFFF
694 IdentifierHash IdHashOld; // default value is 0xFFFFFFFF
695 TRT_RDO_Collection *RDOColl(nullptr);
696
697 Identifier idStraw;
698
699 while (TRTDigitIter != endOfTRTDigits) {
700 ATH_MSG_DEBUG ( "Digit ID " << TRTDigitIter->GetStrawID() << " Digit " << TRTDigitIter->GetDigit() );
701
702 Identifier layer_id;
703 bool identifierOK(false);
704 idStraw = getIdentifier(TRTDigitIter->GetStrawID(), IdHash, layer_id, identifierOK);
705 if (!identifierOK) {
706 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (2)" );
707 ++TRTDigitIter;
708 continue;
709 };
710
711 // Create new TRT RDO Collection
712 ATH_MSG_DEBUG ( " RDO ID " << m_trt_id->print_to_string(idStraw) );
713
714 //TK: wauv - we are really betting the farm on the fact that the
715 //ordering of digits will result in a similar ordering of the
716 //idhash'es here... (this is not immediately the case when noise
717 //hits are appended afterwards).
718
719 if (IdHash != IdHashOld) {
720 RDOColl = new TRT_RDO_Collection(IdHash);
721 ATH_MSG_DEBUG ( "New TRT RDO Collection created with IdHash " << static_cast<int>(IdHash) );
722 IdHashOld = IdHash;
723 RDOColl->setIdentifier(layer_id);
724
725 // Add to the container
726 if (m_trtrdo_container->addCollection(RDOColl, RDOColl->identifyHash()).isFailure()) {
727 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
728 return StatusCode::FAILURE;
729 } else {
730 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
731 }
732 }
733
734 // Put RDO into Collection
735 TRT_LoLumRawData *p_rdo(new TRT_LoLumRawData(idStraw, TRTDigitIter->GetDigit()));
736 if (RDOColl) {
737 RDOColl->push_back(p_rdo);
738 } else {
739 ATH_MSG_FATAL ( "Failed to create the TRT_RDO_Collection before trying to add an RDO to it! IdHash = " << static_cast<int>(IdHash) );
740 delete p_rdo;
741 return StatusCode::FAILURE;
742 }
743 ++TRTDigitIter;
744 }
745
746 m_vDigits.clear();
747 return StatusCode::SUCCESS;
748}
749
750
751//_____________________________________________________________________________
753 IdentifierHash& hashId,
754 Identifier& IdLayer,
755 bool & statusok ) const
756{
757 statusok = true;
758
759 Identifier IdStraw;
760
761 const int mask(0x0000001F);
762 const int word_shift(5);
763 int trtID, ringID, moduleID, layerID, strawID;
764 int wheelID, planeID, sectorID;
765
766 const InDetDD::TRT_BarrelElement *barrelElement;
767 const InDetDD::TRT_EndcapElement *endcapElement;
768
769 if ( !(hitID & 0x00200000) ) { // barrel
770 strawID = hitID & mask;
771 hitID >>= word_shift;
772 layerID = hitID & mask;
773 hitID >>= word_shift;
774 moduleID = hitID & mask;
775 hitID >>= word_shift;
776 ringID = hitID & mask;
777 trtID = hitID >> word_shift;
778
779 barrelElement = m_manager->getBarrelElement(trtID, ringID, moduleID, layerID);
780 if ( barrelElement ) {
781 hashId = barrelElement->identifyHash();
782 IdLayer = barrelElement->identify();
783 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
784 } else {
785 ATH_MSG_ERROR ( "Could not find detector element for barrel identifier with "
786 << "(ipos,iring,imod,ilayer,istraw) = ("
787 << trtID << ", " << ringID << ", " << moduleID << ", "
788 << layerID << ", " << strawID << ")" );
789 statusok = false;
790 }
791 } else { // endcap
792 strawID = hitID & mask;
793 hitID >>= word_shift;
794 planeID = hitID & mask;
795 hitID >>= word_shift;
796 sectorID = hitID & mask;
797 hitID >>= word_shift;
798 wheelID = hitID & mask;
799 trtID = hitID >> word_shift;
800
801 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
802 if (trtID == 3) { trtID = 0; }
803 else { trtID = 1; }
804
805 endcapElement = m_manager->getEndcapElement(trtID, wheelID, planeID, sectorID);
806
807 if ( endcapElement ) {
808 hashId = endcapElement->identifyHash();
809 IdLayer = endcapElement->identify();
810 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
811 } else {
812 ATH_MSG_ERROR ( "Could not find detector element for endcap identifier with "
813 << "(ipos,iwheel,isector,iplane,istraw) = ("
814 << trtID << ", " << wheelID << ", " << sectorID << ", "
815 << planeID << ", " << strawID << ")" );
816 ATH_MSG_ERROR ( "If this happens very rarely, don't be alarmed (it is a Geant4 'feature')" );
817 ATH_MSG_ERROR ( "If it happens a lot, you probably have misconfigured geometry in the sim. job." );
818 statusok = false;
819 }
820
821 }
822
823 return IdStraw;
824}
825
826//_____________________________________________________________________________
828
830 m_settings->print("TRTDigSettings Settings : ");
831 }
832
833 ATH_MSG_INFO ( "TRTDigitizationTool::finalize()" );
834
835 return StatusCode::SUCCESS;
836}
837
838//_____________________________________________________________________________
839double TRTDigitizationTool::getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine) {
840 // 13th February 2015: replace ComTime with a hack (fixme) based on an
841 // event phase distribution from Alex (alejandro.alonso@cern.ch) that
842 // is modelled as a Guassian of mean 5.48 ns and sigma 8.91 ns.
843 return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 5.48, 8.91);
844}
float hitTime(const AFP_SIDSimHit &hit)
#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_DEBUG(x)
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
a sample implementation of IPileUpTool to test the framework
AtlasHitsVector< TRTUncompressedHit > TRTUncompressedHitCollection
This is an Identifier helper class for the TRT subdetector.
InDetRawDataCollection< TRT_RDORawData > TRT_RDO_Collection
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:154
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:108
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
size_type size() const
value_type push_back(value_type pElem)
abstract interface to TRT calibration constants
Give and AlgTool interface to the PAI model.
This is a "hash" representation of an Identifier.
Extended TRT_BaseElement to describe a TRT readout element, this is a planar layer with n ( order of ...
virtual IdentifierHash identifyHash() const override final
identifier hash
virtual Identifier identify() const override final
identifier of this detector element:
Class to hold different TRT detector elements structures.
Extended class of a TRT_BaseElement to describe a readout elment in the endcap.
virtual IdentifierHash identifyHash() const override final
void setIdentifier(Identifier id)
std::pair< HepMcParticleLink, float > Deposit
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
Gaudi::Property< int > m_vetoPileUpTruthLinks
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)
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.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
"Fake" straw map until "real" map is known.
Class containing parameters and settings used by TRT digitization.
Class for TRT digits.
Definition TRTDigit.h:11
unsigned GetDigit() const
Get digit.
Definition TRTDigit.h:27
TRTProcessingOfStraw * m_pProcessingOfStraw
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
virtual StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
called for each active bunch-crossing to process current SubEvents bunchXing is in ns
virtual StatusCode prepareEvent(const EventContext &ctx, const unsigned int nInputEvents) override final
return false if not interested in certain xing times (in ns) implemented by default in PileUpToolBase...
Gaudi::Property< bool > m_printUsedDigSettings
static double getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine)
ToolHandle< ITRT_CalDbTool > m_calDbTool
SG::ReadCondHandleKey< InDetDD::TRT_DetElementContainer > m_trtDetElementsInputKey
std::vector< std::pair< unsigned int, int > > m_seen
ToolHandle< ITRT_PAITool > m_TRTpaiToolXe
Configurable properties.
ToolHandle< ITRT_SimDriftTimeTool > m_TRTsimdrifttimetool
TRTDigSettings * m_settings
SG::ReadHandleKey< TRTUncompressedHitCollection > m_hitsContainerKey
StatusCode processStraws(const EventContext &ctx, TimedHitCollection< TRTUncompressedHit > &thpctrt, std::set< int > &sim_hitids, std::set< Identifier > &simhitsIdentifiers, CLHEP::HepRandomEngine *rndmEngine, CLHEP::HepRandomEngine *strawRndmEngine, CLHEP::HepRandomEngine *elecProcRndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, CLHEP::HepRandomEngine *paiRndmEngine)
ServiceHandle< ITRT_StrawNeighbourSvc > m_TRTStrawNeighbourSvc
Gaudi::Property< bool > m_onlyUseContainerName
std::vector< TRTDigit > m_vDigits
Vector of all digits.
Gaudi::Property< bool > m_printOverrideableSettings
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
TRTDigCondBase * m_pDigConditions
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
Perform digitization:
const InDetDD::TRT_DetectorManager * m_manager
Gaudi::Property< unsigned long int > m_randomSeedOffset
TimedHitCollection< TRTUncompressedHit > * m_thpctrt
virtual StatusCode initialize() override final
Initialize.
virtual StatusCode finalize() override final
Finalize.
Gaudi::Property< int > m_UseGasMix
StatusCode lateInitialize(const EventContext &ctx)
ToolHandle< ITRT_PAITool > m_TRTpaiToolKr
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
TRTElectronicsProcessing * m_pElectronicsProcessing
SG::WriteHandleKey< InDetSimDataCollection > m_outputSDOCollName
name of the output SDOs.
TRTDigitizationTool(const std::string &type, const std::string &name, const IInterface *parent)
SG::WriteHandle< TRT_RDO_Container > m_trtrdo_container
std::vector< TRTUncompressedHitCollection * > m_trtHitCollList
Identifier getIdentifier(int hitID, IdentifierHash &hashId, Identifier &layerID, bool &statusok) const
ServiceHandle< PileUpMergeSvc > m_mergeSvc
const TRT_ID * m_trt_id
TRT Id Helper.
SG::WriteHandleKey< TRT_RDO_Container > m_outputRDOCollName
name of the output RDOs.
ToolHandle< ITRT_StrawStatusSummaryTool > m_sumTool
virtual StatusCode mergeEvent(const EventContext &ctx) override final
called at the end of the subevts loop. Not (necessarily) able to access SubEvents
Gaudi::Property< int > m_HardScatterSplittingMode
ToolHandle< ITRT_PAITool > m_TRTpaiToolAr
Simulate TRT Electronics Noise For description of metod, see Thomas Kittelmanns PhD thesis chapters ...
Simulation of noise hits in the TRT.
Definition TRTNoise.h:39
static void sortDigits(std::vector< TRTDigit > &digitVect)
Definition TRTNoise.cxx:448
TRT Digitization: Processing of a TRT Straws.
void reserve(unsigned int numberOfHits)
reserve a timed vector numberOfHits in size.
bool nextDetectorElement(const_iterator &b, const_iterator &e)
sets an iterator range with the hits of current detector element returns a bool when done
TimedVector::const_iterator const_iterator
void insert(const PileUpTimeEventIndex &timeEventIndex, const AtlasHitsVector< HIT > *inputCollection)
a smart pointer to a hit that also provides access to the extended timing info of the host event.
Definition TimedHitPtr.h:18
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
int StrawGasType(int statusHT, int useGasMix, MsgStream *log)
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
index_type index() const
the index of the component event in PileUpEventInfo
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
time_type time() const
bunch xing time in ns
MsgStream & msg
Definition testRead.cxx:32