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#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
164 ATH_CHECK( m_trtDetElementsInputKey.initialize() );
166
167 return StatusCode::SUCCESS;
168}
169
170//_____________________________________________________________________________
171StatusCode TRTDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
172{
173 m_vDigits.clear();
174 m_trtHitCollList.clear();
177 return StatusCode::SUCCESS;
178}
179
180//_____________________________________________________________________________
182 SubEventIterator bSubEvents,
183 SubEventIterator eSubEvents) {
184
185 m_seen.emplace_back(std::distance(bSubEvents,eSubEvents), bunchXing);
186 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
187 if (m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
188 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
190
191
192 //TRTUncompressedHit
193
195 TimedHitCollList hitCollList;
196
197 if (!(m_mergeSvc->retrieveSubSetEvtData(m_dataObjectName, hitCollList, bunchXing,
198 bSubEvents, eSubEvents).isSuccess()) &&
199 hitCollList.empty()) {
200 ATH_MSG_ERROR("Could not fill TimedHitCollList");
201 return StatusCode::FAILURE;
202 } else {
203 ATH_MSG_VERBOSE(hitCollList.size() << " TRTUncompressedHitCollection with key " <<
204 m_dataObjectName << " found");
205 }
206
207 TimedHitCollList::iterator iColl(hitCollList.begin());
208 TimedHitCollList::iterator endColl(hitCollList.end());
209
210 for( ; iColl != endColl; ++iColl){
211 TRTUncompressedHitCollection *hitCollPtr = new TRTUncompressedHitCollection(*iColl->second);
212 PileUpTimeEventIndex timeIndex(iColl->first);
213 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollPtr->size() <<
214 " hits");
215 ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
216 << " index: " << timeIndex.index()
217 << " type: " << timeIndex.type());
218 m_thpctrt->insert(timeIndex, hitCollPtr);
219 m_trtHitCollList.push_back(hitCollPtr);
220 }
221
222 return StatusCode::SUCCESS;
223}
224
225//_____________________________________________________________________________
226StatusCode TRTDigitizationTool::lateInitialize(const EventContext& ctx) {
227
228 // setup the RNGs which are only used in the first event
229 CLHEP::HepRandomEngine *fakeCondRndmEngine = getRandomEngine("TRT_FakeConditions", m_randomSeedOffset, ctx);
230 CLHEP::HepRandomEngine *noiseInitRndmEngine = getRandomEngine("TRT_Noise", m_randomSeedOffset, ctx);
231 CLHEP::HepRandomEngine *noiseElecRndmEngine = getRandomEngine("TRT_Noise_Electronics", m_randomSeedOffset, ctx);
232 CLHEP::HepRandomEngine *noiseThreshRndmEngine = getRandomEngine("TRT_Noise_ThresholdFluctuations", m_randomSeedOffset, ctx);
233 CLHEP::HepRandomEngine *noiseElecResetRndmEngine = getRandomEngine("TRT_ElectronicsNoiseReset", m_randomSeedOffset, ctx);
234 m_first_event=false;
235
236 //Resuming initialiazation. Section below had to be moved into event loop due to dependence on conditions data
237
238 TRTElectronicsNoise *electronicsNoise(nullptr);
239 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
240 electronicsNoise = new TRTElectronicsNoise(m_settings, noiseElecRndmEngine);
241 }
242 // ElectronicsProcessing is needed for the regular straw processing,
243 // but also for the noise (it assumes ownership of electronicsnoise )
245
247 m_manager,
248 m_trt_id,
250 m_sumTool);
251
252 m_pDigConditions->initialize(fakeCondRndmEngine);
253
254 if ( m_settings->noiseInUnhitStraws() || m_settings->noiseInSimhits() ) {
255
256 // In short this next constructor does 3 things;
257 // i) tunes the amplitude of the electronics noise,
258 // ii) creates a pool of noise digits,
259 // iii) figures out exact low thresholds needed to reproduce actual
260 // straw noise-frequencies:
262 m_manager,
263 noiseInitRndmEngine,
264 noiseElecRndmEngine,
265 noiseThreshRndmEngine,
266 noiseElecResetRndmEngine,
269 electronicsNoise,
270 m_trt_id,
272 m_sumTool);
273
274 ATH_MSG_DEBUG ( "Average straw noise level is " << m_pDigConditions->strawAverageNoiseLevel() );
275
276 } else {
277 m_pNoise = nullptr;
278 }
279
280 ITRT_PAITool *TRTpaiToolXe = &(* m_TRTpaiToolXe);
281 ITRT_PAITool *TRTpaiToolAr = &(* m_TRTpaiToolAr);
282 ITRT_PAITool *TRTpaiToolKr = &(* m_TRTpaiToolKr);
283
284 ITRT_SimDriftTimeTool *pTRTsimdrifttimetool = &(*m_TRTsimdrifttimetool);
285
286 const ITRT_CalDbTool* calDbTool = nullptr;
287 if (m_settings->getT0FromData()) {
288 calDbTool = m_calDbTool.get();
289 }
292 m_manager,
293 TRTpaiToolXe,
294 pTRTsimdrifttimetool,
296 m_pNoise,
299 m_trt_id,
300 TRTpaiToolAr,
301 TRTpaiToolKr,
302 calDbTool);
303
304 ATH_MSG_INFO ( "Gas Property: UseGasMix is " << m_UseGasMix );
305
306 return StatusCode::SUCCESS;
307}
308
309//_____________________________________________________________________________
310StatusCode TRTDigitizationTool::processStraws(const EventContext& ctx,
312 std::set<int>& sim_hitids, std::set<Identifier>& simhitsIdentifiers,
313 CLHEP::HepRandomEngine *rndmEngine,
314 CLHEP::HepRandomEngine *strawRndmEngine,
315 CLHEP::HepRandomEngine *elecProcRndmEngine,
316 CLHEP::HepRandomEngine *elecNoiseRndmEngine,
317 CLHEP::HepRandomEngine *paiRndmEngine) {
318
319 // Create a map for the SDO
321
323 // Access to Conditions objects
324 MagField::AtlasFieldCache fieldCache;
325 if (m_settings->useMagneticFieldMap()) {
326
327 // Get field cache object
329 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
330
331 if (fieldCondObj == nullptr) {
332 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
333 return StatusCode::FAILURE;
334 }
335 fieldCondObj->getInitializedCache (fieldCache);
336 }
337
339 const InDetDD::TRT_DetElementContainer* trtDetElements{*trtDetElementsHandle};
340 if(!trtDetElements) {
341 ATH_MSG_ERROR("Failed to retrieve TRT_DetElementContainer with key " << m_trtDetElementsInputKey.key());
342 return StatusCode::FAILURE;
343 }
345
346
347 ATH_CHECK(simDataMap.record(std::make_unique<InDetSimDataCollection>() ));
348
349 // Register the map into StoreGate
350 if (not simDataMap.isValid()) {
351 ATH_MSG_FATAL ( "InDetSimData map " << m_outputSDOCollName.key() << " could not be registered in StoreGate !" );
352 return StatusCode::FAILURE;
353 } else {
354 ATH_MSG_DEBUG ( "InDetSimData map " << m_outputSDOCollName.key() << " registered in StoreGate" );
355 }
356
357 m_cosmicEventPhase = 0.0;
358 if (m_settings->doCosmicTimingPit()) {
360 };
361
362 // Create a vector of deposits
363 std::vector<InDetSimData::Deposit> depositVector(100);
364
365 // loop over all straws
367 while (thpctrt.nextDetectorElement(i, e)) {
368
369 int hitID((*i)->GetHitID()); // Get hitID
370
371 // evtIndex should be 0 for main event and 1,2,3,... for pileup events:
372 // (event Id is a property of the TimedHitPtr)
373 HepMcParticleLink::index_type evtIndex(i->eventId());
374
375 if ( m_settings->noiseInUnhitStraws() ) {
376 sim_hitids.insert(hitID);
377 }
378 //Safeguard against a rare case of hitID corruption found by Davide:
379 if ( hitID & 0xc0000000 ) {
380 ATH_MSG_ERROR ( "Hit ID not Valid (" << MSG::hex << hitID << ")" << MSG::dec );
381 continue;
382 }
383
384 // Convert hitID to Identifier
385 IdentifierHash IdHash;
386 Identifier idLayer;
387 bool identifierOK;
388 Identifier idStraw(getIdentifier(hitID, IdHash, idLayer, identifierOK));
389 if ( !identifierOK ) {
390 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (1)" );
391 continue;
392 }
393
394 //For crosstalk sim
395 simhitsIdentifiers.insert(idStraw);
396
398 // Fill a vector of deposits
399 depositVector.clear();
400 depositVector.reserve(std::distance(i,e));
401 for (TimedHitCollection<TRTUncompressedHit>::const_iterator hit_iter(i); hit_iter != e; ++hit_iter ) {
402 // create a new deposit
403 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.
404 (*hit_iter)->GetEnergyDeposit() );
406 continue;
407 }
408 ATH_MSG_VERBOSE ( "Deposit: trackID " << deposit.first << " energyDeposit " << deposit.second );
409 depositVector.emplace_back(std::move(deposit));
410 }
411
412 const TimedHitPtr<TRTUncompressedHit>& theHit(*i);
413 const double bunchCrossingTime(hitTime(theHit) - static_cast<double>(theHit->GetGlobalTime()));
414
415 // Add the simdata object to the map.
416 if ( !depositVector.empty() &&
417 (evtIndex == 0 || ((*i)->GetKineticEnergy()>m_minpileuptruthEkin)) &&
418 (bunchCrossingTime < m_maxCrossingTimeSDO) && (bunchCrossingTime > m_minCrossingTimeSDO) ) {
419 simDataMap->try_emplace(idStraw, std::move(depositVector));
420 }
422
423 // Digitization for the given straw
424 TRTDigit digit_straw;
425
427 //if (m_settings->doCosmicTimingPit()) {
428 // if ( StatusCode::SUCCESS == evtStore()->retrieve(m_ComTime,"ComTime")) {
429 // ATH_MSG_VERBOSE ( "Found tool for cosmic timing: ComTime" );
430 // } else {
431 // ATH_MSG_ERROR ( "Did not find tool needed for cosmic timing: ComTime" );
432 // }
433 //}
434
435 // if StatusHT == 6 thats emulate argon, ==7 that's emulate krypton
436 bool emulateArFlag = m_sumTool->getStatusHT(idStraw, ctx) == 6;
437 bool emulateKrFlag = m_sumTool->getStatusHT(idStraw, ctx) == 7;
438 const int statusHT = m_sumTool->getStatusHT(idStraw, ctx);
439 m_pProcessingOfStraw->ProcessStraw(fieldCache, trtDetElements, i, e, digit_straw,
441 m_cosmicEventPhase, //m_ComTime,
443 emulateArFlag,
444 emulateKrFlag,
445 strawRndmEngine,
446 elecProcRndmEngine,
447 elecNoiseRndmEngine,
448 paiRndmEngine);
449
450 // Print out the digits etc (for debugging)
451 //int mstrw = digit_straw.GetStrawID();
452 //unsigned int mword = digit_straw.GetDigit();
453 //std::cout << "AJB " << mstrw << ":" << mword << std::endl;
454 //print_mword_properties(mword);
455 //std::cout << "AJB "; bits24(mword);
456 //std::cout << "AJB "; bits27(mword);
457
458 // finally push back the output digit.
459 if ( digit_straw.GetDigit() ) {
460 m_vDigits.push_back(digit_straw);
461 }
462
463 } // end of straw loop
464
465 return StatusCode::SUCCESS;
466}
467
468//_____________________________________________________________________________
469StatusCode TRTDigitizationTool::processAllSubEvents(const EventContext& ctx) {
470
471 // Set the RNGs to use for this event.
472 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
473 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
474 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
475 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
476 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
477 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
478
479 if (m_first_event) {
480 if(this->lateInitialize(ctx).isFailure()) {
481 ATH_MSG_FATAL ( "lateInitialize method failed!" );
482 return StatusCode::FAILURE;
483 }
484 }
485
487
488 ATH_MSG_DEBUG ( "TRTDigitizationTool::processAllSubEvents()" );
489
491 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
492 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
493
494 if (not m_trtrdo_container.isValid()) {
495 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
496 return StatusCode::FAILURE;
497 }else {
498 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
499 }
500
501 m_vDigits.clear();
502
503 // get the container(s)
506 // In case of single hits container just load the collection using read handles
509 if (!hitCollection.isValid()) {
510 ATH_MSG_ERROR("Could not get TRTUncompressedHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
511 return StatusCode::FAILURE;
512 }
513
514 // Define Hit Collection
515 thpctrt.reserve(1);
516
517 // create a new hits collection
518 thpctrt.insert(0, hitCollection.cptr());
519 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollection->size() << " hits");
520 }
521 else {
522 TimedHitCollList hitCollList; // this is a list<pair<time_t, DataLink<TRTUncompressedHitCollection> > >
523 unsigned int numberOfSimHits(0);
524 if ( !(m_mergeSvc->retrieveSubEvtsData(m_dataObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
525 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
526 return StatusCode::FAILURE;
527 } else {
528 ATH_MSG_DEBUG ( hitCollList.size() << " TRTUncompressedHitCollections with key " << m_dataObjectName << " found" );
529 }
530
531 // Define Hit Collection
532 thpctrt.reserve(numberOfSimHits);
533
534 //now merge all collections into one
535 TimedHitCollList::iterator iColl(hitCollList.begin());
536 TimedHitCollList::iterator endColl(hitCollList.end() );
538 // loop on the hit collections
539 while ( iColl != endColl ) {
540 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
542 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
544 const TRTUncompressedHitCollection* p_collection(iColl->second);
545 thpctrt.insert(iColl->first, p_collection);
546 ATH_MSG_DEBUG ( "TRTUncompressedHitCollection found with " << p_collection->size() << " hits" );
547 ++iColl;
548 }
549 }
550
551 //Set of all hitid's with simhits (used for noise simulation).
552 std::set<int> sim_hitids;
553 std::set<Identifier> simhitsIdentifiers;
554
555 // Process the Hits straw by straw: get the iterator pairs for given straw
556 ATH_CHECK(this->processStraws(ctx, thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
557
558 // no more hits
559
560 //Noise in straws without simhits:
561 if (m_settings->noiseInUnhitStraws()) {
562 const int numberOfDigitsBeforeNoise(m_vDigits.size());
563
564 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
565 if (m_settings->doCrosstalk()) {
566 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
567 }
568
569 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
570
572
573 } else {
574 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
575 }
576
577 // All digits are ready.
578 // We just need to convert to relevant identifiers and output to storegate.
579
580 if (createAndStoreRDOs().isFailure()) {
581 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
582 return StatusCode::FAILURE;
583 }
584 else {
585 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
586 }
587
588 return StatusCode::SUCCESS;
589}
590
591CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName,
592 const EventContext& ctx) const
593{
594 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
595 std::string rngName = name()+streamName;
596 rngWrapper->setSeed( rngName, ctx );
597 return rngWrapper->getEngine(ctx);
598}
599
600//_____________________________________________________________________________
601CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset,
602 const EventContext& ctx) const
603{
604 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
605 rngWrapper->setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
606 return rngWrapper->getEngine(ctx);
607}
608
609//_____________________________________________________________________________
610StatusCode TRTDigitizationTool::mergeEvent(const EventContext& ctx) {
611 std::vector<std::pair<unsigned int, int> >::iterator ii(m_seen.begin());
612 std::vector<std::pair<unsigned int, int> >::iterator ee(m_seen.end());
613 while (ii != ee) {
614 ATH_MSG_DEBUG( "mergeEvent: there are " << ii->first << " events in bunch xing " << ii->second );
615 ++ii;
616 }
617
618 // Set the RNGs to use for this event.
619 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
620 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
621 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
622 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
623 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
624 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
625
626 if (m_first_event) {
627 if(this->lateInitialize(ctx).isFailure()) {
628 ATH_MSG_FATAL ( "lateInitialize method failed!" );
629 return StatusCode::FAILURE;
630 }
631 }
632
634
635 ATH_MSG_DEBUG ( "TRTDigitization::execute()" );
636
638 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
639 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
640 if (not m_trtrdo_container.isValid()) {
641 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
642 return StatusCode::FAILURE;
643 } else {
644 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
645 }
646
647 //Set of all hitid's with simhits (used for noise simulation).
648 std::set<int> sim_hitids;
649 std::set<Identifier> simhitsIdentifiers;
650
651 // Process the Hits straw by straw:
652 // get the iterator pairs for given straw
653 ATH_CHECK(this->processStraws(ctx, *m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
654
655 delete m_thpctrt;
656 for(TRTUncompressedHitCollection* ptr : m_trtHitCollList) delete ptr;
657 m_trtHitCollList.clear();
658 // no more hits
659
660 //Noise in straws without simhits:
661 if (m_settings->noiseInUnhitStraws()) {
662 const unsigned int numberOfDigitsBeforeNoise(m_vDigits.size());
663
664 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
665 if (m_settings->doCrosstalk()) {
666 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
667 }
668
669 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
670
672
673 } else {
674 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
675 };
676
677 // All digits are ready.
678 // We just need to convert to relevant identifiers and output to storegate.
679
680 if (createAndStoreRDOs().isFailure()) {
681 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
682 return StatusCode::FAILURE;
683 }
684 else {
685 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
686 }
687
688 return StatusCode::SUCCESS;
689}
690
691//_____________________________________________________________________________
693{
694
695 std::vector<TRTDigit>::const_iterator TRTDigitIter(m_vDigits.begin());
696 std::vector<TRTDigit>::const_iterator endOfTRTDigits(m_vDigits.end());
697
698 // for testing
699 IdentifierHash IdHash; // default value is 0xFFFFFFFF
700 IdentifierHash IdHashOld; // default value is 0xFFFFFFFF
701 TRT_RDO_Collection *RDOColl(nullptr);
702
703 Identifier idStraw;
704
705 while (TRTDigitIter != endOfTRTDigits) {
706 ATH_MSG_DEBUG ( "Digit ID " << TRTDigitIter->GetStrawID() << " Digit " << TRTDigitIter->GetDigit() );
707
708 Identifier layer_id;
709 bool identifierOK(false);
710 idStraw = getIdentifier(TRTDigitIter->GetStrawID(), IdHash, layer_id, identifierOK);
711 if (!identifierOK) {
712 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (2)" );
713 ++TRTDigitIter;
714 continue;
715 };
716
717 // Create new TRT RDO Collection
718 ATH_MSG_DEBUG ( " RDO ID " << m_trt_id->print_to_string(idStraw) );
719
720 //TK: wauv - we are really betting the farm on the fact that the
721 //ordering of digits will result in a similar ordering of the
722 //idhash'es here... (this is not immediately the case when noise
723 //hits are appended afterwards).
724
725 if (IdHash != IdHashOld) {
726 RDOColl = new TRT_RDO_Collection(IdHash);
727 ATH_MSG_DEBUG ( "New TRT RDO Collection created with IdHash " << static_cast<int>(IdHash) );
728 IdHashOld = IdHash;
729 RDOColl->setIdentifier(layer_id);
730
731 // Add to the container
732 if (m_trtrdo_container->addCollection(RDOColl, RDOColl->identifyHash()).isFailure()) {
733 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
734 return StatusCode::FAILURE;
735 } else {
736 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
737 }
738 }
739
740 // Put RDO into Collection
741 TRT_LoLumRawData *p_rdo(new TRT_LoLumRawData(idStraw, TRTDigitIter->GetDigit()));
742 if (RDOColl) {
743 RDOColl->push_back(p_rdo);
744 } else {
745 ATH_MSG_FATAL ( "Failed to create the TRT_RDO_Collection before trying to add an RDO to it! IdHash = " << static_cast<int>(IdHash) );
746 delete p_rdo;
747 return StatusCode::FAILURE;
748 }
749 ++TRTDigitIter;
750 }
751
752 m_vDigits.clear();
753 return StatusCode::SUCCESS;
754}
755
756
757//_____________________________________________________________________________
759 IdentifierHash& hashId,
760 Identifier& IdLayer,
761 bool & statusok ) const
762{
763 statusok = true;
764
765 Identifier IdStraw;
766
767 const int mask(0x0000001F);
768 const int word_shift(5);
769 int trtID, ringID, moduleID, layerID, strawID;
770 int wheelID, planeID, sectorID;
771
772 const InDetDD::TRT_BarrelElement *barrelElement;
773 const InDetDD::TRT_EndcapElement *endcapElement;
774
775 if ( !(hitID & 0x00200000) ) { // barrel
776 strawID = hitID & mask;
777 hitID >>= word_shift;
778 layerID = hitID & mask;
779 hitID >>= word_shift;
780 moduleID = hitID & mask;
781 hitID >>= word_shift;
782 ringID = hitID & mask;
783 trtID = hitID >> word_shift;
784
785 barrelElement = m_manager->getBarrelElement(trtID, ringID, moduleID, layerID);
786 if ( barrelElement ) {
787 hashId = barrelElement->identifyHash();
788 IdLayer = barrelElement->identify();
789 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
790 } else {
791 ATH_MSG_ERROR ( "Could not find detector element for barrel identifier with "
792 << "(ipos,iring,imod,ilayer,istraw) = ("
793 << trtID << ", " << ringID << ", " << moduleID << ", "
794 << layerID << ", " << strawID << ")" );
795 statusok = false;
796 }
797 } else { // endcap
798 strawID = hitID & mask;
799 hitID >>= word_shift;
800 planeID = hitID & mask;
801 hitID >>= word_shift;
802 sectorID = hitID & mask;
803 hitID >>= word_shift;
804 wheelID = hitID & mask;
805 trtID = hitID >> word_shift;
806
807 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
808 if (trtID == 3) { trtID = 0; }
809 else { trtID = 1; }
810
811 endcapElement = m_manager->getEndcapElement(trtID, wheelID, planeID, sectorID);
812
813 if ( endcapElement ) {
814 hashId = endcapElement->identifyHash();
815 IdLayer = endcapElement->identify();
816 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
817 } else {
818 ATH_MSG_ERROR ( "Could not find detector element for endcap identifier with "
819 << "(ipos,iwheel,isector,iplane,istraw) = ("
820 << trtID << ", " << wheelID << ", " << sectorID << ", "
821 << planeID << ", " << strawID << ")" );
822 ATH_MSG_ERROR ( "If this happens very rarely, don't be alarmed (it is a Geant4 'feature')" );
823 ATH_MSG_ERROR ( "If it happens a lot, you probably have misconfigured geometry in the sim. job." );
824 statusok = false;
825 }
826
827 }
828
829 return IdStraw;
830}
831
832//_____________________________________________________________________________
834
836 m_settings->print("TRTDigSettings Settings : ");
837 }
838
839 ATH_MSG_INFO ( "TRTDigitizationTool::finalize()" );
840
841 return StatusCode::SUCCESS;
842}
843
844//_____________________________________________________________________________
845double TRTDigitizationTool::getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine) {
846 // 13th February 2015: replace ComTime with a hack (fixme) based on an
847 // event phase distribution from Alex (alejandro.alonso@cern.ch) that
848 // is modelled as a Guassian of mean 5.48 ns and sigma 8.91 ns.
849 return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 5.48, 8.91);
850}
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:
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
const HepPDT::ParticleDataTable * m_particleTable
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
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