ATLAS Offline Software
SCT_FrontEnd.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 "SCT_FrontEnd.h"
6 
12 
13 // Random number
14 #include "CLHEP/Random/RandFlat.h"
15 #include "CLHEP/Random/RandGaussZiggurat.h" // for RandGaussZiggurat
16 #include "CLHEP/Random/RandPoisson.h"
17 #include "CLHEP/Random/RandomEngine.h"
18 
19 // C++ Standard Library
20 #include <algorithm>
21 #include <cmath>
22 #include <iostream>
23 
24 // #define SCT_DIG_DEBUG
25 
26 using namespace InDetDD;
27 
28 // constructor
29 SCT_FrontEnd::SCT_FrontEnd(const std::string& type, const std::string& name, const IInterface* parent)
30  : base_class(type, name, parent) {
31 }
32 
33 // ----------------------------------------------------------------------
34 // Initialize
35 // ----------------------------------------------------------------------
37  if (m_NoiseOn and (not m_analogueNoiseOn)) {
38  ATH_MSG_FATAL("AnalogueNoiseOn/m_analogueNoiseOn should be true if NoiseOn/m_NoiseOn is true.");
39  return StatusCode::FAILURE;
40  }
41 
42  ATH_MSG_DEBUG("SCT_FrontEnd::initialize()");
43  // Get SCT helper
44  ATH_CHECK(detStore()->retrieve(m_sct_id, "SCT_ID"));
45  // Get SCT detector manager
47  // Get the amplifier tool
48  ATH_CHECK(m_sct_amplifier.retrieve());
49  ATH_MSG_DEBUG("SCT Amplifier tool located ");
50 
51  // Get the SCT_ReadCaliDataSvc
52  if (m_useCalibData) {
54  ATH_MSG_DEBUG("CalibChipData Service located ");
55  } else {
56  m_ReadCalibChipDataTool.disable();
57  }
58 
59  constexpr float fC = 6242.2;
60  m_Threshold = m_Threshold * fC;
61 
62 #ifdef SCT_DIG_DEBUG
63  ATH_MSG_INFO("\tNoise factors:");
64  ATH_MSG_INFO("\tBarrel = " << m_NoiseBarrel << " Outer Barrel = " << m_NoiseBarrel3 <<
65  " EC, inners = " << m_NoiseInners << " EC, middles = " << m_NoiseMiddles <<
66  " EC, short middles = " << m_NoiseShortMiddles << " EC, outers = " << m_NoiseOuters);
67  ATH_MSG_INFO("\tThreshold=" << m_Threshold << " fC, time of Threshold=" << m_timeOfThreshold);
68 #endif
69 
70  ATH_MSG_INFO("m_Threshold (Threshold) = " << m_Threshold);
71  ATH_MSG_INFO("m_timeOfThreshold (TimeOfThreshold) = " << m_timeOfThreshold);
72  ATH_MSG_INFO("m_data_compression_mode (DataCompressionMode) = " << m_data_compression_mode);
73  ATH_MSG_INFO("m_data_readout_mode (DataReadOutMode) = " << m_data_readout_mode);
74 
75  // Check configuration. If it is invalid, abort this job.
79  ATH_MSG_FATAL("m_data_compression_mode = " << m_data_compression_mode
80  << " is invalid. Abort this job!!!");
81  return StatusCode::FAILURE;
82  }
84  ATH_MSG_FATAL("m_data_readout_mode = " << m_data_readout_mode
85  << " is invalid. Abort this job!!!");
86  return StatusCode::FAILURE;
87  }
90  ATH_MSG_FATAL("m_data_compression_mode = " << m_data_compression_mode
91  << (m_data_compression_mode==Level_X1X ? " (Level_X1X)" : " (AnyHit_1XX_X1X_XX1)")
92  << " requires timing information."
93  << " However, m_data_readout_mode = " << m_data_readout_mode
94  << " (Condensed) does not keep timing information. Abort this job!!!");
95  return StatusCode::FAILURE;
96  }
97 
98  return StatusCode::SUCCESS;
99 }
100 
102 #ifdef SCT_DIG_DEBUG
103  ATH_MSG_INFO("SCT_FrontEnd::finalize()");
104 #endif
105  return StatusCode::SUCCESS;
106 }
107 
108 // ----------------------------------------------------------------------
109 // Init the class variable vectors
110 // ----------------------------------------------------------------------
112  //previously, these were all zero'd as well here
113  //however, this takes up a lot of CPU (especially for ITk)
114  //and doesn't seem necessary
115  data.m_GainFactor.reserve(strips);
116 
118  data.m_Analogue[0].reserve(strips);
119  data.m_Analogue[1].reserve(strips);
120  } else { // Expanded
121  data.m_Analogue[0].reserve(strips);
122  data.m_Analogue[1].reserve(strips);
123  data.m_Analogue[2].reserve(strips);
124  }
125 
126  return StatusCode::SUCCESS;
127 }
128 
129 // ----------------------------------------------------------------------
130 // prepare gain and offset for the strips for a given module
131 // ----------------------------------------------------------------------
132 StatusCode SCT_FrontEnd::prepareGainAndOffset(SiChargedDiodeCollection& collection, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
133  // now we need to generate gain and offset channel by channel: some algebra
134  // for generation of partially correlated random numbers
136  float A = 4.0f * W * W + 1.0f;
137  float x1 = (A - std::sqrt(A)) / (2.0f * A);
138  float sinfi = std::sqrt(x1);
139  float cosfi = sqrt(1.0 - x1);
140 
141  sinfi = sinfi * m_OGcorr / std::abs(m_OGcorr);
142  float S = m_GainRMS * m_GainRMS + m_Ospread * m_Ospread;
143  float D = (m_GainRMS * m_GainRMS - m_Ospread * m_Ospread) / (cosfi * cosfi - sinfi * sinfi);
144  float S1 = std::sqrt((S + D) * 0.5f);
145  float S2 = std::sqrt((S - D) * 0.5f);
146  float Noise = 0;
147  int mode = 1;
148 
149  // To set noise values for different module types, barrel, EC, inners, middles, short middles, and outers
150  if (m_analogueNoiseOn) {
151  if (m_sct_id->barrel_ec(moduleId) == 0) { // barrel_ec=0 corresponds to barrel
152  if (m_sct_id->layer_disk(moduleId) == 3) { // outer barrel layer 10 degrees warmer
153  Noise = m_NoiseBarrel3;
154  } else {
155  Noise = m_NoiseBarrel;
156  }
157  } else {
158  int moduleType = m_sct_id->eta_module(moduleId);
159  switch (moduleType) { // eta = 0, 1, or 2 corresponds to outers, middles and inners?! (at least in the offline world)
160  case 0: {
161  Noise = m_NoiseOuters;
162  break;
163  }
164  case 1: {
165  if (m_sct_id->layer_disk(moduleId) == 7) {
166  Noise = m_NoiseShortMiddles;
167  } else {
168  Noise = m_NoiseMiddles;
169  }
170  break;
171  }
172  case 2: {
173  Noise = m_NoiseInners;
174  break;
175  }
176  default: {
177  Noise = m_NoiseBarrel;
178  ATH_MSG_ERROR("moduleType(eta): " << moduleType << " unknown, using barrel");
179  }
180  }// end of switch structure
181  }
182  }
183 
184  // Loop over collection and setup gain/offset/noise for the hit and neighbouring strips
185  SiChargedDiodeIterator i_chargedDiode = collection.begin();
186  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
187 
188  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
189  SiChargedDiode diode = (*i_chargedDiode).second;
190  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
191  unsigned int flagmask = diode.flag() & 0xFE;
192  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
193  if (!flagmask) { // If the diode is OK (not flagged)
194  const SiReadoutCellId roCell = diode.getReadoutCell();
195  if (roCell.isValid()) {
196  int strip = roCell.strip();
197  int i = std::max(strip - 1, 0);
198  int i_end = std::min(strip + 2, strip_max);
199 
200  // loop over strips
201  for (; i < i_end; i++) {
202  // Need to check if strip is already setup
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);
206 
207  data.m_GainFactor[i] = 1.0f + (cosfi * g + sinfi * o);
208  //offset per channel
209  float offset_val = (cosfi * o - sinfi * g);
210  //noise factor per channel (from calib data noise per chip)
211  float noise_val = Noise * mode;
212 
213  // Fill the noise and offset values into the Analogue
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);
217  } else { // Expanded
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);
221  }
222  }
223  }
224  }
225  }
226  }
227 
228  return StatusCode::SUCCESS;
229 }
230 
231 // ----------------------------------------------------------------------
232 // prepare gain and offset for the strips for a given module using
233 // Cond Db data to get the chip calibration data
234 // ----------------------------------------------------------------------
235 StatusCode SCT_FrontEnd::prepareGainAndOffset(SiChargedDiodeCollection& collection, int side, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
236  // Get chip data from calib DB
237  std::vector<float> gainByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "GainByChip");
238  std::vector<float> gainRMSByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "GainRMSByChip");
239  std::vector<float> offsetByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "OffsetByChip");
240  std::vector<float> offsetRMSByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "OffsetRMSByChip");
241  std::vector<float> noiseByChipVect(6, 0.0);
242 
243  if (m_analogueNoiseOn) { // Check if noise should be on or off
244  noiseByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "NoiseByChip");
245  }
246 
247  // Need to check if empty, most should have data, but a few old DEAD modules don't
248  if (gainByChipVect.empty() or noiseByChipVect.empty()) {
249  ATH_MSG_DEBUG("No calibration data in cond DB for module " << moduleId << " using JO values");
250  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
251  return StatusCode::FAILURE;
252  } else {
253  return StatusCode::SUCCESS;
254  }
255  }
256 
257  // Don't really need to set up values for each chip...
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");
261  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
262  return StatusCode::FAILURE;
263  } else {
264  return StatusCode::SUCCESS;
265  }
266  }
267 
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);
274  float gainRMS = 0.0;
275  float offsetRMS = 0.0;
276 
277  for (int i = 0; i < 6; ++i) {
278  // Some very few chips have 0 values, dead/bypassed/etc, so check and use some fixed values instead
279  if (gainByChipVect[i] > 0.1) {
280  gain[i] = gainByChipVect[i] / gainMeanValue;
281  offset[i] = offsetByChipVect[i] / m_Threshold;
282  gainRMS = gainRMSByChipVect[i] / gainMeanValue;
283  offsetRMS = offsetRMSByChipVect[i] / m_Threshold;
284  } else {
285  gain[i] = 55.0f / gainMeanValue;
286  offset[i] = 42.0f / m_Threshold;
287  gainRMS = 1.3f / gainMeanValue;
288  offsetRMS = 2.0f / m_Threshold;
289  }
290 
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.0f * A);
294  sinfi[i] = std::sqrt(x1);
295  cosfi[i] = std::sqrt(1.0f - x1);
296  sinfi[i] = sinfi[i] * m_OGcorr / std::abs(m_OGcorr);
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.0f);
300  S2[i] = std::sqrt((S - D) / 2.0f);
301  }
302 
303  // Loop over collection and setup gain/offset/noise for the hit and neighbouring strips
304  SiChargedDiodeIterator i_chargedDiode = collection.begin();
305  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
306 
307  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
308  SiChargedDiode diode = (*i_chargedDiode).second;
309  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
310  unsigned int flagmask = diode.flag() & 0xFE;
311  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
312  if (!flagmask) { // If the diode is OK (not flagged)
313  const SiReadoutCellId roCell = diode.getReadoutCell();
314 
315  if (roCell.isValid()) {
316  int strip = roCell.strip();
317  int i = std::max(strip - 1, 0);
318  int i_end = std::min(strip + 2, strip_max);
319 
320  // loop over strips
321  for (; i < i_end; i++) {
322  // Need to check if strip is already setup
323  if (data.m_Analogue[1][i] <= 0.0) {
324  // Values depends on which chip the strip is on (complex when strip is on chip edge)
325  int chip = i / 128;
326  float g = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S1[chip]);
327  float o = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S2[chip]);
328 
329  data.m_GainFactor[i] = gain[chip] + (cosfi[chip] * g + sinfi[chip] * o);
330  //offset per channel
331  float offset_val = offset[chip] + (cosfi[chip] * o - sinfi[chip] * g);
332  //noise factor per channel (from calib data noise per chip)
333  float noise_val = noiseByChipVect[chip];
334 
335  // Fill the noise and offset values into the Analogue
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);
339  } else { // Expanded
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);
343  }
344  }
345  }
346  }
347  }
348  }
349 
350  return StatusCode::SUCCESS;
351 }
352 
353 // ----------------------------------------------------------------------
354 //
355 // ----------------------------------------------------------------------
356 StatusCode SCT_FrontEnd::randomNoise(SiChargedDiodeCollection& collection, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
357  // Add random noise
358 
359  double occupancy = 0.0;
360  double NoiseOccupancy = 0.0;
361  float Noise = 0.0;
362  int nNoisyStrips = 0;
363  double mode = 1.;
364 
365  const bool noise_expanded_mode = (m_data_compression_mode == AnyHit_1XX_X1X_XX1 and m_data_readout_mode == Expanded);
366 
367  // Will give 3 times as much noise occupancy if running in any hit expanded mode
368  if (noise_expanded_mode) {
369  mode = 3.;
370  }
371 
372  // Sets fixed noise occupancy values for different module types, barrel, EC,
373  // inners, middles
374  // short middles, and outers
375  if (m_sct_id->barrel_ec(moduleId) == 0) { // barrel_ec=0 corresponds to barrel
376  if (m_sct_id->layer_disk(moduleId) == 3) { // outer barrel layer 10 degrees warmer
377  NoiseOccupancy = m_NOBarrel3;
378  Noise = m_NoiseBarrel3;
379  } else {
380  NoiseOccupancy = m_NOBarrel;
381  Noise = m_NoiseBarrel;
382  }
383  } else {
384  int moduleType = m_sct_id->eta_module(moduleId);
385  switch (moduleType) { // eta = 0, 1, or 2 corresponds to outers, middles and inners?! (at least in the offline world)
386  case 0: {
387  NoiseOccupancy = m_NOOuters;
388  Noise = m_NoiseOuters;
389  break;
390  }
391  case 1: {
392  if (m_sct_id->layer_disk(moduleId) == 7) {
393  NoiseOccupancy = m_NOShortMiddles;
394  Noise = m_NoiseShortMiddles;
395  } else {
396  NoiseOccupancy = m_NOMiddles;
397  Noise = m_NoiseMiddles;
398  }
399  break;
400  }
401  case 2: {
402  NoiseOccupancy = m_NOInners;
403  Noise = m_NoiseInners;
404  break;
405  }
406  default: {
407  NoiseOccupancy = m_NOBarrel;
408  Noise = m_NoiseBarrel;
409  ATH_MSG_ERROR("moduleType(eta): " << moduleType << " unknown, using barrel");
410  }
411  }// end of switch structure
412  }
413 
414  // Calculate the number of "free strips"
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);
421  ++nEmptyStrips;
422  }
423  }
424 
425  if (nEmptyStrips != 0) {
426  // Should randomize the fixed NO values, so we get some differences per
427  // wafer
428  occupancy = CLHEP::RandGaussZiggurat::shoot(rndmEngine, NoiseOccupancy, NoiseOccupancy * 0.1);
429 
430  // Modify the occupancy if threshold is not 1.0 fC
431  if (m_Threshold > 6242.3 or m_Threshold < 6242.1) {
432  const float fC = 6242.2;
433  occupancy = occupancy * exp(-(0.5 / (Noise * Noise) * (m_Threshold * m_Threshold - fC * fC)));
434  }
435  nNoisyStrips = CLHEP::RandPoisson::shoot(rndmEngine, strip_max * occupancy * mode);
436 
437  // Check and adapt the number of noisy strips to the number of free strips
438  if (nEmptyStrips < nNoisyStrips) {
439  nNoisyStrips = nEmptyStrips;
440  }
441 
442  // Find random strips to get noise hits
443  for (int i = 0; i < nNoisyStrips; i++) {
444  int index = CLHEP::RandFlat::shootInt(rndmEngine, nEmptyStrips - i); // strip == 10, 12 free strips
445  // have vector [10000100100200211001] 20 strips
446  int strip = emptyStrips.at(index);
447  emptyStrips.erase(emptyStrips.begin()+index); // Erase it not to use it again
448  if (data.m_StripHitsOnWafer[strip]!=0) {
449  ATH_MSG_ERROR(index << "-th empty strip, strip " << strip << " should be empty but is not empty! Something is wrong!");
450  }
451  data.m_StripHitsOnWafer[strip] = 3; // !< Random Noise hit
452  // Add tbin info to noise diode
453  if (noise_expanded_mode) { // !< if any hit mode, any time bin otherwise fixed tbin=2
454  int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
455  // !< random number 0, 1 or 2
456  if (noise_tbin == 0) {
457  noise_tbin = 4; // !< now 1,2 or 4
458  }
459  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, noise_tbin)) {
460  ATH_MSG_ERROR("Can't add noise hit diode to collection (1)");
461  }
462  } else {
463  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
464  ATH_MSG_ERROR("Can't add noise hit diode to collection (2)");
465  }
466  }
467  }
468  }
469 
470  return StatusCode::SUCCESS;
471 }
472 
473 // ----------------------------------------------------------------------
474 //
475 // ----------------------------------------------------------------------
476 StatusCode SCT_FrontEnd::randomNoise(SiChargedDiodeCollection& collection, const Identifier& moduleId, int side, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
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);
482  double mode = 1.;
483 
484  const bool noise_expanded_mode = (m_data_compression_mode == AnyHit_1XX_X1X_XX1 and m_data_readout_mode == Expanded);
485 
486  // Will give 3 times as much noise occupancy if running in any hit expanded mode
487  if (noise_expanded_mode) {
488  mode = 3.;
489  }
490 
491  // Get chip data from calib DB
492  NOByChipVect = m_ReadCalibChipDataTool->getNoiseOccupancyData(moduleId, side, "OccupancyByChip");
493  ENCByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "NoiseByChip");
494 
495  // Need to check if empty, most should have data, but a few old DEAD modules don't, and 9C...
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;
500  } else {
501  return StatusCode::SUCCESS;
502  }
503  } else {
504  for (int i = 0; i < n_chips; i++) {
505  // A 0 value can mean two things now, chip out of config for long time and no value was uploaded
506  // or its short middles and inners and the value is for all purposes 0! so ok.
507 
508  // Modify the occupancy if threshold is not 1.0 fC
509  if (m_Threshold > 6242.3 or m_Threshold < 6242.1) {
510  constexpr float fC = 6242.2;
511  NOByChipVect[i] = NOByChipVect[i] * exp(-(0.5 / (ENCByChipVect[i]*ENCByChipVect[i]) * (m_Threshold*m_Threshold - fC*fC)));
512  }
513 
514  nNoisyStrips[i] = CLHEP::RandPoisson::shoot(rndmEngine, chipStripmax * NOByChipVect[i] * mode);
515  }
516  }
517 
518  // Loop over the chips on the wafer
519  for (int chip_index = 0; chip_index < n_chips; ++chip_index) {
520  int chip_strip_offset = chipStripmax * chip_index; // First strip number on chip
521 
522  // Calculate the number of "free strips" on this chip
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;
530  }
531  }
532 
533  // if no empty strips on chip do nothing
534  if (nEmptyStripsOnChip != 0) {
535  // Check and adapt the number of noisy strips to the number of free strips
536  if (nEmptyStripsOnChip < nNoisyStrips[chip_index]) {
537  nNoisyStrips[chip_index] = nEmptyStripsOnChip;
538  }
539 
540  // Find random strips to get noise hits
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); // Erase it not to use it again
545  int strip = strip_on_chip + chip_strip_offset;
546  if (data.m_StripHitsOnWafer[strip]!=0) {
547  ATH_MSG_ERROR(index << "-th empty strip, strip " << strip << " should be empty but is not empty! Something is wrong!");
548  }
549  data.m_StripHitsOnWafer[strip] = 3; // !< Random Noise hit
550  // Add tbin info to noise diode
551  if (noise_expanded_mode) { // !< if any hit mode, any time bin
552  // !< otherwise fixed tbin=2
553  int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
554  // !< random number 0, 1 or 2
555  if (noise_tbin == 0) {
556  noise_tbin = 4; // !< now 1, 2 or 4
557  }
558  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, noise_tbin)) {
559  ATH_MSG_ERROR("Can't add noise hit diode to collection (3)");
560  }
561  } else {
562  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
563  ATH_MSG_ERROR("Can't add noise hit diode to collection (4)");
564  }
565  }
566  }
567  }
568  }
569 
570  return StatusCode::SUCCESS;
571 }
572 
573 // ----------------------------------------------------------------------
574 // process the collection of pre digits this will need to go through
575 // all single-strip pre-digits calculate the amplifier response add noise
576 // (this could be moved elsewhere later) apply threshold do clustering
577 // ----------------------------------------------------------------------
578 void SCT_FrontEnd::process(SiChargedDiodeCollection& collection, CLHEP::HepRandomEngine * rndmEngine) const {
579  // get SCT module side design
580  const SCT_ModuleSideDesign *p_design = static_cast<const SCT_ModuleSideDesign*>(&(collection.design()));
581 
583 
584  // Check number of strips in design and from manager(max number of strips on any module)
585  // The design value should always be equal or lower than the manager one
586  // However, no resising is now done in case of a lower value
587  const int strip_max = p_design->cells();
588  // Init vectors
589  if (StatusCode::SUCCESS != initVectors(strip_max, data)) {
590  ATH_MSG_ERROR("Can't resize class variable vectors");
591  return;
592  }
593 
594  // Contains strip hit info, reset to 0 for each wafer processed
595  data.m_StripHitsOnWafer.assign(strip_max, 0);
596 
597  // Containes the charge for each bin on each hit strip
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;
602  }
603  } else { // Expanded
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;
608  }
609  }
610 
611  // Get wafer, moduleId and side
612  Identifier waferId = collection.identify();
613  Identifier moduleId = m_sct_id->module_id(waferId);
614  const int side = m_sct_id->side(waferId);
615 
616  // Check if collection empty
617  if (not collection.empty()) {
618  // Setup gain/offset/noise to the hit and neighbouring strips
619  if (m_useCalibData) { // Use calib cond DB data
620  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, side, moduleId, rndmEngine, data, strip_max)) {
621  ATH_MSG_ERROR("\tCan't prepare Gain and Offset");
622  }
623  } else { // Use JO values
624  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
625  ATH_MSG_ERROR("\tCan't prepare Gain and Offset");
626  }
627  }
628 
629  if (StatusCode::SUCCESS != doSignalChargeForHits(collection, data, strip_max)) {
630  ATH_MSG_ERROR("\tCan't doSignalChargeForHits");
631  }
632 
633  if (StatusCode::SUCCESS != doThresholdCheckForRealHits(collection, data, strip_max)) {
634  ATH_MSG_ERROR("\tCan't doThresholdCheckForRealHits");
635  }
636 
637  if (StatusCode::SUCCESS != doThresholdCheckForCrosstalkHits(collection, data, strip_max)) {
638  ATH_MSG_ERROR("\tCan't doThresholdCheckForCrosstalkHits");
639  }
640  }
641 
642  if (m_NoiseOn) {
643  if (m_useCalibData) { // Check if using DB or not
644  if (StatusCode::SUCCESS != randomNoise(collection, moduleId, side, rndmEngine, data, strip_max)) {
645  ATH_MSG_ERROR("\tCan't do random noise on wafer?!");
646  }
647  } else { // Use JO fixed values
648  if (StatusCode::SUCCESS != randomNoise(collection, moduleId, rndmEngine, data,strip_max)) {
649  ATH_MSG_ERROR("\tCan't do random noise on wafer?!");
650  }
651  }
652  }
653 
654  // Check for strips above threshold and do clustering
655  if (StatusCode::SUCCESS != doClustering(collection, data,strip_max)) {
656  ATH_MSG_ERROR("\tCan't cluster the hits?!");
657  }
658 }
659 
661  using list_t = SiTotalCharge::list_t;
662 
663  // *****************************************************************************
664  // Loop over the diodes (strips ) and for each of them define the total signal
665  // *****************************************************************************
666 
667  // set up number of needed bins depending on the compression mode
668  short bin_max = 0;
670  bin_max = m_data_compression_mode;
671  } else {
672  bin_max = 3;
673  }
674 
675  std::vector<float> response(bin_max);
676 
677  SiChargedDiodeIterator i_chargedDiode = collection.begin();
678  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
679  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
680  SiChargedDiode diode = (*i_chargedDiode).second;
681  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
682  unsigned int flagmask = diode.flag() & 0xFE;
683  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
684  if (!flagmask) { // If the diode is OK (not flagged)
685  const SiReadoutCellId roCell = diode.getReadoutCell();
686 
687  if (roCell.isValid()) {
688  int strip = roCell.strip();
689 
690  const list_t &ChargesOnStrip = diode.totalCharge().chargeComposition();
691 
693  // Amplifier response
694  m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
695  for (short bin = 0; bin < bin_max; ++bin) {
696  data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
697  }
698  // Add Crosstalk signal for neighboring strip
699  m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
700  for (short bin = 0; bin < bin_max; ++bin) {
701  if (strip + 1 < strip_max) {
702  data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
703  }
704  if (strip > 0) {
705  data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
706  }
707  }
708  } else { // Expanded
709  // Amplifier response
710  m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
711  for (short bin = 0; bin < bin_max; ++bin) {
712  data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
713  }
714  // Add Crosstalk signal for neighboring strip
715  m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
716  for (short bin = 0; bin < bin_max; ++bin) {
717  if (strip + 1 < strip_max) {
718  data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
719  }
720  if (strip > 0) {
721  data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
722  }
723  }
724  }
725  } else { // if roCell not valid
726  ATH_MSG_WARNING("\t Cannot get the cell ");
727  }
728  } else {// If diode is disconnected/disabled skip it
729  ATH_MSG_WARNING("\tDisabled or disconnected diode (strip)");
730  }
731  }
732  return StatusCode::SUCCESS;
733 }
734 
736  // **********************************************************************************
737  // Flag strips below threshold and flag the threshold check into data.m_StripHitsOnWafer
738  // **********************************************************************************
739 
740  SiChargedDiodeIterator i_chargedDiode = collection.begin();
741  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
742 
743  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
744  SiChargedDiode& diode = (*i_chargedDiode).second;
745  SiReadoutCellId roCell = diode.getReadoutCell();
746  if (roCell.isValid()) {
747  int strip = roCell.strip();
748  if (strip > -1 and strip < strip_max) {
750  if ((data.m_Analogue[0][strip] >= m_Threshold or data.m_Analogue[1][strip] < m_Threshold)) {
751  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
752  data.m_StripHitsOnWafer[strip] = -1;
753  } else if (((0x10 & diode.flag()) == 0x10) or ((0x4 & diode.flag()) == 0x4)) {
754  // previously a crazy strip number could have screwed things up here.
755  data.m_StripHitsOnWafer[strip] = -1;
756  } else {
757  data.m_StripHitsOnWafer[strip] = 1;
758  SiHelper::SetTimeBin(diode, 2, &msg()); // set timebin info
759  }
760  } else { // Expanded
761  int have_hit_bin = 0;
762  if (data.m_Analogue[0][strip] >= m_Threshold) {
763  have_hit_bin = 4;
764  }
765  if (data.m_Analogue[1][strip] >= m_Threshold) {
766  have_hit_bin += 2;
767  }
768  if (data.m_Analogue[2][strip] >= m_Threshold) {
769  have_hit_bin += 1;
770  }
771  if (((0x10 & diode.flag()) == 0x10) || ((0x4 & diode.flag()) == 0x4)) {
772  // previously a crazy strip number could have screwed things up here.
773  data.m_StripHitsOnWafer[strip] = -1;
774  } else if (m_data_compression_mode == Level_X1X) { // !< level and expanded mode
775  if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
776  data.m_StripHitsOnWafer[strip] = 1;
777  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
778  } else {
779  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
780  data.m_StripHitsOnWafer[strip] = -1;
781  }
782  } else if (m_data_compression_mode == Edge_01X) { // !< edge and expanded mode
783  if (have_hit_bin == 2 or have_hit_bin == 3) {
784  data.m_StripHitsOnWafer[strip] = 1;
785  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
786  } else {
787  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
788  data.m_StripHitsOnWafer[strip] = -1;
789  }
790  } else if (m_data_compression_mode == AnyHit_1XX_X1X_XX1) { // !< any hit mode
791  if (have_hit_bin == 0) {
792  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
793  data.m_StripHitsOnWafer[strip] = -1;
794  } else {
795  data.m_StripHitsOnWafer[strip] = 1;
796  if (m_data_readout_mode == Expanded) { // !< check for exp mode or not
797  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
798  } else {
799  SiHelper::SetTimeBin(diode, 2, &msg());
800  }
801  }
802  }
803  }
804  }
805  }
806  }
807  return StatusCode::SUCCESS;
808 }
809 
810 // ----------------------------------------------------------------------
811 //
812 // ----------------------------------------------------------------------
814  // Check for noise+crosstalk strips above threshold
815  // data.m_StripHitsOnWafer: real hits above threshold == 1 or below/disconnected
816  // == -1
817  // =0 for free strips or strips with charge to be checked (data.m_Analogue[1]!=0)
818  // Set 2 for crosstalk noise hits and -2 for below ones
819 
820  for (int strip = 0; strip < strip_max; strip++) {
821  // Find strips with data.m_StripHitsOnWafer[strip] == 0
822  if (data.m_StripHitsOnWafer[strip] != 0) { // real hits already checked
823  continue;
824  }
825  if (data.m_Analogue[1][strip] > 0) { // Better way of doing this?!
826  // set data.m_StripHitsOnWafer to x in prepareGainAndOffset
828  if ((data.m_Analogue[0][strip] >= m_Threshold or data.m_Analogue[1][strip] < m_Threshold)) {
829  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
830  } else {
831  data.m_StripHitsOnWafer[strip] = 2; // Crosstalk+Noise hit
832  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
833 
834  ATH_MSG_ERROR("Can't add noise hit diode to collection (5)");
835  }
836  }
837  } else { // Expanded
838  int have_hit_bin = 0;
839  if (data.m_Analogue[0][strip] >= m_Threshold) {
840  have_hit_bin = 4;
841  }
842  if (data.m_Analogue[1][strip] >= m_Threshold) {
843  have_hit_bin += 2;
844  }
845  if (data.m_Analogue[2][strip] >= m_Threshold) {
846  have_hit_bin += 1;
847  }
848  if (m_data_compression_mode == Level_X1X) { // !< level and expanded mode
849  if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
850  data.m_StripHitsOnWafer[strip] = 2; // Crosstalk+Noise hit
851  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
852  ATH_MSG_ERROR("Can't add noise hit diode to collection (6)");
853  }
854  } else {
855  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
856  }
857  } else if (m_data_compression_mode == Edge_01X) { // !< edge and expanded mode
858  if (have_hit_bin == 2 or have_hit_bin == 3) {
859  data.m_StripHitsOnWafer[strip] = 2; // Noise hit
860  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
861  ATH_MSG_ERROR("Can't add noise hit diode to collection (7)");
862  }
863  } else {
864  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
865  }
866  } else if (m_data_compression_mode == AnyHit_1XX_X1X_XX1) { // !< any hit mode
867  if (have_hit_bin == 0) {
868  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
869  } else {
870  data.m_StripHitsOnWafer[strip] = 2; // !< Crosstalk+Noise hit
871  if (m_data_readout_mode == Expanded) { // !< check for exp mode or not
872  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
873  ATH_MSG_ERROR("Can't add noise hit diode to collection (8)");
874  }
875  } else {
876  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
877  ATH_MSG_ERROR("Can't add noise hit diode to collection (9)");
878  }
879  }
880  }
881  }
882  }
883  }
884  }
885 
886  return StatusCode::SUCCESS;
887 }
888 
890  // ********************************
891  // now do clustering
892  // ********************************
893  int strip = 0;
894  int clusterSize = 0;
895 
896  const SCT_ModuleSideDesign& sctDesign = static_cast<const SCT_ModuleSideDesign&>(collection.design());
897 
898  SiCellId hitStrip;
899 
901  do {
902  if (data.m_StripHitsOnWafer[strip] > 0) {
903  // ====== First step: Get the cluster size
904  // ===================================================
905  int clusterFirstStrip = strip;
906 
907  // Find end of cluster. In multi-row sensors, cluster cannot span rows.
908  int row = sctDesign.row(strip);
909  if (row < 0) {
910  row = 0;
911  }
912 
913  int lastStrip1DInRow = 0;
914  for (int i = 0; i < row + 1; ++i) {
915  lastStrip1DInRow += sctDesign.diodesInRow(i);
916  }
917 
918  while (strip < lastStrip1DInRow-1 and data.m_StripHitsOnWafer[strip +1] > 0) {
919  ++strip; // !< Find first strip hit and add up the following strips
920  }
921  int clusterLastStrip = strip;
922 
923  clusterSize = (clusterLastStrip - clusterFirstStrip) + 1;
924  hitStrip = SiCellId(clusterFirstStrip);
925  SiChargedDiode& HitDiode = *(collection.find(hitStrip));
926  SiHelper::SetStripNum(HitDiode, clusterSize, &msg());
927 
928  SiChargedDiode *PreviousHitDiode = &HitDiode;
929  for (int i = clusterFirstStrip+1; i <= clusterLastStrip; ++i) {
930  hitStrip = SiCellId(i);
931  SiChargedDiode& HitDiode2 = *(collection.find(hitStrip));
932  SiHelper::ClusterUsed(HitDiode2, true);
933  PreviousHitDiode->setNextInCluster(&HitDiode2);
934  PreviousHitDiode = &HitDiode2;
935  }
936  }
937  ++strip; // !< This is the starting point of the next cluster within this collection
938  } while (strip < strip_max);
939  } else {
940  // Expanded read out mode, basically one RDO/strip per cluster
941  // But if consecutively fired strips have the same time bin, those are converted into one cluster.
942  do {
943  clusterSize = 1;
944  if (data.m_StripHitsOnWafer[strip] > 0) {
945  hitStrip = SiCellId(strip);
946  SiChargedDiode& hitDiode = *(collection.find(hitStrip));
947  int timeBin = SiHelper::GetTimeBin(hitDiode);
948  SiChargedDiode* previousHitDiode = &hitDiode;
949  // Check if consecutively fired strips have the same time bin
950  for (int newStrip=strip+1; newStrip<strip_max; newStrip++) {
951  if (not (data.m_StripHitsOnWafer[newStrip]>0)) break;
952  SiCellId newHitStrip = SiCellId(newStrip);
953  SiChargedDiode& newHitDiode = *(collection.find(newHitStrip));
954  if (timeBin!=SiHelper::GetTimeBin(newHitDiode)) break;
955  SiHelper::ClusterUsed(newHitDiode, true);
956  previousHitDiode->setNextInCluster(&newHitDiode);
957  previousHitDiode = &newHitDiode;
958  clusterSize++;
959  }
960  SiHelper::SetStripNum(hitDiode, clusterSize, &msg());
961 
962 #ifdef SCT_DIG_DEBUG
963  ATH_MSG_DEBUG("RDO Strip = " << strip << ", tbin = " <<
964  SiHelper::GetTimeBin(hitDiode) <<
965  ", HitInfo(1=real, 2=crosstalk, 3=noise): " <<
966  data.m_StripHitsOnWafer[strip]);
967 #endif
968  }
969  strip += clusterSize; // If more than one strip fires, those following strips are skipped.
970  } while (strip < strip_max);
971  }
972 
973  // clusters below threshold, only from pre-digits that existed before no
974  // pure noise clusters below threshold will be made
975  // D. Costanzo. I don't see why we should cluster the strips below
976  // threshold. I'll pass on the info of strips below threshold
977  // to the SDOs. I'll leave the SCT experts the joy to change this if they
978  // don't like what I did or if this requires too much memory/disk
979 
980  return StatusCode::SUCCESS;
981 }
982 
983 StatusCode SCT_FrontEnd::addNoiseDiode(SiChargedDiodeCollection& collection, int strip, int tbin) const {
984  const SiCellId ndiode(strip); // !< create a new diode
985  const SiCharge noiseCharge(2 * m_Threshold, 0, SiCharge::noise); // !< add some noise to it
986  collection.add(ndiode, noiseCharge); // !< add it to the collection
987 
988  // Get the strip back to check
989  SiChargedDiode *NoiseDiode = (collection.find(strip));
990  if (NoiseDiode == nullptr) {
991  return StatusCode::FAILURE;
992  }
993  SiHelper::SetTimeBin(*NoiseDiode, tbin, &msg()); // set timebin info
994  return StatusCode::SUCCESS;
995 }
996 
997 float SCT_FrontEnd::meanValue(std::vector<float>& calibDataVect) {
998  float mean_value = 0.0;
999  int nData = 0;
1000  const unsigned int vec_size = calibDataVect.size();
1001 
1002  for (unsigned int i = 0; i < vec_size; ++i) {
1003  if (calibDataVect[i] > 0.1) {
1004  mean_value += calibDataVect[i];
1005  ++nData;
1006  }
1007  }
1008 
1009  if (nData == 0) {
1010  return -1;
1011  } else {
1012  return mean_value / nData;
1013  }
1014 }
SCT_FrontEnd::m_timeOfThreshold
FloatProperty m_timeOfThreshold
Definition: SCT_FrontEnd.h:128
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
SCT_FrontEndData
simulation of the SCT front-end electronics working as a SiPreDigitsProcessor models response of ABCD...
Definition: SCT_FrontEnd.h:64
query_example.row
row
Definition: query_example.py:24
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
SCT_FrontEnd::m_data_readout_mode
ShortProperty m_data_readout_mode
Definition: SCT_FrontEnd.h:130
SCT_FrontEnd::m_NoiseOn
BooleanProperty m_NoiseOn
Definition: SCT_FrontEnd.h:122
S1
struct TBPatternUnitContext S1
SCT_FrontEnd::m_data_compression_mode
ShortProperty m_data_compression_mode
Definition: SCT_FrontEnd.h:129
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
SCT_FrontEnd::randomNoise
StatusCode randomNoise(SiChargedDiodeCollection &collection, const Identifier &moduleId, CLHEP::HepRandomEngine *rndmEngine, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:356
SiHelper.h
SiChargedDiode
Definition: SiChargedDiode.h:30
SiliconTech::strip
@ strip
max
#define max(a, b)
Definition: cfImp.cxx:41
SCT_FrontEnd::m_ReadCalibChipDataTool
ToolHandle< ISCT_ReadCalibChipDataTool > m_ReadCalibChipDataTool
Handle to the Calibration ConditionsTool.
Definition: SCT_FrontEnd.h:134
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SCT_FrontEnd::meanValue
static float meanValue(std::vector< float > &calibDataVect)
Definition: SCT_FrontEnd.cxx:997
SCT_FrontEnd::process
virtual void process(SiChargedDiodeCollection &collection, CLHEP::HepRandomEngine *rndmEngine) const override
process the collection of pre digits: needed to go through all single-strip pre-digits to calculate t...
Definition: SCT_FrontEnd.cxx:578
response
MDT_Response response
Definition: MDT_ResponseTest.cxx:28
SCT_ModuleSideDesign.h
index
Definition: index.py:1
JetTiledMap::W
@ W
Definition: TiledEtaPhiMap.h:44
InDetDD::SCT_ModuleSideDesign
Definition: SCT_ModuleSideDesign.h:40
SiChargedDiode::setNextInCluster
void setNextInCluster(SiChargedDiode *nextInCluster)
Definition: SiChargedDiode.h:130
CxxUtils::vec_size
constexpr ATH_ALWAYS_INLINE size_t vec_size()
Return the number of elements in a vectorized type.
Definition: vec.h:227
SiChargedDiode::getReadoutCell
const InDetDD::SiReadoutCellId & getReadoutCell() const
Definition: SiChargedDiode.h:111
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
bin
Definition: BinsDiffFromStripMedian.h:43
SCT_FrontEnd::Level_X1X
@ Level_X1X
Definition: SCT_FrontEnd.h:107
SiChargedDiodeCollection::end
SiChargedDiodeIterator end()
Definition: SiChargedDiodeCollection.h:253
SiCharge
Definition: SiCharge.h:25
SCT_FrontEnd::m_sct_id
const SCT_ID * m_sct_id
Handle to SCT ID helper.
Definition: SCT_FrontEnd.h:137
SCT_FrontEnd::m_NoiseInners
FloatProperty m_NoiseInners
Definition: SCT_FrontEnd.h:112
SCT_ID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: SCT_ID.h:728
SiChargedDiodeCollection::empty
bool empty() const
Definition: SiChargedDiodeCollection.h:274
SCT_FrontEnd::m_OGcorr
FloatProperty m_OGcorr
Definition: SCT_FrontEnd.h:126
InDetDD::SiCellId::strip
int strip() const
Get strip number. Equivalent to phiIndex().
Definition: SiCellId.h:131
SiTotalCharge::list_t
std::vector< SiCharge > list_t
Definition: SiTotalCharge.h:31
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
SCT_FrontEnd::prepareGainAndOffset
StatusCode prepareGainAndOffset(SiChargedDiodeCollection &collection, const Identifier &moduleId, CLHEP::HepRandomEngine *rndmEngine, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:132
SiChargedDiodeCollection::begin
SiChargedDiodeIterator begin()
Definition: SiChargedDiodeCollection.h:248
InDetDD::SCT_ModuleSideDesign::cells
int cells() const
number of readout stips within module side:
Definition: SCT_ModuleSideDesign.h:228
SCT_FrontEnd::m_NOMiddles
DoubleProperty m_NOMiddles
Definition: SCT_FrontEnd.h:119
SCT_ID::module_id
Identifier module_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: SCT_ID.h:416
SCT_FrontEnd::Edge_01X
@ Edge_01X
Definition: SCT_FrontEnd.h:107
SiChargedDiodeIterator
SiChargedDiodeMap::iterator SiChargedDiodeIterator
Definition: SiChargedDiodeCollection.h:70
SCT_FrontEnd::initVectors
StatusCode initVectors(int strips, SCT_FrontEndData &data) const
Definition: SCT_FrontEnd.cxx:111
TRT::Hit::side
@ side
Definition: HitInfo.h:83
SCT_FrontEnd::SCT_FrontEnd
SCT_FrontEnd(const std::string &type, const std::string &name, const IInterface *parent)
constructor
Definition: SCT_FrontEnd.cxx:29
InDetDD::SCT_ModuleSideDesign::row
virtual int row(int stripId1Dim) const
Definition: SCT_ModuleSideDesign.h:271
SiChargedDiodeCollection::find
SiChargedDiode * find(const InDetDD::SiCellId &siId)
Definition: SiChargedDiodeCollection.cxx:63
SiTotalCharge::chargeComposition
const list_t & chargeComposition() const
Definition: SiTotalCharge.h:123
SCT_FrontEnd::m_Threshold
FloatProperty m_Threshold
Definition: SCT_FrontEnd.h:127
A
InDetDD::SCT_ModuleSideDesign::diodesInRow
virtual int diodesInRow(const int row) const
Definition: SCT_ModuleSideDesign.h:224
SiChargedDiode::totalCharge
const SiTotalCharge & totalCharge() const
Definition: SiChargedDiode.h:107
SiCharge::noise
@ noise
Definition: SiCharge.h:28
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SiChargedDiodeCollection
Definition: SiChargedDiodeCollection.h:109
SCT_FrontEnd::m_NOBarrel3
DoubleProperty m_NOBarrel3
Definition: SCT_FrontEnd.h:117
SCT_FrontEnd::m_sct_amplifier
ToolHandle< IAmplifier > m_sct_amplifier
Handle the Amplifier tool.
Definition: SCT_FrontEnd.h:133
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
SCT_FrontEnd::m_GainRMS
FloatProperty m_GainRMS
Definition: SCT_FrontEnd.h:124
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SiHelper::SetTimeBin
static void SetTimeBin(SiChargedDiode &chDiode, int time, MsgStream *log=nullptr)
Definition: SiHelper.h:149
SiHelper::belowThreshold
static void belowThreshold(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition: SiHelper.h:84
test_pyathena.parent
parent
Definition: test_pyathena.py:15
SCT_FrontEnd::addNoiseDiode
StatusCode addNoiseDiode(SiChargedDiodeCollection &collection, int strip, int tbin) const
Definition: SCT_FrontEnd.cxx:983
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Preparation.mode
mode
Definition: Preparation.py:94
hist_file_dump.f
f
Definition: hist_file_dump.py:135
SiHelper::GetTimeBin
static int GetTimeBin(SiChargedDiode &chDiode)
Definition: SiHelper.h:203
SCT_FrontEnd::Condensed
@ Condensed
Definition: SCT_FrontEnd.h:108
SiChargedDiode::flag
int flag() const
Definition: SiChargedDiode.h:102
min
#define min(a, b)
Definition: cfImp.cxx:40
SCT_FrontEnd::m_NoiseShortMiddles
FloatProperty m_NoiseShortMiddles
Definition: SCT_FrontEnd.h:114
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
SCT_FrontEnd::m_useCalibData
BooleanProperty m_useCalibData
Definition: SCT_FrontEnd.h:131
SiHelper::ClusterUsed
static void ClusterUsed(SiChargedDiode &chDiode, bool flag)
Definition: SiHelper.h:121
SCT_FrontEnd::m_Ospread
FloatProperty m_Ospread
Definition: SCT_FrontEnd.h:125
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
IAmplifier.h
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
SCT_FrontEnd::doThresholdCheckForCrosstalkHits
StatusCode doThresholdCheckForCrosstalkHits(SiChargedDiodeCollection &collection, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:813
SCT_FrontEnd::m_NoiseBarrel
FloatProperty m_NoiseBarrel
Definition: SCT_FrontEnd.h:110
SCT_ID::layer_disk
int layer_disk(const Identifier &id) const
Definition: SCT_ID.h:734
SCT_FrontEnd::initialize
virtual StatusCode initialize() override
AlgTool InterfaceID.
Definition: SCT_FrontEnd.cxx:36
SCT_FrontEnd::m_detMgrName
StringProperty m_detMgrName
Definition: SCT_FrontEnd.h:140
SCT_FrontEnd::m_analogueNoiseOn
BooleanProperty m_analogueNoiseOn
Definition: SCT_FrontEnd.h:123
SCT_FrontEnd::m_NoiseMiddles
FloatProperty m_NoiseMiddles
Definition: SCT_FrontEnd.h:113
SCT_FrontEnd::m_NOBarrel
DoubleProperty m_NOBarrel
Definition: SCT_FrontEnd.h:116
SiChargedDiodeCollection::add
void add(const InDetDD::SiCellId &diode, const T &charge)
Definition: SiChargedDiodeCollection.h:299
InDetDD::SiCellId
Definition: SiCellId.h:29
SCT_FrontEnd.h
SCT_FrontEnd::finalize
virtual StatusCode finalize() override
AlgTool finalize.
Definition: SCT_FrontEnd.cxx:101
SCT_FrontEnd::m_NOOuters
DoubleProperty m_NOOuters
Definition: SCT_FrontEnd.h:121
SCT_FrontEnd::m_NOInners
DoubleProperty m_NOInners
Definition: SCT_FrontEnd.h:118
SCT_FrontEnd::doThresholdCheckForRealHits
StatusCode doThresholdCheckForRealHits(SiChargedDiodeCollection &collectione, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:735
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
SCT_FrontEnd::m_SCTdetMgr
const InDetDD::SCT_DetectorManager * m_SCTdetMgr
Handle to SCT detector manager.
Definition: SCT_FrontEnd.h:136
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
SCT_ID::eta_module
int eta_module(const Identifier &id) const
Definition: SCT_ID.h:746
SCT_FrontEnd::m_NOShortMiddles
DoubleProperty m_NOShortMiddles
Definition: SCT_FrontEnd.h:120
S2
struct TBPatternUnitContext S2
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
SCT_ID::side
int side(const Identifier &id) const
Definition: SCT_ID.h:752
SiHelper::SetStripNum
static void SetStripNum(SiChargedDiode &chDiode, int nstrip, MsgStream *log=nullptr)
Definition: SiHelper.h:139
SCT_FrontEnd::m_NoiseBarrel3
FloatProperty m_NoiseBarrel3
Definition: SCT_FrontEnd.h:111
InDetDD::SiReadoutCellId
Definition: SiReadoutCellId.h:42
SCT_DetectorManager.h
SCT_FrontEnd::doSignalChargeForHits
StatusCode doSignalChargeForHits(SiChargedDiodeCollection &collectione, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:660
SCT_FrontEnd::m_NoiseOuters
FloatProperty m_NoiseOuters
Definition: SCT_FrontEnd.h:115
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
SCT_FrontEnd::AnyHit_1XX_X1X_XX1
@ AnyHit_1XX_X1X_XX1
Definition: SCT_FrontEnd.h:107
SCT_FrontEnd::Expanded
@ Expanded
Definition: SCT_FrontEnd.h:108
SCT_FrontEnd::doClustering
StatusCode doClustering(SiChargedDiodeCollection &collection, SCT_FrontEndData &data, const int &stripMax) const
Definition: SCT_FrontEnd.cxx:889
SiChargedDiodeCollection::design
const InDetDD::DetectorDesign & design() const
Definition: SiChargedDiodeCollection.h:224
SiChargedDiodeCollection::identify
virtual Identifier identify() const override final
Definition: SiChargedDiodeCollection.h:230
Identifier
Definition: IdentifierFieldParser.cxx:14