Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SCT_FrontEnd.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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  data.m_GainFactor.resize(strips);
113 
115  data.m_Analogue[0].resize(strips);
116  data.m_Analogue[1].resize(strips);
117  } else { // Expanded
118  data.m_Analogue[0].resize(strips);
119  data.m_Analogue[1].resize(strips);
120  data.m_Analogue[2].resize(strips);
121  }
122 
123  return StatusCode::SUCCESS;
124 }
125 
126 // ----------------------------------------------------------------------
127 // prepare gain and offset for the strips for a given module
128 // ----------------------------------------------------------------------
129 StatusCode SCT_FrontEnd::prepareGainAndOffset(SiChargedDiodeCollection& collection, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
130  // now we need to generate gain and offset channel by channel: some algebra
131  // for generation of partially correlated random numbers
133  float A = 4.0f * W * W + 1.0f;
134  float x1 = (A - std::sqrt(A)) / (2.0f * A);
135  float sinfi = std::sqrt(x1);
136  float cosfi = sqrt(1.0 - x1);
137 
138  sinfi = sinfi * m_OGcorr / std::abs(m_OGcorr);
139  float S = m_GainRMS * m_GainRMS + m_Ospread * m_Ospread;
140  float D = (m_GainRMS * m_GainRMS - m_Ospread * m_Ospread) / (cosfi * cosfi - sinfi * sinfi);
141  float S1 = std::sqrt((S + D) * 0.5f);
142  float S2 = std::sqrt((S - D) * 0.5f);
143  float Noise = 0;
144  int mode = 1;
145 
146  // To set noise values for different module types, barrel, EC, inners, middles, short middles, and outers
147  if (m_analogueNoiseOn) {
148  if (m_sct_id->barrel_ec(moduleId) == 0) { // barrel_ec=0 corresponds to barrel
149  if (m_sct_id->layer_disk(moduleId) == 3) { // outer barrel layer 10 degrees warmer
150  Noise = m_NoiseBarrel3;
151  } else {
152  Noise = m_NoiseBarrel;
153  }
154  } else {
155  int moduleType = m_sct_id->eta_module(moduleId);
156  switch (moduleType) { // eta = 0, 1, or 2 corresponds to outers, middles and inners?! (at least in the offline world)
157  case 0: {
158  Noise = m_NoiseOuters;
159  break;
160  }
161  case 1: {
162  if (m_sct_id->layer_disk(moduleId) == 7) {
163  Noise = m_NoiseShortMiddles;
164  } else {
165  Noise = m_NoiseMiddles;
166  }
167  break;
168  }
169  case 2: {
170  Noise = m_NoiseInners;
171  break;
172  }
173  default: {
174  Noise = m_NoiseBarrel;
175  ATH_MSG_ERROR("moduleType(eta): " << moduleType << " unknown, using barrel");
176  }
177  }// end of switch structure
178  }
179  }
180 
181  // Loop over collection and setup gain/offset/noise for the hit and neighbouring strips
182  SiChargedDiodeIterator i_chargedDiode = collection.begin();
183  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
184 
185  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
186  SiChargedDiode diode = (*i_chargedDiode).second;
187  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
188  unsigned int flagmask = diode.flag() & 0xFE;
189  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
190  if (!flagmask) { // If the diode is OK (not flagged)
191  const SiReadoutCellId roCell = diode.getReadoutCell();
192  if (roCell.isValid()) {
193  int strip = roCell.strip();
194  int i = std::max(strip - 1, 0);
195  int i_end = std::min(strip + 2, strip_max);
196 
197  // loop over strips
198  for (; i < i_end; i++) {
199  // Need to check if strip is already setup
200  if (data.m_Analogue[1][i] <= 0.0) {
201  float g = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S1);
202  float o = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S2);
203 
204  data.m_GainFactor[i] = 1.0f + (cosfi * g + sinfi * o);
205  //offset per channel
206  float offset_val = (cosfi * o - sinfi * g);
207  //noise factor per channel (from calib data noise per chip)
208  float noise_val = Noise * mode;
209 
210  // Fill the noise and offset values into the Analogue
212  data.m_Analogue[0][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
213  data.m_Analogue[1][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
214  } else { // Expanded
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  data.m_Analogue[2][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
218  }
219  }
220  }
221  }
222  }
223  }
224 
225  return StatusCode::SUCCESS;
226 }
227 
228 // ----------------------------------------------------------------------
229 // prepare gain and offset for the strips for a given module using
230 // Cond Db data to get the chip calibration data
231 // ----------------------------------------------------------------------
232 StatusCode SCT_FrontEnd::prepareGainAndOffset(SiChargedDiodeCollection& collection, int side, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
233  // Get chip data from calib DB
234  std::vector<float> gainByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "GainByChip");
235  std::vector<float> gainRMSByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "GainRMSByChip");
236  std::vector<float> offsetByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "OffsetByChip");
237  std::vector<float> offsetRMSByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "OffsetRMSByChip");
238  std::vector<float> noiseByChipVect(6, 0.0);
239 
240  if (m_analogueNoiseOn) { // Check if noise should be on or off
241  noiseByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "NoiseByChip");
242  }
243 
244  // Need to check if empty, most should have data, but a few old DEAD modules don't
245  if (gainByChipVect.empty() or noiseByChipVect.empty()) {
246  ATH_MSG_DEBUG("No calibration data in cond DB for module " << moduleId << " using JO values");
247  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
248  return StatusCode::FAILURE;
249  } else {
250  return StatusCode::SUCCESS;
251  }
252  }
253 
254  // Don't really need to set up values for each chip...
255  float gainMeanValue = meanValue(gainByChipVect);
256  if (gainMeanValue < 0.0) {
257  ATH_MSG_DEBUG("All chip gain values are 0 for module " << moduleId << " using JO values");
258  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
259  return StatusCode::FAILURE;
260  } else {
261  return StatusCode::SUCCESS;
262  }
263  }
264 
265  std::vector<float> gain(6, 0.0);
266  std::vector<float> offset(6, 0.0);
267  std::vector<float> S1(6, 0.0);
268  std::vector<float> S2(6, 0.0);
269  std::vector<float> sinfi(6, 0.0);
270  std::vector<float> cosfi(6, 0.0);
271  float gainRMS = 0.0;
272  float offsetRMS = 0.0;
273 
274  for (int i = 0; i < 6; ++i) {
275  // Some very few chips have 0 values, dead/bypassed/etc, so check and use some fixed values instead
276  if (gainByChipVect[i] > 0.1) {
277  gain[i] = gainByChipVect[i] / gainMeanValue;
278  offset[i] = offsetByChipVect[i] / m_Threshold;
279  gainRMS = gainRMSByChipVect[i] / gainMeanValue;
280  offsetRMS = offsetRMSByChipVect[i] / m_Threshold;
281  } else {
282  gain[i] = 55.0f / gainMeanValue;
283  offset[i] = 42.0f / m_Threshold;
284  gainRMS = 1.3f / gainMeanValue;
285  offsetRMS = 2.0f / m_Threshold;
286  }
287 
288  float W = m_OGcorr * gainRMS * offsetRMS / (gainRMS * gainRMS - offsetRMS * offsetRMS);
289  float A = 4.0f * W * W + 1.0f;
290  float x1 = (A - std::sqrt(A)) / (2.0f * A);
291  sinfi[i] = std::sqrt(x1);
292  cosfi[i] = std::sqrt(1.0f - x1);
293  sinfi[i] = sinfi[i] * m_OGcorr / std::abs(m_OGcorr);
294  float S = gainRMS * gainRMS + offsetRMS * offsetRMS;
295  float D = (gainRMS * gainRMS - offsetRMS * offsetRMS) / (cosfi[i] * cosfi[i] - sinfi[i] * sinfi[i]);
296  S1[i] = std::sqrt((S + D) / 2.0f);
297  S2[i] = std::sqrt((S - D) / 2.0f);
298  }
299 
300  // Loop over collection and setup gain/offset/noise for the hit and neighbouring strips
301  SiChargedDiodeIterator i_chargedDiode = collection.begin();
302  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
303 
304  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
305  SiChargedDiode diode = (*i_chargedDiode).second;
306  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
307  unsigned int flagmask = diode.flag() & 0xFE;
308  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
309  if (!flagmask) { // If the diode is OK (not flagged)
310  const SiReadoutCellId roCell = diode.getReadoutCell();
311 
312  if (roCell.isValid()) {
313  int strip = roCell.strip();
314  int i = std::max(strip - 1, 0);
315  int i_end = std::min(strip + 2, strip_max);
316 
317  // loop over strips
318  for (; i < i_end; i++) {
319  // Need to check if strip is already setup
320  if (data.m_Analogue[1][i] <= 0.0) {
321  // Values depends on which chip the strip is on (complex when strip is on chip edge)
322  int chip = i / 128;
323  float g = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S1[chip]);
324  float o = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, S2[chip]);
325 
326  data.m_GainFactor[i] = gain[chip] + (cosfi[chip] * g + sinfi[chip] * o);
327  //offset per channel
328  float offset_val = offset[chip] + (cosfi[chip] * o - sinfi[chip] * g);
329  //noise factor per channel (from calib data noise per chip)
330  float noise_val = noiseByChipVect[chip];
331 
332  // Fill the noise and offset values into the Analogue
334  data.m_Analogue[0][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
335  data.m_Analogue[1][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
336  } else { // Expanded
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  data.m_Analogue[2][i] = offset_val + noise_val * CLHEP::RandGaussZiggurat::shoot(rndmEngine);
340  }
341  }
342  }
343  }
344  }
345  }
346 
347  return StatusCode::SUCCESS;
348 }
349 
350 // ----------------------------------------------------------------------
351 //
352 // ----------------------------------------------------------------------
353 StatusCode SCT_FrontEnd::randomNoise(SiChargedDiodeCollection& collection, const Identifier& moduleId, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
354  // Add random noise
355 
356  double occupancy = 0.0;
357  double NoiseOccupancy = 0.0;
358  float Noise = 0.0;
359  int nNoisyStrips = 0;
360  double mode = 1.;
361 
362  const bool noise_expanded_mode = (m_data_compression_mode == AnyHit_1XX_X1X_XX1 and m_data_readout_mode == Expanded);
363 
364  // Will give 3 times as much noise occupancy if running in any hit expanded mode
365  if (noise_expanded_mode) {
366  mode = 3.;
367  }
368 
369  // Sets fixed noise occupancy values for different module types, barrel, EC,
370  // inners, middles
371  // short middles, and outers
372  if (m_sct_id->barrel_ec(moduleId) == 0) { // barrel_ec=0 corresponds to barrel
373  if (m_sct_id->layer_disk(moduleId) == 3) { // outer barrel layer 10 degrees warmer
374  NoiseOccupancy = m_NOBarrel3;
375  Noise = m_NoiseBarrel3;
376  } else {
377  NoiseOccupancy = m_NOBarrel;
378  Noise = m_NoiseBarrel;
379  }
380  } else {
381  int moduleType = m_sct_id->eta_module(moduleId);
382  switch (moduleType) { // eta = 0, 1, or 2 corresponds to outers, middles and inners?! (at least in the offline world)
383  case 0: {
384  NoiseOccupancy = m_NOOuters;
385  Noise = m_NoiseOuters;
386  break;
387  }
388  case 1: {
389  if (m_sct_id->layer_disk(moduleId) == 7) {
390  NoiseOccupancy = m_NOShortMiddles;
391  Noise = m_NoiseShortMiddles;
392  } else {
393  NoiseOccupancy = m_NOMiddles;
394  Noise = m_NoiseMiddles;
395  }
396  break;
397  }
398  case 2: {
399  NoiseOccupancy = m_NOInners;
400  Noise = m_NoiseInners;
401  break;
402  }
403  default: {
404  NoiseOccupancy = m_NOBarrel;
405  Noise = m_NoiseBarrel;
406  ATH_MSG_ERROR("moduleType(eta): " << moduleType << " unknown, using barrel");
407  }
408  }// end of switch structure
409  }
410 
411  // Calculate the number of "free strips"
412  int nEmptyStrips = 0;
413  std::vector<int> emptyStrips;
414  emptyStrips.reserve(strip_max);
415  for (int i = 0; i < strip_max; i++) {
416  if (data.m_StripHitsOnWafer[i] == 0) {
417  emptyStrips.push_back(i);
418  ++nEmptyStrips;
419  }
420  }
421 
422  if (nEmptyStrips != 0) {
423  // Should randomize the fixed NO values, so we get some differences per
424  // wafer
425  occupancy = CLHEP::RandGaussZiggurat::shoot(rndmEngine, NoiseOccupancy, NoiseOccupancy * 0.1);
426 
427  // Modify the occupancy if threshold is not 1.0 fC
428  if (m_Threshold > 6242.3 or m_Threshold < 6242.1) {
429  const float fC = 6242.2;
430  occupancy = occupancy * exp(-(0.5 / (Noise * Noise) * (m_Threshold * m_Threshold - fC * fC)));
431  }
432  nNoisyStrips = CLHEP::RandPoisson::shoot(rndmEngine, strip_max * occupancy * mode);
433 
434  // Check and adapt the number of noisy strips to the number of free strips
435  if (nEmptyStrips < nNoisyStrips) {
436  nNoisyStrips = nEmptyStrips;
437  }
438 
439  // Find random strips to get noise hits
440  for (int i = 0; i < nNoisyStrips; i++) {
441  int index = CLHEP::RandFlat::shootInt(rndmEngine, nEmptyStrips - i); // strip == 10, 12 free strips
442  // have vector [10000100100200211001] 20 strips
443  int strip = emptyStrips.at(index);
444  emptyStrips.erase(emptyStrips.begin()+index); // Erase it not to use it again
445  if (data.m_StripHitsOnWafer[strip]!=0) {
446  ATH_MSG_ERROR(index << "-th empty strip, strip " << strip << " should be empty but is not empty! Something is wrong!");
447  }
448  data.m_StripHitsOnWafer[strip] = 3; // !< Random Noise hit
449  // Add tbin info to noise diode
450  if (noise_expanded_mode) { // !< if any hit mode, any time bin otherwise fixed tbin=2
451  int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
452  // !< random number 0, 1 or 2
453  if (noise_tbin == 0) {
454  noise_tbin = 4; // !< now 1,2 or 4
455  }
456  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, noise_tbin)) {
457  ATH_MSG_ERROR("Can't add noise hit diode to collection (1)");
458  }
459  } else {
460  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
461  ATH_MSG_ERROR("Can't add noise hit diode to collection (2)");
462  }
463  }
464  }
465  }
466 
467  return StatusCode::SUCCESS;
468 }
469 
470 // ----------------------------------------------------------------------
471 //
472 // ----------------------------------------------------------------------
473 StatusCode SCT_FrontEnd::randomNoise(SiChargedDiodeCollection& collection, const Identifier& moduleId, int side, CLHEP::HepRandomEngine * rndmEngine, SCT_FrontEndData& data, const int& strip_max) const {
474  const int n_chips = 6;
475  const int chipStripmax = strip_max / n_chips;
476  std::vector<float> NOByChipVect(n_chips, 0.0);
477  std::vector<float> ENCByChipVect(n_chips, 0.0);
478  std::vector<int> nNoisyStrips(n_chips, 0);
479  double mode = 1.;
480 
481  const bool noise_expanded_mode = (m_data_compression_mode == AnyHit_1XX_X1X_XX1 and m_data_readout_mode == Expanded);
482 
483  // Will give 3 times as much noise occupancy if running in any hit expanded mode
484  if (noise_expanded_mode) {
485  mode = 3.;
486  }
487 
488  // Get chip data from calib DB
489  NOByChipVect = m_ReadCalibChipDataTool->getNoiseOccupancyData(moduleId, side, "OccupancyByChip");
490  ENCByChipVect = m_ReadCalibChipDataTool->getNPtGainData(moduleId, side, "NoiseByChip");
491 
492  // Need to check if empty, most should have data, but a few old DEAD modules don't, and 9C...
493  if (NOByChipVect.empty()) {
494  ATH_MSG_DEBUG("No calibration data in cond DB for module " << moduleId << " using JO values");
495  if (StatusCode::SUCCESS != randomNoise(collection, moduleId, rndmEngine, data,strip_max)) {
496  return StatusCode::FAILURE;
497  } else {
498  return StatusCode::SUCCESS;
499  }
500  } else {
501  for (int i = 0; i < n_chips; i++) {
502  // A 0 value can mean two things now, chip out of config for long time and no value was uploaded
503  // or its short middles and inners and the value is for all purposes 0! so ok.
504 
505  // Modify the occupancy if threshold is not 1.0 fC
506  if (m_Threshold > 6242.3 or m_Threshold < 6242.1) {
507  constexpr float fC = 6242.2;
508  NOByChipVect[i] = NOByChipVect[i] * exp(-(0.5 / (ENCByChipVect[i]*ENCByChipVect[i]) * (m_Threshold*m_Threshold - fC*fC)));
509  }
510 
511  nNoisyStrips[i] = CLHEP::RandPoisson::shoot(rndmEngine, chipStripmax * NOByChipVect[i] * mode);
512  }
513  }
514 
515  // Loop over the chips on the wafer
516  for (int chip_index = 0; chip_index < n_chips; ++chip_index) {
517  int chip_strip_offset = chipStripmax * chip_index; // First strip number on chip
518 
519  // Calculate the number of "free strips" on this chip
520  int nEmptyStripsOnChip = 0;
521  std::vector<int> emptyStripsOnChip;
522  emptyStripsOnChip.reserve(chipStripmax);
523  for (int i = 0; i < chipStripmax; i++) {
524  if (data.m_StripHitsOnWafer[i + chip_strip_offset] == 0) {
525  emptyStripsOnChip.push_back(i);
526  ++nEmptyStripsOnChip;
527  }
528  }
529 
530  // if no empty strips on chip do nothing
531  if (nEmptyStripsOnChip != 0) {
532  // Check and adapt the number of noisy strips to the number of free strips
533  if (nEmptyStripsOnChip < nNoisyStrips[chip_index]) {
534  nNoisyStrips[chip_index] = nEmptyStripsOnChip;
535  }
536 
537  // Find random strips to get noise hits
538  for (int i = 0; i < nNoisyStrips[chip_index]; i++) {
539  int index = CLHEP::RandFlat::shootInt(rndmEngine, nEmptyStripsOnChip - i);
540  int strip_on_chip = emptyStripsOnChip.at(index);
541  emptyStripsOnChip.erase(emptyStripsOnChip.begin()+index); // Erase it not to use it again
542  int strip = strip_on_chip + chip_strip_offset;
543  if (data.m_StripHitsOnWafer[strip]!=0) {
544  ATH_MSG_ERROR(index << "-th empty strip, strip " << strip << " should be empty but is not empty! Something is wrong!");
545  }
546  data.m_StripHitsOnWafer[strip] = 3; // !< Random Noise hit
547  // Add tbin info to noise diode
548  if (noise_expanded_mode) { // !< if any hit mode, any time bin
549  // !< otherwise fixed tbin=2
550  int noise_tbin = CLHEP::RandFlat::shootInt(rndmEngine, 3);
551  // !< random number 0, 1 or 2
552  if (noise_tbin == 0) {
553  noise_tbin = 4; // !< now 1, 2 or 4
554  }
555  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, noise_tbin)) {
556  ATH_MSG_ERROR("Can't add noise hit diode to collection (3)");
557  }
558  } else {
559  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
560  ATH_MSG_ERROR("Can't add noise hit diode to collection (4)");
561  }
562  }
563  }
564  }
565  }
566 
567  return StatusCode::SUCCESS;
568 }
569 
570 // ----------------------------------------------------------------------
571 // process the collection of pre digits this will need to go through
572 // all single-strip pre-digits calculate the amplifier response add noise
573 // (this could be moved elsewhere later) apply threshold do clustering
574 // ----------------------------------------------------------------------
575 void SCT_FrontEnd::process(SiChargedDiodeCollection& collection, CLHEP::HepRandomEngine * rndmEngine) const {
576  // get SCT module side design
577  const SCT_ModuleSideDesign *p_design = static_cast<const SCT_ModuleSideDesign*>(&(collection.design()));
578 
580 
581  // Check number of strips in design and from manager(max number of strips on any module)
582  // The design value should always be equal or lower than the manager one
583  // However, no resizing is now done in case of a lower value
584  const int strip_max = p_design->cells();
585  // Init vectors
586  if (StatusCode::SUCCESS != initVectors(strip_max, data)) {
587  ATH_MSG_ERROR("Can't resize class variable vectors");
588  return;
589  }
590 
591  // Contains strip hit info, reset to 0 for each wafer processed
592  data.m_StripHitsOnWafer.assign(strip_max, 0);
593 
594  // data.m_Analogue contains the charge for each bin on each hit strip
595  // These vectors were cleared in initVectors().
596 
597  // Get wafer, moduleId and side
598  Identifier waferId = collection.identify();
599  Identifier moduleId = m_sct_id->module_id(waferId);
600  const int side = m_sct_id->side(waferId);
601 
602  // Check if collection empty
603  if (not collection.empty()) {
604  // Setup gain/offset/noise to the hit and neighbouring strips
605  if (m_useCalibData) { // Use calib cond DB data
606  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, side, moduleId, rndmEngine, data, strip_max)) {
607  ATH_MSG_ERROR("\tCan't prepare Gain and Offset");
608  }
609  } else { // Use JO values
610  if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data,strip_max)) {
611  ATH_MSG_ERROR("\tCan't prepare Gain and Offset");
612  }
613  }
614 
615  if (StatusCode::SUCCESS != doSignalChargeForHits(collection, data, strip_max)) {
616  ATH_MSG_ERROR("\tCan't doSignalChargeForHits");
617  }
618 
619  if (StatusCode::SUCCESS != doThresholdCheckForRealHits(collection, data, strip_max)) {
620  ATH_MSG_ERROR("\tCan't doThresholdCheckForRealHits");
621  }
622 
623  if (StatusCode::SUCCESS != doThresholdCheckForCrosstalkHits(collection, data, strip_max)) {
624  ATH_MSG_ERROR("\tCan't doThresholdCheckForCrosstalkHits");
625  }
626  }
627 
628  if (m_NoiseOn) {
629  if (m_useCalibData) { // Check if using DB or not
630  if (StatusCode::SUCCESS != randomNoise(collection, moduleId, side, rndmEngine, data, strip_max)) {
631  ATH_MSG_ERROR("\tCan't do random noise on wafer?!");
632  }
633  } else { // Use JO fixed values
634  if (StatusCode::SUCCESS != randomNoise(collection, moduleId, rndmEngine, data,strip_max)) {
635  ATH_MSG_ERROR("\tCan't do random noise on wafer?!");
636  }
637  }
638  }
639 
640  // Check for strips above threshold and do clustering
641  if (StatusCode::SUCCESS != doClustering(collection, data,strip_max)) {
642  ATH_MSG_ERROR("\tCan't cluster the hits?!");
643  }
644 }
645 
647  using list_t = SiTotalCharge::list_t;
648 
649  // *****************************************************************************
650  // Loop over the diodes (strips ) and for each of them define the total signal
651  // *****************************************************************************
652 
653  // set up number of needed bins depending on the compression mode
654  short bin_max = 0;
656  bin_max = m_data_compression_mode;
657  } else {
658  bin_max = 3;
659  }
660 
661  std::vector<float> response(bin_max);
662 
663  SiChargedDiodeIterator i_chargedDiode = collection.begin();
664  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
665  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
666  SiChargedDiode diode = (*i_chargedDiode).second;
667  // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
668  unsigned int flagmask = diode.flag() & 0xFE;
669  // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
670  if (!flagmask) { // If the diode is OK (not flagged)
671  const SiReadoutCellId roCell = diode.getReadoutCell();
672 
673  if (roCell.isValid()) {
674  int strip = roCell.strip();
675 
676  const list_t &ChargesOnStrip = diode.totalCharge().chargeComposition();
677 
679  // Amplifier response
680  m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
681  for (short bin = 0; bin < bin_max; ++bin) {
682  data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
683  }
684  // Add Crosstalk signal for neighboring strip
685  m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
686  for (short bin = 0; bin < bin_max; ++bin) {
687  if (strip + 1 < strip_max) {
688  data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
689  }
690  if (strip > 0) {
691  data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
692  }
693  }
694  } else { // Expanded
695  // Amplifier response
696  m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
697  for (short bin = 0; bin < bin_max; ++bin) {
698  data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
699  }
700  // Add Crosstalk signal for neighboring strip
701  m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
702  for (short bin = 0; bin < bin_max; ++bin) {
703  if (strip + 1 < strip_max) {
704  data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
705  }
706  if (strip > 0) {
707  data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
708  }
709  }
710  }
711  } else { // if roCell not valid
712  ATH_MSG_WARNING("\t Cannot get the cell ");
713  }
714  } else {// If diode is disconnected/disabled skip it
715  ATH_MSG_WARNING("\tDisabled or disconnected diode (strip)");
716  }
717  }
718  return StatusCode::SUCCESS;
719 }
720 
722  // **********************************************************************************
723  // Flag strips below threshold and flag the threshold check into data.m_StripHitsOnWafer
724  // **********************************************************************************
725 
726  SiChargedDiodeIterator i_chargedDiode = collection.begin();
727  SiChargedDiodeIterator i_chargedDiode_end = collection.end();
728 
729  for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) {
730  SiChargedDiode& diode = (*i_chargedDiode).second;
731  SiReadoutCellId roCell = diode.getReadoutCell();
732  if (roCell.isValid()) {
733  int strip = roCell.strip();
734  if (strip > -1 and strip < strip_max) {
736  if ((data.m_Analogue[0][strip] >= m_Threshold or data.m_Analogue[1][strip] < m_Threshold)) {
737  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
738  data.m_StripHitsOnWafer[strip] = -1;
739  } else if (((0x10 & diode.flag()) == 0x10) or ((0x4 & diode.flag()) == 0x4)) {
740  // previously a crazy strip number could have screwed things up here.
741  data.m_StripHitsOnWafer[strip] = -1;
742  } else {
743  data.m_StripHitsOnWafer[strip] = 1;
744  SiHelper::SetTimeBin(diode, 2, &msg()); // set timebin info
745  }
746  } else { // Expanded
747  int have_hit_bin = 0;
748  if (data.m_Analogue[0][strip] >= m_Threshold) {
749  have_hit_bin = 4;
750  }
751  if (data.m_Analogue[1][strip] >= m_Threshold) {
752  have_hit_bin += 2;
753  }
754  if (data.m_Analogue[2][strip] >= m_Threshold) {
755  have_hit_bin += 1;
756  }
757  if (((0x10 & diode.flag()) == 0x10) || ((0x4 & diode.flag()) == 0x4)) {
758  // previously a crazy strip number could have screwed things up here.
759  data.m_StripHitsOnWafer[strip] = -1;
760  } else if (m_data_compression_mode == Level_X1X) { // !< level and expanded mode
761  if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
762  data.m_StripHitsOnWafer[strip] = 1;
763  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
764  } else {
765  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
766  data.m_StripHitsOnWafer[strip] = -1;
767  }
768  } else if (m_data_compression_mode == Edge_01X) { // !< edge and expanded mode
769  if (have_hit_bin == 2 or have_hit_bin == 3) {
770  data.m_StripHitsOnWafer[strip] = 1;
771  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
772  } else {
773  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
774  data.m_StripHitsOnWafer[strip] = -1;
775  }
776  } else if (m_data_compression_mode == AnyHit_1XX_X1X_XX1) { // !< any hit mode
777  if (have_hit_bin == 0) {
778  SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
779  data.m_StripHitsOnWafer[strip] = -1;
780  } else {
781  data.m_StripHitsOnWafer[strip] = 1;
782  if (m_data_readout_mode == Expanded) { // !< check for exp mode or not
783  SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
784  } else {
785  SiHelper::SetTimeBin(diode, 2, &msg());
786  }
787  }
788  }
789  }
790  }
791  }
792  }
793  return StatusCode::SUCCESS;
794 }
795 
796 // ----------------------------------------------------------------------
797 //
798 // ----------------------------------------------------------------------
800  // Check for noise+crosstalk strips above threshold
801  // data.m_StripHitsOnWafer: real hits above threshold == 1 or below/disconnected
802  // == -1
803  // =0 for free strips or strips with charge to be checked (data.m_Analogue[1]!=0)
804  // Set 2 for crosstalk noise hits and -2 for below ones
805 
806  for (int strip = 0; strip < strip_max; strip++) {
807  // Find strips with data.m_StripHitsOnWafer[strip] == 0
808  if (data.m_StripHitsOnWafer[strip] != 0) { // real hits already checked
809  continue;
810  }
811  if (data.m_Analogue[1][strip] > 0) { // Better way of doing this?!
812  // set data.m_StripHitsOnWafer to x in prepareGainAndOffset
814  if ((data.m_Analogue[0][strip] >= m_Threshold or data.m_Analogue[1][strip] < m_Threshold)) {
815  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
816  } else {
817  data.m_StripHitsOnWafer[strip] = 2; // Crosstalk+Noise hit
818  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
819 
820  ATH_MSG_ERROR("Can't add noise hit diode to collection (5)");
821  }
822  }
823  } else { // Expanded
824  int have_hit_bin = 0;
825  if (data.m_Analogue[0][strip] >= m_Threshold) {
826  have_hit_bin = 4;
827  }
828  if (data.m_Analogue[1][strip] >= m_Threshold) {
829  have_hit_bin += 2;
830  }
831  if (data.m_Analogue[2][strip] >= m_Threshold) {
832  have_hit_bin += 1;
833  }
834  if (m_data_compression_mode == Level_X1X) { // !< level and expanded mode
835  if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
836  data.m_StripHitsOnWafer[strip] = 2; // Crosstalk+Noise hit
837  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
838  ATH_MSG_ERROR("Can't add noise hit diode to collection (6)");
839  }
840  } else {
841  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
842  }
843  } else if (m_data_compression_mode == Edge_01X) { // !< edge and expanded mode
844  if (have_hit_bin == 2 or have_hit_bin == 3) {
845  data.m_StripHitsOnWafer[strip] = 2; // Noise hit
846  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
847  ATH_MSG_ERROR("Can't add noise hit diode to collection (7)");
848  }
849  } else {
850  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
851  }
852  } else if (m_data_compression_mode == AnyHit_1XX_X1X_XX1) { // !< any hit mode
853  if (have_hit_bin == 0) {
854  data.m_StripHitsOnWafer[strip] = -2; // Below threshold
855  } else {
856  data.m_StripHitsOnWafer[strip] = 2; // !< Crosstalk+Noise hit
857  if (m_data_readout_mode == Expanded) { // !< check for exp mode or not
858  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, have_hit_bin)) {
859  ATH_MSG_ERROR("Can't add noise hit diode to collection (8)");
860  }
861  } else {
862  if (StatusCode::SUCCESS != addNoiseDiode(collection, strip, 2)) {
863  ATH_MSG_ERROR("Can't add noise hit diode to collection (9)");
864  }
865  }
866  }
867  }
868  }
869  }
870  }
871 
872  return StatusCode::SUCCESS;
873 }
874 
876  // ********************************
877  // now do clustering
878  // ********************************
879  int strip = 0;
880  int clusterSize = 0;
881 
882  const SCT_ModuleSideDesign& sctDesign = static_cast<const SCT_ModuleSideDesign&>(collection.design());
883 
884  SiCellId hitStrip;
885 
887  do {
888  if (data.m_StripHitsOnWafer[strip] > 0) {
889  // ====== First step: Get the cluster size
890  // ===================================================
891  int clusterFirstStrip = strip;
892 
893  // Find end of cluster. In multi-row sensors, cluster cannot span rows.
894  int row = sctDesign.row(strip);
895  if (row < 0) {
896  row = 0;
897  }
898 
899  int lastStrip1DInRow = 0;
900  for (int i = 0; i < row + 1; ++i) {
901  lastStrip1DInRow += sctDesign.diodesInRow(i);
902  }
903 
904  while (strip < lastStrip1DInRow-1 and data.m_StripHitsOnWafer[strip +1] > 0) {
905  ++strip; // !< Find first strip hit and add up the following strips
906  }
907  int clusterLastStrip = strip;
908 
909  clusterSize = (clusterLastStrip - clusterFirstStrip) + 1;
910  hitStrip = SiCellId(clusterFirstStrip);
911  SiChargedDiode& HitDiode = *(collection.find(hitStrip));
912  SiHelper::SetStripNum(HitDiode, clusterSize, &msg());
913 
914  SiChargedDiode *PreviousHitDiode = &HitDiode;
915  for (int i = clusterFirstStrip+1; i <= clusterLastStrip; ++i) {
916  hitStrip = SiCellId(i);
917  SiChargedDiode& HitDiode2 = *(collection.find(hitStrip));
918  SiHelper::ClusterUsed(HitDiode2, true);
919  PreviousHitDiode->setNextInCluster(&HitDiode2);
920  PreviousHitDiode = &HitDiode2;
921  }
922  }
923  ++strip; // !< This is the starting point of the next cluster within this collection
924  } while (strip < strip_max);
925  } else {
926  // Expanded read out mode, basically one RDO/strip per cluster
927  // But if consecutively fired strips have the same time bin, those are converted into one cluster.
928  do {
929  clusterSize = 1;
930  if (data.m_StripHitsOnWafer[strip] > 0) {
931  hitStrip = SiCellId(strip);
932  SiChargedDiode& hitDiode = *(collection.find(hitStrip));
933  int timeBin = SiHelper::GetTimeBin(hitDiode);
934  SiChargedDiode* previousHitDiode = &hitDiode;
935  // Check if consecutively fired strips have the same time bin
936  for (int newStrip=strip+1; newStrip<strip_max; newStrip++) {
937  if (not (data.m_StripHitsOnWafer[newStrip]>0)) break;
938  SiCellId newHitStrip = SiCellId(newStrip);
939  SiChargedDiode& newHitDiode = *(collection.find(newHitStrip));
940  if (timeBin!=SiHelper::GetTimeBin(newHitDiode)) break;
941  SiHelper::ClusterUsed(newHitDiode, true);
942  previousHitDiode->setNextInCluster(&newHitDiode);
943  previousHitDiode = &newHitDiode;
944  clusterSize++;
945  }
946  SiHelper::SetStripNum(hitDiode, clusterSize, &msg());
947 
948 #ifdef SCT_DIG_DEBUG
949  ATH_MSG_DEBUG("RDO Strip = " << strip << ", tbin = " <<
950  SiHelper::GetTimeBin(hitDiode) <<
951  ", HitInfo(1=real, 2=crosstalk, 3=noise): " <<
952  data.m_StripHitsOnWafer[strip]);
953 #endif
954  }
955  strip += clusterSize; // If more than one strip fires, those following strips are skipped.
956  } while (strip < strip_max);
957  }
958 
959  // clusters below threshold, only from pre-digits that existed before no
960  // pure noise clusters below threshold will be made
961  // D. Costanzo. I don't see why we should cluster the strips below
962  // threshold. I'll pass on the info of strips below threshold
963  // to the SDOs. I'll leave the SCT experts the joy to change this if they
964  // don't like what I did or if this requires too much memory/disk
965 
966  return StatusCode::SUCCESS;
967 }
968 
969 StatusCode SCT_FrontEnd::addNoiseDiode(SiChargedDiodeCollection& collection, int strip, int tbin) const {
970  const SiCellId ndiode(strip); // !< create a new diode
971  const SiCharge noiseCharge(2 * m_Threshold, 0, SiCharge::noise); // !< add some noise to it
972  collection.add(ndiode, noiseCharge); // !< add it to the collection
973 
974  // Get the strip back to check
975  SiChargedDiode *NoiseDiode = (collection.find(strip));
976  if (NoiseDiode == nullptr) {
977  return StatusCode::FAILURE;
978  }
979  SiHelper::SetTimeBin(*NoiseDiode, tbin, &msg()); // set timebin info
980  return StatusCode::SUCCESS;
981 }
982 
983 float SCT_FrontEnd::meanValue(std::vector<float>& calibDataVect) {
984  float mean_value = 0.0;
985  int nData = 0;
986  const unsigned int vec_size = calibDataVect.size();
987 
988  for (unsigned int i = 0; i < vec_size; ++i) {
989  if (calibDataVect[i] > 0.1) {
990  mean_value += calibDataVect[i];
991  ++nData;
992  }
993  }
994 
995  if (nData == 0) {
996  return -1;
997  } else {
998  return mean_value / nData;
999  }
1000 }
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:353
SiHelper.h
SiChargedDiode
Definition: SiChargedDiode.h:30
SiliconTech::strip
@ strip
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:983
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:575
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
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
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
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
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:129
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
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
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:969
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Preparation.mode
mode
Definition: Preparation.py:107
hist_file_dump.f
f
Definition: hist_file_dump.py:141
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
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:240
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:799
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:721
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
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:646
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:875
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