ATLAS Offline Software
Loading...
Searching...
No Matches
TRTFastDigitizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TRTFastDigitizationTool.cxx
7//
8// Implementation file for class TRTFastDigitizationTool
9//
11
13
20
21#include "GaudiKernel/SystemOfUnits.h"
22
23// Det descr includes:
27
28// Other includes
30
34
35// InDet stuff
37
38// CLHEP
40#include "CLHEP/Vector/ThreeVector.h"
41#include "CLHEP/Random/RandFlat.h"
42#include "CLHEP/Random/RandGaussZiggurat.h"
43
44// Conditions data
45#include "Identifier/Identifier.h"
47
48#include <memory>
49
50// select the High threshold bits of TRT RDO words
51static const unsigned int maskHT=0x04020100;
52
54 const std::string &name,
55 const IInterface *parent )
56 : PileUpToolBase( type, name, parent )
57{
58}
59
60
62{
63 ATH_MSG_DEBUG( "TRTFastDigitizationTool::initialize()" );
64
65 // Get Random Service
66 CHECK( m_rndmSvc.retrieve() );
67
68 // Get the TRT Detector Manager
69 CHECK( detStore()->retrieve( m_trt_manager, "TRT" ) );
70 ATH_MSG_DEBUG( "Retrieved TRT_DetectorManager with version " << m_trt_manager->getVersion().majorNum() );
71
72 CHECK( detStore()->retrieve( m_trt_id, "TRT_ID" ) );
73
74 // PileUp Merge Service
75 CHECK( m_mergeSvc.retrieve() );
76
77 // Argon / Xenon
79 ATH_MSG_DEBUG( "Retrieved TRT_StrawStatusSummaryTool " << m_trtStrawStatusSummaryTool );
80
81 // Check data object name
82 if ( m_trtHitCollectionKey == "" ) {
83 ATH_MSG_FATAL( "Property trtHitCollectionName not set!" );
84 return StatusCode::FAILURE;
85 } else {
86 ATH_MSG_DEBUG( "Input hits: " << m_trtHitCollectionKey );
87 }
88
89 ATH_CHECK(m_trtPrdTruthKey.initialize());
91
92 CHECK( m_trtDriftFunctionTool.retrieve() );
93
95 CHECK( m_trtElectronPidTool.retrieve() );
96 }
97
99
100 StatusCode sc = initializeNumericalConstants();
101
102 return sc;
103}
104
105
106StatusCode TRTFastDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int )
107{
108 m_trtHitCollList.clear();
111
112 StatusCode sc = initializeNumericalConstants();
113
114 return sc;
115
116}
117
118
120 SubEventIterator bSubEvents,
121 SubEventIterator eSubEvents ) {
122
123 // decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
124 if ( m_HardScatterSplittingMode == 2 && !m_HardScatterSplittingSkipper ) { m_HardScatterSplittingSkipper = true; return StatusCode::SUCCESS; }
125 if ( m_HardScatterSplittingMode == 1 && m_HardScatterSplittingSkipper ) { return StatusCode::SUCCESS; }
127
129 TimedHitCollList hitCollList;
130
131 if (!(m_mergeSvc->retrieveSubSetEvtData(m_trtHitCollectionKey.value(), hitCollList, bunchXing,
132 bSubEvents, eSubEvents).isSuccess()) &&
133 hitCollList.empty()) {
134 ATH_MSG_ERROR("Could not fill TimedHitCollList");
135 return StatusCode::FAILURE;
136 } else {
137 ATH_MSG_VERBOSE(hitCollList.size() << " TRTUncompressedHitCollections with key " <<
138 m_trtHitCollectionKey << " found");
139 }
140
141 TimedHitCollList::iterator iColl(hitCollList.begin());
142 TimedHitCollList::iterator endColl(hitCollList.end());
143
144 for( ; iColl != endColl; ++iColl) {
145 TRTUncompressedHitCollection *hitCollPtr = new TRTUncompressedHitCollection(*iColl->second);
146 PileUpTimeEventIndex timeIndex(iColl->first);
147 ATH_MSG_DEBUG("TRTUncompressedHitCollection found with " << hitCollPtr->size() <<
148 " hits");
149 ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time()
150 << " index: " << timeIndex.index()
151 << " type: " << timeIndex.type());
152 m_thpctrt->insert(timeIndex, hitCollPtr);
153 m_trtHitCollList.push_back(hitCollPtr);
154 }
155
156 return StatusCode::SUCCESS;
157}
158
159
160// initialize constants which are the same for all events
162
163 m_trtTailFraction = 4.7e-4; // part of the fraction in Tails
164 m_trtSigmaDriftRadiusTail = 4./sqrt(12.); // sigma of one TRT straw in R (Tail) [mm]
165
166 return StatusCode::SUCCESS;
167}
168
169// set (pileup-dependent) numerical constants
171
172 // Efficiency and resolution dependence on pileup
173 // Resolution is parametrized with a double gaussian so there are two parameters (res1 = core, res2= tail)
174
175 static const float eff_corr_pileup_dependence = -0.0005; // variation of efficiency with the number of Xing
176 static const float res1_corr_pileup_dependence = 0.005; // variation of core resolution (fractional) with the number of Xing
177 static const float res2_corr_pileup_dependence = 0.015; // variation of tail resolution (fractional) with the number of Xing
178 // scale factors relative to the value for mu=20
179 float effcorr = 1+eff_corr_pileup_dependence*(m_NCollPerEvent-20);
180 float res1corr = 1+res1_corr_pileup_dependence*(m_NCollPerEvent-20);
181 float res2corr = 1+res2_corr_pileup_dependence*(m_NCollPerEvent-20);
182
183 // Now the numerical parameters for efficiency and resolution
184 static const float tailRes = 3.600; // scale factor for tail resolution
185 static const float coreFracEndcap_Xe = 0.40; // fraction of events in resolution core (Xe)
186 static const float coreFracEndcap_Ar = 0.40; // fraction of events in resolution core (Ar)
187 static const float coreFracBarrel_Xe = 0.250; // fraction of events in resolution core (Xe)
188 static const float coreFracBarrel_Ar = 0.250; // fraction of events in resolution core (Ar)
189
190
191 static const float eff_BarrelA_Xe = 0.840; // efficiency scale factor
192 static const float eff_EndcapA_Xe = 0.875;
193 static const float eff_BarrelC_Xe = 0.833;
194 static const float eff_EndcapC_Xe = 0.894;
195 static const float eff_BarrelA_Ar = 0.933;
196 static const float eff_EndcapA_Ar = 0.949;
197 static const float eff_BarrelC_Ar = 0.937;
198 static const float eff_EndcapC_Ar = 0.977;
199 static const float err_Barrel_Xe = 0.997; // scale factor for the error as returned by the drift function tool
200 static const float err_Endcap_Xe = 1.065;
201 static const float err_Barrel_Ar = 1.020;
202 static const float err_Endcap_Ar = 1.040;
203
204 static const float coreRes_Barrel_Xe = 0.4; // scale factor for core resolution
205 static const float coreRes_Endcap_Xe = 0.5;
206 static const float coreRes_Barrel_Ar = 0.4;
207 static const float coreRes_Endcap_Ar = 0.5;
208
209 m_cFit[ 0 ][ 0 ] = effcorr*eff_BarrelA_Xe; // Barrel A-side Xenon
210 m_cFit[ 0 ][ 1 ] = err_Barrel_Xe;
211 m_cFit[ 0 ][ 2 ] = coreFracBarrel_Xe;
212 m_cFit[ 0 ][ 3 ] = res1corr*coreRes_Barrel_Xe;
213 m_cFit[ 0 ][ 4 ] = res2corr*tailRes;
214 m_cFit[ 1 ][ 0 ] = effcorr*eff_EndcapA_Xe; // Endcap A-side Xenon
215 m_cFit[ 1 ][ 1 ] = err_Endcap_Xe;
216 m_cFit[ 1 ][ 2 ] = coreFracEndcap_Xe;
217 m_cFit[ 1 ][ 3 ] = res1corr*coreRes_Endcap_Xe;
218 m_cFit[ 1 ][ 4 ] = res2corr*tailRes;
219 m_cFit[ 2 ][ 0 ] = effcorr*eff_BarrelC_Xe; // Barrel C-side Xenon
220 m_cFit[ 2 ][ 1 ] = err_Barrel_Xe;
221 m_cFit[ 2 ][ 2 ] = coreFracBarrel_Xe;
222 m_cFit[ 2 ][ 3 ] = res1corr*coreRes_Barrel_Xe;
223 m_cFit[ 2 ][ 4 ] = res2corr*tailRes;
224 m_cFit[ 3 ][ 0 ] = effcorr*eff_EndcapC_Xe; // Endcap C-side Xenon
225 m_cFit[ 3 ][ 1 ] = err_Endcap_Xe;
226 m_cFit[ 3 ][ 2 ] = coreFracEndcap_Xe;
227 m_cFit[ 3 ][ 3 ] = res1corr*coreRes_Endcap_Xe;
228 m_cFit[ 3 ][ 4 ] = res2corr*tailRes;
229 m_cFit[ 4 ][ 0 ] = effcorr*eff_BarrelA_Ar; // Barrel A-side Argon
230 m_cFit[ 4 ][ 1 ] = err_Barrel_Ar;
231 m_cFit[ 4 ][ 2 ] = coreFracBarrel_Ar;
232 m_cFit[ 4 ][ 3 ] = res1corr*coreRes_Barrel_Ar;
233 m_cFit[ 4 ][ 4 ] = res2corr*tailRes;
234 m_cFit[ 5 ][ 0 ] = effcorr*eff_EndcapA_Ar; // Endcap A-side Argon
235 m_cFit[ 5 ][ 1 ] = err_Endcap_Ar;
236 m_cFit[ 5 ][ 2 ] = coreFracEndcap_Ar;
237 m_cFit[ 5 ][ 3 ] = res1corr*coreRes_Endcap_Ar;
238 m_cFit[ 5 ][ 4 ] = res2corr*tailRes;
239 m_cFit[ 6 ][ 0 ] = effcorr*eff_BarrelC_Ar; // Barrel C-side Argon
240 m_cFit[ 6 ][ 1 ] = err_Barrel_Ar;
241 m_cFit[ 6 ][ 2 ] = coreFracBarrel_Ar;
242 m_cFit[ 6 ][ 3 ] = res1corr*coreRes_Barrel_Ar;
243 m_cFit[ 6 ][ 4 ] = res2corr*tailRes;
244 m_cFit[ 7 ][ 0 ] = effcorr*eff_EndcapC_Ar; // Endcap C-side Argon
245 m_cFit[ 7 ][ 1 ] = err_Endcap_Ar;
246 m_cFit[ 7 ][ 2 ] = coreFracEndcap_Ar;
247 m_cFit[ 7 ][ 3 ] = res1corr*coreRes_Endcap_Ar;
248 m_cFit[ 7 ][ 4 ] = res2corr*tailRes;
249
250 return StatusCode::SUCCESS;
251}
252
253StatusCode TRTFastDigitizationTool::produceDriftCircles(const EventContext& ctx,
254 CLHEP::HepRandomEngine* rndmEngine,
256{
257 // Create OUTPUT PRD_MultiTruthCollection for TRT measurements
259 trtPrdTruth = std::make_unique< PRD_MultiTruthCollection >();
260 if ( !trtPrdTruth.isValid() ) {
261 ATH_MSG_FATAL( "Could not record collection " << trtPrdTruth.name() );
262 return StatusCode::FAILURE;
263 }
264 ATH_MSG_DEBUG( "PRD_MultiTruthCollection " << trtPrdTruth.name() << " registered in StoreGate" );
265
266 if(m_useEventInfo){
267
268 SG::ReadHandle<xAOD::EventInfo> eventInfoContainer(m_EventInfoKey, ctx);
269 if(eventInfoContainer.isValid()){
270 m_NCollPerEvent = (float) eventInfoContainer->averageInteractionsPerCrossing();
271 }
272 else{
273 ATH_MSG_INFO("Cannot retrieve event info");
274 }
275 }
276
277 StatusCode sc = setNumericalConstants();
278 if(sc != StatusCode::SUCCESS) return sc;
279
280 m_driftCircleMap.clear();
281
283 while ( thpctrt.nextDetectorElement( itr1, itr2 ) ) {
284
285 for ( ; itr1 != itr2; ++itr1 ) {
286
287 const TimedHitPtr< TRTUncompressedHit > &hit = *itr1;
288
289 // Get hitID
290 int hitID = hit->GetHitID();
291
292 if ( hitID & 0xc0000000 ) {
293 ATH_MSG_ERROR( "Hit ID not Valid (" << MSG::hex << hitID << ")" << MSG::dec );
294 continue;
295 }
296
297 // Convert hitID to Identifier
298 IdentifierHash hash;
299 Identifier layer_id;
300 bool status;
301 Identifier straw_id = getIdentifier( hitID, hash, layer_id, status );
302 if ( !status ) {
303 ATH_MSG_ERROR( "Ignoring simhits with suspicious identifier (1)" );
304 continue;
305 }
306
307 const InDetDD::TRT_BaseElement *trtBaseElement = m_trt_manager->getElement( hash );
308 Identifier hit_id = trtBaseElement->identify();
309
310 int BEC = m_trt_id->barrel_ec( hit_id );
311 bool isArgon = isArgonStraw( straw_id );
312 int idx = ( BEC > 0 ? BEC : 2 - BEC ) + 4 * isArgon - 1;
313
314 // Get 'track-to-wire' distance
315 double driftRadiusLoc = getDriftRadiusFromXYZ( hit );
316
317 double efficiency = strawEfficiency( driftRadiusLoc, abs( BEC ) );
318 efficiency *= m_cFit[ idx ][ 0 ];
319
320 // Decide wether to throw away this cluster or not
321 if ( CLHEP::RandFlat::shoot( rndmEngine ) < ( 1. - efficiency ) ) continue;
322
323 // Decide core/tail fraction
324 bool isTail = ( CLHEP::RandFlat::shoot( rndmEngine ) < m_trtTailFraction );
325
326 double sigmaTrt = m_trtSigmaDriftRadiusTail;
327 if ( !isTail ) {
328 double driftTime = m_trtDriftFunctionTool->approxDriftTime( std::abs( driftRadiusLoc ) );
329 sigmaTrt = m_trtDriftFunctionTool->errorOfDriftRadius( driftTime, hit_id, m_NCollPerEvent );
330 }
331
332 // driftRadiusLoc smearing procedure
333 double dR = 0;
334 int ii = 0;
335 do {
336 double tailSmearing = CLHEP::RandFlat::shoot( rndmEngine );
337 dR = CLHEP::RandGaussZiggurat::shoot( rndmEngine, 0., ( tailSmearing < m_cFit[ idx ][ 2 ] ? m_cFit[ idx ][ 3 ] : m_cFit[ idx ][ 4 ] ) ) * sigmaTrt;
338 ++ii;
339 if ( ii > 50 ) { // should not appear in simulation
340 dR = 2. - driftRadiusLoc;
341 break;
342 }
343 }
344 while ( driftRadiusLoc + dR > 2. || driftRadiusLoc + dR < 0. );
345 double smearedRadius = driftRadiusLoc + dR;
346
347 Amg::Vector2D hitLocalPosition( smearedRadius, 0. );
348 std::vector< Identifier > rdoList = { straw_id };
349
350 auto hitErrorMatrix = Amg::MatrixX(1, 1);
351 (hitErrorMatrix)(Trk::driftRadius, Trk::driftRadius) =
352 sigmaTrt * sigmaTrt * m_cFit[idx][1] * m_cFit[idx][1];
353
354 // the TRT word simulate only TR information for the moment
355 // consult TRTElectronicsProcessing::EncodeDigit() in TRT_Digitization/src/TRTElectronicsProcessing.cxx
356 unsigned int word = 0x00007c00; // set to a standard low threshold hit: word = 0; for ( unsigned int j = 10; j < 15; ++j ) word += 1 << ( 25 - j - j / 8 );
357
358 // set High Threshold bit
359 HepGeom::Point3D< double > hitGlobalPosition = getGlobalPosition( hit );
360 int particleEncoding = hit->GetParticleEncoding();
361 float kineticEnergy = hit->GetKineticEnergy();
362
364
365 double position = ( std::abs(BEC) == 1 ? hitGlobalPosition.z() : hitGlobalPosition.perp() );
366
367 double probability;
368 if ( abs( particleEncoding ) == 11 && kineticEnergy > 5000. ) { // electron
369 probability = m_trtHighProbabilityBoostEle*getProbHT( particleEncoding, kineticEnergy, straw_id, smearedRadius, position);
370 }
371 else{
372 probability = m_trtHighProbabilityBoostBkg*getProbHT( particleEncoding, kineticEnergy, straw_id, smearedRadius, position);
373 }
374
375 if ( CLHEP::RandFlat::shoot( rndmEngine ) < probability ) word |= maskHT;
376 }
377 else {
378
379 double eta = hitGlobalPosition.pseudoRapidity();
380 // double mass = particleMass( particle );
381 // double p = sqrt( kineticEnergy * kineticEnergy + 2. * kineticEnergy * mass );
382 float p = kineticEnergy; // like in TRT_Digitization ( previously we also use zero mass due to bug in particleMass routine )
383
384 if ( abs( particleEncoding ) == 11 && p > 5000. ) { // electron
385 double probability = ( p < 20000. ? HTProbabilityElectron_low_pt( eta ) : HTProbabilityElectron_high_pt( eta ) );
386 if ( CLHEP::RandFlat::shoot( rndmEngine ) < probability ) word |= maskHT;
387 }
388 else if ( abs( particleEncoding ) == 13 || abs( particleEncoding ) > 100 ) { // muon or other particle
389 double probability = ( p < 20000. ? HTProbabilityMuon_5_20( eta ) : HTProbabilityMuon_60( eta ) );
390 if ( CLHEP::RandFlat::shoot( rndmEngine ) < probability ) word |= maskHT;
391 }
392
393 }
394
395 InDet::TRT_DriftCircle* trtDriftCircle =
396 new InDet::TRT_DriftCircle(straw_id,
397 hitLocalPosition,
398 std::move(rdoList),
399 std::move(hitErrorMatrix),
400 trtBaseElement,
401 word);
402 if (!trtDriftCircle)
403 continue;
404
405 m_driftCircleMap.insert( std::multimap< Identifier, InDet::TRT_DriftCircle * >::value_type( straw_id, trtDriftCircle ) );
406 const HepMcParticleLink particleLink = HepMcParticleLink::getRedirectedLink(hit->particleLink(), hit.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
407 if ( particleLink.isValid() ) {
409 trtPrdTruth->insert( std::make_pair( trtDriftCircle->identify(), particleLink ) );
410 ATH_MSG_DEBUG( "Truth map filled with cluster " << trtDriftCircle << " and link = " << particleLink );
411 }
412 }
413 else {
414 ATH_MSG_DEBUG( "Particle link NOT valid!! Truth map NOT filled with cluster " << trtDriftCircle << " and link = " << particleLink );
415 }
416
417 }
418 }
419
420 return StatusCode::SUCCESS;
421}
422
423
424StatusCode TRTFastDigitizationTool::processAllSubEvents(const EventContext& ctx) {
425
426 ATH_MSG_DEBUG( "TRTFastDigitizationTool::processAllSubEvents()" );
427
429
430 HitCollectionTimedList hitCollectionTimedList;
431 unsigned int numberOfSimHits = 0;
432 if ( m_mergeSvc->retrieveSubEvtsData( m_trtHitCollectionKey.value(), hitCollectionTimedList, numberOfSimHits ).isFailure() && hitCollectionTimedList.empty() ) {
433 ATH_MSG_ERROR( "Could not fill HitCollectionTimedList" );
434 return StatusCode::FAILURE;
435 }
436 else {
437 ATH_MSG_DEBUG( hitCollectionTimedList.size() << " TRTUncompressedHitCollections with key " << m_trtHitCollectionKey << " found" );
438 }
439
441 TimedHitCollection< TRTUncompressedHit > timedHitCollection( numberOfSimHits );
442 for (auto & itr : hitCollectionTimedList) {
443 // decide if this event will be processed depending on HardScatterSplittingMode & bunchXing
447 timedHitCollection.insert( itr.first, static_cast< const TRTUncompressedHitCollection * >( itr.second ) );
448 }
449
450 // Set the RNG to use for this event.
451 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
452 const std::string rngName = name()+m_randomEngineName;
453 rngWrapper->setSeed( rngName, ctx );
454 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
455
456 // Process the Hits straw by straw: get the iterator pairs for given straw
457 CHECK( this->produceDriftCircles(ctx, rndmEngine, timedHitCollection ) );
458
459 CHECK( this->createAndStoreRIOs(ctx, rndmEngine) );
460 ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
461
462 return StatusCode::SUCCESS;
463}
464
465
466StatusCode TRTFastDigitizationTool::mergeEvent(const EventContext& ctx) {
467
468 ATH_MSG_DEBUG( "TRTFastDigitizationTool::mergeEvent()" );
469
470 // Set the RNG to use for this event.
471 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomEngineName);
472 const std::string rngName = name()+m_randomEngineName;
473 rngWrapper->setSeed( rngName, ctx );
474 CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
475
476 // Process the Hits straw by straw: get the iterator pairs for given straw
477 if ( m_thpctrt != nullptr ) {
478 CHECK( this->produceDriftCircles(ctx, rndmEngine, *m_thpctrt) );
479 }
480
481 // Clean up temporary containers
482 delete m_thpctrt;
483 for(TRTUncompressedHitCollection* ptr : m_trtHitCollList) delete ptr;
484 m_trtHitCollList.clear();
485
486 CHECK( this->createAndStoreRIOs(ctx, rndmEngine) );
487 ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
488
489 return StatusCode::SUCCESS;
490}
491
492
493StatusCode TRTFastDigitizationTool::createAndStoreRIOs(const EventContext& ctx, CLHEP::HepRandomEngine* rndmEngine)
494{
495 // Create OUTPUT TRT_DriftCircleContainer and register it in StoreGate
497 trtDriftCircleContainer = std::make_unique< InDet::TRT_DriftCircleContainer >( m_trt_id->straw_layer_hash_max() );
498 if ( !trtDriftCircleContainer.isValid() ) {
499 ATH_MSG_FATAL( "Could not create TRT_DriftCircleContainer" );
500 return StatusCode::FAILURE;
501 }
502 ATH_MSG_DEBUG( "InDet::TRT_DriftCircleContainer " << trtDriftCircleContainer.name() << " registered in StoreGate" );
503
504 using DriftCircleMapItr = std::multimap<Identifier, InDet::TRT_DriftCircle *>::iterator;
505 using HashMapItr = std::multimap<IdentifierHash, InDet::TRT_DriftCircle *>::iterator;
506
507 // empiric parameterization of the probability to merge to LT hits into a HT hit as a function of the number of collisions
508 // TL - I first determined the value of highTRMergeProb which gives a good
509 // agreeement with full simulation as being 0.04 for mu=10 and 0.12 for mu=60;
510 // I decided to use the functional form a*pow(mu,b) to describe the mu
511 // dependence; solving the 2x2 system gives a=0.01 and b=0.61.
512 float highTRMergeProb = 0.012*pow(m_NCollPerEvent,0.61);
513
514 std::multimap< IdentifierHash, InDet::TRT_DriftCircle * > idHashMap;
515
516 for ( DriftCircleMapItr itr = m_driftCircleMap.begin() ; itr != m_driftCircleMap.end(); itr = m_driftCircleMap.upper_bound( itr->first ) ) {
517
518 const Identifier trtid = itr->first;
519 std::pair< DriftCircleMapItr, DriftCircleMapItr > hitsInOneStraw = m_driftCircleMap.equal_range( trtid );
520 unsigned int numberOfHitsInOneStraw = m_driftCircleMap.count( itr->first );
521 InDet::TRT_DriftCircle *trtDriftCircle = ( hitsInOneStraw.first )->second;
522 IdentifierHash hash = trtDriftCircle->detectorElement()->identifyHash();
523
524 // delete all driftCircles in TRT straw excert the first one, see ATLPHYSVAL-395
525 bool isHT=false;
526 for ( DriftCircleMapItr itr2 = ++( hitsInOneStraw.first ); itr2 != hitsInOneStraw.second; ++itr2 ) {
527 InDet::TRT_DriftCircle *trtDriftCircle2 = itr2->second;
528 if(trtDriftCircle2->getWord() & maskHT) isHT = true;
529 delete trtDriftCircle2;
530 }
531
532 // set the word of the first hit to high threshold with some probability, unless any of the hits is HT already
533 if( !(trtDriftCircle->getWord() & maskHT) && !isHT && numberOfHitsInOneStraw > 1) {
534 unsigned int newword = 0;
535 if(highTRMergeProb*(numberOfHitsInOneStraw-1) > CLHEP::RandFlat::shoot( rndmEngine )) newword += 1 << (26-9);
536 const unsigned int newword2 = newword;
537 const Amg::Vector2D locpos = trtDriftCircle->localPosition();
538 const std::vector<Identifier> &rdolist = trtDriftCircle->rdoList();
539 const InDetDD::TRT_BaseElement* detEl = trtDriftCircle->detectorElement();
540 InDet::TRT_DriftCircle* trtDriftCircle2 = new InDet::TRT_DriftCircle(
541 trtid,
542 locpos,
543 std::vector<Identifier>(rdolist),
544 Amg::MatrixX(trtDriftCircle->localCovariance()),
545 detEl,
546 newword2);
547 idHashMap.insert(
548 std::multimap<IdentifierHash, InDet::TRT_DriftCircle*>::value_type(
549 hash, trtDriftCircle2));
550 delete trtDriftCircle;
551 }
552 else{
553 idHashMap.insert( std::multimap<IdentifierHash, InDet::TRT_DriftCircle * >::value_type( hash, trtDriftCircle ) );
554 }
555
556 }
557
558 for ( HashMapItr itr = idHashMap.begin(); itr != idHashMap.end(); itr = idHashMap.upper_bound( itr->first ) ) {
559
560 std::pair< HashMapItr, HashMapItr > itrPair = idHashMap.equal_range( itr->first );
561
562 const InDetDD::TRT_BaseElement *trtBaseElement = ( itrPair.first )->second->detectorElement();
563 IdentifierHash hash = trtBaseElement->identifyHash();
564
565 InDet::TRT_DriftCircleCollection *trtDriftCircleCollection = new InDet::TRT_DriftCircleCollection( hash );
566 trtDriftCircleCollection->setIdentifier( trtBaseElement->identify() );
567
568 for ( HashMapItr itr2 = itrPair.first; itr2 != itrPair.second; ++itr2 ) {
569 InDet::TRT_DriftCircle *trtDriftCircle = itr2->second;
570 trtDriftCircle->setHashAndIndex( trtDriftCircleCollection->identifyHash(), trtDriftCircleCollection->size() );
571 trtDriftCircleCollection->push_back( trtDriftCircle );
572 }
573
574 if ( trtDriftCircleContainer->addCollection( trtDriftCircleCollection, hash ).isFailure() ) {
575 ATH_MSG_WARNING( "Could not add collection to Identifyable container" );
576 }
577 }
578
579 idHashMap.clear();
580 m_driftCircleMap.clear();
581
582 return StatusCode::SUCCESS;
583}
584
585
587{
588 HepGeom::Vector3D< double > vecEnter( hit->GetPreStepX(), hit->GetPreStepY(), hit->GetPreStepZ() );
589 HepGeom::Vector3D< double > vecExit( hit->GetPostStepX(), hit->GetPostStepY(), hit->GetPostStepZ() );
590
591 HepGeom::Vector3D< double > vecDir = vecExit - vecEnter;
592 static const HepGeom::Vector3D< double > vecStraw( 0., 0., 1. );
593
594 vecDir = vecDir.unit();
595
596 double driftRadius = 0.;
597 if ( std::abs( vecDir.x() ) < 1.0e-6 && std::abs( vecDir.y() ) < 1.0e-6 ) {
598 driftRadius = vecEnter.perp();
599 }
600 else {
601 double a = vecEnter.dot( vecStraw );
602 double b = vecEnter.dot( vecDir );
603 double c = vecDir.dot( vecStraw );
604
605 double paramStraw = ( a - b*c ) / ( 1. - c*c );
606 double paramTrack = -( b - a*c ) / ( 1. - c*c );
607
608 HepGeom::Vector3D<double> vecClosestAppr = vecEnter + paramTrack * vecDir - paramStraw * vecStraw;
609 driftRadius = vecClosestAppr.mag();
610 }
611
612 return driftRadius;
613}
614
615
616Identifier TRTFastDigitizationTool::getIdentifier( int hitID, IdentifierHash &hash, Identifier &layer_id, bool &status ) const
617{
618 status = true;
619
620 Identifier straw_id;
621
622 const int mask( 0x0000001F );
623 const int word_shift( 5 );
624
625 if ( hitID & 0x00200000 ) { // endcap
626 int strawID = hitID & mask;
627 int planeID = ( hitID >> word_shift ) & mask;
628 int sectorID = ( hitID >> 2 * word_shift ) & mask;
629 int wheelID = ( hitID >> 3 * word_shift ) & mask;
630 int trtID = ( hitID >> 4 * word_shift );
631
632 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
633 trtID = ( trtID == 3 ? 0 : 1 );
634
635 const InDetDD::TRT_EndcapElement *endcapElement = m_trt_manager->getEndcapElement( trtID, wheelID, planeID, sectorID );
636 if ( endcapElement ) {
637 hash = endcapElement->identifyHash();
638 layer_id = endcapElement->identify();
639 straw_id = m_trt_id->straw_id( layer_id, strawID );
640 }
641 else {
642 ATH_MSG_ERROR( "Could not find detector element for endcap identifier with (ipos,iwheel,isector,iplane,istraw) = ("
643 << trtID << ", " << wheelID << ", " << sectorID << ", " << planeID << ", " << strawID << ")" << endmsg
644 << "If this happens very rarely, don't be alarmed (it is a Geant4 'feature')" << endmsg
645 << "If it happens a lot, you probably have misconfigured geometry in the sim. job." );
646 status = false;
647 }
648
649 }
650 else { // barrel
651 int strawID = hitID & mask;
652 int layerID = ( hitID >> word_shift ) & mask;
653 int moduleID = ( hitID >> 2 * word_shift ) & mask;
654 int ringID = ( hitID >> 3 * word_shift ) & mask;
655 int trtID = ( hitID >> 4 * word_shift );
656
657 const InDetDD::TRT_BarrelElement *barrelElement = m_trt_manager->getBarrelElement( trtID, ringID, moduleID, layerID );
658 if ( barrelElement ) {
659 hash = barrelElement->identifyHash();
660 layer_id = barrelElement->identify();
661 straw_id = m_trt_id->straw_id( layer_id, strawID );
662 } else {
663 ATH_MSG_ERROR( "Could not find detector element for barrel identifier with (ipos,iring,imod,ilayer,istraw) = ("
664 << trtID << ", " << ringID << ", " << moduleID << ", " << layerID << ", " << strawID << ")" );
665 status = false;
666 }
667
668 }
669
670 return straw_id;
671}
672
673
675{
676 int hitID = hit->GetHitID();
677 const HepGeom::Point3D< double > hitPreStep( hit->GetPreStepX(), hit->GetPreStepY(), hit->GetPreStepZ() );
678
679 const int mask( 0x0000001F );
680 const int word_shift( 5 );
681
682 if ( hitID & 0x00200000 ) { // endcap
683 int strawID = hitID & mask;
684 int planeID = ( hitID >> word_shift ) & mask;
685 int sectorID = ( hitID >> 2 * word_shift ) & mask;
686 int wheelID = ( hitID >> 3 * word_shift ) & mask;
687 int trtID = ( hitID >> 4 * word_shift );
688
689 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
690 trtID = ( trtID == 3 ? 0 : 1 );
691
692 const InDetDD::TRT_EndcapElement *endcapElement = m_trt_manager->getEndcapElement( trtID, wheelID, planeID, sectorID );
693 if ( endcapElement ) {
694 return endcapElement->getAbsoluteTransform( strawID ) * hitPreStep;
695 }
696
697 }
698 else { // barrel
699 int strawID = hitID & mask;
700 int layerID = ( hitID >> word_shift ) & mask;
701 int moduleID = ( hitID >> 2 * word_shift ) & mask;
702 int ringID = ( hitID >> 3 * word_shift ) & mask;
703 int trtID = ( hitID >> 4 * word_shift );
704
705 const InDetDD::TRT_BarrelElement *barrelElement = m_trt_manager->getBarrelElement( trtID, ringID, moduleID, layerID );
706 if ( barrelElement ) {
707 return barrelElement->getAbsoluteTransform( strawID ) * hitPreStep;
708 }
709
710 }
711
712 ATH_MSG_WARNING( "Could not find global coordinate of a straw - drifttime calculation will be inaccurate" );
713 return { 0., 0., 0. };
714}
715
716
718{
719 // TRTCond::StrawStatus::Good == Xenon
720 // return ( m_trtStrawStatusSummarySvc->getStatusHT( straw_id ) != TRTCond::StrawStatus::Good ? true : false );
721 return ( gasType( straw_id ) == 1 );
722}
723
724
726{
727 // getStatusHT returns enum EStatus { Undefined, Dead, Good, Xenon, Argon, Krypton } // from 20.7.1
728 // see InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/StrawStatus.h
729 // TRT representation of gasType = Xenon: 0, Argon: 1, Krypton: 2
730
731 int status = m_trtStrawStatusSummaryTool->getStatusHT( straw_id, Gaudi::Hive::currentContext());
732
733 if ( status == 2 || status == 3 )
734 return 0;
735 else if ( status == 1 || status == 4 )
736 return 1;
737 else if ( status == 5 )
738 return 2;
739 else {
740 ATH_MSG_WARNING( "TRTFastDigitizationTool::gasType() getStatusHT = " << status << ", must be in [1..5] range" );
741 return -1;
742 }
743
744}
745
746
747double TRTFastDigitizationTool::getProbHT( int particleEncoding, float kineticEnergy, const Identifier &straw_id, double rTrkWire, double hitGlobalPosition ) const {
748
750
751 switch( abs( particleEncoding ) ) {
752
753 case 11:
754 hypothesis = Trk::electron;
755 break;
756
757 case 13:
758 hypothesis = Trk::muon;
759 break;
760
761 case 321:
762 hypothesis = Trk::kaon;
763 break;
764
765 case 211:
766 default:
767 hypothesis = Trk::pion;
768 break;
769
770 } // end of switch
771
772 float pTrk = sqrt( kineticEnergy * kineticEnergy + 2. * kineticEnergy * Trk::ParticleMasses::mass[ hypothesis ] );
773 if ( pTrk < 250. || pTrk > 7000000. ) return 0.;
774
775 int layerOrWheel = m_trt_id->layer_or_wheel( straw_id );
776 int strawLayer = m_trt_id->straw_layer( straw_id );
777
778 // trtPart = Barrel: 0, EndcapA: 1, EndcapB: 2
779 int trtPart = 0;
780 if ( abs( m_trt_id->barrel_ec( straw_id ) ) == 2 ) trtPart = ( ( layerOrWheel < 6 ) ? 1 : 2 );
781
782 // strawLayer = Barrel: 0-72, Endcap A-side: 0-95 (16 layers in 6 modules), EndcapB: 0-63 (8 layers in 8 modules)
783 if ( trtPart == 0 ) { // Barrel
784 if ( layerOrWheel ) strawLayer += 19 + ( layerOrWheel == 1 ? 0 : 24 );
785 }
786 else if ( trtPart == 1 ) { // EndcapA
787 strawLayer += 16 * layerOrWheel;
788 }
789 else { // EndcapB
790 strawLayer += 8 * ( layerOrWheel - 6 );
791 }
792
793 const int strawLayerMax[] = { 72, 95, 63 };
794 if ( strawLayer > strawLayerMax[ trtPart ] || strawLayer < 0 ) {
795 ATH_MSG_WARNING( "strawLayer was outside allowed range: trtPart = " << trtPart << ", strawLayer = " << strawLayer );
796 return 0.;
797 }
798
799 const double hitGlobalPositionMin[] = { 0., 630., 630. };
800 const double hitGlobalPositionMax[] = { 720., 1030., 1030. };
801
802 if ( std::abs(hitGlobalPosition) < hitGlobalPositionMin[ trtPart ] ) {
803 ATH_MSG_WARNING( "hitGlobalPosition was below allowed range (will be adjusted): trtPart = " << trtPart << ", hitGlobalPosition = " << hitGlobalPosition );
804 hitGlobalPosition = copysign(hitGlobalPositionMin[ trtPart ] + 0.001,hitGlobalPosition);
805 }
806 if ( std::abs(hitGlobalPosition) > hitGlobalPositionMax[ trtPart ] ) {
807 ATH_MSG_WARNING( "hitGlobalPosition was above allowed range (will be adjusted): trtPart = " << trtPart << ", hitGlobalPosition = " << hitGlobalPosition );
808 hitGlobalPosition = copysign(hitGlobalPositionMax[ trtPart ] - 0.001,hitGlobalPosition);
809 }
810
811 if ( rTrkWire > 2.2 ) rTrkWire = 2.175;
812
813 double Occupancy = 0.11+0.014*m_NCollPerEvent;
814
815 double probHT = m_trtElectronPidTool->probHTRun2( pTrk, hypothesis, trtPart, gasType( straw_id ), strawLayer, hitGlobalPosition, rTrkWire, Occupancy );
816 if ( probHT == 0.5 || probHT == 1. ) probHT = 0.;
817 if(hypothesis == Trk::electron) probHT *= 1.3;
818
819 return probHT;
820}
821
822
824{
825 constexpr std::array< double, 14 > bins = { 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 1.05, 1.4, 1.5, 1.6, 1.82 };
826 constexpr std::array< double, 15 > probability = { 0.210, // [ 0., 0.05 ]
827 0.218, // [ 0.05, 0.15 ]
828 0.226, // [ 0.15, 0.25 ]
829 0.234, // [ 0.25, 0.35 ]
830 0.242, // [ 0.35, 0.45 ]
831 0.250, // [ 0.45, 0.55 ]
832 0.258, // [ 0.55, 0.65 ]
833 0.266, // [ 0.65, 0.75 ]
834 0.274, // [ 0.75, 0.85 ]
835 0.280, // [ 0.85, 1.05 ]
836 0.265, // [ 1.05, 1.40 ]
837 0.275, // [ 1.40, 1.50 ]
838 0.295, // [ 1.50, 1.60 ]
839 0.330, // [ 1.60, 1.82 ]
840 0.365 // > 1.82
841 };
842
843 return probability[ std::distance( bins.begin(), std::lower_bound( bins.begin(), bins.end(), std::abs( eta ) ) ) ];
844}
845
846
848{
849 constexpr std::array< double, 14 > bins = { 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 1.05, 1.4, 1.5, 1.6, 1.82 };
850 constexpr std::array< double, 15 > probability = { 0.210, // [ 0., 0.05 ]
851 0.218, // [ 0.05, 0.15 ]
852 0.226, // [ 0.15, 0.25 ]
853 0.234, // [ 0.25, 0.35 ]
854 0.242, // [ 0.35, 0.45 ]
855 0.250*0.88, // [ 0.45, 0.55 ]
856 0.258*0.88, // [ 0.55, 0.65 ]
857 0.266*0.88, // [ 0.65, 0.75 ]
858 0.274*0.88, // [ 0.75, 0.85 ]
859 0.280*0.88, // [ 0.85, 1.05 ]
860 0.265*0.88, // [ 1.05, 1.40 ]
861 0.275*0.88, // [ 1.40, 1.50 ]
862 0.295*0.88, // [ 1.50, 1.60 ]
863 0.330*0.88, // [ 1.60, 1.82 ]
864 0.365 // > 1.82
865 };
866
867 return probability[ std::distance( bins.begin(), std::lower_bound( bins.begin(), bins.end(), std::abs( eta ) ) ) ];
868}
869
870
872{
873 constexpr std::array< double, 41 > bins = { -2.05, -1.95, -1.85, -1.75, -1.65, -1.55, -1.45, -1.35, -1.25, -1.15, -1.05, -0.95, -0.85,
874 -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65,
875 0.75, 0.85, 0.95, 1.05, 1.15, 1.25, 1.35, 1.45, 1.55, 1.65, 1.75, 1.85, 1.95
876 };
877
878 constexpr std::array< double, 42 > probability = { 0.04466501, // < -2.05
879 0.05624099, // [ -2.05, -1.95 ]
880 0.05715916, // [ -1.95, -1.85 ]
881 0.05758092, // [ -1.85, -1.75 ]
882 0.05713670, // [ -1.75, -1.65 ]
883 0.05320733, // [ -1.65, -1.55 ]
884 0.05447418, // [ -1.55, -1.45 ]
885 0.05460775, // [ -1.45, -1.35 ]
886 0.05443998, // [ -1.35, -1.25 ]
887 0.05671015, // [ -1.25, -1.15 ]
888 0.06043842, // [ -1.15, -1.05 ]
889 0.06098093, // [ -1.05, -0.95 ]
890 0.06124813, // [ -0.95, -0.85 ]
891 0.05757168, // [ -0.85, -0.75 ]
892 0.05230566, // [ -0.75, -0.65 ]
893 0.05136644, // [ -0.65, -0.55 ]
894 0.05021782, // [ -0.55, -0.45 ]
895 0.05046960, // [ -0.45, -0.35 ]
896 0.04935652, // [ -0.35, -0.25 ]
897 0.05074021, // [ -0.25, -0.15 ]
898 0.04959613, // [ -0.15, -0.05 ]
899 0.05090863, // [ -0.05, 0.05 ]
900 0.05185448, // [ 0.05, 0.15 ]
901 0.05083610, // [ 0.15, 0.25 ]
902 0.05113032, // [ 0.25, 0.35 ]
903 0.05158703, // [ 0.35, 0.45 ]
904 0.05255587, // [ 0.45, 0.55 ]
905 0.05343067, // [ 0.55, 0.65 ]
906 0.05695859, // [ 0.65, 0.75 ]
907 0.06233243, // [ 0.75, 0.85 ]
908 0.06418306, // [ 0.85, 0.95 ]
909 0.06027916, // [ 0.95, 1.05 ]
910 0.05693816, // [ 1.05, 1.15 ]
911 0.05514142, // [ 1.15, 1.25 ]
912 0.05557067, // [ 1.25, 1.35 ]
913 0.05436613, // [ 1.35, 1.45 ]
914 0.05360627, // [ 1.45, 1.55 ]
915 0.05266918, // [ 1.55, 1.65 ]
916 0.05237728, // [ 1.65, 1.75 ]
917 0.05439599, // [ 1.75, 1.85 ]
918 0.05630533, // [ 1.85, 1.95 ]
919 0.06067052 // > 1.95
920 };
921
922 return probability[ std::distance( bins.begin(), std::lower_bound( bins.begin(), bins.end(), eta ) ) ];
923}
924
925
927{
928 constexpr std::array< double, 41 > bins = { -2.05, -1.95, -1.85, -1.75, -1.65, -1.55, -1.45, -1.35, -1.25, -1.15, -1.05, -0.95, -0.85,
929 -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65,
930 0.75, 0.85, 0.95, 1.05, 1.15, 1.25, 1.35, 1.45, 1.55, 1.65, 1.75, 1.85, 1.95
931 };
932
933 constexpr std::array< double, 42 > probability = { 0.058, // < -2.05
934 0.06316120, // [ -2.05, -1.95 ]
935 0.06552401, // [ -1.95, -1.85 ]
936 0.06462226, // [ -1.85, -1.75 ]
937 0.06435722, // [ -1.75, -1.65 ]
938 0.06404993, // [ -1.65, -1.55 ]
939 0.06324595, // [ -1.55, -1.45 ]
940 0.06318947, // [ -1.45, -1.35 ]
941 0.06381197, // [ -1.35, -1.25 ]
942 0.06366957, // [ -1.25, -1.15 ]
943 0.06561866, // [ -1.15, -1.05 ]
944 0.07307306, // [ -1.05, -0.95 ]
945 0.07682944, // [ -0.95, -0.85 ]
946 0.07430728, // [ -0.85, -0.75 ]
947 0.06897150, // [ -0.75, -0.65 ]
948 0.06393667, // [ -0.65, -0.55 ]
949 0.06049334, // [ -0.55, -0.45 ]
950 0.05774767, // [ -0.45, -0.35 ]
951 0.05544898, // [ -0.35, -0.25 ]
952 0.05456561, // [ -0.25, -0.15 ]
953 0.05378204, // [ -0.15, -0.05 ]
954 0.05196537, // [ -0.05, 0.05 ]
955 0.05391259, // [ 0.05, 0.15 ]
956 0.05474811, // [ 0.15, 0.25 ]
957 0.05734638, // [ 0.25, 0.35 ]
958 0.05959219, // [ 0.35, 0.45 ]
959 0.06266565, // [ 0.45, 0.55 ]
960 0.06806432, // [ 0.55, 0.65 ]
961 0.07347304, // [ 0.65, 0.75 ]
962 0.07654586, // [ 0.75, 0.85 ]
963 0.07328693, // [ 0.85, 0.95 ]
964 0.06541597, // [ 0.95, 1.05 ]
965 0.06348016, // [ 1.05, 1.15 ]
966 0.06322222, // [ 1.15, 1.25 ]
967 0.06428555, // [ 1.25, 1.35 ]
968 0.06299531, // [ 1.35, 1.45 ]
969 0.06469499, // [ 1.45, 1.55 ]
970 0.06560785, // [ 1.55, 1.65 ]
971 0.06777871, // [ 1.65, 1.75 ]
972 0.06843851, // [ 1.75, 1.85 ]
973 0.06727150, // [ 1.85, 1.95 ]
974 0.05935051 // > 1.95
975 };
976
977 return probability[ std::distance( bins.begin(), std::lower_bound( bins.begin(), bins.end(), eta ) ) ];
978}
979
980
981// parametrization of TRT efficiency as function of 'track-to-wire' distance
982double TRTFastDigitizationTool::strawEfficiency( double driftRadius, int BEC )
983{
984 const double p[][ 5 ] = { { 0.478, 0.9386, 0.9325, 0.2509, 0.03232 }, // old parametrization
985 { 0.477001, 1.02865, 1.02910, 0.185082, 0. }, // Barrel
986 { 0.482528, 1.03601, 1.03693, 0.182581, 0. } // EndCap
987 };
988
989 const double &trtFitAmplitude = p[ BEC ][ 0 ];
990 const double &trtFitMu = p[ BEC ][ 1 ];
991 const double &trtFitR = p[ BEC ][ 2 ];
992 const double &trtFitSigma = p[ BEC ][ 3 ];
993 const double &trtFitConstant = p[ BEC ][ 4 ];
994
995 double efficiency = trtFitAmplitude * ( erf( ( trtFitMu + trtFitR - driftRadius ) / ( std::sqrt( 2 ) * trtFitSigma ) )
996 + erf( ( trtFitMu + trtFitR + driftRadius ) / ( std::sqrt( 2 ) * trtFitSigma ) )
997 - erf( ( trtFitMu - trtFitR - driftRadius ) / ( std::sqrt( 2 ) * trtFitSigma ) )
998 - erf( ( trtFitMu - trtFitR + driftRadius ) / ( std::sqrt( 2 ) * trtFitSigma ) )
999 )
1000 + trtFitConstant;
1001
1002 return efficiency;
1003
1004 /*
1005 static const std::vector< double > bins = { 0.05, 1.43, 1.48, 1.53, 1.58, 1.63, 1.68, 1.73, 1.78, 1.83, 1.88, 1.93, 1.99 };
1006 static const std::vector< double > efficiency = { 0.94, // [ 0., 0.05 ]
1007 0.96, // [ 0.05, 1.43 ]
1008 0.955, // [ 1.43, 1.48 ]
1009 0.95, // [ 1.48, 1.53 ]
1010 0.945, // [ 1.53, 1.58 ]
1011 0.94, // [ 1.58, 1.63 ]
1012 0.93, // [ 1.63, 1.68 ]
1013 0.92, // [ 1.68, 1.73 ]
1014 0.89, // [ 1.73, 1.78 ]
1015 0.86, // [ 1.78, 1.83 ]
1016 0.8, // [ 1.83, 1.88 ]
1017 0.74, // [ 1.88, 1.93 ]
1018 0.695, // [ 1.93, 1.99 ]
1019 0.65 // > 1.99
1020 };
1021
1022 return efficiency[ std::distance( bins.begin(), std::lower_bound( bins.begin(), bins.end(), driftRadius ) ) ];
1023 */
1024}
1025
1026
1028{
1029 const double par[][ 6 ] = { { 5.96038, 0.797671, 1.28832, -2.02763, -2.24630, 21.6857 }, // pion
1030 { 0.522755, 0.697029, -3.90787, 6.32952, 1.06347, 3.51847 } // electron
1031 };
1032
1033 int j = ( hypothesis == Trk::electron ? 1 : 0 );
1034 double x0 = momentum * 1.e-3;
1035 double x1 = 1. / ( x0 + par[ j ][ 0 ] );
1036 double x2 = log( x0 ) * x1;
1037 double value = par[ j ][ 1 ] + par[ j ][ 2 ] * x1 + par[ j ][ 3 ] * x1 * x1 + par[ j ][ 4 ] * x2 + par[ j ][ 5 ] * x1 * x2;
1038 return ( momentum > 1500. ? value : 1. );
1039}
1040
1041
1043{
1044 ATH_MSG_DEBUG( "TRTFastDigitizationTool::finalize()" );
1045
1046 return StatusCode::SUCCESS;
1047}
Scalar eta() const
pseudorapidity method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
static Double_t a
static Double_t sc
static const std::vector< std::string > bins
the preferred mechanism to access information from the different event stores in a pileup job.
static const unsigned int maskHT
a sample implementation of IPileUpTool to test the framework
AtlasHitsVector< TRTUncompressedHit > TRTUncompressedHitCollection
This is an Identifier helper class for the TRT subdetector.
constexpr int pow(int base, int exp) noexcept
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
size_type size() const
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 base class of TRT readout elements.
const HepGeom::Transform3D getAbsoluteTransform(int straw) const
This is an alias to strawTransform(int straw)
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.
unsigned int getWord() const
returns the TRT dataword
virtual const InDetDD::TRT_BaseElement * detectorElement() const override final
return the detector element corresponding to this PRD
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 std::string & name() const
Return the StoreGate ID for the referenced object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
bool isArgonStraw(const Identifier &straw_id) const
double getProbHT(int particleEncoding, float kineticEnergy, const Identifier &straw_id, double driftRadiusLoc, double hitGlobalPosition) const
static double HTProbabilityMuon_60(double eta)
static double getDriftRadiusFromXYZ(const TimedHitPtr< TRTUncompressedHit > &hit)
HepGeom::Point3D< double > getGlobalPosition(const TimedHitPtr< TRTUncompressedHit > &hit)
StatusCode produceDriftCircles(const EventContext &ctx, CLHEP::HepRandomEngine *rndmEngine, TimedHitCollection< TRTUncompressedHit > &thpctrt)
static double strawEfficiency(double driftRadius, int BEC=0)
TimedHitCollection< TRTUncompressedHit > * m_thpctrt
StatusCode mergeEvent(const EventContext &ctx)
called at the end of the subevts loop.
StatusCode prepareEvent(const EventContext &ctx, const unsigned int)
return false if not interested in certain xing times (in ns) implemented by default in PileUpToolBase...
SG::WriteHandleKey< InDet::TRT_DriftCircleContainer > m_trtDriftCircleContainerKey
std::multimap< Identifier, InDet::TRT_DriftCircle * > m_driftCircleMap
int gasType(const Identifier &straw_id) const
SG::WriteHandleKey< PRD_MultiTruthCollection > m_trtPrdTruthKey
PublicToolHandle< ITRT_DriftFunctionTool > m_trtDriftFunctionTool
static double correctionHT(double momentum, Trk::ParticleHypothesis hypothesis)
ToolHandle< ITRT_StrawStatusSummaryTool > m_trtStrawStatusSummaryTool
std::vector< TRTUncompressedHitCollection * > m_trtHitCollList
virtual StatusCode initialize()
Initialize.
SG::ReadHandleKey< xAOD::EventInfo > m_EventInfoKey
Identifier getIdentifier(int hitID, IdentifierHash &hash, Identifier &layer_id, bool &status) const
static double HTProbabilityMuon_5_20(double eta)
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
const InDetDD::TRT_DetectorManager * m_trt_manager
static double HTProbabilityElectron_high_pt(double eta)
StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents)
called for each active bunch-crossing to process current SubEvents bunchXing is in ns
static double HTProbabilityElectron_low_pt(double eta)
StatusCode createAndStoreRIOs(const EventContext &ctx, CLHEP::HepRandomEngine *rndmEngine)
PublicToolHandle< Trk::ITRT_ElectronPidTool > m_trtElectronPidTool
ServiceHandle< PileUpMergeSvc > m_mergeSvc
TRTFastDigitizationTool(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode processAllSubEvents(const EventContext &ctx)
alternative interface which uses the PileUpMergeSvc to obtain all the required SubEvents.
float GetPostStepY() const
const HepMcParticleLink & particleLink() const
float GetPostStepZ() const
float GetPreStepZ() const
int GetParticleEncoding() const
float GetPreStepY() const
float GetPreStepX() const
float GetPostStepX() const
float GetKineticEnergy() const
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)
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition TimedHitPtr.h:47
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
@ driftRadius
trt, straws
Definition ParamDefs.h:53
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
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