CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/SimCalorimetry/EcalSimAlgos/src/EcalCoder.cc

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 //#include "CLHEP/Random/RandGaussQ.h"
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 ) , // 4095(MAXADC)*12(gain 2)*0.035(GeVtoADC)*0.97
00020    m_maxEneEE    (      2859.9 ) , // 4095(MAXADC)*12(gain 2)*0.060(GeVtoADC)*0.97
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    //....initialisation
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       // fill in the pedestal and width
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       // set nominal value first
00114       findGains( detId , 
00115                  gains  );               
00116 
00117       LSB[igain] = 0.;
00118       if ( igain > 0 ) LSB[igain]= Emax/(MAXADC*gains[igain]);
00119       maxADC[igain] = ADCGAINSWITCH;                   // saturation at 4080 for middle and high gains x6 & x12
00120       if ( igain == NGAINS ) maxADC[igain] = MAXADC;   // saturation at 4095 for low gain x1 
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] ) ; // high gain
00141       if( 0 == noisy[1] ) noisy[0]->noisify( noiseframe[1] ,
00142                                              &noisy[0]->vecgau() ) ; // med 
00143       if( 0 == noisy[2] ) noisy[0]->noisify( noiseframe[2] ,
00144                                              &noisy[0]->vecgau() ) ; // low
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       // see which gain bin it fits in
00158       int igain ( gainId - 1 ) ;
00159       do
00160       {
00161          ++igain ;
00162 
00163 //       if( igain != gainId ) std::cout <<"$$$$ Gain switch from " << gainId
00164 //                                       <<" to "<< igain << std::endl ;
00165 
00166          if( 1 != igain                    &&   // not high gain
00167              m_addNoise                    &&   // want to add noise
00168              0 != noisy[igain-1]           &&   // exists
00169              noiseframe[igain-1].isBlank()    ) // not already done
00170          {
00171             noisy[igain-1]->noisify( noiseframe[igain-1] ,
00172                                      &noisy[0]->vecgau()   ) ;
00173 //          std::cout<<"....noisifying gain level = "<<igain<<std::endl ;
00174          }
00175         
00176          // noiseframe filled with zeros if !m_addNoise
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          // LogDebug("EcalCoder") << "DetId " << detId.rawId() << " gain " << igain << " caloSample " 
00185          //                       <<  caloSamples[i] << " pededstal " << pedestals[igain] 
00186          //                       << " noise " << widths[igain] << " conversion factor " << LSB[igain] 
00187          //                       << " result (ped,tmpadc)= " << ped << " " << tmpadc;
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       // change the gain for saturation
00215       int storeGainId = gainId;
00216       if ( gainId == 3 && adc == MAXADC ) 
00217       {
00218          storeGainId = 0;
00219          isSaturated = true;
00220       }
00221       // LogDebug("EcalCoder") << " Writing out frame " << i << " ADC = " << adc << " gainId = " << gainId << " storeGainId = " << storeGainId ; 
00222      
00223       df.setSample( i, EcalMGPASample( adc, storeGainId ) );   
00224    }
00225    // handle saturation properly according to IN-2007/056
00226    // N.B. - FIXME 
00227    // still missing the possibility for a signal to pass the saturation threshold
00228    // again within the 5 subsequent samples (higher order effect).
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      EcalPedestalsMapIterator mapItr 
00254      = m_peds->m_pedestals.find(detId.rawId());
00255      // should I care if it doesn't get found?
00256      if(mapItr == m_peds->m_pedestals.end()) {
00257      edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << m_peds->m_pedestals.size();
00258      } else {
00259      EcalPedestals::Item item = mapItr->second;
00260    */
00261    
00262    /*   
00263         EcalPedestals::Item const & item = (*m_peds)(detId);
00264         ped = item.mean(gainId);
00265         width = item.rms(gainId);
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     switch(gainId) {
00279     case 0:
00280       ped = 0.;
00281       width = 0.;
00282     case 1:
00283       ped = item.mean_x12;
00284       width = item.rms_x12;
00285       break;
00286     case 2:
00287       ped = item.mean_x6;
00288       width = item.rms_x6;
00289       break;
00290     case 3:
00291       ped = item.mean_x1;
00292       width = item.rms_x1;
00293       break;
00294     default:
00295       edm::LogError("EcalCoder") << "Bad Pedestal " << gainId;
00296       break;
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     EcalGainRatios::EcalGainRatioMap::const_iterator grit=m_gainRatios->getMap().find(detId.rawId());
00310     EcalMGPAGainRatio mgpa;
00311     if( grit!=m_gainRatios->getMap().end() ){
00312     mgpa = grit->second;
00313     Gains[0] = 0.;
00314     Gains[3] = 1.;
00315     Gains[2] = mgpa.gain6Over1() ;
00316     Gains[1] = Gains[2]*(mgpa.gain12Over6()) ;
00317     LogDebug("EcalCoder") << "Gains for " << detId.rawId() << "\n" << " 1 = " << Gains[1] << "\n" << " 2 = " << Gains[2] << "\n" << " 3 = " << Gains[3];
00318     } else {
00319     edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << m_gainRatios->getMap().size();
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    // find intercalib constant for this xtal
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 }