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
00107 unsigned int detID = det->geographicalId().rawId();
00108 int numStrips = (det->specificTopology()).nstrips();
00109
00110 std::vector<bool>& badChannels = allBadChannels[detID];
00111 size_t thisFirstChannelWithSignal = numStrips;
00112 size_t thisLastChannelWithSignal = numStrips;
00113
00114 float langle = (lorentzAngleHandle.isValid()) ? lorentzAngleHandle->getLorentzAngle(detID) : 0.;
00115
00116 std::vector<double> locAmpl(numStrips, 0.);
00117
00118
00119
00120 uint32_t detId = det->geographicalId().rawId();
00121
00122 if(theFlatDistribution->fire()>inefficiency) {
00123 for (std::vector<PSimHit>::const_iterator simHitIter = inputBegin; simHitIter != inputEnd; ++simHitIter) {
00124
00125 if((*simHitIter).detUnitId() != detId) {
00126 continue;
00127 }
00128
00129 if (std::fabs(simHitIter->tof() - cosmicShift - det->surface().toGlobal(simHitIter->localPosition()).mag()/30.) < tofCut && simHitIter->energyLoss()>0) {
00130 size_t localFirstChannel = numStrips;
00131 size_t localLastChannel = 0;
00132
00133 theSiHitDigitizer->processHit(&*simHitIter, *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel);
00134
00135
00136
00137
00138 if(APVSaturationFromHIP&&!zeroSuppression){
00139 int pdg_id = simHitIter->particleType();
00140 particle = pdt->particle(pdg_id);
00141 if(particle != NULL){
00142 float charge = particle->charge();
00143 bool isHadron = particle->isHadron();
00144 if(charge!=0 && isHadron){
00145 if(theFlatDistribution->fire()<APVSaturationProb){
00146 int FirstAPV = localFirstChannel/128;
00147 int LastAPV = localLastChannel/128;
00148 std::cout << "-------------------HIP--------------" << std::endl;
00149 std::cout << "Killing APVs " << FirstAPV << " - " <<LastAPV << " " << detID <<std::endl;
00150 for(int strip = FirstAPV*128; strip < LastAPV*128 +128; ++strip) {
00151 badChannels[strip] = true;
00152 }
00153
00154
00155
00156 }
00157 }
00158 }
00159 }
00160
00161
00162 if(thisFirstChannelWithSignal > localFirstChannel) thisFirstChannelWithSignal = localFirstChannel;
00163 if(thisLastChannelWithSignal < localLastChannel) thisLastChannelWithSignal = localLastChannel;
00164 }
00165 }
00166 }
00167 theSiPileUpSignals->add(detID, locAmpl, thisFirstChannelWithSignal, thisLastChannelWithSignal);
00168
00169 if(firstChannelsWithSignal[detID] > thisFirstChannelWithSignal) firstChannelsWithSignal[detID] = thisFirstChannelWithSignal;
00170 if(lastChannelsWithSignal[detID] < thisLastChannelWithSignal) lastChannelsWithSignal[detID] = thisLastChannelWithSignal;
00171 }
00172
00173 void
00174 SiStripDigitizerAlgorithm::digitize(
00175 edm::DetSet<SiStripDigi>& outdigi,
00176 edm::DetSet<SiStripRawDigi>& outrawdigi,
00177 const StripGeomDetUnit *det,
00178 edm::ESHandle<SiStripGain> & gainHandle,
00179 edm::ESHandle<SiStripThreshold> & thresholdHandle,
00180 edm::ESHandle<SiStripNoises> & noiseHandle,
00181 edm::ESHandle<SiStripPedestals> & pedestalHandle) {
00182 unsigned int detID = det->geographicalId().rawId();
00183 int numStrips = (det->specificTopology()).nstrips();
00184
00185 const SiPileUpSignals::SignalMapType* theSignal(theSiPileUpSignals->getSignal(detID));
00186
00187 std::vector<double> detAmpl(numStrips, 0.);
00188 if(theSignal) {
00189 for(const auto& amp : *theSignal) {
00190 detAmpl[amp.first] = amp.second;
00191 }
00192 }
00193
00194
00195 std::vector<bool>& badChannels = allBadChannels[detID];
00196 for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
00197
00198 SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00199 SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
00200 SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
00201
00202
00203
00204 auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
00205 auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
00206
00207 if(zeroSuppression){
00208 if(noise){
00209 int RefStrip = int(numStrips/2.);
00210 while(RefStrip<numStrips&&badChannels[RefStrip]){
00211 RefStrip++;
00212 }
00213 if(RefStrip<numStrips){
00214 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
00215 float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
00216 theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue);
00217 }
00218 }
00219 DigitalVecType digis;
00220 theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
00221 outdigi.data = digis;
00222 }
00223
00224
00225 if(!zeroSuppression){
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 if(BaselineShift){
00245 theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
00246 }
00247
00248
00249
00250 if(noise){
00251 std::vector<float> noiseRMSv;
00252 noiseRMSv.clear();
00253 noiseRMSv.insert(noiseRMSv.begin(),numStrips,0.);
00254
00255 if(SingleStripNoise){
00256 for(int strip=0; strip< numStrips; ++strip){
00257 if(!badChannels[strip]) noiseRMSv[strip] = (noiseHandle->getNoise(strip,detNoiseRange))* theElectronPerADC;
00258 }
00259
00260 } else {
00261 int RefStrip = 0;
00262 while(RefStrip<numStrips&&badChannels[RefStrip]){
00263 RefStrip++;
00264 }
00265 if(RefStrip<numStrips){
00266 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange) *theElectronPerADC;
00267 for(int strip=0; strip< numStrips; ++strip){
00268 if(!badChannels[strip]) noiseRMSv[strip] = noiseRMS;
00269 }
00270 }
00271 }
00272
00273 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv);
00274 }
00275
00276
00277
00278 if(CommonModeNoise){
00279 float cmnRMS = 0.;
00280 DetId detId(detID);
00281 uint32_t SubDet = detId.subdetId();
00282 if(SubDet==3){
00283 cmnRMS = cmnRMStib;
00284 }else if(SubDet==4){
00285 cmnRMS = cmnRMStid;
00286 }else if(SubDet==5){
00287 cmnRMS = cmnRMStob;
00288 }else if(SubDet==6){
00289 cmnRMS = cmnRMStec;
00290 }
00291 cmnRMS *= theElectronPerADC;
00292 theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels);
00293 }
00294
00295
00296
00297
00298
00299 std::vector<float> vPeds;
00300 vPeds.clear();
00301 vPeds.insert(vPeds.begin(),numStrips,0.);
00302
00303 if(RealPedestals){
00304 for(int strip=0; strip< numStrips; ++strip){
00305 if(!badChannels[strip]) vPeds[strip] = (pedestalHandle->getPed(strip,detPedestalRange)+pedOffset)* theElectronPerADC;
00306 }
00307 } else {
00308 for(int strip=0; strip< numStrips; ++strip){
00309 if(!badChannels[strip]) vPeds[strip] = pedOffset* theElectronPerADC;
00310 }
00311 }
00312
00313 theSiNoiseAdder->addPedestals(detAmpl, vPeds);
00314
00315
00316
00317
00318
00319
00320 DigitalRawVecType rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle, detID);
00321 outrawdigi.data = rawdigis;
00322
00323
00324 }
00325 }