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
00017
00018
00019
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
00050 void init(const edm::EventSetup& es);
00051
00052 void initializeEvent() {
00053 _signal.clear();
00054 }
00055
00056
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
00069 edm::ESHandle<SiPixelLorentzAngle> SiPixelLorentzAngle_;
00070
00071
00072 edm::ESHandle<SiPixelQuality> SiPixelBadModule_;
00073
00074
00075 edm::ESHandle<SiPixelFedCablingMap> map_;
00076 edm::ESHandle<TrackerGeometry> geom_;
00077
00078
00079
00080
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
00088
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
00098
00099 if (_frac[0]<-0.5) {
00100 _frac.pop_back();
00101 _hitInfo->trackIds_.pop_back();
00102 }
00103 }
00104
00105
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
00117
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) {
00139 _amp = amplitude;
00140 }
00141
00142
00143
00144 private:
00145 float _amp;
00146 std::vector<float> _frac;
00147 std::shared_ptr<SimHitInfoForLinks> _hitInfo;
00148 };
00149
00150
00151
00152 class CalParameters {
00153 public:
00154 float p0;
00155 float p1;
00156 float p2;
00157 float p3;
00158 };
00159
00160
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
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;
00220 float _sigma_y;
00221 const PSimHit* _hitp;
00222 };
00223
00224
00225
00226
00230 struct PixelEfficiencies {
00231 PixelEfficiencies(const edm::ParameterSet& conf, bool AddPixelInefficiency, int NumberOfBarrelLayers, int NumberOfEndcapDisks);
00232 float thePixelEfficiency[20];
00233 float thePixelColEfficiency[20];
00234 float thePixelChipEfficiency[20];
00235 unsigned int FPixIndex;
00236 };
00237
00238 private:
00239
00240
00241 typedef std::map<int, Amplitude, std::less<int> > signal_map_type;
00242 typedef signal_map_type::iterator signal_map_iterator;
00243 typedef signal_map_type::const_iterator signal_map_const_iterator;
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
00250 signalMaps _signal;
00251
00252 const bool makeDigiSimLinks_;
00253
00254 const bool use_ineff_from_db_;
00255 const bool use_module_killing_;
00256 const bool use_deadmodule_DB_;
00257 const bool use_LorentzAngle_DB_;
00258
00259 const Parameters DeadModules;
00260
00261
00262
00263
00264 const float GeVperElectron;
00265
00266
00267 const float Sigma0;
00268 const float Dist300;
00269 const bool alpha2Order;
00270
00271
00272
00273
00274 const float ClusterWidth;
00275
00276 const int NumberOfBarrelLayers;
00277 const int NumberOfEndcapDisks;
00278
00279
00280 const float theElectronPerADC;
00281 const int theAdcFullScale;
00282 const int theAdcFullScaleStack;
00283 const int theFirstStackLayer;
00284 const float theNoiseInElectrons;
00285 const float theReadoutNoise;
00286
00287
00288 const float theThresholdInE_FPix;
00289 const float theThresholdInE_BPix;
00290 const float theThresholdInE_BPix_L1;
00291
00292 const double theThresholdSmearing_FPix;
00293 const double theThresholdSmearing_BPix;
00294 const double theThresholdSmearing_BPix_L1;
00295
00296 const double electronsPerVCAL;
00297 const double electronsPerVCAL_Offset;
00298
00299 const float theTofLowerCut;
00300 const float theTofUpperCut;
00301 const float tanLorentzAnglePerTesla_FPix;
00302 const float tanLorentzAnglePerTesla_BPix;
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
00315 const bool addNoise;
00316 const bool addChargeVCALSmearing;
00317 const bool addNoisyPixels;
00318 const bool fluctuateCharge;
00319
00320 const bool AddPixelInefficiency;
00321
00322 const bool addThresholdSmearing;
00323
00324
00325 const bool doMissCalibrate;
00326 const float theGainSmearing;
00327 const float theOffsetSmearing;
00328
00329
00330 const double pseudoRadDamage;
00331 const double pseudoRadDamageRadius;
00332
00333
00334
00335
00336
00337 const double tMax;
00338
00339
00340
00341 const std::unique_ptr<SiG4UniversalFluctuation> fluctuate;
00342 const std::unique_ptr<GaussianTailNoiseGenerator> theNoiser;
00343
00344
00345 const std::map<int,CalParameters,std::less<int> > calmap;
00346
00347
00348
00349
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
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);
00384 void module_killing_DB(uint32_t detID);
00385
00386 const PixelEfficiencies pixelEfficiencies_;
00387
00388
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
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
00400
00401
00402
00403
00404
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