14 #include "CLHEP/Random/RandFlat.h"
15 #include "CLHEP/Random/RandGaussZiggurat.h"
16 #include "CLHEP/Random/RandPoisson.h"
17 #include "CLHEP/Random/RandomEngine.h"
38 ATH_MSG_FATAL(
"AnalogueNoiseOn/m_analogueNoiseOn should be true if NoiseOn/m_NoiseOn is true.");
39 return StatusCode::FAILURE;
59 constexpr
float fC = 6242.2;
80 <<
" is invalid. Abort this job!!!");
81 return StatusCode::FAILURE;
85 <<
" is invalid. Abort this job!!!");
86 return StatusCode::FAILURE;
92 <<
" requires timing information."
94 <<
" (Condensed) does not keep timing information. Abort this job!!!");
95 return StatusCode::FAILURE;
98 return StatusCode::SUCCESS;
105 return StatusCode::SUCCESS;
115 data.m_GainFactor.reserve(strips);
118 data.m_Analogue[0].reserve(strips);
119 data.m_Analogue[1].reserve(strips);
121 data.m_Analogue[0].reserve(strips);
122 data.m_Analogue[1].reserve(strips);
123 data.m_Analogue[2].reserve(strips);
126 return StatusCode::SUCCESS;
136 float A = 4.0f *
W *
W + 1.0f;
137 float x1 = (
A - std::sqrt(
A)) / (2.0
f *
A);
138 float sinfi = std::sqrt(
x1);
139 float cosfi = sqrt(1.0 -
x1);
144 float S1 = std::sqrt((
S + D) * 0.5
f);
145 float S2 = std::sqrt((
S - D) * 0.5
f);
159 switch (moduleType) {
178 ATH_MSG_ERROR(
"moduleType(eta): " << moduleType <<
" unknown, using barrel");
188 for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
191 unsigned int flagmask = diode.
flag() & 0xFE;
201 for (;
i < i_end;
i++) {
203 if (
data.m_Analogue[1][
i] <= 0.0) {
204 float g = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0,
S1);
205 float o = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0,
S2);
207 data.m_GainFactor[
i] = 1.0f + (cosfi *
g + sinfi * o);
209 float offset_val = (cosfi * o - sinfi *
g);
211 float noise_val = Noise *
mode;
215 data.m_Analogue[0][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
216 data.m_Analogue[1][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
218 data.m_Analogue[0][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
219 data.m_Analogue[1][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
220 data.m_Analogue[2][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
228 return StatusCode::SUCCESS;
241 std::vector<float> noiseByChipVect(6, 0.0);
248 if (gainByChipVect.empty() or noiseByChipVect.empty()) {
249 ATH_MSG_DEBUG(
"No calibration data in cond DB for module " << moduleId <<
" using JO values");
251 return StatusCode::FAILURE;
253 return StatusCode::SUCCESS;
258 float gainMeanValue =
meanValue(gainByChipVect);
259 if (gainMeanValue < 0.0) {
260 ATH_MSG_DEBUG(
"All chip gain values are 0 for module " << moduleId <<
" using JO values");
262 return StatusCode::FAILURE;
264 return StatusCode::SUCCESS;
268 std::vector<float>
gain(6, 0.0);
269 std::vector<float>
offset(6, 0.0);
270 std::vector<float>
S1(6, 0.0);
271 std::vector<float>
S2(6, 0.0);
272 std::vector<float> sinfi(6, 0.0);
273 std::vector<float> cosfi(6, 0.0);
275 float offsetRMS = 0.0;
277 for (
int i = 0;
i < 6; ++
i) {
279 if (gainByChipVect[
i] > 0.1) {
280 gain[
i] = gainByChipVect[
i] / gainMeanValue;
282 gainRMS = gainRMSByChipVect[
i] / gainMeanValue;
285 gain[
i] = 55.0f / gainMeanValue;
287 gainRMS = 1.3f / gainMeanValue;
291 float W =
m_OGcorr * gainRMS * offsetRMS / (gainRMS * gainRMS - offsetRMS * offsetRMS);
292 float A = 4.0f *
W *
W + 1.0f;
293 float x1 = (
A - std::sqrt(
A)) / (2.0
f *
A);
294 sinfi[
i] = std::sqrt(
x1);
295 cosfi[
i] = std::sqrt(1.0
f -
x1);
297 float S = gainRMS * gainRMS + offsetRMS * offsetRMS;
298 float D = (gainRMS * gainRMS - offsetRMS * offsetRMS) / (cosfi[
i] * cosfi[
i] - sinfi[
i] * sinfi[
i]);
299 S1[
i] = std::sqrt((
S + D) / 2.0
f);
300 S2[
i] = std::sqrt((
S - D) / 2.0
f);
307 for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
310 unsigned int flagmask = diode.
flag() & 0xFE;
321 for (;
i < i_end;
i++) {
323 if (
data.m_Analogue[1][
i] <= 0.0) {
326 float g = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0,
S1[chip]);
327 float o = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0,
S2[chip]);
329 data.m_GainFactor[
i] =
gain[chip] + (cosfi[chip] *
g + sinfi[chip] * o);
331 float offset_val =
offset[chip] + (cosfi[chip] * o - sinfi[chip] *
g);
333 float noise_val = noiseByChipVect[chip];
337 data.m_Analogue[0][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
338 data.m_Analogue[1][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
340 data.m_Analogue[0][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
341 data.m_Analogue[1][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
342 data.m_Analogue[2][
i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
350 return StatusCode::SUCCESS;
359 double occupancy = 0.0;
360 double NoiseOccupancy = 0.0;
362 int nNoisyStrips = 0;
368 if (noise_expanded_mode) {
385 switch (moduleType) {
409 ATH_MSG_ERROR(
"moduleType(eta): " << moduleType <<
" unknown, using barrel");
415 int nEmptyStrips = 0;
416 std::vector<int> emptyStrips;
417 emptyStrips.reserve(strip_max);
418 for (
int i = 0;
i < strip_max;
i++) {
419 if (
data.m_StripHitsOnWafer[
i] == 0) {
420 emptyStrips.push_back(
i);
425 if (nEmptyStrips != 0) {
428 occupancy = CLHEP::RandGaussZiggurat::shoot(rndmEngine, NoiseOccupancy, NoiseOccupancy * 0.1);
432 const float fC = 6242.2;
435 nNoisyStrips = CLHEP::RandPoisson::shoot(rndmEngine, strip_max * occupancy *
mode);
438 if (nEmptyStrips < nNoisyStrips) {
439 nNoisyStrips = nEmptyStrips;
443 for (
int i = 0;
i < nNoisyStrips;
i++) {
444 int index = CLHEP::RandFlat::shootInt(rndmEngine, nEmptyStrips -
i);
447 emptyStrips.erase(emptyStrips.begin()+
index);
449 ATH_MSG_ERROR(
index <<
"-th empty strip, strip " <<
strip <<
" should be empty but is not empty! Something is wrong!");
453 if (noise_expanded_mode) {
454 int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
456 if (noise_tbin == 0) {
460 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (1)");
464 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (2)");
470 return StatusCode::SUCCESS;
477 const int n_chips = 6;
478 const int chipStripmax = strip_max / n_chips;
479 std::vector<float> NOByChipVect(n_chips, 0.0);
480 std::vector<float> ENCByChipVect(n_chips, 0.0);
481 std::vector<int> nNoisyStrips(n_chips, 0);
487 if (noise_expanded_mode) {
496 if (NOByChipVect.empty()) {
497 ATH_MSG_DEBUG(
"No calibration data in cond DB for module " << moduleId <<
" using JO values");
498 if (StatusCode::SUCCESS !=
randomNoise(collection, moduleId, rndmEngine,
data,strip_max)) {
499 return StatusCode::FAILURE;
501 return StatusCode::SUCCESS;
504 for (
int i = 0;
i < n_chips;
i++) {
510 constexpr
float fC = 6242.2;
514 nNoisyStrips[
i] = CLHEP::RandPoisson::shoot(rndmEngine, chipStripmax * NOByChipVect[
i] *
mode);
519 for (
int chip_index = 0; chip_index < n_chips; ++chip_index) {
520 int chip_strip_offset = chipStripmax * chip_index;
523 int nEmptyStripsOnChip = 0;
524 std::vector<int> emptyStripsOnChip;
525 emptyStripsOnChip.reserve(chipStripmax);
526 for (
int i = 0;
i < chipStripmax;
i++) {
527 if (
data.m_StripHitsOnWafer[
i + chip_strip_offset] == 0) {
528 emptyStripsOnChip.push_back(
i);
529 ++nEmptyStripsOnChip;
534 if (nEmptyStripsOnChip != 0) {
536 if (nEmptyStripsOnChip < nNoisyStrips[chip_index]) {
537 nNoisyStrips[chip_index] = nEmptyStripsOnChip;
541 for (
int i = 0;
i < nNoisyStrips[chip_index];
i++) {
542 int index = CLHEP::RandFlat::shootInt(rndmEngine, nEmptyStripsOnChip -
i);
543 int strip_on_chip = emptyStripsOnChip.at(
index);
544 emptyStripsOnChip.erase(emptyStripsOnChip.begin()+
index);
545 int strip = strip_on_chip + chip_strip_offset;
547 ATH_MSG_ERROR(
index <<
"-th empty strip, strip " <<
strip <<
" should be empty but is not empty! Something is wrong!");
551 if (noise_expanded_mode) {
553 int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
555 if (noise_tbin == 0) {
559 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (3)");
563 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (4)");
570 return StatusCode::SUCCESS;
587 const int strip_max = p_design->
cells();
595 data.m_StripHitsOnWafer.assign(strip_max, 0);
599 for (
int i = 0;
i < strip_max; ++
i) {
600 data.m_Analogue[0][
i] = 0.0;
601 data.m_Analogue[1][
i] = 0.0;
604 for (
int i = 0;
i < strip_max; ++
i) {
605 data.m_Analogue[0][
i] = 0.0;
606 data.m_Analogue[1][
i] = 0.0;
607 data.m_Analogue[2][
i] = 0.0;
617 if (not collection.
empty()) {
644 if (StatusCode::SUCCESS !=
randomNoise(collection, moduleId,
side, rndmEngine,
data, strip_max)) {
648 if (StatusCode::SUCCESS !=
randomNoise(collection, moduleId, rndmEngine,
data,strip_max)) {
675 std::vector<float>
response(bin_max);
679 for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
682 unsigned int flagmask = diode.
flag() & 0xFE;
695 for (
short bin = 0;
bin < bin_max; ++
bin) {
700 for (
short bin = 0;
bin < bin_max; ++
bin) {
701 if (
strip + 1 < strip_max) {
711 for (
short bin = 0;
bin < bin_max; ++
bin) {
716 for (
short bin = 0;
bin < bin_max; ++
bin) {
717 if (
strip + 1 < strip_max) {
732 return StatusCode::SUCCESS;
743 for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
753 }
else if (((0x10 & diode.
flag()) == 0x10) or ((0x4 & diode.
flag()) == 0x4)) {
761 int have_hit_bin = 0;
771 if (((0x10 & diode.
flag()) == 0x10) || ((0x4 & diode.
flag()) == 0x4)) {
775 if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
783 if (have_hit_bin == 2 or have_hit_bin == 3) {
791 if (have_hit_bin == 0) {
807 return StatusCode::SUCCESS;
822 if (
data.m_StripHitsOnWafer[
strip] != 0) {
834 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (5)");
838 int have_hit_bin = 0;
849 if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
852 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (6)");
858 if (have_hit_bin == 2 or have_hit_bin == 3) {
861 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (7)");
867 if (have_hit_bin == 0) {
873 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (8)");
877 ATH_MSG_ERROR(
"Can't add noise hit diode to collection (9)");
886 return StatusCode::SUCCESS;
902 if (
data.m_StripHitsOnWafer[
strip] > 0) {
905 int clusterFirstStrip =
strip;
913 int lastStrip1DInRow = 0;
914 for (
int i = 0;
i <
row + 1; ++
i) {
918 while (
strip < lastStrip1DInRow-1 and
data.m_StripHitsOnWafer[
strip +1] > 0) {
921 int clusterLastStrip =
strip;
923 clusterSize = (clusterLastStrip - clusterFirstStrip) + 1;
924 hitStrip =
SiCellId(clusterFirstStrip);
929 for (
int i = clusterFirstStrip+1;
i <= clusterLastStrip; ++
i) {
934 PreviousHitDiode = &HitDiode2;
938 }
while (
strip < strip_max);
944 if (
data.m_StripHitsOnWafer[
strip] > 0) {
950 for (
int newStrip=
strip+1; newStrip<strip_max; newStrip++) {
951 if (not (
data.m_StripHitsOnWafer[newStrip]>0))
break;
957 previousHitDiode = &newHitDiode;
965 ", HitInfo(1=real, 2=crosstalk, 3=noise): " <<
969 strip += clusterSize;
970 }
while (
strip < strip_max);
980 return StatusCode::SUCCESS;
986 collection.
add(ndiode, noiseCharge);
990 if (NoiseDiode ==
nullptr) {
991 return StatusCode::FAILURE;
994 return StatusCode::SUCCESS;
998 float mean_value = 0.0;
1000 const unsigned int vec_size = calibDataVect.size();
1003 if (calibDataVect[
i] > 0.1) {
1004 mean_value += calibDataVect[
i];
1012 return mean_value / nData;