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
00018
00019
00020
00021
00022
00023
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);
00146 bin[1] = ((thisRndCell - hBin2*bin[2])/hBin);
00147 bin[0] = (thisRndCell - hBin*(bin[1] + hBin*bin[2]));
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