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