CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.h

Go to the documentation of this file.
00001 #ifndef SiPixelDigitizerAlgorithm_h
00002 #define SiPixelDigitizerAlgorithm_h
00003 
00004 #include <map>
00005 #include <memory>
00006 #include <vector>
00007 #include <iostream>
00008 #include "DataFormats/GeometrySurface/interface/GloballyPositioned.h"
00009 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011 #include "SimDataFormats/EncodedEventId/interface/EncodedEventId.h"
00012 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00013 #include "SimTracker/Common/interface/SimHitInfoForLinks.h"
00014 #include "DataFormats/Math/interface/approx_exp.h"
00015 
00016 // forward declarations
00017 
00018 
00019 // For the random numbers
00020 namespace CLHEP {
00021   class HepRandomEngine;
00022   class RandGaussQ;
00023   class RandFlat;
00024 }
00025 
00026 namespace edm {
00027   class EventSetup;
00028   class ParameterSet;
00029 }
00030 
00031 class DetId;
00032 class GaussianTailNoiseGenerator;
00033 class PixelDigi;
00034 class PixelDigiSimLink;
00035 class PixelGeomDetUnit;
00036 class SiG4UniversalFluctuation;
00037 class SiPixelFedCablingMap;
00038 class SiPixelGainCalibrationOfflineSimService;
00039 class SiPixelLorentzAngle;
00040 class SiPixelQuality;
00041 class TrackerGeometry;
00042 class TrackerTopology;
00043 
00044 class SiPixelDigitizerAlgorithm  {
00045  public:
00046   SiPixelDigitizerAlgorithm(const edm::ParameterSet& conf, CLHEP::HepRandomEngine&);
00047   ~SiPixelDigitizerAlgorithm();
00048 
00049   // initialization that cannot be done in the constructor
00050   void init(const edm::EventSetup& es);
00051   
00052   void initializeEvent() {
00053     _signal.clear();
00054   }
00055 
00056   //run the algorithm to digitize a single det
00057   void accumulateSimHits(const std::vector<PSimHit>::const_iterator inputBegin,
00058                          const std::vector<PSimHit>::const_iterator inputEnd,
00059                          const PixelGeomDetUnit *pixdet,
00060                          const GlobalVector& bfield);
00061   void digitize(const PixelGeomDetUnit *pixdet,
00062                 std::vector<PixelDigi>& digis,
00063                 std::vector<PixelDigiSimLink>& simlinks,
00064                 const TrackerTopology *tTopo);
00065 
00066  private:
00067   
00068   //Accessing Lorentz angle from DB:
00069   edm::ESHandle<SiPixelLorentzAngle> SiPixelLorentzAngle_;
00070 
00071   //Accessing Dead pixel modules from DB:
00072   edm::ESHandle<SiPixelQuality> SiPixelBadModule_;
00073 
00074   //Accessing Map and Geom:
00075   edm::ESHandle<SiPixelFedCablingMap> map_;
00076   edm::ESHandle<TrackerGeometry> geom_;
00077 
00078   // Define internal classes
00079 
00080   // definition class
00081   //
00082   class Amplitude {
00083   public:
00084     Amplitude() : _amp(0.0) {}
00085     Amplitude( float amp, float frac) :
00086       _amp(amp), _frac(1, frac), _hitInfo() {
00087     //in case of digi from noisypixels
00088       //the MC information are removed 
00089       if (_frac[0]<-0.5) {
00090         _frac.pop_back();
00091       }
00092     }
00093 
00094     Amplitude( float amp, const PSimHit* hitp, float frac) :
00095       _amp(amp), _frac(1, frac), _hitInfo(new SimHitInfoForLinks(hitp)) {
00096 
00097     //in case of digi from noisypixels
00098       //the MC information are removed 
00099       if (_frac[0]<-0.5) {
00100         _frac.pop_back();
00101         _hitInfo->trackIds_.pop_back();
00102       }
00103     }
00104 
00105     // can be used as a float by convers.
00106     operator float() const { return _amp;}
00107     float ampl() const {return _amp;}
00108     std::vector<float> individualampl() const {return _frac;}
00109     const std::vector<unsigned int>& trackIds() const {
00110       return _hitInfo->trackIds_;
00111     }
00112     const std::shared_ptr<SimHitInfoForLinks>& hitInfo() const {return _hitInfo;}
00113 
00114     void operator+=( const Amplitude& other) {
00115       _amp += other._amp;
00116       //in case of contribution of noise to the digi
00117       //the MC information are removed 
00118       if (other._frac[0]>-0.5){
00119         if(other._hitInfo) {
00120           std::vector<unsigned int>& otherTrackIds = other._hitInfo->trackIds_;
00121           if(_hitInfo) {
00122             std::vector<unsigned int>& trackIds = _hitInfo->trackIds_;
00123             trackIds.insert(trackIds.end(), otherTrackIds.begin(), otherTrackIds.end());
00124           } else {
00125             _hitInfo.reset(new SimHitInfoForLinks(*other._hitInfo));
00126           }
00127         }
00128         _frac.insert(_frac.end(), other._frac.begin(), other._frac.end());
00129       }
00130    }
00131    const EncodedEventId& eventId() const {
00132      return _hitInfo->eventId_;
00133    }
00134     void operator+=( const float& amp) {
00135       _amp += amp;
00136     }
00137    
00138     void set (const float amplitude) {  // Used to reset the amplitude
00139       _amp = amplitude;
00140     }
00141 /*     void setind (const float indamplitude) {  // Used to reset the amplitude */
00142 /*       _frac = idamplitude; */
00143 /*     } */
00144   private:
00145     float _amp;
00146     std::vector<float> _frac;
00147     std::shared_ptr<SimHitInfoForLinks> _hitInfo;
00148   };  // end class Amplitude
00149 
00150   // Define a class to hold the calibration parameters per pixel
00151   // Internal
00152   class CalParameters {
00153   public:
00154     float p0;
00155     float p1;
00156     float p2;
00157     float p3;
00158   };
00159   //
00160   // Define a class for 3D ionization points and energy
00161   //
00165   class EnergyDepositUnit{
00166   public:
00167     EnergyDepositUnit(): _energy(0),_position(0,0,0){}
00168     EnergyDepositUnit(float energy,float x, float y, float z):
00169     _energy(energy),_position(x,y,z){}
00170     EnergyDepositUnit(float energy, Local3DPoint position):
00171     _energy(energy),_position(position){}
00172     float x() const{return _position.x();}
00173     float y() const{return _position.y();}
00174     float z() const{return _position.z();}
00175     float energy() const { return _energy;}
00176   private:
00177     float _energy;
00178     Local3DPoint _position;
00179   };
00180 
00181   //
00182   // define class to store signals on the collection surface
00183   //
00188   class SignalPoint {
00189   public:
00190     SignalPoint() : _pos(0,0), _time(0), _amplitude(0), 
00191       _sigma_x(1.), _sigma_y(1.), _hitp(0) {}
00192     
00193     SignalPoint( float x, float y, float sigma_x, float sigma_y,
00194                  float t, float a=1.0) :
00195     _pos(x,y), _time(t), _amplitude(a), _sigma_x(sigma_x), 
00196       _sigma_y(sigma_y), _hitp(0) {}
00197     
00198     SignalPoint( float x, float y, float sigma_x, float sigma_y,
00199                  float t, const PSimHit& hit, float a=1.0) :
00200     _pos(x,y), _time(t), _amplitude(a), _sigma_x(sigma_x), 
00201       _sigma_y(sigma_y),_hitp(&hit) {}
00202     
00203     const LocalPoint& position() const { return _pos;}
00204     float x()         const { return _pos.x();}
00205     float y()         const { return _pos.y();}
00206     float sigma_x()   const { return _sigma_x;}
00207     float sigma_y()   const { return _sigma_y;}
00208     float time()      const { return _time;}
00209     float amplitude() const { return _amplitude;}
00210     const PSimHit& hit()           { return *_hitp;}
00211     SignalPoint& set_amplitude( float amp) { _amplitude = amp; return *this;}
00212     
00213   
00214 
00215   private:
00216     LocalPoint         _pos;
00217     float              _time;
00218     float              _amplitude;
00219     float              _sigma_x;   // gaussian sigma in the x direction (cm)
00220     float              _sigma_y;   //    "       "          y direction (cm) */
00221     const PSimHit*   _hitp;
00222   };
00223  
00224   //
00225   // PixelEfficiencies struct
00226   //
00230    struct PixelEfficiencies {
00231      PixelEfficiencies(const edm::ParameterSet& conf, bool AddPixelInefficiency, int NumberOfBarrelLayers, int NumberOfEndcapDisks);
00232      float thePixelEfficiency[20];     // Single pixel effciency
00233      float thePixelColEfficiency[20];  // Column effciency
00234      float thePixelChipEfficiency[20]; // ROC efficiency
00235      unsigned int FPixIndex;         // The Efficiency index for FPix Disks
00236    };
00237 
00238  private:
00239 
00240     // Internal typedefs
00241     typedef std::map<int, Amplitude, std::less<int> > signal_map_type;  // from Digi.Skel.
00242     typedef signal_map_type::iterator          signal_map_iterator; // from Digi.Skel.  
00243     typedef signal_map_type::const_iterator    signal_map_const_iterator; // from Digi.Skel.  
00244     typedef std::map<unsigned int, std::vector<float>,std::less<unsigned int> > simlink_map;
00245     typedef std::map<uint32_t, signal_map_type> signalMaps;
00246     typedef GloballyPositioned<double>      Frame;
00247     typedef std::vector<edm::ParameterSet> Parameters;
00248 
00249     // Contains the accumulated hit info.
00250     signalMaps _signal;
00251 
00252     const bool makeDigiSimLinks_;
00253 
00254     const bool use_ineff_from_db_;
00255     const bool use_module_killing_; // remove or not the dead pixel modules
00256     const bool use_deadmodule_DB_; // if we want to get dead pixel modules from the DataBase.
00257     const bool use_LorentzAngle_DB_; // if we want to get Lorentz angle from the DataBase.
00258 
00259     const Parameters DeadModules;
00260 
00261     // Variables 
00262     //external parameters 
00263     // go from Geant energy GeV to number of electrons
00264     const float GeVperElectron; // 3.7E-09 
00265     
00266     //-- drift
00267     const float Sigma0; //=0.0007  // Charge diffusion in microns for 300 micron Si
00268     const float Dist300;  //=0.0300  // Define 300microns for normalization 
00269     const bool alpha2Order;          // Switch on/off of E.B effect 
00270 
00271 
00272  
00273     //-- induce_signal
00274     const float ClusterWidth;       // Gaussian charge cutoff width in sigma units
00275     //-- Allow for upgrades
00276     const int NumberOfBarrelLayers;     // Default = 3
00277     const int NumberOfEndcapDisks;      // Default = 2
00278 
00279     //-- make_digis 
00280     const float theElectronPerADC;     // Gain, number of electrons per adc count.
00281     const int theAdcFullScale;         // Saturation count, 255=8bit.
00282     const int theAdcFullScaleStack;    // Saturation count for stack layers, 1=1bit.
00283     const int theFirstStackLayer;      // The first BPix layer to use theAdcFullScaleStack.
00284     const float theNoiseInElectrons;   // Noise (RMS) in units of electrons.
00285     const float theReadoutNoise;       // Noise of the readount chain in elec,
00286                                  //inludes DCOL-Amp,TBM-Amp, Alt, AOH,OptRec.
00287 
00288     const float theThresholdInE_FPix;  // Pixel threshold in electrons FPix.
00289     const float theThresholdInE_BPix;  // Pixel threshold in electrons BPix.
00290     const float theThresholdInE_BPix_L1; // In case the BPix layer1 gets a different threshold
00291 
00292     const double theThresholdSmearing_FPix;
00293     const double theThresholdSmearing_BPix;
00294     const double theThresholdSmearing_BPix_L1;
00295 
00296     const double electronsPerVCAL;          // for electrons - VCAL conversion
00297     const double electronsPerVCAL_Offset;   // in misscalibrate()
00298 
00299     const float theTofLowerCut;             // Cut on the particle TOF
00300     const float theTofUpperCut;             // Cut on the particle TOF
00301     const float tanLorentzAnglePerTesla_FPix;   //FPix Lorentz angle tangent per Tesla
00302     const float tanLorentzAnglePerTesla_BPix;   //BPix Lorentz angle tangent per Tesla
00303 
00304     const float FPix_p0;
00305     const float FPix_p1;
00306     const float FPix_p2;
00307     const float FPix_p3;
00308     const float BPix_p0;
00309     const float BPix_p1;
00310     const float BPix_p2;
00311     const float BPix_p3;
00312 
00313 
00314     //-- add_noise
00315     const bool addNoise;
00316     const bool addChargeVCALSmearing;
00317     const bool addNoisyPixels;
00318     const bool fluctuateCharge;
00319     //-- pixel efficiency
00320     const bool AddPixelInefficiency;        // bool to read in inefficiencies
00321 
00322     const bool addThresholdSmearing;
00323         
00324     //-- calibration smearing
00325     const bool doMissCalibrate;         // Switch on the calibration smearing
00326     const float theGainSmearing;        // The sigma of the gain fluctuation (around 1)
00327     const float theOffsetSmearing;      // The sigma of the offset fluct. (around 0)
00328     
00329     // pseudoRadDamage
00330     const double pseudoRadDamage;       // Decrease the amount off freed charge that reaches the collector
00331     const double pseudoRadDamageRadius; // Only apply pseudoRadDamage to pixels with radius<=pseudoRadDamageRadius
00332     // The PDTable
00333     //HepPDTable *particleTable;
00334     //ParticleDataTable *particleTable;
00335 
00336     //-- charge fluctuation
00337     const double tMax;  // The delta production cut, should be as in OSCAR = 30keV
00338     //                                           cmsim = 100keV
00339 
00340     // The eloss fluctuation class from G4. Is the right place? 
00341     const std::unique_ptr<SiG4UniversalFluctuation> fluctuate;   // make a pointer
00342     const std::unique_ptr<GaussianTailNoiseGenerator> theNoiser;
00343 
00344     // To store calibration constants
00345     const std::map<int,CalParameters,std::less<int> > calmap;
00346 
00347 
00348     //-- additional member functions    
00349     // Private methods
00350     std::map<int,CalParameters,std::less<int> > initCal() const;
00351     void primary_ionization( const PSimHit& hit, std::vector<EnergyDepositUnit>& ionization_points) const;
00352     void drift(const PSimHit& hit,
00353                const PixelGeomDetUnit *pixdet,
00354                const GlobalVector& bfield,
00355                const std::vector<EnergyDepositUnit>& ionization_points,
00356                std::vector<SignalPoint>& collection_points) const;
00357     void induce_signal(const PSimHit& hit,
00358                        const PixelGeomDetUnit *pixdet,
00359                        const std::vector<SignalPoint>& collection_points);
00360     void fluctuateEloss(int particleId, float momentum, float eloss, 
00361                         float length, int NumberOfSegments,
00362                         float elossVector[]) const;
00363     void add_noise(const PixelGeomDetUnit *pixdet,
00364                    float thePixelThreshold);
00365     void make_digis(float thePixelThresholdInE,
00366                     uint32_t detID,
00367                     std::vector<PixelDigi>& digis,
00368                     std::vector<PixelDigiSimLink>& simlinks,
00369                     const TrackerTopology *tTopo) const;
00370     void pixel_inefficiency(const PixelEfficiencies& eff,
00371                             const PixelGeomDetUnit* pixdet,
00372                             const TrackerTopology *tTopo);
00373 
00374     void pixel_inefficiency_db(uint32_t detID);
00375 
00376     // access to the gain calibration payloads in the db. Only gets initialized if check_dead_pixels_ is set to true.
00377     const std::unique_ptr<SiPixelGainCalibrationOfflineSimService> theSiPixelGainCalibrationService_;    
00378     float missCalibrate(uint32_t detID, int col, int row, float amp) const;  
00379     LocalVector DriftDirection(const PixelGeomDetUnit* pixdet,
00380                                const GlobalVector& bfield,
00381                                const DetId& detId) const;
00382 
00383     void module_killing_conf(uint32_t detID); // remove dead modules using the list in the configuration file PixelDigi_cfi.py
00384     void module_killing_DB(uint32_t detID);  // remove dead modules uisng the list in the DB
00385 
00386     const PixelEfficiencies pixelEfficiencies_;
00387 
00388    // For random numbers
00389     const std::unique_ptr<CLHEP::RandFlat> flatDistribution_;
00390     const std::unique_ptr<CLHEP::RandGaussQ> gaussDistribution_;
00391     const std::unique_ptr<CLHEP::RandGaussQ> gaussDistributionVCALNoise_;
00392 
00393     // Threshold gaussian smearing:
00394     const std::unique_ptr<CLHEP::RandGaussQ> smearedThreshold_FPix_;
00395     const std::unique_ptr<CLHEP::RandGaussQ> smearedThreshold_BPix_;
00396     const std::unique_ptr<CLHEP::RandGaussQ> smearedThreshold_BPix_L1_;
00397 
00398     double calcQ(float x) const {
00399       // need erf(x/sqrt2)
00400       //float x2=0.5*x*x;
00401       //float a=0.147;
00402       //double erf=sqrt(1.0f-exp( -1.0f*x2*( (4/M_PI)+a*x2)/(1.0+a*x2)));
00403       //if (x<0.) erf*=-1.0;
00404       //return 0.5*(1.0-erf);
00405 
00406       auto xx=std::min(0.5f*x*x,12.5f);
00407       return 0.5*(1.0-std::copysign(std::sqrt(1.f- unsafe_expf<4>(-xx*(1.f+0.2733f/(1.f+0.147f*xx)) )),x));
00408     }
00409 
00410 
00411 };
00412 
00413 #endif