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