Go to the documentation of this file.00001 #include "SimCalorimetry/EcalSimAlgos/interface/EcalCoder.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "SimGeneral/NoiseGenerators/interface/CorrelatedNoisifier.h"
00004 #include "DataFormats/EcalDigi/interface/EcalMGPASample.h"
00005 #include "DataFormats/EcalDigi/interface/EcalDataFrame.h"
00006
00007 #include <iostream>
00008
00009 EcalCoder::EcalCoder( bool addNoise ,
00010 EcalCoder::Noisifier* ebCorrNoise0 ,
00011 EcalCoder::Noisifier* eeCorrNoise0 ,
00012 EcalCoder::Noisifier* ebCorrNoise1 ,
00013 EcalCoder::Noisifier* eeCorrNoise1 ,
00014 EcalCoder::Noisifier* ebCorrNoise2 ,
00015 EcalCoder::Noisifier* eeCorrNoise2 ) :
00016 m_peds ( 0 ) ,
00017 m_gainRatios ( 0 ) ,
00018 m_intercals ( 0 ) ,
00019 m_maxEneEB ( 1668.3 ) ,
00020 m_maxEneEE ( 2859.9 ) ,
00021 m_addNoise ( addNoise )
00022 {
00023 m_ebCorrNoise[0] = ebCorrNoise0 ;
00024 assert( 0 != m_ebCorrNoise[0] ) ;
00025 m_eeCorrNoise[0] = eeCorrNoise0 ;
00026 m_ebCorrNoise[1] = ebCorrNoise1 ;
00027 m_eeCorrNoise[1] = eeCorrNoise1 ;
00028 m_ebCorrNoise[2] = ebCorrNoise2 ;
00029 m_eeCorrNoise[2] = eeCorrNoise2 ;
00030 }
00031
00032 EcalCoder::~EcalCoder()
00033 {
00034 }
00035
00036 void
00037 EcalCoder::setFullScaleEnergy( double EBscale ,
00038 double EEscale )
00039 {
00040 m_maxEneEB = EBscale ;
00041 m_maxEneEE = EEscale ;
00042 }
00043
00044
00045 void
00046 EcalCoder::setPedestals( const EcalPedestals* pedestals )
00047 {
00048 m_peds = pedestals ;
00049 }
00050
00051 void
00052 EcalCoder::setGainRatios( const EcalGainRatios* gainRatios )
00053 {
00054 m_gainRatios = gainRatios ;
00055 }
00056
00057 void
00058 EcalCoder::setIntercalibConstants( const EcalIntercalibConstantsMC* ical )
00059 {
00060 m_intercals = ical ;
00061 }
00062
00063 double
00064 EcalCoder::fullScaleEnergy( const DetId & detId ) const
00065 {
00066 return detId.subdetId() == EcalBarrel ? m_maxEneEB : m_maxEneEE ;
00067 }
00068
00069 void
00070 EcalCoder::analogToDigital( const CaloSamples& clf ,
00071 EcalDataFrame& df ) const
00072 {
00073 df.setSize( clf.size() ) ;
00074 encode( clf, df );
00075 }
00076
00077 void
00078 EcalCoder::encode( const CaloSamples& caloSamples ,
00079 EcalDataFrame& df ) const
00080 {
00081 assert( 0 != m_peds ) ;
00082
00083 const unsigned int csize ( caloSamples.size() ) ;
00084
00085
00086 DetId detId = caloSamples.id();
00087 double Emax = fullScaleEnergy(detId);
00088
00089
00090 if ( caloSamples[5] > 0. ) LogDebug("EcalCoder") << "Input caloSample" << "\n" << caloSamples;
00091
00092 double LSB[NGAINS+1];
00093 double pedestals[NGAINS+1];
00094 double widths[NGAINS+1];
00095 double gains[NGAINS+1];
00096 int maxADC[NGAINS+1];
00097 double trueRMS[NGAINS+1];
00098
00099 double icalconst = 1. ;
00100 findIntercalibConstant( detId, icalconst );
00101
00102 for( unsigned int igain ( 0 ); igain <= NGAINS ; ++igain )
00103 {
00104
00105 findPedestal( detId ,
00106 igain ,
00107 pedestals[igain] ,
00108 widths[igain] ) ;
00109
00110 if( 0 < igain )
00111 trueRMS[igain] = std::sqrt( widths[igain]*widths[igain] - 1./12. ) ;
00112
00113
00114 findGains( detId ,
00115 gains );
00116
00117 LSB[igain] = 0.;
00118 if ( igain > 0 ) LSB[igain]= Emax/(MAXADC*gains[igain]);
00119 maxADC[igain] = ADCGAINSWITCH;
00120 if ( igain == NGAINS ) maxADC[igain] = MAXADC;
00121 }
00122
00123 CaloSamples noiseframe[] = { CaloSamples( detId , csize ) ,
00124 CaloSamples( detId , csize ) ,
00125 CaloSamples( detId , csize ) } ;
00126
00127 const Noisifier* noisy[3] = { ( 0 == m_eeCorrNoise[0] ||
00128 EcalBarrel == detId.subdetId() ?
00129 m_ebCorrNoise[0] :
00130 m_eeCorrNoise[0] ) ,
00131 ( EcalBarrel == detId.subdetId() ?
00132 m_ebCorrNoise[1] :
00133 m_eeCorrNoise[1] ) ,
00134 ( EcalBarrel == detId.subdetId() ?
00135 m_ebCorrNoise[2] :
00136 m_eeCorrNoise[2] ) } ;
00137
00138 if( m_addNoise )
00139 {
00140 noisy[0]->noisify( noiseframe[0] ) ;
00141 if( 0 == noisy[1] ) noisy[0]->noisify( noiseframe[1] ,
00142 &noisy[0]->vecgau() ) ;
00143 if( 0 == noisy[2] ) noisy[0]->noisify( noiseframe[2] ,
00144 &noisy[0]->vecgau() ) ;
00145 }
00146
00147 int wait = 0 ;
00148 int gainId = 0 ;
00149 bool isSaturated = 0;
00150
00151 for( unsigned int i ( 0 ) ; i != csize ; ++i )
00152 {
00153 bool done ( false ) ;
00154 int adc = MAXADC ;
00155 if( 0 == wait ) gainId = 1 ;
00156
00157
00158 int igain ( gainId - 1 ) ;
00159 do
00160 {
00161 ++igain ;
00162
00163
00164
00165
00166 if( 1 != igain &&
00167 m_addNoise &&
00168 0 != noisy[igain-1] &&
00169 noiseframe[igain-1].isBlank() )
00170 {
00171 noisy[igain-1]->noisify( noiseframe[igain-1] ,
00172 &noisy[0]->vecgau() ) ;
00173
00174 }
00175
00176
00177 const double signal ( pedestals[igain] +
00178 caloSamples[i] /( LSB[igain]*icalconst ) +
00179 trueRMS[igain]*noiseframe[igain-1][i] ) ;
00180
00181 const int isignal ( signal ) ;
00182 const int tmpadc ( signal - (double)isignal < 0.5 ?
00183 isignal : isignal + 1 ) ;
00184
00185
00186
00187
00188
00189 if( tmpadc <= maxADC[igain] )
00190 {
00191 adc = tmpadc;
00192 done = true ;
00193 }
00194 }
00195 while( !done &&
00196 igain < 3 ) ;
00197
00198 if (igain == 1 )
00199 {
00200 wait = 0 ;
00201 gainId = igain ;
00202 }
00203 else
00204 {
00205 if (igain == gainId) --wait ;
00206 else
00207 {
00208 wait = 5 ;
00209 gainId = igain ;
00210 }
00211 }
00212
00213
00214
00215 int storeGainId = gainId;
00216 if ( gainId == 3 && adc == MAXADC )
00217 {
00218 storeGainId = 0;
00219 isSaturated = true;
00220 }
00221
00222
00223 df.setSample( i, EcalMGPASample( adc, storeGainId ) );
00224 }
00225
00226
00227
00228
00229
00230 if ( isSaturated )
00231 {
00232 for (int i = 0 ; i < caloSamples.size() ; ++i)
00233 {
00234 if ( df.sample(i).gainId() == 0 )
00235 {
00236 int hyst = i+1+2;
00237 for ( int j = i+1; j < hyst && j < caloSamples.size(); ++j )
00238 {
00239 df.setSample(j, EcalMGPASample(MAXADC, 0));
00240 }
00241 }
00242 }
00243 }
00244 }
00245
00246 void
00247 EcalCoder::findPedestal( const DetId & detId ,
00248 int gainId ,
00249 double& ped ,
00250 double& width ) const
00251 {
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 EcalPedestalsMap::const_iterator itped = m_peds->getMap().find( detId );
00269 ped = (*itped).mean(gainId);
00270 width = (*itped).rms(gainId);
00271
00272 if ( (detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap) )
00273 {
00274 edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << m_peds->getMap().size();
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 LogDebug("EcalCoder") << "Pedestals for " << detId.rawId() << " gain range " << gainId << " : \n" << "Mean = " << ped << " rms = " << width;
00301 }
00302
00303
00304 void
00305 EcalCoder::findGains( const DetId & detId ,
00306 double Gains[] ) const
00307 {
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 EcalGainRatioMap::const_iterator grit = m_gainRatios->getMap().find( detId );
00324 Gains[0] = 0.;
00325 Gains[3] = 1.;
00326 Gains[2] = (*grit).gain6Over1();
00327 Gains[1] = Gains[2]*( (*grit).gain12Over6() );
00328
00329
00330 if ( (detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap) )
00331 {
00332 edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << m_gainRatios->getMap().size();
00333 }
00334
00335 }
00336
00337 void
00338 EcalCoder::findIntercalibConstant( const DetId& detId,
00339 double& icalconst ) const
00340 {
00341 EcalIntercalibConstantMC thisconst = 1.;
00342
00343 const EcalIntercalibConstantMCMap &icalMap = m_intercals->getMap();
00344 EcalIntercalibConstantMCMap::const_iterator icalit = icalMap.find(detId);
00345 if( icalit!=icalMap.end() )
00346 {
00347 thisconst = (*icalit);
00348 if ( icalconst == 0. ) { thisconst = 1.; }
00349 }
00350 else
00351 {
00352 edm::LogError("EcalCoder") << "No intercalib const found for xtal " << detId.rawId() << "! something wrong with EcalIntercalibConstants in your DB? ";
00353 }
00354 icalconst = thisconst;
00355 }