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