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