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 // Get the Particle Properties Service
127 ATH_CHECK(m_ppSvc.retrieve());
128 m_particleTable = m_ppSvc->PDT();
129
130 //locate the PileUpMergeSvc and initialize our local ptr
132 ATH_CHECK(m_mergeSvc.retrieve());
133 }
134
135 //Retrieve TRT_StrawNeighbourService.
137
138 //Retrieve TRT_CalDbTool
139 if (m_settings->getT0FromData()) {
140 ATH_CHECK(m_calDbTool.retrieve());
141 }
142 else {
143 m_calDbTool.disable();
144 }
145
146 m_minpileuptruthEkin = m_settings->pileUpSDOsMinEkin();
147
148 // Set SDO readout range
149 const double intervalBetweenCrossings(m_settings->timeInterval() / 3.);
150
151 switch ( (m_settings->storeSDO() )) {
152 case 0: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = -1.*CLHEP::ns; break;
153 case 1: m_minCrossingTimeSDO = -1.*CLHEP::ns; m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
154 case 2: m_minCrossingTimeSDO = -(intervalBetweenCrossings * 2. + 1.*CLHEP::ns); m_maxCrossingTimeSDO = (intervalBetweenCrossings * 2. + 1.*CLHEP::ns); break;
155 default:
156 ATH_MSG_ERROR ( "storeSDO is out of range:"<<m_settings->storeSDO()<<"allowed values are: 0,1,2. Setting storeSDO = 2 " );
157 m_minCrossingTimeSDO = -51.*CLHEP::ns; m_maxCrossingTimeSDO = 51.*CLHEP::ns;
158 break;
159 }
160
163 ATH_CHECK( m_trtDetElementsInputKey.initialize() );
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 // Access to Conditions objects
323 MagField::AtlasFieldCache fieldCache;
324 if (m_settings->useMagneticFieldMap()) {
325
326 // Get field cache object
328 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
329
330 if (fieldCondObj == nullptr) {
331 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
332 return StatusCode::FAILURE;
333 }
334 fieldCondObj->getInitializedCache (fieldCache);
335 }
336
338 const InDetDD::TRT_DetElementContainer* trtDetElements{*trtDetElementsHandle};
339 if(!trtDetElements) {
340 ATH_MSG_ERROR("Failed to retrieve TRT_DetElementContainer with key " << m_trtDetElementsInputKey.key());
341 return StatusCode::FAILURE;
342 }
344
345
346 ATH_CHECK(simDataMap.record(std::make_unique<InDetSimDataCollection>() ));
347
348 // Register the map into StoreGate
349 if (not simDataMap.isValid()) {
350 ATH_MSG_FATAL ( "InDetSimData map " << m_outputSDOCollName.key() << " could not be registered in StoreGate !" );
351 return StatusCode::FAILURE;
352 } else {
353 ATH_MSG_DEBUG ( "InDetSimData map " << m_outputSDOCollName.key() << " registered in StoreGate" );
354 }
355
356 m_cosmicEventPhase = 0.0;
357 if (m_settings->doCosmicTimingPit()) {
359 };
360
361 // Create a vector of deposits
362 std::vector<InDetSimData::Deposit> depositVector(100);
363
364 // loop over all straws
366 while (thpctrt.nextDetectorElement(i, e)) {
367
368 int hitID((*i)->GetHitID()); // Get hitID
369
370 // evtIndex should be 0 for main event and 1,2,3,... for pileup events:
371 // (event Id is a property of the TimedHitPtr)
372 HepMcParticleLink::index_type evtIndex(i->eventId());
373
374 if ( m_settings->noiseInUnhitStraws() ) {
375 sim_hitids.insert(hitID);
376 }
377 //Safeguard against a rare case of hitID corruption found by Davide:
378 if ( hitID & 0xc0000000 ) {
379 ATH_MSG_ERROR ( "Hit ID not Valid (" << MSG::hex << hitID << ")" << MSG::dec );
380 continue;
381 }
382
383 // Convert hitID to Identifier
384 IdentifierHash IdHash;
385 Identifier idLayer;
386 bool identifierOK;
387 Identifier idStraw(getIdentifier(hitID, IdHash, idLayer, identifierOK));
388 if ( !identifierOK ) {
389 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (1)" );
390 continue;
391 }
392
393 //For crosstalk sim
394 simhitsIdentifiers.insert(idStraw);
395
397 // Fill a vector of deposits
398 depositVector.clear();
399 depositVector.reserve(std::distance(i,e));
400 for (TimedHitCollection<TRTUncompressedHit>::const_iterator hit_iter(i); hit_iter != e; ++hit_iter ) {
401 // create a new deposit
402 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.
403 (*hit_iter)->GetEnergyDeposit() );
405 continue;
406 }
407 ATH_MSG_VERBOSE ( "Deposit: trackID " << deposit.first << " energyDeposit " << deposit.second );
408 depositVector.emplace_back(std::move(deposit));
409 }
410
411 const TimedHitPtr<TRTUncompressedHit>& theHit(*i);
412 const double bunchCrossingTime(hitTime(theHit) - static_cast<double>(theHit->GetGlobalTime()));
413
414 // Add the simdata object to the map.
415 if ( !depositVector.empty() &&
416 (evtIndex == 0 || ((*i)->GetKineticEnergy()>m_minpileuptruthEkin)) &&
417 (bunchCrossingTime < m_maxCrossingTimeSDO) && (bunchCrossingTime > m_minCrossingTimeSDO) ) {
418 simDataMap->try_emplace(idStraw, std::move(depositVector));
419 }
421
422 // Digitization for the given straw
423 TRTDigit digit_straw;
424
426 //if (m_settings->doCosmicTimingPit()) {
427 // if ( StatusCode::SUCCESS == evtStore()->retrieve(m_ComTime,"ComTime")) {
428 // ATH_MSG_VERBOSE ( "Found tool for cosmic timing: ComTime" );
429 // } else {
430 // ATH_MSG_ERROR ( "Did not find tool needed for cosmic timing: ComTime" );
431 // }
432 //}
433
434 // if StatusHT == 6 thats emulate argon, ==7 that's emulate krypton
435 bool emulateArFlag = m_sumTool->getStatusHT(idStraw, ctx) == 6;
436 bool emulateKrFlag = m_sumTool->getStatusHT(idStraw, ctx) == 7;
437 const int statusHT = m_sumTool->getStatusHT(idStraw, ctx);
438 m_pProcessingOfStraw->ProcessStraw(fieldCache, trtDetElements, i, e, digit_straw,
440 m_cosmicEventPhase, //m_ComTime,
442 emulateArFlag,
443 emulateKrFlag,
444 strawRndmEngine,
445 elecProcRndmEngine,
446 elecNoiseRndmEngine,
447 paiRndmEngine);
448
449 // Print out the digits etc (for debugging)
450 //int mstrw = digit_straw.GetStrawID();
451 //unsigned int mword = digit_straw.GetDigit();
452 //std::cout << "AJB " << mstrw << ":" << mword << std::endl;
453 //print_mword_properties(mword);
454 //std::cout << "AJB "; bits24(mword);
455 //std::cout << "AJB "; bits27(mword);
456
457 // finally push back the output digit.
458 if ( digit_straw.GetDigit() ) {
459 m_vDigits.push_back(digit_straw);
460 }
461
462 } // end of straw loop
463
464 return StatusCode::SUCCESS;
465}
466
467//_____________________________________________________________________________
468StatusCode TRTDigitizationTool::processAllSubEvents(const EventContext& ctx) {
469
470 // Set the RNGs to use for this event.
471 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
472 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
473 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
474 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
475 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
476 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
477
478 if (m_first_event) {
479 if(this->lateInitialize(ctx).isFailure()) {
480 ATH_MSG_FATAL ( "lateInitialize method failed!" );
481 return StatusCode::FAILURE;
482 }
483 }
484
486
487 ATH_MSG_DEBUG ( "TRTDigitizationTool::processAllSubEvents()" );
488
490 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
491 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
492
493 if (not m_trtrdo_container.isValid()) {
494 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
495 return StatusCode::FAILURE;
496 }else {
497 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
498 }
499
500 m_vDigits.clear();
501
502 // get the container(s)
505 // In case of single hits container just load the collection using read handles
508 if (!hitCollection.isValid()) {
509 ATH_MSG_ERROR("Could not get TRTUncompressedHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
510 return StatusCode::FAILURE;
511 }
512
513 // Define Hit Collection
514 thpctrt.reserve(1);
515
516 // create a new hits collection
517 thpctrt.insert(0, hitCollection.cptr());
518 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollection->size() << " hits");
519 }
520 else {
521 TimedHitCollList hitCollList; // this is a list<pair<time_t, DataLink<TRTUncompressedHitCollection> > >
522 unsigned int numberOfSimHits(0);
523 if ( !(m_mergeSvc->retrieveSubEvtsData(m_dataObjectName, hitCollList, numberOfSimHits).isSuccess()) && hitCollList.empty() ) {
524 ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
525 return StatusCode::FAILURE;
526 } else {
527 ATH_MSG_DEBUG ( hitCollList.size() << " TRTUncompressedHitCollections with key " << m_dataObjectName << " found" );
528 }
529
530 // Define Hit Collection
531 thpctrt.reserve(numberOfSimHits);
532
533 //now merge all collections into one
534 TimedHitCollList::iterator iColl(hitCollList.begin());
535 TimedHitCollList::iterator endColl(hitCollList.end() );
537 // loop on the hit collections
538 while ( iColl != endColl ) {
539 //decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
541 if (m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { ++iColl; continue; }
543 const TRTUncompressedHitCollection* p_collection(iColl->second);
544 thpctrt.insert(iColl->first, p_collection);
545 ATH_MSG_DEBUG ( "TRTUncompressedHitCollection found with " << p_collection->size() << " hits" );
546 ++iColl;
547 }
548 }
549
550 //Set of all hitid's with simhits (used for noise simulation).
551 std::set<int> sim_hitids;
552 std::set<Identifier> simhitsIdentifiers;
553
554 // Process the Hits straw by straw: get the iterator pairs for given straw
555 ATH_CHECK(this->processStraws(ctx, thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
556
557 // no more hits
558
559 //Noise in straws without simhits:
560 if (m_settings->noiseInUnhitStraws()) {
561 const int numberOfDigitsBeforeNoise(m_vDigits.size());
562
563 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
564 if (m_settings->doCrosstalk()) {
565 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
566 }
567
568 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
569
571
572 } else {
573 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
574 }
575
576 // All digits are ready.
577 // We just need to convert to relevant identifiers and output to storegate.
578
579 if (createAndStoreRDOs().isFailure()) {
580 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
581 return StatusCode::FAILURE;
582 }
583 else {
584 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
585 }
586
587 return StatusCode::SUCCESS;
588}
589
590CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName,
591 const EventContext& ctx) const
592{
593 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
594 std::string rngName = name()+streamName;
595 rngWrapper->setSeed( rngName, ctx );
596 return rngWrapper->getEngine(ctx);
597}
598
599//_____________________________________________________________________________
600CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset,
601 const EventContext& ctx) const
602{
603 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
604 rngWrapper->setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
605 return rngWrapper->getEngine(ctx);
606}
607
608//_____________________________________________________________________________
609StatusCode TRTDigitizationTool::mergeEvent(const EventContext& ctx) {
610 std::vector<std::pair<unsigned int, int> >::iterator ii(m_seen.begin());
611 std::vector<std::pair<unsigned int, int> >::iterator ee(m_seen.end());
612 while (ii != ee) {
613 ATH_MSG_DEBUG( "mergeEvent: there are " << ii->first << " events in bunch xing " << ii->second );
614 ++ii;
615 }
616
617 // Set the RNGs to use for this event.
618 CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
619 CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
620 CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
621 CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
622 CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
623 CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
624
625 if (m_first_event) {
626 if(this->lateInitialize(ctx).isFailure()) {
627 ATH_MSG_FATAL ( "lateInitialize method failed!" );
628 return StatusCode::FAILURE;
629 }
630 }
631
633
634 ATH_MSG_DEBUG ( "TRTDigitization::execute()" );
635
637 ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
638 ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
639 if (not m_trtrdo_container.isValid()) {
640 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
641 return StatusCode::FAILURE;
642 } else {
643 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
644 }
645
646 //Set of all hitid's with simhits (used for noise simulation).
647 std::set<int> sim_hitids;
648 std::set<Identifier> simhitsIdentifiers;
649
650 // Process the Hits straw by straw:
651 // get the iterator pairs for given straw
652 ATH_CHECK(this->processStraws(ctx, *m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
653
654 delete m_thpctrt;
655 for(TRTUncompressedHitCollection* ptr : m_trtHitCollList) delete ptr;
656 m_trtHitCollList.clear();
657 // no more hits
658
659 //Noise in straws without simhits:
660 if (m_settings->noiseInUnhitStraws()) {
661 const unsigned int numberOfDigitsBeforeNoise(m_vDigits.size());
662
663 m_pNoise->appendPureNoiseToProperDigits(m_vDigits, sim_hitids, noiseRndmEngine);
664 if (m_settings->doCrosstalk()) {
665 m_pNoise->appendCrossTalkNoiseToProperDigits(m_vDigits, simhitsIdentifiers,m_TRTStrawNeighbourSvc, noiseRndmEngine);
666 }
667
668 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() << " (" << m_vDigits.size()-numberOfDigitsBeforeNoise << " of those are pure noise)" );
669
671
672 } else {
673 ATH_MSG_DEBUG ( " Number of digits " << m_vDigits.size() );
674 };
675
676 // All digits are ready.
677 // We just need to convert to relevant identifiers and output to storegate.
678
679 if (createAndStoreRDOs().isFailure()) {
680 ATH_MSG_FATAL ( "createAndStoreRDOs() failed!" );
681 return StatusCode::FAILURE;
682 }
683 else {
684 ATH_MSG_DEBUG ( "createAndStoreRDOs() succeeded" );
685 }
686
687 return StatusCode::SUCCESS;
688}
689
690//_____________________________________________________________________________
692{
693
694 std::vector<TRTDigit>::const_iterator TRTDigitIter(m_vDigits.begin());
695 std::vector<TRTDigit>::const_iterator endOfTRTDigits(m_vDigits.end());
696
697 // for testing
698 IdentifierHash IdHash; // default value is 0xFFFFFFFF
699 IdentifierHash IdHashOld; // default value is 0xFFFFFFFF
700 TRT_RDO_Collection *RDOColl(nullptr);
701
702 Identifier idStraw;
703
704 while (TRTDigitIter != endOfTRTDigits) {
705 ATH_MSG_DEBUG ( "Digit ID " << TRTDigitIter->GetStrawID() << " Digit " << TRTDigitIter->GetDigit() );
706
707 Identifier layer_id;
708 bool identifierOK(false);
709 idStraw = getIdentifier(TRTDigitIter->GetStrawID(), IdHash, layer_id, identifierOK);
710 if (!identifierOK) {
711 ATH_MSG_ERROR ( "Ignoring simhits with suspicious identifier (2)" );
712 ++TRTDigitIter;
713 continue;
714 };
715
716 // Create new TRT RDO Collection
717 ATH_MSG_DEBUG ( " RDO ID " << m_trt_id->print_to_string(idStraw) );
718
719 //TK: wauv - we are really betting the farm on the fact that the
720 //ordering of digits will result in a similar ordering of the
721 //idhash'es here... (this is not immediately the case when noise
722 //hits are appended afterwards).
723
724 if (IdHash != IdHashOld) {
725 RDOColl = new TRT_RDO_Collection(IdHash);
726 ATH_MSG_DEBUG ( "New TRT RDO Collection created with IdHash " << static_cast<int>(IdHash) );
727 IdHashOld = IdHash;
728 RDOColl->setIdentifier(layer_id);
729
730 // Add to the container
731 if (m_trtrdo_container->addCollection(RDOColl, RDOColl->identifyHash()).isFailure()) {
732 ATH_MSG_FATAL ( "Container " << m_outputRDOCollName.key() << " could not be registered in StoreGate !" );
733 return StatusCode::FAILURE;
734 } else {
735 ATH_MSG_DEBUG ( "Container " << m_outputRDOCollName.key() << " registered in StoreGate" );
736 }
737 }
738
739 // Put RDO into Collection
740 TRT_LoLumRawData *p_rdo(new TRT_LoLumRawData(idStraw, TRTDigitIter->GetDigit()));
741 if (RDOColl) {
742 RDOColl->push_back(p_rdo);
743 } else {
744 ATH_MSG_FATAL ( "Failed to create the TRT_RDO_Collection before trying to add an RDO to it! IdHash = " << static_cast<int>(IdHash) );
745 delete p_rdo;
746 return StatusCode::FAILURE;
747 }
748 ++TRTDigitIter;
749 }
750
751 m_vDigits.clear();
752 return StatusCode::SUCCESS;
753}
754
755
756//_____________________________________________________________________________
758 IdentifierHash& hashId,
759 Identifier& IdLayer,
760 bool & statusok ) const
761{
762 statusok = true;
763
764 Identifier IdStraw;
765
766 const int mask(0x0000001F);
767 const int word_shift(5);
768 int trtID, ringID, moduleID, layerID, strawID;
769 int wheelID, planeID, sectorID;
770
771 const InDetDD::TRT_BarrelElement *barrelElement;
772 const InDetDD::TRT_EndcapElement *endcapElement;
773
774 if ( !(hitID & 0x00200000) ) { // barrel
775 strawID = hitID & mask;
776 hitID >>= word_shift;
777 layerID = hitID & mask;
778 hitID >>= word_shift;
779 moduleID = hitID & mask;
780 hitID >>= word_shift;
781 ringID = hitID & mask;
782 trtID = hitID >> word_shift;
783
784 barrelElement = m_manager->getBarrelElement(trtID, ringID, moduleID, layerID);
785 if ( barrelElement ) {
786 hashId = barrelElement->identifyHash();
787 IdLayer = barrelElement->identify();
788 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
789 } else {
790 ATH_MSG_ERROR ( "Could not find detector element for barrel identifier with "
791 << "(ipos,iring,imod,ilayer,istraw) = ("
792 << trtID << ", " << ringID << ", " << moduleID << ", "
793 << layerID << ", " << strawID << ")" );
794 statusok = false;
795 }
796 } else { // endcap
797 strawID = hitID & mask;
798 hitID >>= word_shift;
799 planeID = hitID & mask;
800 hitID >>= word_shift;
801 sectorID = hitID & mask;
802 hitID >>= word_shift;
803 wheelID = hitID & mask;
804 trtID = hitID >> word_shift;
805
806 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
807 if (trtID == 3) { trtID = 0; }
808 else { trtID = 1; }
809
810 endcapElement = m_manager->getEndcapElement(trtID, wheelID, planeID, sectorID);
811
812 if ( endcapElement ) {
813 hashId = endcapElement->identifyHash();
814 IdLayer = endcapElement->identify();
815 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
816 } else {
817 ATH_MSG_ERROR ( "Could not find detector element for endcap identifier with "
818 << "(ipos,iwheel,isector,iplane,istraw) = ("
819 << trtID << ", " << wheelID << ", " << sectorID << ", "
820 << planeID << ", " << strawID << ")" );
821 ATH_MSG_ERROR ( "If this happens very rarely, don't be alarmed (it is a Geant4 'feature')" );
822 ATH_MSG_ERROR ( "If it happens a lot, you probably have misconfigured geometry in the sim. job." );
823 statusok = false;
824 }
825
826 }
827
828 return IdStraw;
829}
830
831//_____________________________________________________________________________
833
835 m_settings->print("TRTDigSettings Settings : ");
836 }
837
838 ATH_MSG_INFO ( "TRTDigitizationTool::finalize()" );
839
840 return StatusCode::SUCCESS;
841}
842
843//_____________________________________________________________________________
844double TRTDigitizationTool::getCosmicEventPhase(CLHEP::HepRandomEngine *rndmEngine) {
845 // 13th February 2015: replace ComTime with a hack (fixme) based on an
846 // event phase distribution from Alex (alejandro.alonso@cern.ch) that
847 // is modelled as a Guassian of mean 5.48 ns and sigma 8.91 ns.
848 return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 5.48, 8.91);
849}
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
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