00001
00002
00003
00004 #include <vector>
00005 #include <algorithm>
00006 #include <iostream>
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "SimTracker/SiStripDigitizer/interface/SiStripDigitizerAlgorithm.h"
00010 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00011 #include "DataFormats/Common/interface/DetSetVector.h"
00012 #include "DataFormats/GeometrySurface/interface/BoundSurface.h"
00013 #include "CLHEP/Random/RandFlat.h"
00014
00015 #define CBOLTZ (1.38E-23)
00016 #define e_SI (1.6E-19)
00017
00018 SiStripDigitizerAlgorithm::SiStripDigitizerAlgorithm(const edm::ParameterSet& conf, CLHEP::HepRandomEngine& eng):
00019 conf_(conf),rndEngine(eng){
00020 theThreshold = conf_.getParameter<double>("NoiseSigmaThreshold");
00021 theFedAlgo = conf_.getParameter<int>("FedAlgorithm");
00022 peakMode = conf_.getParameter<bool>("APVpeakmode");
00023 theElectronPerADC = conf_.getParameter<double>( peakMode ? "electronPerAdcPeak" : "electronPerAdcDec" );
00024 noise = conf_.getParameter<bool>("Noise");
00025 zeroSuppression = conf_.getParameter<bool>("ZeroSuppression");
00026 theTOFCutForPeak = conf_.getParameter<double>("TOFCutForPeak");
00027 theTOFCutForDeconvolution = conf_.getParameter<double>("TOFCutForDeconvolution");
00028 cosmicShift = conf_.getUntrackedParameter<double>("CosmicDelayShift");
00029 inefficiency = conf_.getParameter<double>("Inefficiency");
00030 RealPedestals = conf_.getParameter<bool>("RealPedestals");
00031 SingleStripNoise = conf_.getParameter<bool>("SingleStripNoise");
00032 CommonModeNoise = conf_.getParameter<bool>("CommonModeNoise");
00033 BaselineShift = conf_.getParameter<bool>("BaselineShift");
00034 APVSaturationFromHIP = conf_.getParameter<bool>("APVSaturationFromHIP");
00035 APVSaturationProb = conf_.getParameter<double>("APVSaturationProb");
00036 cmnRMStib = conf_.getParameter<double>("cmnRMStib");
00037 cmnRMStob = conf_.getParameter<double>("cmnRMStob");
00038 cmnRMStid = conf_.getParameter<double>("cmnRMStid");
00039 cmnRMStec = conf_.getParameter<double>("cmnRMStec");
00040 pedOffset = (unsigned int)conf_.getParameter<double>("PedestalsOffset");
00041 if (peakMode) {
00042 tofCut=theTOFCutForPeak;
00043 LogDebug("StripDigiInfo")<<"APVs running in peak mode (poor time resolution)";
00044 } else {
00045 tofCut=theTOFCutForDeconvolution;
00046 LogDebug("StripDigiInfo")<<"APVs running in deconvolution mode (good time resolution)";
00047 };
00048
00049 theSiHitDigitizer = new SiHitDigitizer(conf_,rndEngine);
00050 theSiPileUpSignals = new SiPileUpSignals();
00051 theSiNoiseAdder = new SiGaussianTailNoiseAdder(theThreshold,rndEngine);
00052 theSiDigitalConverter = new SiTrivialDigitalConverter(theElectronPerADC);
00053 theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo);
00054 theFlatDistribution = new CLHEP::RandFlat(rndEngine, 0., 1.);
00055
00056
00057 }
00058
00059 SiStripDigitizerAlgorithm::~SiStripDigitizerAlgorithm(){
00060 delete theSiHitDigitizer;
00061 delete theSiPileUpSignals;
00062 delete theSiNoiseAdder;
00063 delete theSiDigitalConverter;
00064 delete theSiZeroSuppress;
00065 delete theFlatDistribution;
00066
00067
00068 }
00069
00070
00071
00072
00073 void SiStripDigitizerAlgorithm::run(edm::DetSet<SiStripDigi>& outdigi,
00074 edm::DetSet<SiStripRawDigi>& outrawdigi,
00075 const std::vector<std::pair<const PSimHit*, int > > &input,
00076 StripGeomDetUnit *det,
00077 GlobalVector bfield,float langle,
00078 edm::ESHandle<SiStripGain> & gainHandle,
00079 edm::ESHandle<SiStripThreshold> & thresholdHandle,
00080 edm::ESHandle<SiStripNoises> & noiseHandle,
00081 edm::ESHandle<SiStripPedestals> & pedestalHandle,
00082 edm::ESHandle<SiStripBadStrip> & deadChannelHandle
00083 ) {
00084 theSiPileUpSignals->reset();
00085 unsigned int detID = det->geographicalId().rawId();
00086 SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00087 SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
00088 SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
00089 SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detID);
00090 numStrips = (det->specificTopology()).nstrips();
00091
00092
00093 std::vector<bool> badChannels;
00094 badChannels.clear();
00095 badChannels.insert(badChannels.begin(),numStrips,false);
00096 SiStripBadStrip::data fs;
00097 for(SiStripBadStrip::ContainerIterator it=detBadStripRange.first;it!=detBadStripRange.second;++it){
00098 fs=deadChannelHandle->decode(*it);
00099 for(int strip = fs.firstStrip; strip <fs.firstStrip+fs.range; ++strip )badChannels[strip] = true;
00100 }
00101
00102
00103
00104
00105 detAmpl.clear();
00106
00107
00108 detAmpl.insert(detAmpl.begin(),numStrips,0.);
00109
00110 firstChannelWithSignal = numStrips;
00111 lastChannelWithSignal = 0;
00112
00113
00114 std::vector<std::pair<const PSimHit*, int > >::const_iterator simHitIter = input.begin();
00115 std::vector<std::pair<const PSimHit*, int > >::const_iterator simHitIterEnd = input.end();
00116 if(theFlatDistribution->fire()>inefficiency) {
00117 for (;simHitIter != simHitIterEnd; ++simHitIter) {
00118 locAmpl.clear();
00119 locAmpl.insert(locAmpl.begin(),numStrips,0.);
00120
00121 if ( std::fabs( ((*simHitIter).first)->tof() - cosmicShift - det->surface().toGlobal(((*simHitIter).first)->localPosition()).mag()/30.) < tofCut && ((*simHitIter).first)->energyLoss()>0) {
00122 localFirstChannel = numStrips;
00123 localLastChannel = 0;
00124
00125 theSiHitDigitizer->processHit(((*simHitIter).first),*det,bfield,langle, locAmpl, localFirstChannel, localLastChannel);
00126
00127
00128
00129
00130 if(APVSaturationFromHIP&&!zeroSuppression){
00131 int pdg_id = ((*simHitIter).first)->particleType();
00132 particle = pdt->particle(pdg_id);
00133 if(particle != NULL){
00134 float charge = particle->charge();
00135 bool isHadron = particle->isHadron();
00136 if(charge!=0 && isHadron){
00137 if(theFlatDistribution->fire()<APVSaturationProb){
00138 int FirstAPV = localFirstChannel/128;
00139 int LastAPV = localLastChannel/128;
00140 std::cout << "-------------------HIP--------------" << std::endl;
00141 std::cout << "Killing APVs " << FirstAPV << " - " <<LastAPV << " " << detID <<std::endl;
00142 for(int strip = FirstAPV*128; strip < LastAPV*128 +128; ++strip) badChannels[strip] = true;
00143
00144
00145
00146 }
00147 }
00148 }
00149 }
00150
00151
00152 theSiPileUpSignals->add(locAmpl, localFirstChannel, localLastChannel, ((*simHitIter).first), (*simHitIter).second);
00153
00154
00155 for (size_t iChannel=localFirstChannel; iChannel<localLastChannel; iChannel++) {
00156 if(locAmpl[iChannel]>0.) {
00157
00158
00159 detAmpl[iChannel]+=locAmpl[iChannel];
00160 }
00161 }
00162 if(firstChannelWithSignal>localFirstChannel) firstChannelWithSignal=localFirstChannel;
00163 if(lastChannelWithSignal<localLastChannel) lastChannelWithSignal=localLastChannel;
00164 }
00165 }
00166 }
00167
00168
00169 for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] =0;
00170
00171 const SiPileUpSignals::HitToDigisMapType& theLink(theSiPileUpSignals->dumpLink());
00172 const SiPileUpSignals::HitCounterToDigisMapType& theCounterLink(theSiPileUpSignals->dumpCounterLink());
00173
00174 if(zeroSuppression){
00175 if(noise){
00176 int RefStrip = int(numStrips/2.);
00177 while(RefStrip<numStrips&&badChannels[RefStrip]){
00178 RefStrip++;
00179 }
00180 if(RefStrip<numStrips){
00181 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
00182 float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
00183 theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue);
00184 }
00185 }
00186 digis.clear();
00187 theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
00188 push_link(digis, theLink, theCounterLink, detAmpl,detID);
00189 outdigi.data = digis;
00190 }
00191
00192
00193 if(!zeroSuppression){
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 if(BaselineShift){
00213 theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
00214 }
00215
00216
00217
00218 if(noise){
00219 std::vector<float> noiseRMSv;
00220 noiseRMSv.clear();
00221 noiseRMSv.insert(noiseRMSv.begin(),numStrips,0.);
00222
00223 if(SingleStripNoise){
00224 for(int strip=0; strip< numStrips; ++strip){
00225 if(!badChannels[strip]) noiseRMSv[strip] = (noiseHandle->getNoise(strip,detNoiseRange))* theElectronPerADC;
00226 }
00227
00228 } else {
00229 int RefStrip = 0;
00230 while(RefStrip<numStrips&&badChannels[RefStrip]){
00231 RefStrip++;
00232 }
00233 if(RefStrip<numStrips){
00234 float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange) *theElectronPerADC;
00235 for(int strip=0; strip< numStrips; ++strip){
00236 if(!badChannels[strip]) noiseRMSv[strip] = noiseRMS;
00237 }
00238 }
00239 }
00240
00241 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv);
00242 }
00243
00244
00245
00246 if(CommonModeNoise){
00247 float cmnRMS = 0.;
00248 DetId detId(detID);
00249 uint32_t SubDet = detId.subdetId();
00250 if(SubDet==3){
00251 cmnRMS = cmnRMStib;
00252 }else if(SubDet==4){
00253 cmnRMS = cmnRMStid;
00254 }else if(SubDet==5){
00255 cmnRMS = cmnRMStob;
00256 }else if(SubDet==6){
00257 cmnRMS = cmnRMStec;
00258 }
00259 cmnRMS *= theElectronPerADC;
00260 theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels);
00261 }
00262
00263
00264
00265
00266
00267 std::vector<float> vPeds;
00268 vPeds.clear();
00269 vPeds.insert(vPeds.begin(),numStrips,0.);
00270
00271 if(RealPedestals){
00272 for(int strip=0; strip< numStrips; ++strip){
00273 if(!badChannels[strip]) vPeds[strip] = (pedestalHandle->getPed(strip,detPedestalRange)+pedOffset)* theElectronPerADC;
00274 }
00275 } else {
00276 for(int strip=0; strip< numStrips; ++strip){
00277 if(!badChannels[strip]) vPeds[strip] = pedOffset* theElectronPerADC;
00278 }
00279 }
00280
00281 theSiNoiseAdder->addPedestals(detAmpl, vPeds);
00282
00283
00284
00285
00286
00287
00288 rawdigis.clear();
00289 rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle, detID);
00290 push_link_raw(rawdigis, theLink, theCounterLink, detAmpl,detID);
00291 outrawdigi.data = rawdigis;
00292
00293
00294 }
00295 }
00296
00297 void SiStripDigitizerAlgorithm::push_link(const DigitalVecType &digis,
00298 const HitToDigisMapType& htd,
00299 const HitCounterToDigisMapType& hctd,
00300 const std::vector<double>& afterNoise,
00301 unsigned int detID) {
00302 link_coll.clear();
00303 for ( DigitalVecType::const_iterator i=digis.begin(); i!=digis.end(); i++) {
00304
00305
00306 HitToDigisMapType::const_iterator mi(htd.find(i->strip()));
00307 if (mi == htd.end()) continue;
00308 HitCounterToDigisMapType::const_iterator cmi(hctd.find(i->strip()));
00309 std::map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
00310 for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul =
00311 (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
00312 totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
00313 }
00314
00315
00316 double totalAmplitude1 = afterNoise[(*mi).first];
00317
00318
00319 int sim_counter=0;
00320 for (std::map<const PSimHit *, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
00321 iter != totalAmplitudePerSimHit.end(); iter++){
00322 float threshold = 0.;
00323 float fraction = (*iter).second/totalAmplitude1;
00324 if ( fraction >= threshold) {
00325
00326 if(fraction > 1.) fraction = 1.;
00327 for (std::vector < std::pair < const PSimHit*, int > >::const_iterator
00328 simcount = (*cmi).second.begin() ; simcount != (*cmi).second.end(); simcount ++){
00329 if((*iter).first == (*simcount).first) sim_counter = (*simcount).second;
00330 }
00331 link_coll.push_back(StripDigiSimLink( (*mi).first,
00332 ((*iter).first)->trackId(),
00333 sim_counter,
00334 ((*iter).first)->eventId(),
00335 fraction));
00336 }
00337 }
00338 }
00339 }
00340
00341 void SiStripDigitizerAlgorithm::push_link_raw(const DigitalRawVecType &digis,
00342 const HitToDigisMapType& htd,
00343 const HitCounterToDigisMapType& hctd,
00344 const std::vector<double>& afterNoise,
00345 unsigned int detID) {
00346 link_coll.clear();
00347 int nstrip = -1;
00348 for ( DigitalRawVecType::const_iterator i=digis.begin(); i!=digis.end(); i++) {
00349 nstrip++;
00350
00351
00352 HitToDigisMapType::const_iterator mi(htd.find(nstrip));
00353 HitCounterToDigisMapType::const_iterator cmi(hctd.find(nstrip));
00354 if (mi == htd.end()) continue;
00355 std::map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
00356 for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul =
00357 (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
00358 totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
00359 }
00360
00361
00362 double totalAmplitude1 = afterNoise[(*mi).first];
00363
00364
00365 int sim_counter_raw=0;
00366 for (std::map<const PSimHit *, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
00367 iter != totalAmplitudePerSimHit.end(); iter++){
00368 float threshold = 0.;
00369 float fraction = (*iter).second/totalAmplitude1;
00370 if (fraction >= threshold) {
00371
00372 if(fraction >1.) fraction = 1.;
00373
00374 for (std::vector < std::pair < const PSimHit*, int > >::const_iterator
00375 simcount = (*cmi).second.begin() ; simcount != (*cmi).second.end(); simcount ++){
00376 if((*iter).first == (*simcount).first) sim_counter_raw = (*simcount).second;
00377 }
00378 link_coll.push_back(StripDigiSimLink( (*mi).first,
00379 ((*iter).first)->trackId(),
00380 sim_counter_raw,
00381 ((*iter).first)->eventId(),
00382 fraction));
00383 }
00384 }
00385 }
00386 }