CMS 3D CMS Logo

ESElectronicsSimFast.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/EcalSimAlgos/interface/ESElectronicsSimFast.h"
00002 #include "DataFormats/EcalDigi/interface/ESSample.h"
00003 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00004 
00005 #include "FWCore/ServiceRegistry/interface/Service.h"
00006 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00007 #include "CLHEP/Random/RandFlat.h"
00008 #include "CLHEP/Random/RandGaussQ.h"
00009 #include "CLHEP/Random/RandGeneral.h"
00010 #include "FWCore/Utilities/interface/Exception.h"
00011 
00012 using namespace std;
00013 
00014 ESElectronicsSimFast::ESElectronicsSimFast (bool addNoise, double sigma, int gain, int baseline, double MIPADC, double MIPkeV):
00015   addNoise_(addNoise), sigma_ (sigma), gain_ (gain), baseline_(baseline), MIPADC_(MIPADC), MIPkeV_(MIPkeV)
00016 {
00017   // Preshower "Fast" Electronics Simulation
00018   // The default pedestal baseline is 1000
00019   // gain = 0 : old gain used in ORCA (1 ADC count = 1 keV in CMSSW)
00020   //            In ORCA, preshower noise was 15 keV
00021   // gain = 1 : low gain for data taking  (S =  9 ADC counts, N = 3 ADC counts)
00022   // gain = 2 : high gain for calibration (S = 50 ADC counts, N = 7 ADC counts)
00023   // For 300(310/320) um Si, the MIP is 78.47(81.08/83.7) keV
00024 }
00025 
00026 void ESElectronicsSimFast::setNoiseSigma (const double sigma)
00027 {
00028   sigma_ = sigma ;
00029   return ;
00030 }
00031 
00032 void ESElectronicsSimFast::setGain (const int gain)
00033 {
00034   gain_ = gain ;
00035   return ;
00036 }
00037 
00038 void ESElectronicsSimFast::setBaseline (const int baseline)
00039 {
00040   baseline_ = baseline ;
00041   return ;
00042 }
00043 
00044 void ESElectronicsSimFast::setMIPADC (const double MIPADC) 
00045 {
00046   MIPADC_ = MIPADC ;
00047   return ;
00048 }
00049 
00050 void ESElectronicsSimFast::setMIPkeV (const double MIPkeV) 
00051 {
00052   MIPkeV_ = MIPkeV ;
00053   return ;
00054 }
00055 
00056 void ESElectronicsSimFast::analogToDigital(const CaloSamples& cs, ESDataFrame& df, bool wasEmpty, CLHEP::RandGeneral *histoDistribution, double hInf, double hSup, double hBin) const 
00057 {
00058   std::vector<ESSample> essamples;
00059   if (!wasEmpty) essamples = standEncode(cs);
00060   if ( wasEmpty) essamples = fastEncode(cs, histoDistribution, hInf, hSup, hBin);
00061   
00062   df.setSize(cs.size());
00063   for(int i=0; i<df.size(); i++) {
00064     df.setSample(i, essamples[i]);
00065   }
00066 }
00067 
00068 void ESElectronicsSimFast::digitalToAnalog(const ESDataFrame& df, CaloSamples& cs) const 
00069 {
00070   for(int i = 0; i < df.size(); i++) {
00071     cs[i] = decode(df[i], df.id());
00072   } 
00073 }
00074 
00075 std::vector<ESSample>
00076 ESElectronicsSimFast::standEncode(const CaloSamples& timeframe) const
00077 {
00078   edm::Service<edm::RandomNumberGenerator> rng;
00079   if ( ! rng.isAvailable()) {
00080     throw cms::Exception("Configuration")
00081       << "ESElectroncSimFast requires the RandomNumberGeneratorService\n"
00082       "which is not present in the configuration file.  You must add the service\n"
00083       "in the configuration file or remove the modules that require it.";
00084   }
00085   
00086   std::vector<ESSample> results;
00087   results.reserve(timeframe.size());
00088   
00089   int adc = 0; 
00090   double ADCkeV = MIPADC_/MIPkeV_;
00091   for (int i=0; i<timeframe.size(); i++) {
00092     
00093     double noi = 0;
00094     double signal = 0;    
00095     
00096     if (addNoise_) {
00097       CLHEP::RandGaussQ gaussQDistribution(rng->getEngine(), 0, sigma_);
00098       noi = gaussQDistribution.fire();
00099     }
00100     
00101     if (gain_ == 0) { 
00102       signal = timeframe[i]*1000000. + noi + baseline_;     
00103       
00104       if (signal>0) 
00105         signal += 0.5;
00106       else if (signal<0)
00107         signal -= 0.5;
00108       
00109       adc = int(signal);
00110     }
00111     else if (gain_ == 1 || gain_ == 2) {
00112       signal = timeframe[i]*1000000.*ADCkeV + noi + baseline_;
00113       
00114       if (signal>0) 
00115         signal += 0.5;
00116       else if (signal<0)
00117         signal -= 0.5;
00118       
00119       adc = int(signal);
00120     }
00121    
00122     if (adc>MAXADC) adc = MAXADC;
00123     if (adc<MINADC) adc = MINADC;
00124     
00125     results.push_back(ESSample(adc));
00126   }
00127   
00128   return results;
00129 }
00130 
00131 
00132 std::vector<ESSample>
00133 ESElectronicsSimFast::fastEncode(const CaloSamples& timeframe, CLHEP::RandGeneral *histoDistribution, double hInf, double hSup, double hBin) const
00134 {
00135   std::vector<ESSample> results;
00136   results.reserve(timeframe.size());
00137 
00138   int bin[3]; 
00139   double hBin2 = hBin*hBin;
00140   double hBin3 = hBin*hBin*hBin;
00141   double width = (hSup - hInf)/hBin;  
00142 
00143   double thisRnd  = histoDistribution->fire();  
00144   int thisRndCell = (hBin3)*(thisRnd)/width;  
00145   bin[2] = (thisRndCell/hBin2);                              // sample2 - bin [0,N-1]
00146   bin[1] = ((thisRndCell - hBin2*bin[2])/hBin);              // sample1
00147   bin[0] = (thisRndCell - hBin*(bin[1] + hBin*bin[2]));      // sample0
00148 
00149   int adc[3];
00150   double noi[3];
00151   for(int ii=0; ii<3; ii++){
00152 
00153     noi[ii] = hInf + bin[ii]*width; 
00154     if (noi[ii]>0)      noi[ii] += 0.5;
00155     else if (noi[ii]<0) noi[ii] -= 0.5;
00156     
00157     adc[ii] = int(noi[ii]);      
00158     if (adc[ii]>MAXADC) adc[ii] = MAXADC;
00159     if (adc[ii]<MINADC) adc[ii] = MINADC;
00160     
00161     results.push_back(ESSample(adc[ii]));
00162   }
00163   
00164   return results;
00165 }
00166 
00167 double ESElectronicsSimFast::decode(const ESSample & sample, const DetId & id) const
00168 {
00169   return 0. ;
00170 }
00171 
00172 
00173 

Generated on Tue Jun 9 17:46:16 2009 for CMSSW by  doxygen 1.5.4