CMS 3D CMS Logo

SiStripDigitizerAlgorithm.cc

Go to the documentation of this file.
00001 // File: SiStripDigitizerAlgorithm.cc
00002 // Description:  Steering class for digitization.
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   //  std::cout << "Created new SiPileUpSignals" << std::endl;
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 //  Run the algorithm
00065 //  ------------------
00066 
00067 void SiStripDigitizerAlgorithm::run(edm::DetSet<SiStripDigi>& outdigi,
00068                                     edm::DetSet<SiStripRawDigi>& outrawdigi,
00069                                     //const std::vector<PSimHit> &input,
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   // WARNING!!!
00085   // here only the value for noise and pedestal from the central strip are taken
00086   //    in case the noise RMS / pedestal values are not flat
00087   //    the value strip-by-strip must be taken in SiGaussianTailNoiseAdded
00088   noiseRMS = noiseHandle->getNoise(strip,detNoiseRange);
00089   pedValue = pedestalHandle->getPed(strip,detPedestalRange);
00090 
00091   /*
00092   // We will work on ONE copy of the map only,
00093   //  and pass references where it is needed.
00094   //  signal_map_type theSignal;
00095   //  signal_map_type theSignal_forLink;
00096   */
00097   
00098   std::vector<double> locAmpl(numStrips,0.); // local amplitude of detector channels (from processed PSimHit)
00099   // std::vector<double> detAmpl(numStrips,0.); // total amplitude of detector channels
00100   std::vector<double> detAmpl(locAmpl); // total amplitude of detector channels
00101 
00102   // to speed-up vector filling (only for channels with signal)
00103   //  the unsigned int corresponds to the channel number
00104   //  and NOT to the vector position (which is channel-1)
00105   unsigned int firstChannelWithSignal = numStrips+1;
00106   unsigned int lastChannelWithSignal  = 0;
00107   //
00108   //  std::cout << "SiStripDigitizerAlgorithm: First " << firstChannelWithSignal << "\t Last " << lastChannelWithSignal << std::endl;
00109   
00110   //
00111   // First: loop on the SimHits
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     //    const PSimHit & ihit = *simHitIter;
00117     const PSimHit & ihit = (*simHitIter).first;
00118     float dist = det->surface().toGlobal(ihit.localPosition()).mag();
00119     float t0 = dist/30.;  // light velocity = 30 cm/ns      
00120     
00121     // std::fill(locAmpl.begin(),locAmpl.end(),0.); // fill local Amplitudes with zeroes
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       //      std::cout << "SiStripDigitizerAlgorithm: First " << firstChannelWithSignal << "\t Last " << lastChannelWithSignal << std::endl;
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       //      std::fill_n(locAmpl.begin()+localFirstChannel-1,localLastChannel-localFirstChannel,0.); // fill local Amplitudes with zeroes
00135  
00136      if(firstChannelWithSignal>localFirstChannel) firstChannelWithSignal=localFirstChannel;
00137      if(lastChannelWithSignal<localLastChannel) lastChannelWithSignal=localLastChannel;
00138  
00139     }
00140     //    theSignal_forLink.clear();
00141   }
00142   
00143   const SiPileUpSignals::HitToDigisMapType& theLink = theSiPileUpSignals->dumpLink();  
00144   //added
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       // the constant pedestal offset is needed because
00160       //   negative adc counts are not allowed in case
00161       //   Pedestal and CMN subtraction is performed.
00162       //   The pedestal value read from the conditions
00163       //   is pedValue and after the pedestal subtraction
00164       //   the baseline is zero. The Common Mode Noise
00165       //   is not subtracted from the negative adc counts
00166       //   channels. Adding pedOffset the baseline is set
00167       //   to pedOffset after pedestal subtraction and CMN
00168       //   is subtracted to all the channels since none of
00169       //   them has negative adc value. The pedOffset is
00170       //   treated as a constant component in the CMN
00171       //   estimation and subtracted as CMN.
00172       float pedOffset = 128.; // ADC counts
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     // Instead of checking the validity of the links against the digis,
00195     //  let's loop over digis and push the corresponding link
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     //--- include the noise as well
00206     
00207     SiPileUpSignals::signal_map_type& temp1 = const_cast<SiPileUpSignals::signal_map_type&>(afterNoise);
00208     float totalAmplitude1 = temp1[(*mi).first];
00209     
00210     //--- digisimlink
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         //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
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           std::cout << "Make simlink:(channel, id, counter) " 
00231           <<   (*mi).first << ", " 
00232           << ((*iter).first)->trackId() << ", " 
00233           << sim_counter << std::endl;
00234         */
00235         link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
00236                                               ((*iter).first)->trackId(), //simhit trackId
00237                                               sim_counter, //simhit counter
00238                                               ((*iter).first)->eventId(), //simhit eventId
00239                                               fraction)); //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     // Instead of checking the validity of the links against the digis,
00256     //  let's loop over digis and push the corresponding link
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     //--- include the noise as well
00267     
00268     SiPileUpSignals::signal_map_type& temp1 = const_cast<SiPileUpSignals::signal_map_type&>(afterNoise);
00269     float totalAmplitude1 = temp1[(*mi).first];
00270     
00271     //--- digisimlink
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         //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
00282         if(fraction >1.) fraction = 1.;
00283 
00284         //add counter information
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         /*      std::cout << "Make simlink:(channel, id, counter) " 
00291                   <<   (*mi).first << ", " 
00292                   << ((*iter).first)->trackId() << ", " 
00293                   << sim_counter_raw << std::endl;
00294         */
00295         link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
00296                                               ((*iter).first)->trackId(), //simhit trackId
00297                                               sim_counter_raw, //simhit counter
00298                                               ((*iter).first)->eventId(), //simhit eventId
00299                                               fraction)); //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     // Instead of checking the validity of the links against the digis,
00314     //  let's loop over digis and push the corresponding link
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     //--- include the noise as well
00325     
00326     double totalAmplitude1 = afterNoise[(*mi).first];
00327     
00328     //--- digisimlink
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         // Noise fluctuation could make fraction>1. Unphysical, set it by hand = 1.
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           std::cout << "Make simlink:(channel, id, counter) " 
00349           <<   (*mi).first << ", " 
00350           << ((*iter).first)->trackId() << ", " 
00351           << sim_counter << std::endl;
00352         */
00353         link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
00354                                               ((*iter).first)->trackId(), //simhit trackId
00355                                               sim_counter, //simhit counter
00356                                               ((*iter).first)->eventId(), //simhit eventId
00357                                               fraction)); //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     // Instead of checking the validity of the links against the digis,
00374     //  let's loop over digis and push the corresponding link
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     //--- include the noise as well
00385     
00386     double totalAmplitude1 = afterNoise[(*mi).first];
00387     
00388     //--- digisimlink
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         //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
00399         if(fraction >1.) fraction = 1.;
00400 
00401         //add counter information
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         /*      std::cout << "Make simlink:(channel, id, counter) " 
00408                   <<   (*mi).first << ", " 
00409                   << ((*iter).first)->trackId() << ", " 
00410                   << sim_counter_raw << std::endl;
00411         */
00412         link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
00413                                               ((*iter).first)->trackId(), //simhit trackId
00414                                               sim_counter_raw, //simhit counter
00415                                               ((*iter).first)->eventId(), //simhit eventId
00416                                               fraction)); //fraction
00417       }
00418     }
00419   }
00420 }
00421 
00422 void SiStripDigitizerAlgorithm::setParticleDataTable(const ParticleDataTable * pdt)
00423 {
00424   theSiHitDigitizer->setParticleDataTable(pdt);
00425 }

Generated on Tue Jun 9 17:47:53 2009 for CMSSW by  doxygen 1.5.4