CMS 3D CMS Logo

Phase2TrackerDigitizerAlgorithm.cc
Go to the documentation of this file.
1 #include<typeinfo>
2 #include <iostream>
3 #include <cmath>
4 
6 
10 
12 #include "CLHEP/Random/RandGaussQ.h"
13 #include "CLHEP/Random/RandFlat.h"
14 
15 //#include "PixelIndices.h"
20 
26 
41 
48 
49 // Geometry
54 
56 using namespace edm;
57 using namespace sipixelobjects;
58 
60  const edm::ParameterSet& conf_specific):
61  _signal(),
62  makeDigiSimLinks_(conf_common.getUntrackedParameter<bool>("makeDigiSimLinks", true)),
63  use_ineff_from_db_(conf_specific.getParameter<bool>("Inefficiency_DB")),
64  use_module_killing_(conf_specific.getParameter<bool>("KillModules")), // boolean to kill or not modules
65  use_deadmodule_DB_(conf_specific.getParameter<bool>("DeadModules_DB")), // boolean to access dead modules from DB
66  use_LorentzAngle_DB_(conf_specific.getParameter<bool>("LorentzAngle_DB")), // boolean to access Lorentz angle from DB
67 
68  DeadModules(use_deadmodule_DB_ ? Parameters() : conf_specific.getParameter<Parameters>("DeadModules")), // get dead module from cfg file
69 
70  // Common pixel parameters
71  // These are parameters which are not likely to be changed
72  GeVperElectron(3.61E-09), // 1 electron(3.61eV, 1keV(277e, mod 9/06 d.k.
73  alpha2Order(conf_specific.getParameter<bool>("Alpha2Order")), // switch on/off of E.B effect
74  addXtalk(conf_specific.getParameter<bool>("AddXTalk")),
75  interstripCoupling(conf_specific.getParameter<double>("InterstripCoupling")), // Interstrip Coupling - Not used in PixelDigitizerAlgorithm
76 
77  Sigma0(conf_specific.getParameter<double>("SigmaZero")), // Charge diffusion constant 7->3.7
78  SigmaCoeff(conf_specific.getParameter<double>("SigmaCoeff")), // delta in the diffusion across the strip pitch
79  // (set between 0 to 0.9, 0-->flat Sigma0, 1-->Sigma_min=0 & Sigma_max=2*Sigma0
80  // D.B.: Dist300 replaced by moduleThickness, may not work with partially depleted sensors but works otherwise
81  // Dist300(0.0300), // normalized to 300micron Silicon
82 
83  ClusterWidth(conf_specific.getParameter<double>("ClusterWidth")), // Charge integration spread on the collection plane
84 
85  // Allowed modes of readout which has following values :
86  // 0 ---> Digital or binary readout
87  // -1 ---> Analog readout, current digitizer (Inner Pixel) (TDR version) with no threshold subtraction
88  // Analog readout with dual slope with the "second" slope being 1/2^(n-1) and threshold subtraction (n = 1, 2, 3,4)
89  thePhase2ReadoutMode(conf_specific.getParameter<int>("Phase2ReadoutMode")),
90 
91  // ADC calibration 1adc count(135e.
92  // Corresponds to 2adc/kev, 270[e/kev]/135[e/adc](2[adc/kev]
93  // Be careful, this parameter is also used in SiPixelDet.cc to
94  // calculate the noise in adc counts from noise in electrons.
95  // Both defaults should be the same.
96  theElectronPerADC(conf_specific.getParameter<double>("ElectronPerAdc")),
97 
98  // ADC saturation value, 255(8bit adc.
99  theAdcFullScale(conf_specific.getParameter<int>("AdcFullScale")),
100 
101  // Noise in electrons:
102  // Pixel cell noise, relevant for generating noisy pixels
103  theNoiseInElectrons(conf_specific.getParameter<double>("NoiseInElectrons")),
104 
105  // Fill readout noise, including all readout chain, relevant for smearing
106  theReadoutNoise(conf_specific.getParameter<double>("ReadoutNoiseInElec")),
107 
108  // Threshold in units of noise:
109  // thePixelThreshold(conf.getParameter<double>("ThresholdInNoiseUnits")),
110  // Pixel threshold in electron units.
111  theThresholdInE_Endcap(conf_specific.getParameter<double>("ThresholdInElectrons_Endcap")),
112  theThresholdInE_Barrel(conf_specific.getParameter<double>("ThresholdInElectrons_Barrel")),
113 
114  // Add threshold gaussian smearing:
115  theThresholdSmearing_Endcap(conf_specific.getParameter<double>("ThresholdSmearing_Endcap")),
116  theThresholdSmearing_Barrel(conf_specific.getParameter<double>("ThresholdSmearing_Barrel")),
117 
118  // Add HIP Threshold in electron units.
119  theHIPThresholdInE_Endcap(conf_specific.getParameter<double>("HIPThresholdInElectrons_Endcap")),
120  theHIPThresholdInE_Barrel(conf_specific.getParameter<double>("HIPThresholdInElectrons_Barrel")),
121 
122  // theTofCut 12.5, cut in particle TOD +/- 12.5ns
123  theTofLowerCut(conf_specific.getParameter<double>("TofLowerCut")),
124  theTofUpperCut(conf_specific.getParameter<double>("TofUpperCut")),
125 
126  // Get the Lorentz angle from the cfg file:
127  tanLorentzAnglePerTesla_Endcap(use_LorentzAngle_DB_ ? 0.0 : conf_specific.getParameter<double>("TanLorentzAnglePerTesla_Endcap")),
128  tanLorentzAnglePerTesla_Barrel(use_LorentzAngle_DB_ ? 0.0 : conf_specific.getParameter<double>("TanLorentzAnglePerTesla_Barrel")),
129 
130  // Add noise
131  addNoise(conf_specific.getParameter<bool>("AddNoise")),
132 
133  // Add noisy pixels
134  addNoisyPixels(conf_specific.getParameter<bool>("AddNoisyPixels")),
135 
136  // Fluctuate charge in track subsegments
137  fluctuateCharge(conf_specific.getUntrackedParameter<bool>("FluctuateCharge",true)),
138 
139  // Control the pixel inefficiency
140  AddPixelInefficiency(conf_specific.getParameter<bool>("AddInefficiency")),
141 
142  // Add threshold gaussian smearing:
143  addThresholdSmearing(conf_specific.getParameter<bool>("AddThresholdSmearing")),
144 
145  // Add some pseudo-red damage
146  pseudoRadDamage(conf_specific.exists("PseudoRadDamage")?conf_specific.getParameter<double>("PseudoRadDamage"):double(0.0)),
147  pseudoRadDamageRadius(conf_specific.exists("PseudoRadDamageRadius")?conf_specific.getParameter<double>("PseudoRadDamageRadius"):double(0.0)),
148 
149  // delta cutoff in MeV, has to be same as in OSCAR(0.030/cmsim=1.0 MeV
150  // tMax(0.030), // In MeV.
151  // tMax(conf.getUntrackedParameter<double>("DeltaProductionCut",0.030)),
152  tMax(conf_common.getParameter<double>("DeltaProductionCut")),
153 
154  badPixels(conf_specific.getParameter<std::vector<edm::ParameterSet> >("CellsToKill")),
155  fluctuate(fluctuateCharge ? new SiG4UniversalFluctuation() : nullptr),
156  theNoiser(addNoise ? new GaussianTailNoiseGenerator() : nullptr),
157  theSiPixelGainCalibrationService_(use_ineff_from_db_ ? new SiPixelGainCalibrationOfflineSimService(conf_specific) : nullptr),
158  subdetEfficiencies_(conf_specific)
159 {
160 
161  LogInfo("Phase2TrackerDigitizerAlgorithm") << "Phase2TrackerDigitizerAlgorithm constructed\n"
162  << "Configuration parameters:\n"
163  << "Threshold/Gain = "
164  << "threshold in electron Endcap = "
166  << "\nthreshold in electron Barrel = "
168  << " ElectronPerADC " << theElectronPerADC
169  << " ADC Scale (in bits) " << theAdcFullScale
170  << " The delta cut-off is set to " << tMax
171  << " pix-inefficiency " << AddPixelInefficiency;
172 }
173 
175  LogDebug("Phase2TrackerDigitizerAlgorithm") << "Phase2TrackerDigitizerAlgorithm deleted";
176 }
177 
179  barrel_efficiencies = conf.getParameter< std::vector<double> >("EfficiencyFactors_Barrel");
180  endcap_efficiencies = conf.getParameter< std::vector<double> >("EfficiencyFactors_Endcap");
181 }
182 // =================================================================
183 //
184 // Generate primary ionization along the track segment.
185 // Divide the track into small sub-segments
186 //
187 // =================================================================
189  std::vector<DigitizerUtility::EnergyDepositUnit>& ionization_points) const {
190  // Straight line approximation for trajectory inside active media
191  const float SegmentLength = 0.0010; // in cm (10 microns)
192  float energy;
193 
194  // Get the 3D segment direction vector
195  LocalVector direction = hit.exitPoint() - hit.entryPoint();
196 
197  float eLoss = hit.energyLoss(); // Eloss in GeV
198  float length = direction.mag(); // Track length in Silicon
199 
200  int NumberOfSegments = int (length / SegmentLength); // Number of segments
201  if (NumberOfSegments < 1) NumberOfSegments = 1;
202  LogDebug("Phase2TrackerDigitizerAlgorithm")
203  << "enter primary_ionzation " << NumberOfSegments
204  << " shift = "
205  << hit.exitPoint().x() - hit.entryPoint().x() << " "
206  << hit.exitPoint().y() - hit.entryPoint().y() << " "
207  << hit.exitPoint().z() - hit.entryPoint().z() << " "
208  << hit.particleType()
209  << " " << hit.pabs();
210 
211  std::vector<float> elossVector; // Eloss vector
212  elossVector.reserve(NumberOfSegments);
213  if (fluctuateCharge) {
214  int pid = hit.particleType();
215  // int pid=211; // assume it is a pion
216 
217  float momentum = hit.pabs();
218  // Generate fluctuated charge points
219  fluctuateEloss(pid, momentum, eLoss, length, NumberOfSegments, elossVector);
220  }
221  ionization_points.reserve(NumberOfSegments); // set size
222 
223  // loop over segments
224  for (int i = 0; i != NumberOfSegments; ++i) {
225  // Divide the segment into equal length subsegments
226  Local3DPoint point = hit.entryPoint() + float((i+0.5)/NumberOfSegments) * direction;
227  if (fluctuateCharge)
228  energy = elossVector[i]/GeVperElectron; // Convert charge to elec.
229  else
230  energy = hit.energyLoss()/GeVperElectron/float(NumberOfSegments);
231 
232  DigitizerUtility::EnergyDepositUnit edu(energy, point); // define position,energy point
233  ionization_points.push_back(edu); // save
234  LogDebug("Phase2TrackerDigitizerAlgorithm")
235  << i << " " << ionization_points[i].x() << " "
236  << ionization_points[i].y() << " "
237  << ionization_points[i].z() << " "
238  << ionization_points[i].energy();
239  }
240 }
241 //==============================================================================
242 //
243 // Fluctuate the charge comming from a small (10um) track segment.
244 // Use the G4 routine. For mip pions for the moment.
245 //
246 //==============================================================================
248  float particleMomentum,
249  float eloss,
250  float length,
251  int NumberOfSegs,
252  std::vector<float> & elossVector) const {
253 
254  // Get dedx for this track
255  //float dedx;
256  //if( length > 0.) dedx = eloss/length;
257  //else dedx = eloss;
258 
259  double particleMass = 139.6; // Mass in MeV, Assume pion
260  pid = std::abs(pid);
261  if (pid != 211) { // Mass in MeV
262  if (pid == 11) particleMass = 0.511;
263  else if (pid == 13) particleMass = 105.7;
264  else if (pid == 321) particleMass = 493.7;
265  else if (pid == 2212) particleMass = 938.3;
266  }
267  // What is the track segment length.
268  float segmentLength = length/NumberOfSegs;
269 
270  // Generate charge fluctuations.
271  float de = 0.;
272  float sum = 0.;
273  double segmentEloss = (1000. * eloss)/NumberOfSegs; //eloss in MeV
274  for (int i = 0; i < NumberOfSegs; ++i) {
275  // material,*, momentum,energy,*, *, mass
276  //myglandz_(14.,segmentLength,2.,2.,dedx,de,0.14);
277  // The G4 routine needs momentum in MeV, mass in Mev, delta-cut in MeV,
278  // track segment length in mm, segment eloss in MeV
279  // Returns fluctuated eloss in MeV
280  double deltaCutoff = tMax; // the cutoff is sometimes redefined inside, so fix it.
281  de = fluctuate->SampleFluctuations(static_cast<double>(particleMomentum*1000.),
282  particleMass, deltaCutoff,
283  static_cast<double>(segmentLength*10.),
284  segmentEloss,
285  rengine_ )/1000.; //convert to GeV
286  elossVector.push_back(de);
287  sum += de;
288  }
289  if (sum > 0.) { // If fluctuations give eloss>0.
290  // Rescale to the same total eloss
291  float ratio = eloss/sum;
292  for (int ii = 0; ii < NumberOfSegs; ++ii) elossVector[ii] = ratio*elossVector[ii];
293  }
294  else { // If fluctuations gives 0 eloss
295  float averageEloss = eloss/NumberOfSegs;
296  for (int ii = 0; ii < NumberOfSegs; ++ii) elossVector[ii] = averageEloss;
297  }
298 
299 }
300 
301 // ======================================================================
302 //
303 // Drift the charge segments to the sensor surface (collection plane)
304 // Include the effect of E-field and B-field
305 //
306 // =====================================================================
308  const Phase2TrackerGeomDetUnit* pixdet,
309  const GlobalVector& bfield,
310  const std::vector<DigitizerUtility::EnergyDepositUnit>& ionization_points,
311  std::vector<DigitizerUtility::SignalPoint>& collection_points) const {
312  LogDebug("Phase2TrackerDigitizerAlgorithm") << "enter drift ";
313 
314  collection_points.resize(ionization_points.size()); // set size
315  LocalVector driftDir = DriftDirection(pixdet, bfield, hit.detUnitId()); // get the charge drift direction
316  if (driftDir.z() == 0.) {
317  LogWarning("Phase2TrackerDigitizerAlgorithm") << " pxlx: drift in z is zero ";
318  return;
319  }
320 
321  float TanLorenzAngleX,
322  TanLorenzAngleY,
323  dir_z,
324  CosLorenzAngleX,
325  CosLorenzAngleY;
326  if (alpha2Order) {
327  TanLorenzAngleX = driftDir.x(); // tangen of Lorentz angle
328  TanLorenzAngleY = driftDir.y();
329  dir_z = driftDir.z(); // The z drift direction
330  CosLorenzAngleX = 1./std::sqrt(1. + TanLorenzAngleX * TanLorenzAngleX); // cosine
331  CosLorenzAngleY = 1./std::sqrt(1. + TanLorenzAngleY * TanLorenzAngleY); // cosine;
332  }
333  else {
334  TanLorenzAngleX = driftDir.x();
335  TanLorenzAngleY = 0.; // force to 0, driftDir.y()/driftDir.z();
336  dir_z = driftDir.z(); // The z drift direction
337  CosLorenzAngleX = 1./std::sqrt(1. + TanLorenzAngleX * TanLorenzAngleX); // cosine to estimate the path length
338  CosLorenzAngleY = 1.;
339  }
340 
341  float moduleThickness = pixdet->specificSurface().bounds().thickness();
342  float stripPitch = pixdet->specificTopology().pitch().first;
343 
344  LogDebug("Phase2TrackerDigitizerAlgorithm")
345  << " Lorentz Tan " << TanLorenzAngleX << " " << TanLorenzAngleY <<" "
346  << CosLorenzAngleX << " " << CosLorenzAngleY << " "
347  << moduleThickness*TanLorenzAngleX << " " << driftDir;
348 
349  float Sigma_x = 1.; // Charge spread
350  float Sigma_y = 1.;
351  float DriftDistance; // Distance between charge generation and collection
352  float DriftLength; // Actual Drift Lentgh
353  float Sigma;
354 
355  for (unsigned int i = 0; i != ionization_points.size(); ++i) {
356  float SegX, SegY, SegZ; // position
357  SegX = ionization_points[i].x();
358  SegY = ionization_points[i].y();
359  SegZ = ionization_points[i].z();
360 
361  // Distance from the collection plane
362  // DriftDistance = (moduleThickness/2. + SegZ); // Drift to -z
363  // Include explixitely the E drift direction (for CMS dir_z=-1)
364  DriftDistance = moduleThickness/2. - (dir_z * SegZ); // Drift to -z
365 
366  if (DriftDistance < 0.)
367  DriftDistance = 0.;
368  else if (DriftDistance > moduleThickness)
369  DriftDistance = moduleThickness;
370 
371  // Assume full depletion now, partial depletion will come later.
372  float XDriftDueToMagField = DriftDistance * TanLorenzAngleX;
373  float YDriftDueToMagField = DriftDistance * TanLorenzAngleY;
374 
375  // Shift cloud center
376  float CloudCenterX = SegX + XDriftDueToMagField;
377  float CloudCenterY = SegY + YDriftDueToMagField;
378 
379  // Calculate how long is the charge drift path
380  DriftLength = std::sqrt(DriftDistance*DriftDistance +
381  XDriftDueToMagField*XDriftDueToMagField +
382  YDriftDueToMagField*YDriftDueToMagField);
383 
384  // What is the charge diffusion after this path
385  // Sigma0=0.00037 is for 300um thickness (make sure moduleThickness is in [cm])
386  Sigma = std::sqrt(DriftLength/moduleThickness) * (Sigma0 * moduleThickness/0.0300);
387  // D.B.: sigmaCoeff=0 means no modulation
388  if (SigmaCoeff) Sigma *= (SigmaCoeff * cos(SegX*M_PI/stripPitch) * cos(SegX*M_PI/stripPitch) + 1);
389  // NB: divided by 4 to get a periodicity of stripPitch
390 
391  // Project the diffusion sigma on the collection plane
392  Sigma_x = Sigma / CosLorenzAngleX;
393  Sigma_y = Sigma / CosLorenzAngleY;
394 
395  // Insert a charge loss due to Rad Damage here
396  float energyOnCollector = ionization_points[i].energy(); // The energy that reaches the collector
397 
398  // pseudoRadDamage
399  if (pseudoRadDamage >= 0.001) {
400  float moduleRadius = pixdet->surface().position().perp();
401  if (moduleRadius <= pseudoRadDamageRadius) {
402  float kValue = pseudoRadDamage/(moduleRadius * moduleRadius);
403  energyOnCollector = energyOnCollector * exp(-1 * kValue * DriftDistance/moduleThickness);
404  }
405  }
406  LogDebug("Phase2TrackerDigitizerAlgorithm")
407  << "Dift DistanceZ = " << DriftDistance << " module thickness = " << moduleThickness
408  << " Start Energy = " << ionization_points[i].energy() << " Energy after loss= " << energyOnCollector;
409  DigitizerUtility::SignalPoint sp(CloudCenterX, CloudCenterY, Sigma_x, Sigma_y, hit.tof(), energyOnCollector);
410  // Load the Charge distribution parameters
411  collection_points[i] = sp;
412  }
413 }
414 
415 // ====================================================================
416 //
417 // Induce the signal on the collection plane of the active sensor area.
419  const size_t hitIndex,
420  const unsigned int tofBin,
421  const Phase2TrackerGeomDetUnit* pixdet,
422  const std::vector<DigitizerUtility::SignalPoint>& collection_points) {
423 
424  // X - Rows, Left-Right, 160, (1.6cm) for barrel
425  // Y - Columns, Down-Up, 416, (6.4cm)
426  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
427  uint32_t detID = pixdet->geographicalId().rawId();
428  signal_map_type& theSignal = _signal[detID];
429 
430  LogDebug("Phase2TrackerDigitizerAlgorithm")
431  << " enter induce_signal, "
432  << topol->pitch().first << " " << topol->pitch().second; //OK
433 
434  // local map to store pixels hit by 1 Hit.
435  using hit_map_type = std::map<int, float, std::less<int> >;
436  hit_map_type hit_signal;
437 
438  // map to store pixel integrals in the x and in the y directions
439  std::map<int, float, std::less<int> > x,y;
440 
441  // Assign signals to readout channels and store sorted by channel number
442  int iseg = 0;
443  float ESum = 0.0;
444 
445  // Iterate over collection points on the collection plane
446  for (auto const & v : collection_points) {
447  iseg++;
448  float CloudCenterX = v.position().x(); // Charge position in x
449  float CloudCenterY = v.position().y(); // in y
450  float SigmaX = v.sigma_x(); // Charge spread in x
451  float SigmaY = v.sigma_y(); // in y
452  float Charge = v.amplitude(); // Charge amplitude
453 
454  LogDebug("Phase2TrackerDigitizerAlgorithm")
455  << " cloud " << v.position().x() << " " << v.position().y() << " "
456  << v.sigma_x() << " " << v.sigma_y() << " " << v.amplitude();
457 
458  // Find the maximum cloud spread in 2D plane , assume 3*sigma
459  float CloudRight = CloudCenterX + ClusterWidth * SigmaX;
460  float CloudLeft = CloudCenterX - ClusterWidth * SigmaX;
461  float CloudUp = CloudCenterY + ClusterWidth * SigmaY;
462  float CloudDown = CloudCenterY - ClusterWidth * SigmaY;
463 
464  // Define 2D cloud limit points
465  LocalPoint PointRightUp = LocalPoint(CloudRight,CloudUp);
466  LocalPoint PointLeftDown = LocalPoint(CloudLeft,CloudDown);
467 
468  // This points can be located outside the sensor area.
469  // The conversion to measurement point does not check for that
470  // so the returned pixel index might be wrong (outside range).
471  // We rely on the limits check below to fix this.
472  // But remember whatever we do here THE CHARGE OUTSIDE THE ACTIVE
473  // PIXEL ARE IS LOST, it should not be collected.
474 
475  // Convert the 2D points to pixel indices
476  MeasurementPoint mp = topol->measurementPosition(PointRightUp ); //OK
477 
478  int IPixRightUpX = int(floor( mp.x()));
479  int IPixRightUpY = int(floor( mp.y()));
480 
481  LogDebug("Phase2TrackerDigitizerAlgorithm") << " right-up " << PointRightUp << " "
482  << mp.x() << " " << mp.y() << " "
483  << IPixRightUpX << " " << IPixRightUpY ;
484 
485  mp = topol->measurementPosition(PointLeftDown); // OK
486 
487  int IPixLeftDownX = int(floor( mp.x()));
488  int IPixLeftDownY = int(floor( mp.y()));
489 
490  LogDebug("Phase2TrackerDigitizerAlgorithm") << " left-down " << PointLeftDown << " "
491  << mp.x() << " " << mp.y() << " "
492  << IPixLeftDownX << " " << IPixLeftDownY ;
493 
494  // Check detector limits to correct for pixels outside range.
495  int numColumns = topol->ncolumns(); // det module number of cols&rows
496  int numRows = topol->nrows();
497 
498  IPixRightUpX = numRows > IPixRightUpX ? IPixRightUpX : numRows-1;
499  IPixRightUpY = numColumns > IPixRightUpY ? IPixRightUpY : numColumns-1;
500  IPixLeftDownX = 0 < IPixLeftDownX ? IPixLeftDownX : 0;
501  IPixLeftDownY = 0 < IPixLeftDownY ? IPixLeftDownY : 0;
502 
503  x.clear(); // clear temporary integration array
504  y.clear();
505 
506  // First integrate cahrge strips in x
507  int ix; // TT for compatibility
508  for (ix = IPixLeftDownX; ix <= IPixRightUpX; ix++) { // loop over x index
509  float xUB, xLB, UpperBound, LowerBound;
510 
511  // Why is set to 0 if ix=0, does it meen that we accept charge
512  // outside the sensor?
513  if (ix == 0 || SigmaX==0.) // skip for surface segemnts
514  LowerBound = 0.;
515  else {
516  mp = MeasurementPoint( float(ix), 0.0);
517  xLB = topol->localPosition(mp).x();
518  LowerBound = 1-calcQ((xLB-CloudCenterX)/SigmaX);
519  }
520 
521  if (ix == numRows-1 || SigmaX == 0.)
522  UpperBound = 1.;
523  else {
524  mp = MeasurementPoint(float(ix+1), 0.0);
525  xUB = topol->localPosition(mp).x();
526  UpperBound = 1. - calcQ((xUB-CloudCenterX)/SigmaX);
527  }
528  float TotalIntegrationRange = UpperBound - LowerBound; // get strip
529  x[ix] = TotalIntegrationRange; // save strip integral
530  }
531 
532  // Now integarte strips in y
533  int iy; // TT for compatibility
534  for (iy = IPixLeftDownY; iy <= IPixRightUpY; iy++) { //loope over y ind
535  float yUB, yLB, UpperBound, LowerBound;
536 
537  if (iy == 0 || SigmaY==0.)
538  LowerBound = 0.;
539  else {
540  mp = MeasurementPoint(0.0, float(iy));
541  yLB = topol->localPosition(mp).y();
542  LowerBound = 1. - calcQ((yLB-CloudCenterY)/SigmaY);
543  }
544 
545  if (iy == numColumns-1 || SigmaY==0. )
546  UpperBound = 1.;
547  else {
548  mp = MeasurementPoint(0.0, float(iy+1));
549  yUB = topol->localPosition(mp).y();
550  UpperBound = 1. - calcQ((yUB-CloudCenterY)/SigmaY);
551  }
552 
553  float TotalIntegrationRange = UpperBound - LowerBound;
554  y[iy] = TotalIntegrationRange; // save strip integral
555  }
556 
557  // Get the 2D charge integrals by folding x and y strips
558  int chan;
559  for (ix = IPixLeftDownX; ix <= IPixRightUpX; ix++) { // loop over x index
560  for (iy = IPixLeftDownY; iy <= IPixRightUpY; iy++) { //loope over y ind
561  float ChargeFraction = Charge*x[ix]*y[iy];
562  if (ChargeFraction > 0.) {
563  chan = (pixelFlag) ? PixelDigi::pixelToChannel(ix, iy)
564  : Phase2TrackerDigi::pixelToChannel(ix, iy); // Get index
565  // Load the amplitude
566  hit_signal[chan] += ChargeFraction;
567  }
568 
569  mp = MeasurementPoint(float(ix), float(iy));
570  LocalPoint lp = topol->localPosition(mp);
571  chan = topol->channel(lp);
572 
573  LogDebug("Phase2TrackerDigitizerAlgorithm")
574  << " pixel " << ix << " " << iy << " - "<<" "
575  << chan << " " << ChargeFraction<<" "
576  << mp.x() << " " << mp.y() <<" "
577  << lp.x() << " " << lp.y() << " " // givex edge position
578  << chan; // edge belongs to previous ?
579  ESum += ChargeFraction;
580  }
581  }
582  }
583  // Fill the global map with all hit pixels from this event
584  for (auto const & hit_s : hit_signal) {
585  int chan = hit_s.first;
586  theSignal[chan] += (makeDigiSimLinks_ ? DigitizerUtility::Amplitude( hit_s.second, &hit, hit_s.second, hitIndex, tofBin)
587  : DigitizerUtility::Amplitude( hit_s.second, nullptr, hit_s.second) ) ;
588  }
589 }
590 // ======================================================================
591 //
592 // Add electronic noise to pixel charge
593 //
594 // ======================================================================
596  uint32_t detID = pixdet->geographicalId().rawId();
597  signal_map_type& theSignal = _signal[detID];
598  for (auto & s : theSignal) {
599  float noise = gaussDistribution_->fire();
600  if ((s.second.ampl() + noise) < 0.)
601  s.second.set(0);
602  else
603  s.second += noise;
604  }
605 }
606 // ======================================================================
607 //
608 // Add Cross-talk contribution
609 //
610 // ======================================================================
612  uint32_t detID = pixdet->geographicalId().rawId();
613  signal_map_type& theSignal = _signal[detID];
614  signal_map_type signalNew;
615  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
616  int numRows = topol->nrows();
617 
618  for (auto & s : theSignal) {
619  float signalInElectrons = s.second.ampl(); // signal in electrons
620 
621  std::pair<int,int> hitChan;
622  if (pixelFlag) hitChan = PixelDigi::channelToPixel(s.first);
623  else hitChan = Phase2TrackerDigi::channelToPixel(s.first);
624 
625  float signalInElectrons_Xtalk = signalInElectrons * interstripCoupling;
626  //subtract the charge which will be shared
627  s.second.set(signalInElectrons-signalInElectrons_Xtalk);
628 
629  if (hitChan.first != 0) {
630  auto XtalkPrev = std::make_pair(hitChan.first-1, hitChan.second);
631  int chanXtalkPrev = (pixelFlag) ? PixelDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second)
632  : Phase2TrackerDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second);
633  signalNew.emplace(chanXtalkPrev,
634  DigitizerUtility::Amplitude(signalInElectrons_Xtalk, nullptr, -1.0));
635  }
636  if (hitChan.first < (numRows-1)) {
637  auto XtalkNext = std::make_pair(hitChan.first+1, hitChan.second);
638  int chanXtalkNext = (pixelFlag) ? PixelDigi::pixelToChannel(XtalkNext.first, XtalkNext.second)
639  : Phase2TrackerDigi::pixelToChannel(XtalkNext.first, XtalkNext.second);
640  signalNew.emplace(chanXtalkNext,
641  DigitizerUtility::Amplitude(signalInElectrons_Xtalk, nullptr, -1.0));
642  }
643  }
644  for (auto const & l : signalNew) {
645  int chan = l.first;
646  auto iter = theSignal.find(chan);
647  if (iter != theSignal.end()) {
648  theSignal[chan] += l.second.ampl();
649  } else {
650  theSignal.emplace(chan, DigitizerUtility::Amplitude(l.second.ampl(), nullptr, -1.0));
651  }
652  }
653 }
654 
655 // ======================================================================
656 //
657 // Add noise on non-hit cells
658 //
659 // ======================================================================
661  uint32_t detID = pixdet->geographicalId().rawId();
662  signal_map_type& theSignal = _signal[detID];
663  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
664  int numColumns = topol->ncolumns(); // det module number of cols&rows
665  int numRows = topol->nrows();
666 
667  int numberOfPixels = numRows * numColumns;
668  std::map<int,float, std::less<int> > otherPixels;
669  std::map<int,float, std::less<int> >::iterator mapI;
670 
671  theNoiser->generate(numberOfPixels,
672  thePixelThreshold, //thr. in un. of nois
673  theNoiseInElectrons, // noise in elec.
674  otherPixels,
675  rengine_ );
676 
677  LogDebug("Phase2TrackerDigitizerAlgorithm")
678  << " Add noisy pixels " << numRows << " "
679  << numColumns << " " << theNoiseInElectrons << " "
680  << theThresholdInE_Endcap << " " << theThresholdInE_Barrel << " " << numberOfPixels << " "
681  << otherPixels.size() ;
682 
683  // Add noisy pixels
684  for (mapI = otherPixels.begin(); mapI!= otherPixels.end(); mapI++) {
685  int iy = ((*mapI).first) / numRows;
686  int ix = ((*mapI).first) - (iy*numRows);
687  // Keep for a while for testing.
688  if( iy < 0 || iy > (numColumns-1) )
689  LogWarning("Phase2TrackerDigitizerAlgorithm") << " error in iy " << iy;
690  if( ix < 0 || ix > (numRows-1) )
691  LogWarning("Phase2TrackerDigitizerAlgorithm") << " error in ix " << ix;
692 
693  int chan;
695 
696  LogDebug ("Phase2TrackerDigitizerAlgorithm")
697  <<" Storing noise = " << (*mapI).first << " " << (*mapI).second
698  << " " << ix << " " << iy << " " << chan ;
699 
700  if (theSignal[chan] == 0) {
701  int noise = int((*mapI).second);
702  theSignal[chan] = DigitizerUtility::Amplitude (noise, nullptr, -1.);
703  }
704  }
705 }
706 // ============================================================================
707 //
708 // Simulate the readout inefficiencies.
709 // Delete a selected number of single pixels, dcols and rocs.
711  const Phase2TrackerGeomDetUnit* pixdet,
712  const TrackerTopology *tTopo) {
713 
714  uint32_t detID = pixdet->geographicalId().rawId();
715 
716  signal_map_type& theSignal = _signal[detID]; // check validity
717 
718  // Predefined efficiencies
719  float subdetEfficiency = 1.0;
720 
721  // setup the chip indices conversion
722  unsigned int Subid=DetId(detID).subdetId();
723  if (Subid == PixelSubdetector::PixelBarrel || Subid == StripSubdetector::TOB) { // barrel layers
724  unsigned int layerIndex = tTopo->pxbLayer(detID);
725  if (layerIndex-1 < eff.barrel_efficiencies.size()) subdetEfficiency = eff.barrel_efficiencies[layerIndex-1];
726  } else { // forward disks
727  unsigned int diskIndex = 2 * tTopo->pxfDisk(detID) - tTopo->pxfSide(detID);
728  if (diskIndex-1 < eff.endcap_efficiencies.size()) subdetEfficiency = eff.endcap_efficiencies[diskIndex-1];
729  }
730 
731  LogDebug ("Phase2TrackerDigitizerAlgorithm") << " enter pixel_inefficiency " << subdetEfficiency;
732 
733  // Now loop again over pixels to kill some of them.
734  // Loop over hits, amplitude in electrons, channel = coded row,col
735  for (auto & s : theSignal) {
736  float rand = rengine_->flat();
737  if( rand>subdetEfficiency ) {
738  // make amplitude =0
739  s.second.set(0.); // reset amplitude,
740  }
741  }
742 }
743 void Phase2TrackerDigitizerAlgorithm::initializeEvent(CLHEP::HepRandomEngine& eng) {
745 
746  gaussDistribution_ = std::make_unique<CLHEP::RandGaussQ>(eng, 0., theReadoutNoise);
747  }
748  // Threshold smearing with gaussian distribution:
749  if (addThresholdSmearing) {
750  smearedThreshold_Endcap_ = std::make_unique<CLHEP::RandGaussQ> (eng, theThresholdInE_Endcap , theThresholdSmearing_Endcap);
751  smearedThreshold_Barrel_ = std::make_unique<CLHEP::RandGaussQ> (eng, theThresholdInE_Barrel , theThresholdSmearing_Barrel);
752  }
753  rengine_ = (&eng);
754  _signal.clear();
755 }
756 
757 // =======================================================================================
758 //
759 // Set the drift direction accoring to the Bfield in local det-unit frame
760 // Works for both barrel and forward pixels.
761 // Replace the sign convention to fit M.Swartz's formulaes.
762 // Configurations for barrel and foward pixels possess different tanLorentzAngleperTesla
763 // parameter value
764 
766  const GlobalVector& bfield,
767  const DetId& detId) const {
768  Frame detFrame(pixdet->surface().position(),pixdet->surface().rotation());
769  LocalVector Bfield = detFrame.toLocal(bfield);
770  float alpha2_Endcap;
771  float alpha2_Barrel;
772  float alpha2;
773 
774  float dir_x = 0.0;
775  float dir_y = 0.0;
776  float dir_z = 0.0;
777  float scale = 0.0;
778 
779  uint32_t detID = pixdet->geographicalId().rawId();
780  unsigned int Sub_detid = DetId(detID).subdetId();
781 
782  // Read Lorentz angle from cfg file:
783  if (!use_LorentzAngle_DB_) {
784  if (alpha2Order) {
787  } else {
788  alpha2_Endcap = 0.0;
789  alpha2_Barrel = 0.0;
790  }
791 
792  if (Sub_detid == PixelSubdetector::PixelBarrel || Sub_detid == StripSubdetector::TOB) { // barrel layers
793  dir_x = -( tanLorentzAnglePerTesla_Barrel * Bfield.y() + alpha2_Barrel* Bfield.z()* Bfield.x() );
794  dir_y = +( tanLorentzAnglePerTesla_Barrel * Bfield.x() - alpha2_Barrel* Bfield.z()* Bfield.y() );
795  dir_z = -(1 + alpha2_Barrel* Bfield.z()*Bfield.z() );
796  scale = (1 + alpha2_Barrel* Bfield.z()*Bfield.z() );
797 
798  } else { // forward disks
799  dir_x = -( tanLorentzAnglePerTesla_Endcap * Bfield.y() + alpha2_Endcap* Bfield.z()* Bfield.x() );
800  dir_y = +( tanLorentzAnglePerTesla_Endcap * Bfield.x() - alpha2_Endcap* Bfield.z()* Bfield.y() );
801  dir_z = -(1 + alpha2_Endcap* Bfield.z()*Bfield.z() );
802  scale = (1 + alpha2_Endcap* Bfield.z()*Bfield.z() );
803  }
804  }
805 
806  // Read Lorentz angle from DB:
807  if (use_LorentzAngle_DB_) {
808  float lorentzAngle = SiPixelLorentzAngle_->getLorentzAngle(detId);
809  alpha2 = lorentzAngle * lorentzAngle;
810 
811  dir_x = -( lorentzAngle * Bfield.y() + alpha2 * Bfield.z()* Bfield.x() );
812  dir_y = +( lorentzAngle * Bfield.x() - alpha2 * Bfield.z()* Bfield.y() );
813  dir_z = -(1 + alpha2 * Bfield.z()*Bfield.z() );
814  scale = (1 + alpha2 * Bfield.z()*Bfield.z() );
815  }
816 
817  LocalVector theDriftDirection = LocalVector(dir_x/scale, dir_y/scale, dir_z/scale );
818 
819  LogDebug ("Phase2TrackerDigitizerAlgorithm") << " The drift direction in local coordinate is "
820  << theDriftDirection ;
821  return theDriftDirection;
822 }
823 
824 // =============================================================================
825 
827  signal_map_type& theSignal = _signal[detID]; // check validity
828 
829  // Loop over hit pixels, amplitude in electrons, channel = coded row,col
830  for (auto & s : theSignal) {
831  std::pair<int,int> ip;
832  if (pixelFlag) ip = PixelDigi::channelToPixel(s.first);//get pixel pos
833  else ip = Phase2TrackerDigi::channelToPixel(s.first);//get pixel pos
834  int row = ip.first; // X in row
835  int col = ip.second; // Y is in col
836  //transform to ROC index coordinates
837  if (theSiPixelGainCalibrationService_->isDead(detID, col, row)) {
838  s.second.set(0.); // reset amplitude,
839  }
840  }
841 }
842 
843 // ==========================================================================
844 
846  bool isbad = false;
847  int detid = detID;
849  for ( auto const & det_m : DeadModules) {
850  int Dead_detID = det_m.getParameter<int>("Dead_detID");
851  Module = det_m.getParameter<std::string>("Module");
852  if (detid == Dead_detID){
853  isbad = true;
854  break;
855  }
856  }
857 
858  if (!isbad) return;
859 
860  signal_map_type& theSignal = _signal[detID]; // check validity
861 
862 
863  for (auto & s : theSignal) {
864  std::pair<int,int> ip;
865  if (pixelFlag) ip = PixelDigi::channelToPixel(s.first);
866  else ip = Phase2TrackerDigi::channelToPixel(s.first);//get pixel pos
867 
868  if (Module == "whole") s.second.set(0.); // reset amplitude
869  else if (Module == "tbmA" && ip.first >= 80 && ip.first <= 159) s.second.set(0.);
870  else if (Module == "tbmB" && ip.first <= 79) s.second.set(0.);
871  }
872 }
873 // ==========================================================================
875  bool isbad = false;
876 
877  std::vector<SiPixelQuality::disabledModuleType>disabledModules = SiPixelBadModule_->getBadComponentList();
878 
880  for (size_t id = 0;id < disabledModules.size(); id++) {
881  if (detID == disabledModules[id].DetID) {
882  isbad = true;
883  badmodule = disabledModules[id];
884  break;
885  }
886  }
887 
888  if (!isbad)
889  return;
890 
891 
892  signal_map_type& theSignal = _signal[detID]; // check validity
893 
894  if (badmodule.errorType == 0) { // this is a whole dead module.
895  for (auto & s : theSignal) {
896  s.second.set(0.); // reset amplitude
897  }
898  }
899  else { // all other module types: half-modules and single ROCs.
900  // Get Bad ROC position:
901  // follow the example of getBadRocPositions in CondFormats/SiPixelObjects/src/SiPixelQuality.cc
902  std::vector<GlobalPixel> badrocpositions (0);
903  for (unsigned int j = 0; j < 16; j++) {
904  if (SiPixelBadModule_->IsRocBad(detID, j) == true) {
905  std::vector<CablingPathToDetUnit> path = map_.product()->pathToDetUnit(detID);
906  for (auto const & p : path) {
907  const PixelROC* myroc = map_.product()->findItem(p);
908  if (myroc->idInDetUnit() == j) {
909  LocalPixel::RocRowCol local = {39, 25}; //corresponding to center of ROC row, col
910  GlobalPixel global = myroc->toGlobal(LocalPixel(local));
911  badrocpositions.push_back(global);
912  break;
913  }
914  }
915  }
916  }
917 
918 
919  for (auto & s : theSignal) {
920  std::pair<int,int> ip;
921  if (pixelFlag) ip = PixelDigi::channelToPixel(s.first);
922  else ip = Phase2TrackerDigi::channelToPixel(s.first);
923 
924  for (auto const & p : badrocpositions) {
925  for (auto & k : badPixels ) {
926  if ( p.row == k.getParameter<int>("row") &&
927  ip.first == k.getParameter<int>("row") &&
928  std::abs(ip.second - p.col) < k.getParameter<int>("col")) {s.second.set(0.);}
929  }
930  }
931  }
932  }
933 }
934 
935 // For premixing
936 void Phase2TrackerDigitizerAlgorithm::loadAccumulator(unsigned int detId, const std::map<int, float>& accumulator) {
937  auto& theSignal = _signal[detId];
938  // the input channel is always with PixelDigi definition
939  // if needed, that has to be converted to Phase2TrackerDigi convention
940  for(const auto& elem: accumulator) {
941  auto inserted = theSignal.emplace(elem.first, DigitizerUtility::Amplitude(elem.second, nullptr));
942  if(!inserted.second) {
943  throw cms::Exception("LogicError") << "Signal was already set for DetId " << detId;
944  }
945  }
946 }
947 
949  std::map<int, DigitizerUtility::DigiSimInfo> & digi_map,
950  const TrackerTopology* tTopo)
951 {
952  uint32_t detID = pixdet->geographicalId().rawId();
953  auto it = _signal.find(detID);
954  if (it == _signal.end()) return;
955 
956  const signal_map_type& theSignal = _signal[detID];
957 
958 
959  unsigned int Sub_detid = DetId(detID).subdetId();
960 
961  float theThresholdInE = 0.;
962  float theHIPThresholdInE = 0.;
963  // Define Threshold
964  if (Sub_detid == PixelSubdetector::PixelBarrel || Sub_detid == StripSubdetector::TOB) { // Barrel modules
965  if (addThresholdSmearing) theThresholdInE = smearedThreshold_Barrel_->fire(); // gaussian smearing
966  else theThresholdInE = theThresholdInE_Barrel; // no smearing
967  theHIPThresholdInE = theHIPThresholdInE_Barrel;
968  } else { // Forward disks modules
969  if (addThresholdSmearing) theThresholdInE = smearedThreshold_Endcap_->fire(); // gaussian smearing
970  else theThresholdInE = theThresholdInE_Endcap; // no smearing
971  theHIPThresholdInE = theHIPThresholdInE_Endcap;
972  }
973 
974  // if (addNoise) add_noise(pixdet, theThresholdInE/theNoiseInElectrons); // generate noise
975  if (addNoise) add_noise(pixdet); // generate noise
976  if (addXtalk) add_cross_talk(pixdet);
977  if (addNoisyPixels) add_noisy_cells(pixdet, theHIPThresholdInE/theElectronPerADC);
978 
979  // Do only if needed
980  if (AddPixelInefficiency && !theSignal.empty()) {
981  if (use_ineff_from_db_)
982  pixel_inefficiency_db(detID);
983  else
984  pixel_inefficiency(subdetEfficiencies_, pixdet, tTopo);
985  }
986  if (use_module_killing_) {
987  if (use_deadmodule_DB_) // remove dead modules using DB
988  module_killing_DB(detID);
989  else // remove dead modules using the list in cfg file
990  module_killing_conf(detID);
991  }
992 
993  // Digitize if the signal is greater than threshold
994  for (auto const & s : theSignal) {
995  // DigitizerUtility::Amplitude sig_data = s.second;
996  const DigitizerUtility::Amplitude& sig_data = s.second;
997  float signalInElectrons = sig_data.ampl();
998  unsigned short adc;
999  if (signalInElectrons >= theThresholdInE) { // check threshold
1000  adc = convertSignalToAdc(detID, signalInElectrons, theThresholdInE);
1002  info.sig_tot = adc;
1003  info.ot_bit = ( signalInElectrons > theHIPThresholdInE ? true : false);
1004  if (makeDigiSimLinks_ ) {
1005  for (auto const & l : sig_data.simInfoList()) {
1006  float charge_frac = l.first/signalInElectrons;
1007  if (l.first > -5.0) info.simInfoList.push_back({charge_frac, l.second.get()});
1008  }
1009  }
1010  digi_map.insert({s.first, info});
1011  }
1012  }
1013 }
1014 //
1015 // Scale the Signal using Dual Slope option
1016 //
1017 int Phase2TrackerDigitizerAlgorithm::convertSignalToAdc(uint32_t detID, float signal_in_elec,float threshold) {
1018  int signal_in_adc;
1019  int temp_signal;
1020  const int max_limit = 10;
1021  if (thePhase2ReadoutMode == 0) signal_in_adc = theAdcFullScale;
1022  else {
1023 
1024  if (thePhase2ReadoutMode == -1) {
1025  temp_signal = std::min( int(signal_in_elec / theElectronPerADC), theAdcFullScale );
1026  } else {
1027  // calculate the kink point and the slope
1028  const int dualslope_param = std::min(abs(thePhase2ReadoutMode), max_limit);
1029  const int kink_point = int(theAdcFullScale/2) +1;
1030  temp_signal = std::floor((signal_in_elec-threshold) / theElectronPerADC) + 1;
1031  if ( temp_signal > kink_point) temp_signal = std::floor((temp_signal - kink_point)/(pow(2, dualslope_param-1))) + kink_point;
1032  }
1033  signal_in_adc = std::min(temp_signal, theAdcFullScale );
1034  LogInfo("Phase2TrackerDigitizerAlgorithm") << " DetId " << detID
1035  << " signal_in_elec " << signal_in_elec
1036  << " threshold " << threshold << " signal_above_thr "
1037  << (signal_in_elec-threshold)
1038  << " temp conversion " << std::floor((signal_in_elec-threshold)/theElectronPerADC)+1
1039  << " signal after slope correction " << temp_signal
1040  << " signal_in_adc " << signal_in_adc;
1041  }
1042  return signal_in_adc;
1043 }
void primary_ionization(const PSimHit &hit, std::vector< DigitizerUtility::EnergyDepositUnit > &ionization_points) const
#define LogDebug(id)
T getParameter(std::string const &) const
virtual int nrows() const =0
LocalVector DriftDirection(const Phase2TrackerGeomDetUnit *pixdet, const GlobalVector &bfield, const DetId &detId) const
static const TGPicture * info(bool iBackgroundIsBlack)
Local3DVector LocalVector
Definition: LocalVector.h:12
float tof() const
deprecated name for timeOfFlight()
Definition: PSimHit.h:76
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
T y() const
Definition: PV2DBase.h:46
T perp() const
Definition: PV3DBase.h:72
unsigned int pxfDisk(const DetId &id) const
void drift(const PSimHit &hit, const Phase2TrackerGeomDetUnit *pixdet, const GlobalVector &bfield, const std::vector< DigitizerUtility::EnergyDepositUnit > &ionization_points, std::vector< DigitizerUtility::SignalPoint > &collection_points) const
const std::unique_ptr< SiG4UniversalFluctuation > fluctuate
#define nullptr
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
T y() const
Definition: PV3DBase.h:63
virtual void initializeEvent(CLHEP::HepRandomEngine &eng)
virtual std::pair< float, float > pitch() const =0
edm::ESHandle< SiPixelFedCablingMap > map_
const Bounds & bounds() const
Definition: Surface.h:120
virtual void add_cross_talk(const Phase2TrackerGeomDetUnit *pixdet)
bool IsRocBad(const uint32_t &detid, const short &rocNb) const
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
virtual void add_noise(const Phase2TrackerGeomDetUnit *pixdet)
SigmaX
Definition: gun_cff.py:25
virtual void module_killing_conf(uint32_t detID)
identify pixel inside single ROC
Definition: LocalPixel.h:7
static int pixelToChannel(int row, int col)
Definition: PixelDigi.h:68
global coordinates (row and column in DetUnit, as in PixelDigi)
Definition: GlobalPixel.h:6
const std::unique_ptr< SiPixelGainCalibrationOfflineSimService > theSiPixelGainCalibrationService_
virtual void add_noisy_cells(const Phase2TrackerGeomDetUnit *pixdet, float thePixelThreshold)
std::unique_ptr< CLHEP::RandGaussQ > gaussDistribution_
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:46
T mag() const
Definition: PV3DBase.h:67
std::vector< edm::ParameterSet > badPixels
T sqrt(T t)
Definition: SSEVec.h:18
static PackedDigiType pixelToChannel(unsigned int row, unsigned int col)
edm::ESHandle< SiPixelLorentzAngle > SiPixelLorentzAngle_
T z() const
Definition: PV3DBase.h:64
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Phase2TrackerDigitizerAlgorithm(const edm::ParameterSet &conf_common, const edm::ParameterSet &conf_specific)
virtual MeasurementPoint measurementPosition(const LocalPoint &) const =0
unsigned int idInDetUnit() const
id of this ROC in DetUnit etermined by token path
Definition: PixelROC.h:40
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
virtual int channel(const LocalPoint &p) const =0
virtual void pixel_inefficiency_db(uint32_t detID)
const std::vector< disabledModuleType > getBadComponentList() const
T min(T a, T b)
Definition: MathUtil.h:58
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
Definition: PSimHit.h:67
std::unique_ptr< CLHEP::RandGaussQ > smearedThreshold_Endcap_
virtual void digitize(const Phase2TrackerGeomDetUnit *pixdet, std::map< int, DigitizerUtility::DigiSimInfo > &digi_map, const TrackerTopology *tTopo)
std::map< int, DigitizerUtility::Amplitude, std::less< int > > signal_map_type
def elem(elemtype, innerHTML='', html_class='', kwargs)
Definition: HTMLExport.py:19
ii
Definition: cuy.py:590
void loadAccumulator(unsigned int detId, const std::map< int, float > &accumulator)
#define M_PI
std::vector< edm::ParameterSet > Parameters
int k[5][pyjets_maxn]
unsigned int pxbLayer(const DetId &id) const
void fluctuateEloss(int particleId, float momentum, float eloss, float length, int NumberOfSegments, std::vector< float > &elossVector) const
Definition: DetId.h:18
void induce_signal(const PSimHit &hit, const size_t hitIndex, const unsigned int tofBin, const Phase2TrackerGeomDetUnit *pixdet, const std::vector< DigitizerUtility::SignalPoint > &collection_points)
virtual float thickness() const =0
SigmaY
Definition: gun_cff.py:26
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:62
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
row and collumn in ROC representation
Definition: LocalPixel.h:15
const sipixelobjects::PixelROC * findItem(const sipixelobjects::CablingPathToDetUnit &path) const final
std::unique_ptr< CLHEP::RandGaussQ > smearedThreshold_Barrel_
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
std::vector< sipixelobjects::CablingPathToDetUnit > pathToDetUnit(uint32_t rawDetId) const final
#define Module(md)
Definition: vmac.h:203
float energyLoss() const
The energy deposit in the PSimHit, in ???.
Definition: PSimHit.h:79
HLT enums.
virtual int ncolumns() const =0
int particleType() const
Definition: PSimHit.h:89
col
Definition: cuy.py:1010
Signal rand(Signal arg)
Definition: vlib.cc:442
float getLorentzAngle(const uint32_t &) const
unsigned int pxfSide(const DetId &id) const
const RotationType & rotation() const
std::vector< std::pair< float, SimHitInfoForLinks * > > simInfoList
virtual void pixel_inefficiency(const SubdetEfficiencies &eff, const Phase2TrackerGeomDetUnit *pixdet, const TrackerTopology *tTopo)
const std::vector< std::pair< float, std::unique_ptr< SimHitInfoForLinks > > > & simInfoList() const
const std::unique_ptr< GaussianTailNoiseGenerator > theNoiser
T x() const
Definition: PV2DBase.h:45
T x() const
Definition: PV3DBase.h:62
const PositionType & position() const
T const * product() const
Definition: ESHandle.h:86
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:43
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
static std::pair< unsigned int, unsigned int > channelToPixel(unsigned int ch)
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
unsigned int detUnitId() const
Definition: PSimHit.h:97
const Plane & specificSurface() const
Same as surface(), kept for backward compatibility.
Definition: GeomDet.h:45
int convertSignalToAdc(uint32_t detID, float signal_in_elec, float threshold)
GlobalPixel toGlobal(const LocalPixel &loc) const
Definition: PixelROC.h:59
edm::ESHandle< SiPixelQuality > SiPixelBadModule_