ATLAS Offline Software
Loading...
Searching...
No Matches
TRTNoise.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TRTNoise.h"
6
7#include "TRTDigCondBase.h"
8#include "TRTDigiHelper.h"
10#include "TRTElectronicsNoise.h"
11
12#include "TRTDigSettings.h"
13
14#include "GaudiKernel/ServiceHandle.h"
15#include "GaudiKernel/ToolHandle.h"
16
17#include "CLHEP/Random/RandFlat.h"
18
19#include "CLHEP/Units/SystemOfUnits.h"
20
21
22
25
26#include <algorithm>
27#include <exception>
28#include <utility>
29#include <cmath>
30#include <cstdlib> //Always include this when including cmath!
31
33 bool operator() (const TRTDigit& digit1, const TRTDigit& digit2) { return (digit1.GetStrawID()<digit2.GetStrawID());}
35
36//_____________________________________________________________________________
38 const InDetDD::TRT_DetectorManager* detmgr,
39 CLHEP::HepRandomEngine* noiseRndmEngine,
40 CLHEP::HepRandomEngine* elecNoiseRndmEngine,
41 CLHEP::HepRandomEngine* elecProcRndmEngine,
42 CLHEP::HepRandomEngine* elecNoiseResetRndmEngine,
43 TRTDigCondBase* digcond,
45 TRTElectronicsNoise * electronicsnoise,
46 const TRT_ID* trt_id,
47 int UseGasMix,
48 const ToolHandle<ITRT_StrawStatusSummaryTool> &sumTool
49 )
50: AthMessaging("TRTNoise"),
51 m_settings(digset),
52 m_detmgr(detmgr),
53 m_pDigConditions(digcond),
55 m_pElectronicsNoise(electronicsnoise),
56 m_id_helper(trt_id),
59 m_UseGasMix(UseGasMix),
60 m_sumTool(sumTool)
61{
62 InitThresholdsAndNoiseAmplitudes_and_ProduceNoiseDigitPool(noiseRndmEngine,elecNoiseRndmEngine,elecProcRndmEngine);
63 if ( m_settings->noiseInSimhits() ) m_pElectronicsNoise->reinitElectronicsNoise( 1000, elecNoiseResetRndmEngine );
64}
65
66//_____________________________________________________________________________
67TRTNoise::~TRTNoise() = default;
68
69//_____________________________________________________________________________
71 CLHEP::HepRandomEngine* elecNoiseRndmEngine,
72 CLHEP::HepRandomEngine* elecProcRndmEngine) {
73
75 //Strategy: //
76 // //
77 //First we create a lookup table so that we can, based on the //
78 //noiselevel_i (i=straw_id), calculate for each straw: (LT/NA)_i //
79 //(NA=Noise Amplitude). //
80 // //
81 //We also know for each straw their relative noise amplitude, r_i. //
82 // //
83 //C.f. the noise note, one finds that the lowthreshold and noise //
84 //amplitude for each straw is given by the formulas: //
85 // //
86 // LT_i = (LT/NA)_i * r_i * k and NA_i = r_i * k //
87 // //
88 // with k = <LT_i>/<(LT/NA)_i * r_i> //
89 // //
90 // So now we first figure out the value of k, and afterwards we go //
91 // through the straws and set LT_i and NA_i. //
93
94
96 // Step 1 - create lookup table for mapping: noiselevel -> LT/NA //
98 // According to Anatoli, the noise shaping function is not very different for Argon and Xenon(and Krypton).
99 std::vector<float> maxLTOverNoiseAmp;
100 m_pElectronicsNoise->getSamplesOfMaxLTOverNoiseAmp(maxLTOverNoiseAmp,10000,elecNoiseRndmEngine);
101
102 std::stable_sort( maxLTOverNoiseAmp.begin(), maxLTOverNoiseAmp.end() );
103 reverse( maxLTOverNoiseAmp.begin(), maxLTOverNoiseAmp.end() );
104
105 // If we have LT event-event fluctuations, we need to include that effect in the curve
106
107 double relfluct = m_settings->relativeLowThresholdFluctuation();
108
109 if ( relfluct > 0. ) {
110 std::vector<float> nl_given_LT2Amp;
111 float min_lt2amp, max_lt2amp;
112 makeInvertedLookupTable( maxLTOverNoiseAmp, 0., 1.,
113 nl_given_LT2Amp, min_lt2amp, max_lt2amp);
114 float new_min_lt2amp, new_max_lt2amp;
116 min_lt2amp, max_lt2amp,
117 relfluct,
118 new_min_lt2amp, new_max_lt2amp,
119 static_cast<unsigned int>(0.1*nl_given_LT2Amp.size()));
120 float min_nl,max_nl; //Sanity check could be that ~0 and ~1 are returned.
121 makeInvertedLookupTable( nl_given_LT2Amp,new_min_lt2amp, new_max_lt2amp, maxLTOverNoiseAmp,min_nl,max_nl);
122 }
123
125 // Step 2 - figure out constant, k = <LT_i> / <(LT/NA)_i * r_i> //
127
128 //Figure out <(LT/NA)_i * r_i>:
129
130 unsigned long nstrawsBa_Xe(0), nstrawsEC_Xe(0);
131 unsigned long nstrawsBa_Kr(0), nstrawsEC_Kr(0);
132 unsigned long nstrawsBa_Ar(0), nstrawsEC_Ar(0);
133 double sumBa_Xe(0.), sumEC_Xe(0.);
134 double sumBa_Kr(0.), sumEC_Kr(0.);
135 double sumBa_Ar(0.), sumEC_Ar(0.);
136 int hitid(0);
137 float noiselevel(0.), noiseamp(0.);
138
139 m_pDigConditions->resetGetNextStraw();
140
142 while ( m_pDigConditions->getNextStraw(hitid, noiselevel, noiseamp) ) {
143
144 const bool isBarrel(!(hitid & 0x00200000));
145 const int statusHT = m_sumTool->getStatusHT(getStrawIdentifier(hitid), Gaudi::Hive::currentContext());
146 const int strawGasType = TRTDigiHelper::StrawGasType(statusHT,m_UseGasMix, &msg());
147 float lt = useLookupTable(noiselevel, maxLTOverNoiseAmp, 0., 1.) * noiseamp;
148
149 if (strawGasType==0) {
150 if ( isBarrel ) { ++nstrawsBa_Xe; sumBa_Xe += lt; }
151 else { ++nstrawsEC_Xe; sumEC_Xe += lt; }
152 }
153 else if (strawGasType==1) {
154 if ( isBarrel ) { ++nstrawsBa_Kr; sumBa_Kr += lt; }
155 else { ++nstrawsEC_Kr; sumEC_Kr += lt; }
156 }
157 else if (strawGasType==2) {
158 if ( isBarrel ) { ++nstrawsBa_Ar; sumBa_Ar += lt; }
159 else { ++nstrawsEC_Ar; sumEC_Ar += lt; }
160 }
161
162 }; // end "Loop through all non-dead straws"
163
164 //This gives us k right away:
165 double kBa_Xe(0.), kEC_Xe(0.);
166 double kBa_Kr(0.), kEC_Kr(0.);
167 double kBa_Ar(0.), kEC_Ar(0.);
168 if (sumBa_Xe !=0.) kBa_Xe = m_settings->lowThresholdBar(0) * (nstrawsBa_Xe/sumBa_Xe);
169 if (sumBa_Kr !=0.) kBa_Kr = m_settings->lowThresholdBar(1) * (nstrawsBa_Kr/sumBa_Kr);
170 if (sumBa_Ar !=0.) kBa_Ar = m_settings->lowThresholdBar(2) * (nstrawsBa_Ar/sumBa_Ar);
171 if (sumEC_Xe !=0.) kEC_Xe = m_settings->lowThresholdEC(0) * (nstrawsEC_Xe/sumEC_Xe);
172 if (sumEC_Kr !=0.) kEC_Kr = m_settings->lowThresholdEC(1) * (nstrawsEC_Kr/sumEC_Kr);
173 if (sumEC_Ar !=0.) kEC_Ar = m_settings->lowThresholdEC(2) * (nstrawsEC_Ar/sumEC_Ar);
174
176 // Step 3 - Calculate and set actual LT_i and NA_i //
178
179 std::vector<float> actual_LTs, actual_noiseamps;
180 std::vector<int> strawTypes;
181 if ( m_settings->noiseInUnhitStraws() ) {
182 int nstraws = m_pDigConditions->totalNumberOfActiveStraws();
183 actual_LTs.reserve(nstraws);
184 actual_noiseamps.reserve(nstraws);
185 };
186
187 float actualLT, actualNA;
188
189 m_pDigConditions->resetGetNextStraw();
190
191 double sumLT_Ar(0.), sumLTsq_Ar(0.), sumNA_Ar(0.), sumNAsq_Ar(0.);
192 double sumLT_Xe(0.), sumLTsq_Xe(0.), sumNA_Xe(0.), sumNAsq_Xe(0.);
193 double sumLT_Kr(0.), sumLTsq_Kr(0.), sumNA_Kr(0.), sumNAsq_Kr(0.);
194
195 while ( m_pDigConditions->getNextStraw( hitid, noiselevel, noiseamp) ) {
196
197 const int statusHT = m_sumTool->getStatusHT(getStrawIdentifier(hitid), Gaudi::Hive::currentContext());
198 const int strawGasType = TRTDigiHelper::StrawGasType(statusHT,m_UseGasMix, &msg());
199
200 const bool isBarrel(!(hitid & 0x00200000));
201 if (strawGasType==0) { actualNA = noiseamp*( isBarrel ? kBa_Xe : kEC_Xe ); }
202 else if (strawGasType==1) { actualNA = noiseamp*( isBarrel ? kBa_Kr : kEC_Kr ); }
203 else if (strawGasType==2) { actualNA = noiseamp*( isBarrel ? kBa_Ar : kEC_Ar ); }
204 else { actualNA = 0.0; } // should never happen
205
206 actualLT = useLookupTable(noiselevel, maxLTOverNoiseAmp, 0., 1.)*actualNA;
207
208 if (strawGasType==0) {
209 sumNA_Xe += actualNA; sumNAsq_Xe += actualNA*actualNA;
210 sumLT_Xe += actualLT; sumLTsq_Xe += actualLT*actualLT;
211 }
212 else if (strawGasType==1) {
213 sumNA_Kr += actualNA; sumNAsq_Kr += actualNA*actualNA;
214 sumLT_Kr += actualLT; sumLTsq_Kr += actualLT*actualLT;
215 }
216 else if (strawGasType==2) {
217 sumNA_Ar += actualNA; sumNAsq_Ar += actualNA*actualNA;
218 sumLT_Ar += actualLT; sumLTsq_Ar += actualLT*actualLT;
219 }
220
221 m_pDigConditions->setRefinedStrawParameters( hitid, actualLT, actualNA );
222
223 if ( m_settings->noiseInUnhitStraws() ) {
224 actual_LTs.push_back(actualLT);
225 actual_noiseamps.push_back(actualNA);
226 strawTypes.push_back(strawGasType);
227 }
228
229 };
230
231
232 if (msgLvl(MSG::INFO)) {
233
234 unsigned long nstraws_Kr = nstrawsBa_Kr + nstrawsEC_Kr;
235 unsigned long nstraws_Xe = nstrawsBa_Xe + nstrawsEC_Xe;
236 unsigned long nstraws_Ar = nstrawsBa_Ar + nstrawsEC_Ar;
237
238 if (nstraws_Xe) {
239 ATH_MSG_INFO("Xe Average LT is " << sumLT_Xe/nstraws_Xe/CLHEP::eV << " eV, with an RMS of "
240 << sqrt((sumLTsq_Xe/nstraws_Xe)-(sumLT_Xe/nstraws_Xe)*(sumLT_Xe/nstraws_Xe))/CLHEP::eV << " eV");
241 ATH_MSG_INFO("Xe Average NA is " << sumNA_Xe/nstraws_Xe/CLHEP::eV << " eV, with an RMS of "
242 << sqrt((sumNAsq_Xe/nstraws_Xe)-(sumNA_Xe/nstraws_Xe)*(sumNA_Xe/nstraws_Xe))/CLHEP::eV << " eV");
243 }
244 if (nstraws_Kr) {
245 ATH_MSG_INFO("Kr Average LT is " << sumLT_Kr/nstraws_Kr/CLHEP::eV << " eV, with an RMS of "
246 << sqrt((sumLTsq_Kr/nstraws_Kr)-(sumLT_Kr/nstraws_Kr)*(sumLT_Kr/nstraws_Kr))/CLHEP::eV << " eV");
247 ATH_MSG_INFO("Kr Average NA is " << sumNA_Kr/nstraws_Kr/CLHEP::eV << " eV, with an RMS of "
248 << sqrt((sumNAsq_Kr/nstraws_Kr)-(sumNA_Kr/nstraws_Kr)*(sumNA_Kr/nstraws_Kr))/CLHEP::eV << " eV");
249 }
250 if (nstraws_Ar) {
251 ATH_MSG_INFO("Ar Average LT is " << sumLT_Ar/nstraws_Ar/CLHEP::eV << " eV, with an RMS of "
252 << sqrt((sumLTsq_Ar/nstraws_Ar)-(sumLT_Ar/nstraws_Ar)*(sumLT_Ar/nstraws_Ar))/CLHEP::eV << " eV");
253 ATH_MSG_INFO("Ar Average NA is " << sumNA_Ar/nstraws_Ar/CLHEP::eV << " eV, with an RMS of "
254 << sqrt((sumNAsq_Ar/nstraws_Ar)-(sumNA_Ar/nstraws_Ar)*(sumNA_Ar/nstraws_Ar))/CLHEP::eV << " eV");
255 }
256
257 }
258
260 // Step 4 - Produce pool of pure noise digits //
262 if ( m_settings->noiseInUnhitStraws() ) {
263 ProduceNoiseDigitPool( actual_LTs, actual_noiseamps, strawTypes, noiseRndmEngine, elecNoiseRndmEngine, elecProcRndmEngine );
264 }
265
266 }
267
268//_____________________________________________________________________________
269void TRTNoise::ProduceNoiseDigitPool( const std::vector<float>& lowthresholds,
270 const std::vector<float>& noiseamps,
271 const std::vector<int>& strawType,
272 CLHEP::HepRandomEngine* noiseRndmEngine,
273 CLHEP::HepRandomEngine* elecNoiseRndmEngine,
274 CLHEP::HepRandomEngine* elecProcRndmEngine) {
275
276 unsigned int nstraw = lowthresholds.size();
277 unsigned int istraw;
278
280
281 std::vector<TRTElectronicsProcessing::Deposit> deposits;
282 int dummyhitid(0);
283 TRTDigit digit;
284 unsigned int nokdigits(0);
285 unsigned int ntries(0);
286
287 while ( nokdigits < m_digitPoolLength ) {
288
289 // Once and a while, create new vectors of shaped electronics noise.
290 // These are used as inputs to TRTElectronicsProcessing::ProcessDeposits
291 // to create noise digits
292 if ( ntries%400==0 ) {
293 m_pElectronicsNoise->reinitElectronicsNoise(200, elecNoiseRndmEngine);
294 }
295 // Initialize stuff (is that necessary)?
296 digit = TRTDigit();
297 deposits.clear();
298
299 // Choose straw to simulate
300 istraw = CLHEP::RandFlat::shootInt(noiseRndmEngine, nstraw );
301
302 // Process deposits this straw. Since there are no deposits, only noise will contrinute
303 m_pElectronicsProcessing->ProcessDeposits( deposits,
304 dummyhitid,
305 digit,
306 lowthresholds.at(istraw),
307 noiseamps.at(istraw),
308 strawType.at(istraw),
309 elecProcRndmEngine,
310 elecNoiseRndmEngine
311 );
312
313 // If this process produced a digit, store in pool
314 if ( digit.GetDigit() ) {
315 m_digitPool[nokdigits++] = digit.GetDigit();
316 }
317 ntries++;
318 };
319
320 if (msgLvl(MSG::VERBOSE)) {
321 if(0==ntries) {
322 ATH_MSG_FATAL("ntries==0 this should not be possible!");
323 throw std::exception();
324 }
325 ATH_MSG_VERBOSE("Produced noise digit pool of size " << m_digitPool.size()
326 << " (efficiency was " << static_cast<double>(m_digitPool.size())/ntries << ")");
327 }
328
330
331}
332
333//_____________________________________________________________________________
334void TRTNoise::appendPureNoiseToProperDigits( std::vector<TRTDigit>& digitVect, const std::set<int>& sim_hitids,
335 CLHEP::HepRandomEngine* noiseRndmEngine )
336{
337
338 const std::set<int>::const_iterator sim_hitids_end(sim_hitids.end());
339
340 m_pDigConditions->resetGetNextNoisyStraw();
341 int hitid;
342 float noiselevel;
343
344 while (m_pDigConditions->getNextNoisyStraw(noiseRndmEngine,hitid,noiselevel) ) {
345 //returned noiselevel not used for anything right now (fixme?).
346 // If this strawID does not have a sim_hit, add a pure noise digit
347 if ( sim_hitids.find(hitid) == sim_hitids_end ) {
348 const int ndigit(m_digitPool[CLHEP::RandFlat::shootInt(noiseRndmEngine,m_digitPoolLength)]);
349 digitVect.emplace_back(hitid,ndigit);
350 }
351 };
352
353 digitVect.pop_back(); }
354
355//_____________________________________________________________________________
356
357void TRTNoise::appendCrossTalkNoiseToProperDigits(std::vector<TRTDigit>& digitVect,
358 const std::set<Identifier>& simhitsIdentifiers,
359 const ServiceHandle<ITRT_StrawNeighbourSvc>& TRTStrawNeighbourSvc,
360 CLHEP::HepRandomEngine* noiseRndmEngine) {
361
362 //id helper:
363 const TRTHitIdHelper* hitid_helper = TRTHitIdHelper::GetHelper();
364
365 std::vector<Identifier> IdsFromChip;
366 std::vector<Identifier> CrossTalkIds;
367 std::vector<Identifier> CrossTalkIdsOtherEnd;
368 std::set<Identifier>::const_iterator simhitsIdentifiers_end = simhitsIdentifiers.end();
369 std::set<Identifier>::const_iterator simhitsIdentifiers_begin = simhitsIdentifiers.begin();
370 std::set<Identifier>::iterator simhitsIdentifiersIter;
371
372 for (simhitsIdentifiersIter=simhitsIdentifiers_begin; simhitsIdentifiersIter!=simhitsIdentifiers_end; ++simhitsIdentifiersIter) {
373
374 TRTStrawNeighbourSvc->getStrawsFromChip(*simhitsIdentifiersIter,IdsFromChip);
375 CrossTalkIds.assign(IdsFromChip.begin(),IdsFromChip.end());
376
377 //for barrel only - treated exactly equally as id's on the right end
378 if (!(abs(m_id_helper->barrel_ec(IdsFromChip[0]))==1)) { continue; }
379
380 Identifier otherEndID = m_id_helper->straw_id((-1)*m_id_helper->barrel_ec(*simhitsIdentifiersIter),
381 m_id_helper->phi_module(*simhitsIdentifiersIter),
382 m_id_helper->layer_or_wheel(*simhitsIdentifiersIter),
383 m_id_helper->straw_layer(*simhitsIdentifiersIter),
384 m_id_helper->straw(*simhitsIdentifiersIter));
385 if (otherEndID.get_compact()) { CrossTalkIdsOtherEnd.push_back(otherEndID); }
386
387 for (auto & CrossTalkId : CrossTalkIds) {
388
389 if ( simhitsIdentifiers.find(CrossTalkId) == simhitsIdentifiers_end ) {
390 if (m_pDigConditions->crossTalkNoise(noiseRndmEngine)==1 ) {
391 const int ndigit(m_digitPool[CLHEP::RandFlat::shootInt(noiseRndmEngine,
393 int barrel_endcap, isneg;
394 switch ( m_id_helper->barrel_ec(CrossTalkId) ) {
395 case -1: barrel_endcap = 0; isneg = 0; break;
396 case 1: barrel_endcap = 0; isneg = 1; break;
397 default:
398 ATH_MSG_WARNING("TRTDigitization::TRTNoise - identifier problems - skipping detector element!!");
399 continue;
400 }
401 const int ringwheel(m_id_helper->layer_or_wheel(CrossTalkId));
402 const int phisector(m_id_helper->phi_module(CrossTalkId));
403 const int layer (m_id_helper->straw_layer(CrossTalkId));
404 const int straw (m_id_helper->straw(CrossTalkId));
405
406 //built hit id
407 int hitid = hitid_helper->buildHitId( barrel_endcap, isneg, ringwheel, phisector,layer, straw);
408 //add to digit vector
409 digitVect.emplace_back(hitid,ndigit);
410 }
411 }
412 }
413
414 for (auto & i : CrossTalkIdsOtherEnd) {
415 if ( simhitsIdentifiers.find(i) == simhitsIdentifiers_end ) {
416 if (m_pDigConditions->crossTalkNoiseOtherEnd(noiseRndmEngine)==1 ) {
417
418 const int ndigit(m_digitPool[CLHEP::RandFlat::shootInt(noiseRndmEngine,m_digitPoolLength)]);
419
420 int barrel_endcap, isneg;
421 switch ( m_id_helper->barrel_ec(i) ) {
422 case -1: barrel_endcap = 0; isneg = 0; break;
423 case 1: barrel_endcap = 0; isneg = 1; break;
424 default:
425 ATH_MSG_WARNING("TRTDigitization::TRTNoise - identifier problems - skipping detector element!!");
426 continue;
427 }
428
429 const int ringwheel(m_id_helper->layer_or_wheel(i));
430 const int phisector(m_id_helper->phi_module(i));
431 const int layer (m_id_helper->straw_layer(i));
432 const int straw (m_id_helper->straw(i));
433
434 //built hit id
435 int hitid = hitid_helper->buildHitId( barrel_endcap, isneg, ringwheel, phisector,layer, straw);
436 //add to digit vector
437 digitVect.emplace_back(hitid,ndigit);
438 }
439 }
440 }
441
442 IdsFromChip.resize(0);
443 CrossTalkIdsOtherEnd.resize(0);
444 CrossTalkIds.resize(0);
445 }
446}
447
448void TRTNoise::sortDigits(std::vector<TRTDigit>& digitVect)
449{
450 std::stable_sort(digitVect.begin(), digitVect.end(), TRTDigitSorterObject);
451}
452
453//_____________________________________________________________________________
454float TRTNoise::useLookupTable(float x, // noise_level
455 const std::vector<float>& y_given_x,
456 float min_x,
457 float max_x ) {
458
459 double bin_withfrac;
460 unsigned int lower_index;
461 double fraction_into_bin;
462
463 // Assumes that y_given_x is homogeneous (and not entirely flat)
464
465 // Low x-value, return first y-value
466 if ( x < min_x ) {
467 return y_given_x.front();
468 }
469
470 // Which bin?
471 bin_withfrac = (x-min_x)*(y_given_x.size()-1)/(max_x-min_x);
472 lower_index = static_cast<unsigned int>(bin_withfrac);
473
474 // High x-value, return last y-value
475 if ( lower_index >= y_given_x.size()-1 ) {
476 return y_given_x.back();
477 }
478
479 // Normal case: return weighted sum of two neighbouring bin values
480 fraction_into_bin = bin_withfrac - lower_index;
481 return (1.-fraction_into_bin) * y_given_x[lower_index] + fraction_into_bin * y_given_x[lower_index+1];
482
483}
484
485//_____________________________________________________________________________
486void TRTNoise::makeInvertedLookupTable( const std::vector<float>& y_given_x,
487 float min_x,
488 float max_x,
489 std::vector<float>& x_given_y,
490 float & min_y,
491 float & max_y ) {
492
493 //Only works well when y_given_x.size() is large.
494 //
495 //Also assumes that y_given_x is homogeneous.
496
497 //Figure out if rising or falling, and y limits:
498 bool rising;
499
500 if ( y_given_x.front() < y_given_x.back() ) {
501 //NB: All use-cases have so far been on rising=false lookuptables
502 rising = true;
503 min_y = y_given_x.front();
504 max_y = y_given_x.back();
505 } else {
506 rising = false;
507 min_y = y_given_x.back();
508 max_y = y_given_x.front();
509 };
510
511 const unsigned int n(y_given_x.size());
512 if ( x_given_y.size() != n ) {
513 x_given_y.resize(n);
514 }
515
516 //Fill new array:
517 const float step_y((max_y-min_y)/(n-1));
518 const float step_x((max_x-min_x)/(n-1));
519
520 unsigned int searchindex = rising ? 0 : n-1;
521 float yval;
522 x_given_y.front() = rising ? min_x : max_x;
523 for (unsigned int i = 1; i < n-1; ++i) {
524 yval = min_y + i*step_y;
525 if (rising) {
526 // increase index in old array until we come to the index
527 // with a appropriate yval
528 while ( y_given_x[searchindex] < yval ) { ++searchindex; };
529 x_given_y[i] = min_x + searchindex*step_x;
530 } else {
531 while ( y_given_x[searchindex]<yval ) { --searchindex; };
532 x_given_y[i] = min_x + searchindex*step_x;
533 }
534 };
535 x_given_y.back() = rising ? max_x : min_x;
536
537}
538
539//_____________________________________________________________________________
540void TRTNoise::evolve_LT2AmpVsNL_to_include_LTfluct( std::vector<float>& nl_given_lt2na,
541 float min_lt2na,
542 float max_lt2na,
543 float relativeLTFluct,
544 float & new_min_lt2na,
545 float & new_max_lt2na,
546 unsigned int number_new_bins )
547{
548 //RelativeLTfluct should be less than 0.2.
549
550 // unsigned int n = nl_given_lt2na.size();
551 std::vector<float> new_nl_given_lt2na(number_new_bins);
552 constexpr double reciprocalSqrt2Pi = M_2_SQRTPI * 0.5 * M_SQRT1_2;//cmath definitions
553 new_min_lt2na = min_lt2na;
554 new_max_lt2na = relativeLTFluct < 0.4 ? max_lt2na/(1.0-2.0*relativeLTFluct) : 5*max_lt2na;
555
556 for (unsigned int i = 0; i<number_new_bins;++i) {
557 const float new_lt2naval(new_min_lt2na + (new_max_lt2na-new_min_lt2na)*static_cast<float>(i)/(number_new_bins-1));
558 float sigma = new_lt2naval*relativeLTFluct;
559 if ( sigma <= 0 ) {
560 if (sigma<0) { sigma *= -1.0; }
561 else { sigma = 1.0e-8; }
562 }
563 const float lowerintrange(new_lt2naval - 5.0*sigma);
564 float upperintrange(new_lt2naval + 5.0*sigma);
565 if (upperintrange>max_lt2na) {
566 upperintrange = max_lt2na; //Since the NL is zero above anyway
567 }
568 const double du((upperintrange-lowerintrange)/100.0);
569 double sum(0.);
570 const double minusoneover2sigmasq(- 1.0 / (2.0*sigma*sigma));
571
572 for (double u(lowerintrange); u < upperintrange; u += du) {
573 sum += useLookupTable(u,nl_given_lt2na,min_lt2na,max_lt2na) *
574 exp(minusoneover2sigmasq * (u-new_lt2naval) * (u-new_lt2naval));
575 }
576 sum *= du*reciprocalSqrt2Pi /sigma;
577 new_nl_given_lt2na[i] = sum;
578 };
579
580 nl_given_lt2na.resize(number_new_bins);
581 copy(new_nl_given_lt2na.begin(),
582 new_nl_given_lt2na.end(),
583 nl_given_lt2na.begin());
584}
585
587{
588 Identifier IdStraw;
589 Identifier IdLayer;
590
591 const int mask(0x0000001F);
592 const int word_shift(5);
593 int trtID, ringID, moduleID, layerID, strawID;
594 int wheelID, planeID, sectorID;
595
596 const InDetDD::TRT_BarrelElement *barrelElement;
597 const InDetDD::TRT_EndcapElement *endcapElement;
598
599 if ( !(hitID & 0x00200000) ) { // barrel
600 strawID = hitID & mask;
601 hitID >>= word_shift;
602 layerID = hitID & mask;
603 hitID >>= word_shift;
604 moduleID = hitID & mask;
605 hitID >>= word_shift;
606 ringID = hitID & mask;
607 trtID = hitID >> word_shift;
608
609 barrelElement = m_detmgr->getBarrelElement(trtID, ringID, moduleID, layerID);
610 if ( barrelElement ) {
611 IdLayer = barrelElement->identify();
612 IdStraw = m_id_helper->straw_id(IdLayer, strawID);
613 } else {
614 ATH_MSG_ERROR("Could not find detector element for barrel identifier with "
615 << "(ipos,iring,imod,ilayer,istraw) = ("
616 << trtID << ", " << ringID << ", " << moduleID << ", "
617 << layerID << ", " << strawID << ")");
618 }
619 } else { // endcap
620 strawID = hitID & mask;
621 hitID >>= word_shift;
622 planeID = hitID & mask;
623 hitID >>= word_shift;
624 sectorID = hitID & mask;
625 hitID >>= word_shift;
626 wheelID = hitID & mask;
627 trtID = hitID >> word_shift;
628
629 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
630 if (trtID == 3) { trtID = 0; }
631 else { trtID = 1; }
632
633 endcapElement = m_detmgr->getEndcapElement(trtID, wheelID, planeID, sectorID);
634
635 if ( endcapElement ) {
636 IdLayer = endcapElement->identify();
637 IdStraw = m_id_helper->straw_id(IdLayer, strawID);
638 } else {
639 ATH_MSG_ERROR("Could not find detector element for endcap identifier with "
640 << "(ipos,iwheel,isector,iplane,istraw) = ("
641 << trtID << ", " << wheelID << ", " << sectorID << ", "
642 << planeID << ", " << strawID << ")");
643 ATH_MSG_ERROR("If this happens very rarely, don't be alarmed "
644 "(it is a Geant4 'feature')");
645 ATH_MSG_ERROR("If it happens a lot, you probably have misconfigured geometry "
646 "in the sim. job.");
647 }
648
649 }
650
651 return IdStraw;
652}
#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)
struct TRTDigitSorter TRTDigitSorterObject
#define x
MsgStream & msg() const
The standard message stream.
bool msgLvl(const MSG::Level lvl) const
Test the output level.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
value_type get_compact() const
Get the compact id.
Extended TRT_BaseElement to describe a TRT readout element, this is a planar layer with n ( order of ...
virtual Identifier identify() const override final
identifier of this detector element:
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Extended class of a TRT_BaseElement to describe a readout elment in the endcap.
Communication with CondDB.
Class containing parameters and settings used by TRT digitization.
Class for TRT digits.
Definition TRTDigit.h:11
int GetStrawID() const
Get straw ID.
Definition TRTDigit.h:24
Simulate TRT Electronics Noise For description of metod, see Thomas Kittelmanns PhD thesis chapters ...
static const TRTHitIdHelper * GetHelper()
int buildHitId(const int, const int, const int, const int, const int, const int) const
const TRT_ID * m_id_helper
Definition TRTNoise.h:139
unsigned int m_digitPoolLength
Length of noise digit pool m_digitPool.
Definition TRTNoise.h:141
std::vector< unsigned int > m_digitPool
Pool of noise digits for noise in unhit straws.
Definition TRTNoise.h:145
ToolHandle< ITRT_StrawStatusSummaryTool > m_sumTool
Definition TRTNoise.h:210
void InitThresholdsAndNoiseAmplitudes_and_ProduceNoiseDigitPool(CLHEP::HepRandomEngine *noiseRndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, CLHEP::HepRandomEngine *elecProcRndmEngine)
Initialize thresholds and noise amplitudes.
Definition TRTNoise.cxx:70
TRTElectronicsProcessing * m_pElectronicsProcessing
Definition TRTNoise.h:89
void ProduceNoiseDigitPool(const std::vector< float > &lowthresholds, const std::vector< float > &noiseamps, const std::vector< int > &strawType, CLHEP::HepRandomEngine *noiseRndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, CLHEP::HepRandomEngine *elecProcRndmEngine)
Produce pool of pure noise digits (for simulation of noise in unhit straws) and store them in m_digit...
Definition TRTNoise.cxx:269
void appendCrossTalkNoiseToProperDigits(std::vector< TRTDigit > &digitVect, const std::set< Identifier > &simhitsIdentifiers, const ServiceHandle< ITRT_StrawNeighbourSvc > &m_TRTStrawNeighbourSvc, CLHEP::HepRandomEngine *noiseRndmEngine)
Definition TRTNoise.cxx:357
const InDetDD::TRT_DetectorManager * m_detmgr
Definition TRTNoise.h:86
static void evolve_LT2AmpVsNL_to_include_LTfluct(std::vector< float > &nl_given_lt2na, float min_lt2na, float max_lt2na, float relativeLTFluct, float &new_min_lt2na, float &new_max_lt2na, unsigned int number_new_bins)
Refined noise treatment by allowing for event-by-event fluctuations in the low threshold settings.
Definition TRTNoise.cxx:540
TRTElectronicsNoise * m_pElectronicsNoise
Definition TRTNoise.h:90
int m_UseGasMix
Definition TRTNoise.h:209
const TRTDigSettings * m_settings
Definition TRTNoise.h:85
static float useLookupTable(float x, const std::vector< float > &y_given_x, float min_x, float max_x)
Return y value corresponding to input x value from LUT.
Definition TRTNoise.cxx:454
unsigned int m_digitPoolLength_nextaccessindex
Pointer into noise digit pool m_digitPool.
Definition TRTNoise.h:143
static void sortDigits(std::vector< TRTDigit > &digitVect)
Definition TRTNoise.cxx:448
TRTDigCondBase * m_pDigConditions
Definition TRTNoise.h:88
void appendPureNoiseToProperDigits(std::vector< TRTDigit > &digitVect, const std::set< int > &sim_hitids, CLHEP::HepRandomEngine *noiseRndmEngine)
Append noise digits to list of digits from proper hits.
Definition TRTNoise.cxx:334
static void makeInvertedLookupTable(const std::vector< float > &y_given_x, float min_x, float max_x, std::vector< float > &x_given_y, float &min_y, float &max_y)
Invert look-up-table: Go from tabulated y values vs.
Definition TRTNoise.cxx:486
TRTNoise(const TRTDigSettings *, const InDetDD::TRT_DetectorManager *, CLHEP::HepRandomEngine *noiseRndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, CLHEP::HepRandomEngine *elecProcRndmEngine, CLHEP::HepRandomEngine *elecNoiseResetRndmEngine, TRTDigCondBase *digcond, TRTElectronicsProcessing *ep, TRTElectronicsNoise *electronicsnoise, const TRT_ID *trt_id, int UseGasMix, const ToolHandle< ITRT_StrawStatusSummaryTool > &sumTool)
Constructor.
Definition TRTNoise.cxx:37
Identifier getStrawIdentifier(int hitID)
Definition TRTNoise.cxx:586
This is an Identifier helper class for the TRT subdetector.
Definition TRT_ID.h:84
int StrawGasType(int statusHT, int useGasMix, MsgStream *log)
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
bool operator()(const TRTDigit &digit1, const TRTDigit &digit2)
Definition TRTNoise.cxx:33