Pointing hand Link to the DPG Tracker Simulation twiki


The Pixel digitizer reads the collection of SimHit and writes a collection of Pixel Digi and a collection of links between digi and simhits. The source code of the PixelDigitizer is available at SimTracker/SiPixelDigitizer.

From Geant-4 simulations we get for each track so called SimHits: the entrance and exit points ($P_{in}$, $P_{out}$) and the deposited energy in keV (ΔE). Only the pixel detector geometry is needed to obtain this. To convert SimHits to something that looks similar to the experimental raw data (Digis) we need the digitizer. The pixel digitizer knows the pixel pitch, signal thresholds, ADC bits, noise, ....

SimHits.png Track_split.png

The process can logically be split into the sensor response and the readout chip response, which is also reflected in the structure of the code.

The sensor response is packed into the accumulateSimHits function and performs these steps for each individual SimHit:

  • The track is split into many segments (length of 10 um) each with charge $q_i$ which is fluctuated according to the G4 dEdx fluctuation formula.
  • Each negative point charge is drifted to the detector surface under the influence of the B-field ($2^{nd}$ order Lorentz force used, with Lorentz angle read from a DB - optionally overwritten via the configration).
  • The point charge is diffused with a Gaussian smearing. Based on the drift distance, the charge is expanded to a 2D Gaussian cloud.
  • A numerical integration over this cloud calculates the charge propagated to each individual pixel ($Q_n$) within 3sigma of the cloud.
  • A cluster charge re-weighting is performed to describe the effects arising from radiation damage (see below).

The actual digitization process is implemented in the digitize and the makedigis function:

  • The threshold in units of kiloelectrons (ke) is smeared (drawn from a Gaussian distribution with a configurable sigma).
  • Noise is added, drawn from a Gaussian distribution (add_noise()), split in so called VCal noise and readout noise.
  • Noisy pixels are added with a low probability.
  • Inefficiencies are applied (signals in single pixels and/or full modules / TBMs deleted)
  • A threshold is applied and the charge is converted to ADC counts (integer) using the conversion described here.

Steps in the pixel digitizer

(from Danek, November 28, 2009. Slight rework by P. Schuetze, 2019)

Some more information on the above mentioned steps:


  • Generate pixel charge using: primary_ionization(), drift() and induce_signal(). Pixel signal is in electrons.


  • Smear pixel thresholds with a Gaussian, given the sigma. Separate for bpix and fpix.
  • Apply the smearing of the signal due to the VCAL variation. The smearing is a Gaussian where the sigma depends on the pixel charge.
  • Add noise to the hit pixels and add new "noisy" pixels.
  • Delete random hit pixels to simulate the effect of dynamical efficiency losses. Important only at higher luminosities.
  • Delete pixels in dead modules. Use either the config files or the DB (The list of official dead pixel modules accessible via the Database can be found here). Presently the list from the config files is used.
  • Delete hits in known "dead" pixels. It is not used for the moment. It uses the SiPixelGainCalibrationOfflineSimService() object to call ->isDead().


  • Check threshold, keep only pixels above the threshold. Separate for bpix and fpix.
  • Apply the signal response. Convert electrons to VcalLow and than use the TANH function to obtain ADC values (see here). The same parameter are used for all pixels (no pixel2pixel variation). Separate for bpix and fpix.
  • Saturate the ADC count at the maximum value (255).
  • Construct the sim-links for the MC association.

Signal response in the simulation

A more realistic parameterization of the signal response has been implemented. The analog response is simulated (with distinction between Fpix and Bpix) as:

p3 + p2 * tanh(p0*signal - p1) with signal(in VCAL units)= (signalInElectrons - electronsPerVCAL_Offset) / electronsPerVCAL

where signalInElectrons is the signal in electrons for a hit pixel, electronsPerVCAL = 65.5 and electronsPerVCAL_Offset = -414.

The two sets of parameters (from Danek's results) to be used for the new parameterization are shown in the following table. These are average of all ROCs. There are variations of course but we decided a while ago to ignore them.

Bpix_analog_signal = 126.5 + 97.4 * tanh(0.0035*signal - 1.23)   Fpix_analog_signal = 134.6 + 93.6 * tanh(0.0043*signal - 1.31)
bpix_vs_elec_lin.gif   fpix_vs_elec_lin.gif

We also update the gain calibrations in MC as well. We update the DB payload with the following input numbers: bpix_gain= 3.501, bpix_ped=25.520, bpix_rmsgain=0.513, bpix_rmsped=8.149 and fpix_gain=2.915, fpix_ped=28.030, fpix_rmsgain=0.475, fpix_rmsped=9.534. We don't need to update the clusterizer to read the separate numbers for bpix and fpix because the differentiation is already in the payload. The clusterizer just reads it from the DB.

Result of the new parameterization in the pixel digitizer: V02-17-08 (Nov. 20th 2009)

Pixel thresholds in electrons

The official 2009 pixel threshold in electrons (obtained from Cosmic data) are:
  • ThresholdInElectrons_FPix is 2483e (RMS 163e)
  • ThresholdInElectrons_BPix is 2733e (RMS 196e)
  • All is 2666 (RMS 218)

Contributions that smear the pixel charge

  • The readout noise from the electronics is a "permanent" contribution. (The upper limit would be 500e)
  • The VCAL contribution is a "permanent" contribution. Even if we find a way to correct each ROC the pixel2pixel contribution is still there. Following the study made by D. Kotlinski on the VCAL calibration, we implemented a smearing of the pixel charge using an RMS value (obtained from that study) which is a function of the pixel charge value as shown in the plot below:
The pixel charge smearing is defined in 3 regions: 
charge < 3000           RMS = 543.6  0.093*charge
3000 < charge < 6000    RMS = 307.6  0.01*charge
charge > 6000           RMS= -432.4 + 0.123*charge

Cluster Charge Re-weighting (CCR)

For the Phase I Pixel Detector severe radiation damage is expected, drastically altering the detector response. An attempt to describe this behavior is the CCR algorithm.

In a nutshell:

This algorithm changes the charges in a cluster arising from a single SimHit such, that a better description of the sensor response is obtained, while maintaining the randomized nature of the signal creation process. The method of CCR sets in at the end of the first part of the digitization process and applies to clusters of pixel charges resulting from a single primary particle. The CCR is implemented as the very final step of the accumulateSimHits function. Hence, the CCR happens in the pre-mixing step, before the charges in the pixels are summed and thresholds are applied.

In a bit more detail:

For this methods, so called templates are used. Templates comprise representative clusters of pixel charges and are generated for various incidence angles and positions, as well as for different levels of irradiation to cover a large set of possible scenarios. A single cluster template is created by repeatedly simulating the particle traversal for a certain incidence angle and position within a pixel using the pixelav software, see reference.

To apply the CCR to a simulated cluster, the incidence angle and position of the corresponding primary particle and the module ID are used to find the most suitable cluster templates from a set of templates. The templates are read from a database, and an interpolation is performed between the simulated particle parameters. The initially induced charge $q_{in}$ of any pixel in the cluster is then scaled with the quotient $w$ of the template pixel charges at the same position inside the cluster for an irradiated ($t_{irr}$) and an unirradiated sensor ($t_{unirr}$). A matrix of $13\times21$ pixels is defined, which covers the full cluster and has the particle hit position in its center. For any pixel, specified by its pixel coordinate $(i,j)$ with respect to the lower left pixel of this matrix, the re-weighted charge $q_{out}$ is determined as

$q_{out}(i,j) = w(i,j) \cdot q_{in}(i,j) = \frac{t_{irr}(i,j)}{t_{unirr}(i,j)} \cdot q_{in}(i,j) .$

For pixel charges of the templates below a defined threshold, no weights are computed, and instead the pixel charge is computed using the weight of the closest pixel with a weight.

One way to verify the effect of the CCR is to extract the collected charge as a function of the charge carrier creation depth from very long clusters. For unirradiated sensors, this profile is flat, and it is tilted for strongly irradiated sensors, as shown in the following graph. The CCR can reproduce this effect.

Cluster Charge Re-weighting

Time of flight of simhits

The ToF of simhits was measured in a cosmic sample (look at the pixel simhit TOF in a SimHits root file). They peak around 31nsec. For the cosmics we use 31 $\pm$ 12.5 nsec window. For collisions the TOF peak is at zero so the window is $\pm$ 12.5.
  • Cosmics: process.simSiPixelDigis.TofLowerCut = 18.5 and process.simSiPixelDigis.TofUpperCut = 43.5
  • Collisions: process.simSiPixelDigis.TofLowerCut = -12.5 and process.simSiPixelDigis.TofUpperCut = 12.5

Pixel inefficiency (mostly due to Luminosity)

The pixel inefficiency is defined below. Basically we can consider that the efficiency is 100%. Or we can include only the static inefficiency: static means that no readout related luminosity dependent losses are considered. But, we can include the readout losses for low-luminosity (2 10^33) or high luminosity (10^34). All this is needed because the MC productions will be done most likely not for the so called "low" luminosity (2 10^33) but for some very low lumi where there will be no readout losses, however some "static" losses comming from bad pixels, bad bump-bonds etc. will be present.

The three inefficiency are: PixelEfficiency (pixels), PixelColEfficiency (columns) and PixelChipEfficiency (readout chips): | thePixelEfficiency[i] | thePixelColEfficiency[i] | thePixelChipEfficiency[i] | where the first 3 settings [0], [1], [2] are for the pixel barrel layer 1, 2, 3 and the next 3 settings [3], [4], [5] are for the endcaps. Different scenarios have been implemented:

  • If AddPixelInefficiency = -1: All is 100% efficient.
for (int i=0; i<6;i++) {
      thePixelEfficiency[i]     = 1.;  // pixels = 100%
      thePixelColEfficiency[i]  = 1.;  // columns = 100%
      thePixelChipEfficiency[i] = 1.; // chips = 100%
  • If AddPixelInefficiency = 0: We include only the static (non rate depedent) inefficiency. This is useful for very low rates (luminosity). For both barrel and endcaps, we will assume the following settings:
for (int i=0; i<6;i++) {
      thePixelEfficiency[i]     = 1.-0.001;  // pixels = 99.9% (Assume 1% inefficiency that is given by faulty bump-bonding and seus.)
      thePixelColEfficiency[i]  = 1.-0.001;  // columns = 99.9% (Make 0.1% default)
      thePixelChipEfficiency[i] = 1.-0.001; // chips = 99.9% (A flat 0.1% inefficiency due to lost ROCs)
  • If AddPixelInefficiency > 0: We include also luminosity rate dependent inefficiency. For both barrel and endcaps, we will assume the following settings:
for (int i=0; i<6;i++) {
      thePixelEfficiency[i]     = 1.-0.01;  // pixels = 99% (Assume 1% inefficiency that is given by faulty bump-bonding and seus.)
      thePixelColEfficiency[i]  = 1.-0.01;  // columns = 99% (Make 0.1% default)
      thePixelChipEfficiency[i] = 1.-0.0025; // chips = 99.75% (A flat 0.25% inefficiency due to lost data packets from TBM)
  • If AddPixelInefficiency = 10: Special cases ( High-lumi for 4cm layer ) where the readout losses are higher. This case is for high luminosity and affects the Barrel layer1.
      thePixelColEfficiency[0] = 1.-0.034; // (Make 3.4% inefficiency for pixel barrel layer 1)
      thePixelEfficiency[0]    = 1.-0.015; // (Make 1.5% inefficiency for pixel barrel layer 1)

Pixel dead modules

Default pixel digitizer parameters and configuration

Attention: These values are effective 2009 (Phase 0 pixel detector). For the CMS Phase 1 Pixel Detector (>=2017) different parameters are used

Parameter Default value Comment
ReadoutNoiseInElec 350 Readout noise from the electronics in front of the ADC, including all readout chain, relevant for smearing
DeltaProductionCut 0.03 GeV Delta ray cutoff in MeV, has to be same as in OSCAR. Max = 0.030 MeV.
ThresholdInElectrons_FPix 2483 CRAFT09 result
ThresholdInElectrons_BPix 2733 CRAFT09 result
AddThresholdSmearing True Add threshold gaussian smearing
ThresholdSmearing_FPix 160 CRAFT09 result
ThresholdSmearing_BPix 200 CRAFT09 result
MissCalibrate True Enable miss-calibration (pixel gain)
GainSmearing 0 Get the constant for the miss-calibration studies: Sigma of the gain smearing.
OffsetSmearing 0 Get the constant for the miss-calibration studies: Sigma of the offset smearing.
ElectronsPerVcal 65.5 Calibration electrons/adc: electrons to VCAL conversion needed in misscalibrate()
ElectronsPerVcal_Offset -414 electrons to VCAL conversion Offset needed in misscalibrate()
ElectronPerAdc 135 ADC calibration
TofUpperCut 12.5 Time of flight cut in nanoseconds
TofLowerCut -12.5 Time of flight cut in nanoseconds
AdcFullScale 255 ADC saturation value is 255 = 8bit adc
TanLorentzAnglePerTesla_FPix 0.106 Lorentz angle per unit B field
TanLorentzAnglePerTesla_BPix 0.106 Lorentz angle per unit B field
AddNoisyPixels True Add pixels generated by noise
NoiseInElectrons 175 Pixel cell noise in electrons, relevant for generating noisy pixels
Alpha2Order True  
AddPixelInefficiency 0 Controls the pixel inefficiency
AddNoise True Add noise to the pixel signal
ChargeVCALSmearing True Smear the pixel charge with a gaussian which RMS is a function of the pixel charge (Danek's study)
GeometryType 'idealForDigi'  
useDB True  
CMS.LorentzAngle_DB True  
DeadModules_DB True  
killModules True  
DeadModules VPSet()  

Still hard-coded: Fluctuate generated charge along track subsegments: fluctuateCharge=conf_.getUntrackedParameter("FluctuateCharge",true); (SimTracker/SiPixelDigitizer/src/SiPixelDigitizerAlgorithm.cc)

How to run the pixel digitizer

You will need a file of SimHits. Usually you can choose a file containing SimHits on DBS, e.g /store/relval/CMSSW_3_3_3/RelValSingleMuPt10/GEN-SIM-RECO. In
there is a python script named testPixelDigitizer.py. This scripts has been implemented ( tested with CMSSW_3_3_3) with several process that you can run depending on what you want. You can choose among the following process:
Run the digitizer
process.p1 = cms.Path(process.mix*process.simSiPixelDigis)
Run the digis validation
process.p1 = cms.Path(process.mix*process.simSiPixelDigis*process.pixelDigisValid)
Look at cluster charge
process.p1 = cms.Path(process.mix*process.digis*process.siPixelRawData*process.siPixelDigis*process.pixeltrackerlocalreco)
Make DQM occupancy maps
process.p1 = cms.Path(process.mix*process.simSiPixelDigis*process.siPixelRawData*process.siPixelDigis)
followed by
cmsRun DQM_Pixel_digi.py
Look at residuals and pulls
process.p1 = cms.Path(process.mix*process.digis*process.siPixelRawData*process.siPixelDigis*process.rechits*process.tracks

with the following path for process.simhits, process.digis, process.rechits, process.tracks and process.trackinghits:

Simulation of hits in the tracker
process.simhits = cms.Sequence(process.g4SimHits*process.trackerHitsValidation)
Pixel digitization
process.digis = cms.Sequence(process.simSiPixelDigis*process.pixelDigisValid)
Pixel reconstruction-clusterisation
process.rechits = cms.Sequence(process.pixeltrackerlocalreco*process.siStripMatchedRecHits*process.pixRecHitsValid)
Tracker reconstructed hits
process.tracks = cms.Sequence(process.offlineBeamSpot*process.recopixelvertexing*process.trackingParticles
process.trackinghits = cms.Sequence(process.TrackRefitter*process.trackingRecHitsValid)

Validation plots

Configuration parameters: results (by M. Pioppi - Feb. 2006)

Created on 21-Oct-2009 by VesnaCuplov, Merged all informations from the old pixeldigitizer twiki page on 05-Dec-2009.

Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formateps chargeProfileAll.eps r1 manage 15.3 K 2019-05-09 - 16:56 PaulJeanSchutze Charge profiles before/after re-weighting, compared to data
PNGpng chargeProfileAll.png r1 manage 38.0 K 2019-05-09 - 17:00 PaulJeanSchutze Charge profiles before/after re-weighting, compared to data
Edit | Attach | Watch | Print version | History: r24 < r23 < r22 < r21 < r20 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r24 - 2019-05-09 - PaulJeanSchutze
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    CMSPublic All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2023 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback