CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/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 //#include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
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 ) , // 4095(MAXADC)*12(gain 2)*0.035(GeVtoADC)*0.97
00023    m_maxEneEE    (      2859.9 ) , // 4095(MAXADC)*12(gain 2)*0.060(GeVtoADC)*0.97
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 /*   std::cout<<"   **Id=" ;
00079    if( CaloGenericDetId( clf.id() ).isEB() )
00080    {
00081       std::cout<<EBDetId( clf.id() ) ;
00082    }
00083    else
00084    {
00085       std::cout<<EEDetId( clf.id() ) ;
00086    }
00087    std::cout<<", size="<<df.size();
00088    for( int i ( 0 ) ; i != df.size() ; ++i )
00089    {
00090       std::cout<<", "<<df[i];
00091    }
00092    std::cout<<std::endl ;*/
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    //....initialisation
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       // fill in the pedestal and width
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       // set nominal value first
00132       findGains( detId , 
00133                  gains  );               
00134 
00135       LSB[igain] = 0.;
00136       if ( igain > 0 ) LSB[igain]= Emax/(MAXADC*gains[igain]);
00137       maxADC[igain] = ADCGAINSWITCH;                   // saturation at 4080 for middle and high gains x6 & x12
00138       if ( igain == NGAINS ) maxADC[igain] = MAXADC;   // saturation at 4095 for low gain x1 
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] ) ; // high gain
00159       if( 0 == noisy[1] ) noisy[0]->noisify( noiseframe[1] ,
00160                                              &noisy[0]->vecgau() ) ; // med 
00161       if( 0 == noisy[2] ) noisy[0]->noisify( noiseframe[2] ,
00162                                              &noisy[0]->vecgau() ) ; // low
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       // see which gain bin it fits in
00176       int igain ( gainId - 1 ) ;
00177       do
00178       {
00179          ++igain ;
00180 
00181 //       if( igain != gainId ) std::cout <<"$$$$ Gain switch from " << gainId
00182 //                                       <<" to "<< igain << std::endl ;
00183 
00184          if( 1 != igain                    &&   // not high gain
00185              m_addNoise                    &&   // want to add noise
00186              0 != noisy[igain-1]           &&   // exists
00187              noiseframe[igain-1].isBlank()    ) // not already done
00188          {
00189             noisy[igain-1]->noisify( noiseframe[igain-1] ,
00190                                      &noisy[0]->vecgau()   ) ;
00191 //          std::cout<<"....noisifying gain level = "<<igain<<std::endl ;
00192          }
00193         
00194          // noiseframe filled with zeros if !m_addNoise
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          // LogDebug("EcalCoder") << "DetId " << detId.rawId() << " gain " << igain << " caloSample " 
00203          //                       <<  ecalSamples[i] << " pededstal " << pedestals[igain] 
00204          //                       << " noise " << widths[igain] << " conversion factor " << LSB[igain] 
00205          //                       << " result (ped,tmpadc)= " << ped << " " << tmpadc;
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       // change the gain for saturation
00233       int storeGainId = gainId;
00234       if ( gainId == 3 && adc == MAXADC ) 
00235       {
00236          storeGainId = 0;
00237          isSaturated = true;
00238       }
00239       // LogDebug("EcalCoder") << " Writing out frame " << i << " ADC = " << adc << " gainId = " << gainId << " storeGainId = " << storeGainId ; 
00240      
00241       df.setSample( i, EcalMGPASample( adc, storeGainId ) );   
00242    }
00243    // handle saturation properly according to IN-2007/056
00244    // N.B. - FIXME 
00245    // still missing the possibility for a signal to pass the saturation threshold
00246    // again within the 5 subsequent samples (higher order effect).
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      EcalPedestalsMapIterator mapItr 
00272      = m_peds->m_pedestals.find(detId.rawId());
00273      // should I care if it doesn't get found?
00274      if(mapItr == m_peds->m_pedestals.end()) {
00275      edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << m_peds->m_pedestals.size();
00276      } else {
00277      EcalPedestals::Item item = mapItr->second;
00278    */
00279    
00280    /*   
00281         EcalPedestals::Item const & item = (*m_peds)(detId);
00282         ped = item.mean(gainId);
00283         width = item.rms(gainId);
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     switch(gainId) {
00297     case 0:
00298       ped = 0.;
00299       width = 0.;
00300     case 1:
00301       ped = item.mean_x12;
00302       width = item.rms_x12;
00303       break;
00304     case 2:
00305       ped = item.mean_x6;
00306       width = item.rms_x6;
00307       break;
00308     case 3:
00309       ped = item.mean_x1;
00310       width = item.rms_x1;
00311       break;
00312     default:
00313       edm::LogError("EcalCoder") << "Bad Pedestal " << gainId;
00314       break;
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     EcalGainRatios::EcalGainRatioMap::const_iterator grit=m_gainRatios->getMap().find(detId.rawId());
00328     EcalMGPAGainRatio mgpa;
00329     if( grit!=m_gainRatios->getMap().end() ){
00330     mgpa = grit->second;
00331     Gains[0] = 0.;
00332     Gains[3] = 1.;
00333     Gains[2] = mgpa.gain6Over1() ;
00334     Gains[1] = Gains[2]*(mgpa.gain12Over6()) ;
00335     LogDebug("EcalCoder") << "Gains for " << detId.rawId() << "\n" << " 1 = " << Gains[1] << "\n" << " 2 = " << Gains[2] << "\n" << " 3 = " << Gains[3];
00336     } else {
00337     edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << m_gainRatios->getMap().size();
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    // find intercalib constant for this xtal
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 }