71 CLHEP::HepRandomEngine* elecNoiseRndmEngine,
72 CLHEP::HepRandomEngine* elecProcRndmEngine) {
99 std::vector<float> maxLTOverNoiseAmp;
100 m_pElectronicsNoise->getSamplesOfMaxLTOverNoiseAmp(maxLTOverNoiseAmp,10000,elecNoiseRndmEngine);
103 reverse( maxLTOverNoiseAmp.begin(), maxLTOverNoiseAmp.end() );
107 double relfluct =
m_settings->relativeLowThresholdFluctuation();
109 if ( relfluct > 0. ) {
110 std::vector<float> nl_given_LT2Amp;
111 float min_lt2amp, max_lt2amp;
113 nl_given_LT2Amp, min_lt2amp, max_lt2amp);
114 float new_min_lt2amp, new_max_lt2amp;
116 min_lt2amp, max_lt2amp,
118 new_min_lt2amp, new_max_lt2amp,
119 static_cast<unsigned int>(0.1*nl_given_LT2Amp.size()));
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.);
137 float noiselevel(0.), noiseamp(0.);
144 const bool isBarrel(!(hitid & 0x00200000));
147 float lt =
useLookupTable(noiselevel, maxLTOverNoiseAmp, 0., 1.) * noiseamp;
149 if (strawGasType==0) {
150 if ( isBarrel ) { ++nstrawsBa_Xe; sumBa_Xe += lt; }
151 else { ++nstrawsEC_Xe; sumEC_Xe += lt; }
153 else if (strawGasType==1) {
154 if ( isBarrel ) { ++nstrawsBa_Kr; sumBa_Kr += lt; }
155 else { ++nstrawsEC_Kr; sumEC_Kr += lt; }
157 else if (strawGasType==2) {
158 if ( isBarrel ) { ++nstrawsBa_Ar; sumBa_Ar += lt; }
159 else { ++nstrawsEC_Ar; sumEC_Ar += lt; }
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);
179 std::vector<float> actual_LTs, actual_noiseamps;
180 std::vector<int> strawTypes;
183 actual_LTs.reserve(nstraws);
184 actual_noiseamps.reserve(nstraws);
187 float actualLT, actualNA;
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.);
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; }
206 actualLT =
useLookupTable(noiselevel, maxLTOverNoiseAmp, 0., 1.)*actualNA;
208 if (strawGasType==0) {
209 sumNA_Xe += actualNA; sumNAsq_Xe += actualNA*actualNA;
210 sumLT_Xe += actualLT; sumLTsq_Xe += actualLT*actualLT;
212 else if (strawGasType==1) {
213 sumNA_Kr += actualNA; sumNAsq_Kr += actualNA*actualNA;
214 sumLT_Kr += actualLT; sumLTsq_Kr += actualLT*actualLT;
216 else if (strawGasType==2) {
217 sumNA_Ar += actualNA; sumNAsq_Ar += actualNA*actualNA;
218 sumLT_Ar += actualLT; sumLTsq_Ar += actualLT*actualLT;
224 actual_LTs.push_back(actualLT);
225 actual_noiseamps.push_back(actualNA);
226 strawTypes.push_back(strawGasType);
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;
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");
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");
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");
263 ProduceNoiseDigitPool( actual_LTs, actual_noiseamps, strawTypes, noiseRndmEngine, elecNoiseRndmEngine, elecProcRndmEngine );
358 const std::set<Identifier>& simhitsIdentifiers,
360 CLHEP::HepRandomEngine* noiseRndmEngine) {
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;
372 for (simhitsIdentifiersIter=simhitsIdentifiers_begin; simhitsIdentifiersIter!=simhitsIdentifiers_end; ++simhitsIdentifiersIter) {
374 TRTStrawNeighbourSvc->getStrawsFromChip(*simhitsIdentifiersIter,IdsFromChip);
375 CrossTalkIds.assign(IdsFromChip.begin(),IdsFromChip.end());
378 if (!(abs(
m_id_helper->barrel_ec(IdsFromChip[0]))==1)) {
continue; }
382 m_id_helper->layer_or_wheel(*simhitsIdentifiersIter),
385 if (otherEndID.
get_compact()) { CrossTalkIdsOtherEnd.push_back(otherEndID); }
387 for (
auto & CrossTalkId : CrossTalkIds) {
389 if ( simhitsIdentifiers.find(CrossTalkId) == simhitsIdentifiers_end ) {
391 const int ndigit(
m_digitPool[CLHEP::RandFlat::shootInt(noiseRndmEngine,
393 int barrel_endcap, isneg;
395 case -1: barrel_endcap = 0; isneg = 0;
break;
396 case 1: barrel_endcap = 0; isneg = 1;
break;
398 ATH_MSG_WARNING(
"TRTDigitization::TRTNoise - identifier problems - skipping detector element!!");
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));
407 int hitid = hitid_helper->
buildHitId( barrel_endcap, isneg, ringwheel, phisector,layer, straw);
409 digitVect.emplace_back(hitid,ndigit);
414 for (
auto & i : CrossTalkIdsOtherEnd) {
415 if ( simhitsIdentifiers.find(i) == simhitsIdentifiers_end ) {
420 int barrel_endcap, isneg;
422 case -1: barrel_endcap = 0; isneg = 0;
break;
423 case 1: barrel_endcap = 0; isneg = 1;
break;
425 ATH_MSG_WARNING(
"TRTDigitization::TRTNoise - identifier problems - skipping detector element!!");
429 const int ringwheel(
m_id_helper->layer_or_wheel(i));
435 int hitid = hitid_helper->
buildHitId( barrel_endcap, isneg, ringwheel, phisector,layer, straw);
437 digitVect.emplace_back(hitid,ndigit);
442 IdsFromChip.resize(0);
443 CrossTalkIdsOtherEnd.resize(0);
444 CrossTalkIds.resize(0);
489 std::vector<float>& x_given_y,
500 if ( y_given_x.front() < y_given_x.back() ) {
503 min_y = y_given_x.front();
504 max_y = y_given_x.back();
507 min_y = y_given_x.back();
508 max_y = y_given_x.front();
511 const unsigned int n(y_given_x.size());
512 if ( x_given_y.size() != n ) {
517 const float step_y((max_y-min_y)/(n-1));
518 const float step_x((max_x-min_x)/(n-1));
520 unsigned int searchindex = rising ? 0 : n-1;
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;
528 while ( y_given_x[searchindex] < yval ) { ++searchindex; };
529 x_given_y[i] = min_x + searchindex*step_x;
531 while ( y_given_x[searchindex]<yval ) { --searchindex; };
532 x_given_y[i] = min_x + searchindex*step_x;
535 x_given_y.back() = rising ? max_x : min_x;
543 float relativeLTFluct,
544 float & new_min_lt2na,
545 float & new_max_lt2na,
546 unsigned int number_new_bins )
551 std::vector<float> new_nl_given_lt2na(number_new_bins);
552 constexpr double reciprocalSqrt2Pi = M_2_SQRTPI * 0.5 * M_SQRT1_2;
553 new_min_lt2na = min_lt2na;
554 new_max_lt2na = relativeLTFluct < 0.4 ? max_lt2na/(1.0-2.0*relativeLTFluct) : 5*max_lt2na;
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;
560 if (sigma<0) { sigma *= -1.0; }
561 else { sigma = 1.0e-8; }
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;
568 const double du((upperintrange-lowerintrange)/100.0);
570 const double minusoneover2sigmasq(- 1.0 / (2.0*sigma*sigma));
572 for (
double u(lowerintrange); u < upperintrange; u += du) {
574 exp(minusoneover2sigmasq * (u-new_lt2naval) * (u-new_lt2naval));
576 sum *= du*reciprocalSqrt2Pi /sigma;
577 new_nl_given_lt2na[i] = sum;
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());