00001
00002
00003
00004 #include <vector>
00005 #include <algorithm>
00006 #include <iostream>
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "SiStripDigitizerAlgorithm.h"
00011 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00012 #include "DataFormats/Common/interface/DetSetVector.h"
00013 #include "DataFormats/GeometrySurface/interface/BoundSurface.h"
00014 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
00015 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
00016 #include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h"
00017 #include "CondFormats/DataRecord/interface/SiStripCondDataRecords.h"
00018 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00019 #include "CondFormats/SiStripObjects/interface/SiStripThreshold.h"
00020 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
00021 #include "CondFormats/SiStripObjects/interface/SiStripBadStrip.h"
00022 #include "CLHEP/Random/RandFlat.h"
00023
00024 SiStripDigitizerAlgorithm::SiStripDigitizerAlgorithm(const edm::ParameterSet& conf, CLHEP::HepRandomEngine& eng):
00025 lorentzAngleName(conf.getParameter<std::string>("LorentzAngle")),
00026 theThreshold(conf.getParameter<double>("NoiseSigmaThreshold")),
00027 cmnRMStib(conf.getParameter<double>("cmnRMStib")),
00028 cmnRMStob(conf.getParameter<double>("cmnRMStob")),
00029 cmnRMStid(conf.getParameter<double>("cmnRMStid")),
00030 cmnRMStec(conf.getParameter<double>("cmnRMStec")),
00031 APVSaturationProb(conf.getParameter<double>("APVSaturationProb")),
00032 makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false)),
00033 peakMode(conf.getParameter<bool>("APVpeakmode")),
00034 noise(conf.getParameter<bool>("Noise")),
00035 RealPedestals(conf.getParameter<bool>("RealPedestals")),
00036 SingleStripNoise(conf.getParameter<bool>("SingleStripNoise")),
00037 CommonModeNoise(conf.getParameter<bool>("CommonModeNoise")),
00038 BaselineShift(conf.getParameter<bool>("BaselineShift")),
00039 APVSaturationFromHIP(conf.getParameter<bool>("APVSaturationFromHIP")),
00040 theFedAlgo(conf.getParameter<int>("FedAlgorithm")),
00041 zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
00042 theElectronPerADC(conf.getParameter<double>( peakMode ? "electronPerAdcPeak" : "electronPerAdcDec" )),
00043 theTOFCutForPeak(conf.getParameter<double>("TOFCutForPeak")),
00044 theTOFCutForDeconvolution(conf.getParameter<double>("TOFCutForDeconvolution")),
00045 tofCut(peakMode ? theTOFCutForPeak : theTOFCutForDeconvolution),
00046 cosmicShift(conf.getUntrackedParameter<double>("CosmicDelayShift")),
00047 inefficiency(conf.getParameter<double>("Inefficiency")),
00048 pedOffset((unsigned int)conf.getParameter<double>("PedestalsOffset")),
00049 theSiHitDigitizer(new SiHitDigitizer(conf, eng)),
00050 theSiPileUpSignals(new SiPileUpSignals()),
00051 theSiNoiseAdder(new SiGaussianTailNoiseAdder(theThreshold, eng)),
00052 theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC)),
00053 theSiZeroSuppress(new SiStripFedZeroSuppression(theFedAlgo)),
00054 theFlatDistribution(new CLHEP::RandFlat(eng, 0., 1.)) {
00055
00056 if (peakMode) {
00057 LogDebug("StripDigiInfo")<<"APVs running in peak mode (poor time resolution)";
00058 } else {
00059 LogDebug("StripDigiInfo")<<"APVs running in deconvolution mode (good time resolution)";
00060 };
00061 }
00062
00063 SiStripDigitizerAlgorithm::~SiStripDigitizerAlgorithm(){
00064 }
00065
00066 void
00067 SiStripDigitizerAlgorithm::initializeDetUnit(StripGeomDetUnit* det, const edm::EventSetup& iSetup) {
00068 edm::ESHandle<SiStripBadStrip> deadChannelHandle;
00069 iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
00070
00071 unsigned int detId = det->geographicalId().rawId();
00072 int numStrips = (det->specificTopology()).nstrips();
00073
00074 SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
00075
00076 std::vector<bool>& badChannels = allBadChannels[detId];
00077 badChannels.clear();
00078 badChannels.insert(badChannels.begin(), numStrips, false);
00079 for(SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
00080 SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
00081 for(int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) badChannels[strip] = true;
00082 }
00083 firstChannelsWithSignal[detId] = numStrips;
00084 lastChannelsWithSignal[detId]= 0;
00085 }
00086
00087 void
00088 SiStripDigitizerAlgorithm::initializeEvent(const edm::EventSetup& iSetup) {
00089 theSiPileUpSignals->reset();
00090
00091
00092 edm::ESHandle<ParticleDataTable> pdt;
00093 iSetup.getData(pdt);
00094 setParticleDataTable(&*pdt);
00095 iSetup.get<SiStripLorentzAngleSimRcd>().get(lorentzAngleName,lorentzAngleHandle);
00096 }
00097
00098
00099
00100
00101 void
00102 SiStripDigitizerAlgorithm::accumulateSimHits(std::vector<PSimHit>::const_iterator inputBegin,
00103 std::vector<PSimHit>::const_iterator inputEnd,
00104 const StripGeomDetUnit* det,
00105 const GlobalVector& bfield,
00106 const TrackerTopology *tTopo) {
00107
00108 unsigned int detID = det->geographicalId().rawId();
00109 int numStrips = (det->specificTopology()).nstrips();
00110
00111 std::vector<bool>& badChannels = allBadChannels[detID];
00112 size_t thisFirstChannelWithSignal = numStrips;
00113 size_t thisLastChannelWithSignal = numStrips;
00114
00115 float langle = (lorentzAngleHandle.isValid()) ? lorentzAngleHandle->getLorentzAngle(detID) : 0.;
00116
00117 std::vector<double> locAmpl(numStrips, 0.);
00118
00119
00120
00121 uint32_t detId = det->geographicalId().rawId();
00122
00123 if(theFlatDistribution->fire()>inefficiency) {
00124 for (std::vector<PSimHit>::const_iterator simHitIter = inputBegin; simHitIter != inputEnd; ++simHitIter) {
00125
00126 if((*simHitIter).detUnitId() != detId) {
00127 continue;
00128 }
00129
00130 if (std::fabs(simHitIter->tof() - cosmicShift - det->surface().toGlobal(simHitIter->localPosition()).mag()/30.) < tofCut && simHitIter->energyLoss()>0) {
00131 size_t localFirstChannel = numStrips;
00132 size_t localLastChannel = 0;
00133
00134 theSiHitDigitizer->processHit(&*simHitIter, *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo);
00135
00136
00137
00138
00139 if(APVSaturationFromHIP&&!zeroSuppression){
00140 int pdg_id = simHitIter->particleType();
00141 particle = pdt->particle(pdg_id);
00142 if(particle != NULL){
00143 float charge = particle->charge();
00144 bool isHadron = particle->isHadron();
00145 if(charge!=0 && isHadron){
00146 if(theFlatDistribution->fire()<APVSaturationProb){
00147 int FirstAPV = localFirstChannel/128;
00148 int LastAPV = localLastChannel/128;
00149 std::cout << "-------------------HIP--------------" << std::endl;
00150 std::cout << "Killing APVs " << FirstAPV << " - " <<LastAPV << " " << detID <<std::endl;
00151 for(int strip = FirstAPV*128; strip < LastAPV*128 +128; ++strip) {
00152 badChannels[strip] = true;
00153 }
00154
00155
00156
00157 }
00158 }
00159 }
00160 }
00161
00162
00163 if(thisFirstChannelWithSignal > localFirstChannel) thisFirstChannelWithSignal = localFirstChannel;
00164 if(thisLastChannelWithSignal < localLastChannel) thisLastChannelWithSignal = localLastChannel;
00165 }
00166 }
00167 }
00168 theSiPileUpSignals->add(detID, locAmpl, thisFirstChannelWithSignal, thisLastChannelWithSignal);
00169
00170 if(firstChannelsWithSignal[detID] > thisFirstChannelWithSignal) firstChannelsWithSignal[detID] = thisFirstChannelWithSignal;
00171 if(lastChannelsWithSignal[detID] < thisLastChannelWithSignal) lastChannelsWithSignal[detID] = thisLastChannelWithSignal;
00172 }
00173
00174 void
00175 SiStripDigitizerAlgorithm::digitize(
00176 edm::DetSet<SiStripDigi>& outdigi,
00177 edm::DetSet<SiStripRawDigi>& outrawdigi,
00178 const StripGeomDetUnit *det,
00179 edm::ESHandle<SiStripGain> & gainHandle,
00180 edm::ESHandle<SiStripThreshold> & thresholdHandle,
00181 edm::ESHandle<SiStripNoises> & noiseHandle,
00182 edm::ESHandle<SiStripPedestals> & pedestalHandle) {
00183 unsigned int detID = det->geographicalId().rawId();
00184 int numStrips = (det->specificTopology()).nstrips();
00185
00186 const SiPileUpSignals::SignalMapType* theSignal(theSiPileUpSignals->getSignal(detID));
00187
00188 std::vector<double> detAmpl(numStrips, 0.);
00189 if(theSignal) {
00190 for(const auto& amp : *theSignal) {
00191 detAmpl[amp.first] = amp.second;
00192 }
00193 }
00194
00195
00196 std::vector<bool>& badChannels = allBadChannels[detID];
00197 for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
00198
00199 SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00200 SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
00201 SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
00202
00203
00204
00205 auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
00206 auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
00207
00208 if(zeroSuppression){
00209 if(noise){
00210 int RefStrip = int(numStrips/2.);
00211 while(RefStrip<numStrips&&badChannels[RefStrip]){
00212 RefStrip++;
00213 }
00214 if(RefStrip<numStrips){
00215 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
00216 float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
00217 theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue);
00218 }
00219 }
00220 DigitalVecType digis;
00221 theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
00222 outdigi.data = digis;
00223 }
00224
00225
00226 if(!zeroSuppression){
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 if(BaselineShift){
00246 theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
00247 }
00248
00249
00250
00251 if(noise){
00252 std::vector<float> noiseRMSv;
00253 noiseRMSv.clear();
00254 noiseRMSv.insert(noiseRMSv.begin(),numStrips,0.);
00255
00256 if(SingleStripNoise){
00257 for(int strip=0; strip< numStrips; ++strip){
00258 if(!badChannels[strip]) noiseRMSv[strip] = (noiseHandle->getNoise(strip,detNoiseRange))* theElectronPerADC;
00259 }
00260
00261 } else {
00262 int RefStrip = 0;
00263 while(RefStrip<numStrips&&badChannels[RefStrip]){
00264 RefStrip++;
00265 }
00266 if(RefStrip<numStrips){
00267 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange) *theElectronPerADC;
00268 for(int strip=0; strip< numStrips; ++strip){
00269 if(!badChannels[strip]) noiseRMSv[strip] = noiseRMS;
00270 }
00271 }
00272 }
00273
00274 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv);
00275 }
00276
00277
00278
00279 if(CommonModeNoise){
00280 float cmnRMS = 0.;
00281 DetId detId(detID);
00282 uint32_t SubDet = detId.subdetId();
00283 if(SubDet==3){
00284 cmnRMS = cmnRMStib;
00285 }else if(SubDet==4){
00286 cmnRMS = cmnRMStid;
00287 }else if(SubDet==5){
00288 cmnRMS = cmnRMStob;
00289 }else if(SubDet==6){
00290 cmnRMS = cmnRMStec;
00291 }
00292 cmnRMS *= theElectronPerADC;
00293 theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels);
00294 }
00295
00296
00297
00298
00299
00300 std::vector<float> vPeds;
00301 vPeds.clear();
00302 vPeds.insert(vPeds.begin(),numStrips,0.);
00303
00304 if(RealPedestals){
00305 for(int strip=0; strip< numStrips; ++strip){
00306 if(!badChannels[strip]) vPeds[strip] = (pedestalHandle->getPed(strip,detPedestalRange)+pedOffset)* theElectronPerADC;
00307 }
00308 } else {
00309 for(int strip=0; strip< numStrips; ++strip){
00310 if(!badChannels[strip]) vPeds[strip] = pedOffset* theElectronPerADC;
00311 }
00312 }
00313
00314 theSiNoiseAdder->addPedestals(detAmpl, vPeds);
00315
00316
00317
00318
00319
00320
00321 DigitalRawVecType rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle, detID);
00322 outrawdigi.data = rawdigis;
00323
00324
00325 }
00326 }