ATLAS Offline Software
Loading...
Searching...
No Matches
TRTDigitizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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#include "GaudiKernel/ThreadLocalContext.h"
42
43//CondDB
45
46// Random Number Generation
48#include "CLHEP/Random/RandomEngine.h"
49#include "CLHEP/Random/RandGaussZiggurat.h"
50
51
52//_____________________________________________________________________________
54 const std::string& name,
55 const IInterface* parent)
56: PileUpToolBase(type, name, parent)
57{
59 m_settings->addPropertiesForOverrideableParameters(static_cast<AlgTool*>(this));
60}
61
62//_____________________________________________________________________________
64
65 ATH_MSG_VERBOSE ( "Begin TRTDigitizationTool::Destructor");
68 delete m_pDigConditions;
69 delete m_pNoise;
70 delete m_settings;
71 ATH_MSG_VERBOSE ( "End TRTDigitizationTool::Destructor");
72
73}
74
75//_____________________________________________________________________________
77{
78
79 ATH_MSG_DEBUG ( name()<<"::initialize() begin" );
80
81 // Get the TRT Detector Manager
82 ATH_CHECK(detStore()->retrieve(m_manager,"TRT"));
83 ATH_MSG_DEBUG ( "Retrieved TRT_DetectorManager with version " << m_manager->getVersion().majorNum() );
84
85 ATH_CHECK(detStore()->retrieve(m_trt_id, "TRT_ID"));
86
87 // Fill setting defaults and process joboption overrides:
88 m_settings->initialize(m_manager);
89
91 m_settings->printFlagsForOverrideableParameters("TRTDigSettings Overrideables : ");
92 }
93
95
96 ATH_CHECK(m_TRTpaiToolXe.retrieve());
97 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Xe straws" );
98
99 ATH_CHECK(m_TRTpaiToolAr.retrieve());
100 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Ar straws" );
101
102 ATH_CHECK(m_TRTpaiToolKr.retrieve());
103 ATH_MSG_DEBUG ( "Retrieved the PAI Tool for Kr straws" );
104
107 ATH_MSG_DEBUG ( "Retrieved the Sim. Drifttime Tool" );
108
109 // Check data object name
110 if (m_hitsContainerKey.key().empty()) {
111 ATH_MSG_FATAL ( "Property DataObjectName not set!" );
112 return StatusCode::FAILURE;
113 }
115 ATH_MSG_DEBUG ( "Input hits: " << m_dataObjectName );
116
117 // Initialize ReadHandleKey
118 ATH_CHECK(m_hitsContainerKey.initialize(true));
119
120 // Initialize data handle keys
121 ATH_CHECK(m_outputRDOCollName.initialize());
122 ATH_CHECK(m_outputSDOCollName.initialize());
123
124 // Get Random Service
125 ATH_CHECK(m_rndmSvc.retrieve());
126
127 // Get the Particle Properties Service
128 ATH_CHECK(m_ppSvc.retrieve());
129 m_particleTable = m_ppSvc->PDT();
130
131 //locate the PileUpMergeSvc and initialize our local ptr
133 ATH_CHECK(m_mergeSvc.retrieve());
134 }
135
136 //Retrieve TRT_StrawNeighbourService.
138
139 //Retrieve TRT_CalDbTool
140 if (m_settings->getT0FromData()) {
141 ATH_CHECK(m_calDbTool.retrieve());
142 }
143 else {
144 m_calDbTool.disable();
145 }
146
147 m_minpileuptruthEkin = m_settings->pileUpSDOsMinEkin();
148
149 // Set SDO readout range
150 const double intervalBetweenCrossings(m_settings->timeInterval() / 3.);
151
152 switch ( (m_settings->storeSDO() )) {
153 case 0: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = -1.*CLHEP::ns; break;
154 case 1: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
155 case 2: m_minCrossingTimeSDO = -(intervalBetweenCrossings * 2. + 1.*CLHEP::ns); m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
156 default:
157 ATH_MSG_ERROR ( "storeSDO is out of range:"<<m_settings->storeSDO()<<"allowed values are: 0,1,2. Setting storeSDO = 2 " );
158 m_minCrossingTimeSDO = -51.*CLHEP::ns; m_maxCrossingTimeSDO = 51.*CLHEP::ns;
159 break;
160 }
161
165
166 return StatusCode::SUCCESS;
167}
168
169//_____________________________________________________________________________
170StatusCode TRTDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
171{
172 m_vDigits.clear();
173 m_trtHitCollList.clear();
176 return StatusCode::SUCCESS;
177}
178
179//_____________________________________________________________________________
181 SubEventIterator bSubEvents,
182 SubEventIterator eSubEvents) {
183
184 m_seen.emplace_back(std::distance(bSubEvents,eSubEvents), bunchXing);
185 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
186 if (m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
187 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
189
190
191 //TRTUncompressedHit
192
194 TimedHitCollList hitCollList;
195
196 if (!(m_mergeSvc->retrieveSubSetEvtData(m_dataObjectName, hitCollList, bunchXing,
197 bSubEvents, eSubEvents).isSuccess()) &&
198 hitCollList.empty()) {
199 ATH_MSG_ERROR("Could not fill TimedHitCollList");
200 return StatusCode::FAILURE;
201 } else {
202 ATH_MSG_VERBOSE(hitCollList.size() << " TRTUncompressedHitCollection with key " <<
203 m_dataObjectName << " found");
204 }
205
206 TimedHitCollList::iterator iColl(hitCollList.begin());
207 TimedHitCollList::iterator endColl(hitCollList.end());
208
209 for( ; iColl != endColl; ++iColl){
210 TRTUncompressedHitCollection *hitCollPtr = new TRTUncompressedHitCollection(*iColl->second);
211 PileUpTimeEventIndex timeIndex(iColl->first);
212 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollPtr->size() <<
213 " hits");
214 ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
215 << " index: " << timeIndex.index()
216 << " type: " << timeIndex.type());
217 m_thpctrt->insert(timeIndex, hitCollPtr);
218 m_trtHitCollList.push_back(hitCollPtr);
219 }
220
221 return StatusCode::SUCCESS;
222}
223
224//_____________________________________________________________________________
225StatusCode TRTDigitizationTool::lateInitialize(const EventContext& ctx) {
226
227 // setup the RNGs which are only used in the first event
228 CLHEP::HepRandomEngine *fakeCondRndmEngine = getRandomEngine("TRT_FakeConditions", m_randomSeedOffset, ctx);
229 CLHEP::HepRandomEngine *noiseInitRndmEngine = getRandomEngine("TRT_Noise", m_randomSeedOffset, ctx);
230 CLHEP::HepRandomEngine *noiseElecRndmEngine = getRandomEngine("TRT_Noise_Electronics", m_randomSeedOffset, ctx);
231 CLHEP::HepRandomEngine *noiseThreshRndmEngine = getRandomEngine("TRT_Noise_ThresholdFluctuations", m_randomSeedOffset, ctx);
232 CLHEP::HepRandomEngine *noiseElecResetRndmEngine = getRandomEngine("TRT_ElectronicsNoiseReset", m_randomSeedOffset, ctx);
233 m_first_event=false;
234
235 //Resuming initialiazation. Section below had to be moved into event loop due to dependence on conditions data
236
237 TRTElectronicsNoise *electronicsNoise(nullptr);
238 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
239 electronicsNoise = new TRTElectronicsNoise(m_settings, noiseElecRndmEngine);
240 }
241 // ElectronicsProcessing is needed for the regular straw processing,
242 // but also for the noise (it assumes ownership of electronicsnoise )
244
246 m_manager,
247 m_trt_id,
249 m_sumTool);
250
251 m_pDigConditions->initialize(fakeCondRndmEngine);
252
253 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
254
255 // In short this next constructor does 3 things;
256 // i) tunes the amplitude of the electronics noise,
257 // ii) creates a pool of noise digits,
258 // iii) figures out exact low thresholds needed to reproduce actual
259 // straw noise-frequencies:
261 m_manager,
262 noiseInitRndmEngine,
263 noiseElecRndmEngine,
264 noiseThreshRndmEngine,
265 noiseElecResetRndmEngine,
268 electronicsNoise,
269 m_trt_id,
271 m_sumTool);
272
273 ATH_MSG_DEBUG ( "Average straw noise level is " << m_pDigConditions->strawAverageNoiseLevel() );
274
275 } else {
276 m_pNoise = nullptr;
277 }
278
279 ITRT_PAITool *TRTpaiToolXe = &(* m_TRTpaiToolXe);
280 ITRT_PAITool *TRTpaiToolAr = &(* m_TRTpaiToolAr);
281 ITRT_PAITool *TRTpaiToolKr = &(* m_TRTpaiToolKr);
282
283 ITRT_SimDriftTimeTool *pTRTsimdrifttimetool = &(*m_TRTsimdrifttimetool);
284
285 const ITRT_CalDbTool* calDbTool = nullptr;
286 if (m_settings->getT0FromData()) {
287 calDbTool = m_calDbTool.get();
288 }
291 m_manager,
292 TRTpaiToolXe,
293 pTRTsimdrifttimetool,
295 m_pNoise,
298 m_trt_id,
299 TRTpaiToolAr,
300 TRTpaiToolKr,
301 calDbTool);
302
303 ATH_MSG_INFO ( "Gas Property: UseGasMix is " << m_UseGasMix );
304
305 return StatusCode::SUCCESS;
306}
307
308//_____________________________________________________________________________
309StatusCode TRTDigitizationTool::processStraws(const EventContext& ctx,
311 std::set<int>& sim_hitids, std::set<Identifier>& simhitsIdentifiers,
312 CLHEP::HepRandomEngine *rndmEngine,
313 CLHEP::HepRandomEngine *strawRndmEngine,
314 CLHEP::HepRandomEngine *elecProcRndmEngine,
315 CLHEP::HepRandomEngine *elecNoiseRndmEngine,
316 CLHEP::HepRandomEngine *paiRndmEngine) {
317
318 // Create a map for the SDO
320
322 MagField::AtlasFieldCache fieldCache;
323 if (m_settings->useMagneticFieldMap()) {
324
325 // Get field cache object
327 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
328
329 if (fieldCondObj == nullptr) {
330 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
331 return StatusCode::FAILURE;
332 }
333 fieldCondObj->getInitializedCache (fieldCache);
334 }
335
337
338
339 ATH_CHECK(simDataMap.record(std::make_unique<InDetSimDataCollection>() ));
340
341 // Register the map into StoreGate
342 if (not simDataMap.isValid()) {
343 ATH_MSG_FATAL ( "InDetSimData map " << m_outputSDOCollName.key() << " could not be registered in StoreGate !" );
344 return StatusCode::FAILURE;
345 } else {
346 ATH_MSG_DEBUG ( "InDetSimData map " << m_outputSDOCollName.key() << " registered in StoreGate" );
347 }
348
349 m_cosmicEventPhase = 0.0;
350 if (m_settings->doCosmicTimingPit()) {
352 };
353
354 // Create a vector of deposits
355 std::vector<InDetSimData::Deposit> depositVector(100);
356
357 // loop over all straws
359 while (thpctrt.nextDetectorElement(i, e)) {
360
361 int hitID((*i)->GetHitID()); // Get hitID
362
363 // evtIndex should be 0 for main event and 1,2,3,... for pileup events:
364 // (event Id is a property of the TimedHitPtr)
365 HepMcParticleLink::index_type evtIndex(i->eventId());
366
367 if ( m_settings->noiseInUnhitStraws() ) {
368 sim_hitids.insert(hitID);
369 }
370 //Safeguard against a rare case of hitID corruption found by Davide:
371 if ( hitID & 0xc0000000 ) {
372 ATH_MSG_ERROR ( "Hit ID not Valid (" << MSG::hex << hitID << ")" << MSG::dec );
373 continue;
374 }
375
376 // Convert hitID to Identifier
377 IdentifierHash IdHash;
378 Identifier idLayer;
379 bool identifierOK;
380 Identifier idStraw(getIdentifier(hitID, IdHash, idLayer, identifierOK));
381 if ( !identifierOK ) {
382 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (1)" );
383 continue;
384 }
385
386 //For crosstalk sim
387 simhitsIdentifiers.insert(idStraw);
388
390 // Fill a vector of deposits
391 depositVector.clear();
392 depositVector.reserve(std::distance(i,e));
393 for (TimedHitCollection<TRTUncompressedHit>::const_iterator hit_iter(i); hit_iter != e; ++hit_iter ) {
394 // create a new deposit
395 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.
396 (*hit_iter)->GetEnergyDeposit() );
398 continue;
399 }
400 ATH_MSG_VERBOSE ( "Deposit: trackID " << deposit.first << " energyDeposit " << deposit.second );
401 depositVector.emplace_back(std::move(deposit));
402 }
403
404 const TimedHitPtr<TRTUncompressedHit>& theHit(*i);
405 const double bunchCrossingTime(hitTime(theHit) - static_cast<double>(theHit->GetGlobalTime()));
406
407 // Add the simdata object to the map.
408 if ( !depositVector.empty() &&
409 (evtIndex == 0 || ((*i)->GetKineticEnergy()>m_minpileuptruthEkin)) &&
410 (bunchCrossingTime < m_maxCrossingTimeSDO) && (bunchCrossingTime > m_minCrossingTimeSDO) ) {
411 simDataMap->try_emplace(idStraw, std::move(depositVector));
412 }
414
415 // Digitization for the given straw
416 TRTDigit digit_straw;
417
419 //if (m_settings->doCosmicTimingPit()) {
420 // if ( StatusCode::SUCCESS == evtStore()->retrieve(m_ComTime,"ComTime")) {
421 // ATH_MSG_VERBOSE ( "Found tool for cosmic timing: ComTime" );
422 // } else {
423 // ATH_MSG_ERROR ( "Did not find tool needed for cosmic timing: ComTime" );
424 // }
425 //}
426
427 // if StatusHT == 6 thats emulate argon, ==7 that's emulate krypton
428 bool emulateArFlag = m_sumTool->getStatusHT(idStraw, ctx) == 6;
429 bool emulateKrFlag = m_sumTool->getStatusHT(idStraw, ctx) == 7;
430 const int statusHT = m_sumTool->getStatusHT(idStraw, ctx);
431 m_pProcessingOfStraw->ProcessStraw(fieldCache, i, e, digit_straw,
433 m_cosmicEventPhase, //m_ComTime,
435 emulateArFlag,
436 emulateKrFlag,
437 strawRndmEngine,
438 elecProcRndmEngine,
439 elecNoiseRndmEngine,
440 paiRndmEngine);
441
442 // Print out the digits etc (for debugging)
443 //int mstrw = digit_straw.GetStrawID();
444 //unsigned int mword = digit_straw.GetDigit();
445 //std::cout << "AJB " << mstrw << ":" << mword << std::endl;
446 //print_mword_properties(mword);
447 //std::cout << "AJB "; bits24(mword);
448 //std::cout << "AJB "; bits27(mword);
449
450 // finally push back the output digit.
451 if ( digit_straw.GetDigit() ) {
452 m_vDigits.push_back(digit_straw);
453 }
454
455 } // end of straw loop
456
457 return StatusCode::SUCCESS;
458}
459
460//_____________________________________________________________________________
461StatusCode TRTDigitizationTool::processAllSubEvents(const EventContext& ctx) {
462
463 // Set the RNGs to use for this event.
464 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
465 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
466 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
467 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
468 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
469 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
470
471 if (m_first_event) {
472 if(this->lateInitialize(ctx).isFailure()) {
473 ATH_MSG_FATAL ( "lateInitialize method failed!" );
474 return StatusCode::FAILURE;
475 }
476 }
477
479
480 ATH_MSG_DEBUG ( "TRTDigitizationTool::processAllSubEvents()" );
481
483 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
484 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
485
486 if (not m_trtrdo_container.isValid()) {
487 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
488 return StatusCode::FAILURE;
489 }else {
490 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
491 }
492
493 m_vDigits.clear();
494
495 // get the container(s)
498 // In case of single hits container just load the collection using read handles
501 if (!hitCollection.isValid()) {
502 ATH_MSG_ERROR("Could not get TRTUncompressedHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
503 return StatusCode::FAILURE;
504 }
505
506 // Define Hit Collection
507 thpctrt.reserve(1);
508
509 // create a new hits collection
510 thpctrt.insert(0, hitCollection.cptr());
511 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollection->size() << " hits");
512 }
513 else {
514 TimedHitCollList hitCollList; // this is a list<pair<time_t, DataLink<TRTUncompressedHitCollection> > >
515 unsigned int numberOfSimHits(0);
516 if ( !(m_mergeSvc->retrieveSubEvtsData(m_dataObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
517 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
518 return StatusCode::FAILURE;
519 } else {
520 ATH_MSG_DEBUG ( hitCollList.size() << " TRTUncompressedHitCollections with key " << m_dataObjectName << " found" );
521 }
522
523 // Define Hit Collection
524 thpctrt.reserve(numberOfSimHits);
525
526 //now merge all collections into one
527 TimedHitCollList::iterator iColl(hitCollList.begin());
528 TimedHitCollList::iterator endColl(hitCollList.end() );
530 // loop on the hit collections
531 while ( iColl != endColl ) {
532 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
534 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
536 const TRTUncompressedHitCollection* p_collection(iColl->second);
537 thpctrt.insert(iColl->first, p_collection);
538 ATH_MSG_DEBUG ( "TRTUncompressedHitCollection found with " << p_collection->size() << " hits" );
539 ++iColl;
540 }
541 }
542
543 //Set of all hitid's with simhits (used for noise simulation).
544 std::set<int> sim_hitids;
545 std::set<Identifier> simhitsIdentifiers;
546
547 // Process the Hits straw by straw: get the iterator pairs for given straw
548 ATH_CHECK(this->processStraws(ctx, thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
549
550 // no more hits
551
552 //Noise in straws without simhits:
553 if (m_settings->noiseInUnhitStraws()) {
554 const int numberOfDigitsBeforeNoise(m_vDigits.size());
555
556 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
557 if (m_settings->doCrosstalk()) {
558 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
559 }
560
561 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
562
564
565 } else {
566 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
567 }
568
569 // All digits are ready.
570 // We just need to convert to relevant identifiers and output to storegate.
571
572 if (createAndStoreRDOs().isFailure()) {
573 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
574 return StatusCode::FAILURE;
575 }
576 else {
577 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
578 }
579
580 return StatusCode::SUCCESS;
581}
582
583CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName,
584 const EventContext& ctx) const
585{
586 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
587 std::string rngName = name()+streamName;
588 rngWrapper->setSeed( rngName, ctx );
589 return rngWrapper->getEngine(ctx);
590}
591
592//_____________________________________________________________________________
593CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset,
594 const EventContext& ctx) const
595{
596 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
597 rngWrapper->setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
598 return rngWrapper->getEngine(ctx);
599}
600
601//_____________________________________________________________________________
602StatusCode TRTDigitizationTool::mergeEvent(const EventContext& ctx) {
603 std::vector<std::pair<unsigned int, int> >::iterator ii(m_seen.begin());
604 std::vector<std::pair<unsigned int, int> >::iterator ee(m_seen.end());
605 while (ii != ee) {
606 ATH_MSG_DEBUG( "mergeEvent: there are " << ii->first << " events in bunch xing " << ii->second );
607 ++ii;
608 }
609
610 // Set the RNGs to use for this event.
611 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
612 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
613 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
614 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
615 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
616 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
617
618 if (m_first_event) {
619 if(this->lateInitialize(ctx).isFailure()) {
620 ATH_MSG_FATAL ( "lateInitialize method failed!" );
621 return StatusCode::FAILURE;
622 }
623 }
624
626
627 ATH_MSG_DEBUG ( "TRTDigitization::execute()" );
628
630 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
631 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
632 if (not m_trtrdo_container.isValid()) {
633 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
634 return StatusCode::FAILURE;
635 } else {
636 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
637 }
638
639 //Set of all hitid's with simhits (used for noise simulation).
640 std::set<int> sim_hitids;
641 std::set<Identifier> simhitsIdentifiers;
642
643 // Process the Hits straw by straw:
644 // get the iterator pairs for given straw
645 ATH_CHECK(this->processStraws(ctx, *m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
646
647 delete m_thpctrt;
648 for(TRTUncompressedHitCollection* ptr : m_trtHitCollList) delete ptr;
649 m_trtHitCollList.clear();
650 // no more hits
651
652 //Noise in straws without simhits:
653 if (m_settings->noiseInUnhitStraws()) {
654 const unsigned int numberOfDigitsBeforeNoise(m_vDigits.size());
655
656 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
657 if (m_settings->doCrosstalk()) {
658 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
659 }
660
661 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
662
664
665 } else {
666 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
667 };
668
669 // All digits are ready.
670 // We just need to convert to relevant identifiers and output to storegate.
671
672 if (createAndStoreRDOs().isFailure()) {
673 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
674 return StatusCode::FAILURE;
675 }
676 else {
677 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
678 }
679
680 return StatusCode::SUCCESS;
681}
682
683//_____________________________________________________________________________
685{
686
687 std::vector<TRTDigit>::const_iterator TRTDigitIter(m_vDigits.begin());
688 std::vector<TRTDigit>::const_iterator endOfTRTDigits(m_vDigits.end());
689
690 // for testing
691 IdentifierHash IdHash; // default value is 0xFFFFFFFF
692 IdentifierHash IdHashOld; // default value is 0xFFFFFFFF
693 TRT_RDO_Collection *RDOColl(nullptr);
694
695 Identifier idStraw;
696
697 while (TRTDigitIter != endOfTRTDigits) {
698 ATH_MSG_DEBUG ( "Digit ID " << TRTDigitIter->GetStrawID() << " Digit " << TRTDigitIter->GetDigit() );
699
700 Identifier layer_id;
701 bool identifierOK(false);
702 idStraw = getIdentifier(TRTDigitIter->GetStrawID(), IdHash, layer_id, identifierOK);
703 if (!identifierOK) {
704 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (2)" );
705 ++TRTDigitIter;
706 continue;
707 };
708
709 // Create new TRT RDO Collection
710 ATH_MSG_DEBUG ( " RDO ID " << m_trt_id->print_to_string(idStraw) );
711
712 //TK: wauv - we are really betting the farm on the fact that the
713 //ordering of digits will result in a similar ordering of the
714 //idhash'es here... (this is not immediately the case when noise
715 //hits are appended afterwards).
716
717 if (IdHash != IdHashOld) {
718 RDOColl = new TRT_RDO_Collection(IdHash);
719 ATH_MSG_DEBUG ( "New TRT RDO Collection created with IdHash " << static_cast<int>(IdHash) );
720 IdHashOld = IdHash;
721 RDOColl->setIdentifier(layer_id);
722
723 // Add to the container
724 if (m_trtrdo_container->addCollection(RDOColl, RDOColl->identifyHash()).isFailure()) {
725 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
726 return StatusCode::FAILURE;
727 } else {
728 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
729 }
730 }
731
732 // Put RDO into Collection
733 TRT_LoLumRawData *p_rdo(new TRT_LoLumRawData(idStraw, TRTDigitIter->GetDigit()));
734 if (RDOColl) {
735 RDOColl->push_back(p_rdo);
736 } else {
737 ATH_MSG_FATAL ( "Failed to create the TRT_RDO_Collection before trying to add an RDO to it! IdHash = " << static_cast<int>(IdHash) );
738 delete p_rdo;
739 return StatusCode::FAILURE;
740 }
741 ++TRTDigitIter;
742 }
743
744 m_vDigits.clear();
745 return StatusCode::SUCCESS;
746}
747
748
749//_____________________________________________________________________________
751 IdentifierHash& hashId,
752 Identifier& IdLayer,
753 bool & statusok ) const
754{
755 statusok = true;
756
757 Identifier IdStraw;
758
759 const int mask(0x0000001F);
760 const int word_shift(5);
761 int trtID, ringID, moduleID, layerID, strawID;
762 int wheelID, planeID, sectorID;
763
764 const InDetDD::TRT_BarrelElement *barrelElement;
765 const InDetDD::TRT_EndcapElement *endcapElement;
766
767 if ( !(hitID & 0x00200000) ) { // barrel
768 strawID = hitID & mask;
769 hitID >>= word_shift;
770 layerID = hitID & mask;
771 hitID >>= word_shift;
772 moduleID = hitID & mask;
773 hitID >>= word_shift;
774 ringID = hitID & mask;
775 trtID = hitID >> word_shift;
776
777 barrelElement = m_manager->getBarrelElement(trtID, ringID, moduleID, layerID);
778 if ( barrelElement ) {
779 hashId = barrelElement->identifyHash();
780 IdLayer = barrelElement->identify();
781 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
782 } else {
783 ATH_MSG_ERROR ( "Could not find detector element for barrel identifier with "
784 << "(ipos,iring,imod,ilayer,istraw) = ("
785 << trtID << ", " << ringID << ", " << moduleID << ", "
786 << layerID << ", " << strawID << ")" );
787 statusok = false;
788 }
789 } else { // endcap
790 strawID = hitID & mask;
791 hitID >>= word_shift;
792 planeID = hitID & mask;
793 hitID >>= word_shift;
794 sectorID = hitID & mask;
795 hitID >>= word_shift;
796 wheelID = hitID & mask;
797 trtID = hitID >> word_shift;
798
799 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
800 if (trtID == 3) { trtID = 0; }
801 else { trtID = 1; }
802
803 endcapElement = m_manager->getEndcapElement(trtID, wheelID, planeID, sectorID);
804
805 if ( endcapElement ) {
806 hashId = endcapElement->identifyHash();
807 IdLayer = endcapElement->identify();
808 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
809 } else {
810 ATH_MSG_ERROR ( "Could not find detector element for endcap identifier with "
811 << "(ipos,iwheel,isector,iplane,istraw) = ("
812 << trtID << ", " << wheelID << ", " << sectorID << ", "
813 << planeID << ", " << strawID << ")" );
814 ATH_MSG_ERROR ( "If this happens very rarely, don't be alarmed (it is a Geant4 'feature')" );
815 ATH_MSG_ERROR ( "If it happens a lot, you probably have misconfigured geometry in the sim. job." );
816 statusok = false;
817 }
818
819 }
820
821 return IdStraw;
822}
823
824//_____________________________________________________________________________
826
828 m_settings->print("TRTDigSettings Settings : ");
829 }
830
831 ATH_MSG_INFO ( "TRTDigitizationTool::finalize()" );
832
833 return StatusCode::SUCCESS;
834}
835
836//_____________________________________________________________________________
837double TRTDigitizationTool::getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine) {
838 // 13th February 2015: replace ComTime with a hack (fixme) based on an
839 // event phase distribution from Alex (alejandro.alonso@cern.ch) that
840 // is modelled as a Guassian of mean 5.48 ns and sigma 8.91 ns.
841 return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 5.48, 8.91);
842}
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:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
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:
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
const HepPDT::ParticleDataTable * m_particleTable
static double getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine)
ToolHandle< ITRT_CalDbTool > m_calDbTool
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
ServiceHandle< IPartPropSvc > m_ppSvc
Handle on the particle property service.
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:447
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