#include <SimCalorimetry/EcalSimAlgos/interface/EcalCoder.h>
Public Types | |
enum | { NBITS = 12 } |
number of available bits More... | |
enum | { MAXADC = 4095 } |
adc max range More... | |
enum | { ADCGAINSWITCH = 4079 } |
adc gain switch More... | |
enum | { NGAINS = 3 } |
number of electronic gains More... | |
Public Member Functions | |
virtual void | analogToDigital (const CaloSamples &clf, EcalDataFrame &df) const |
from CaloSamples to EcalDataFrame | |
virtual void | digitalToAnalog (const EEDataFrame &df, CaloSamples &lf) const |
from EEDataFrame to CaloSamples | |
virtual void | digitalToAnalog (const EBDataFrame &df, CaloSamples &lf) const |
from EBDataFrame to CaloSamples | |
EcalCoder (bool addNoise, CorrelatedNoisifier< EcalCorrMatrix > *theCorrNoise) | |
ctor | |
void | newEvent () |
anything that needs to be done once per event | |
void | setFullScaleEnergy (const double EBscale, const double EEscale) |
void | setGainRatios (const EcalGainRatios *gainRatios) |
void | setPedestals (const EcalPedestals *pedestals) |
can be fetched every event from the EventSetup | |
virtual | ~EcalCoder () |
dtor | |
Private Member Functions | |
double | decode (const EcalMGPASample &sample, const DetId &detId) const |
void | encode (const CaloSamples &caloSamples, EcalDataFrame &df) const |
produce the pulse-shape | |
void | findGains (const DetId &detId, double theGains[]) const |
void | findPedestal (const DetId &detId, int gainId, double &pedestal, double &width) const |
look for the right pedestal according to the electronics gain | |
double | fullScaleEnergy (const DetId &) const |
limit on the energy scale due to the electronics range | |
void | noisify (float *values, int size) const |
not yet implemented | |
Private Attributes | |
bool | addNoise_ |
whether add noise to the pedestals and the gains | |
double | m_maxEneEB |
max attainable energy in the ecal barrel | |
double | m_maxEneEE |
max attainable energy in the ecal endcap | |
CorrelatedNoisifier < EcalCorrMatrix > * | theCorrNoise_ |
Correlated noisifier. | |
const EcalGainRatios * | theGainRatios |
the electronics gains | |
double | theGains [NGAINS+1] |
const EcalPedestals * | thePedestals |
the pedestals |
Definition at line 30 of file EcalCoder.h.
anonymous enum |
anonymous enum |
anonymous enum |
anonymous enum |
EcalCoder::EcalCoder | ( | bool | addNoise, | |
CorrelatedNoisifier< EcalCorrMatrix > * | theCorrNoise | |||
) |
ctor
Definition at line 11 of file EcalCoder.cc.
References m_maxEneEB, and m_maxEneEE.
00012 : thePedestals(0), 00013 addNoise_(addNoise), 00014 theCorrNoise_(theCorrNoise) 00015 00016 { 00017 00018 // 4095(MAXADC)*12(gain 2)*0.035(GeVtoADC)*0.97 00019 00020 m_maxEneEB = 1668.3 ; 00021 00022 // 4095(MAXADC)*12(gain 2)*0.060(GeVtoADC)*0.97 00023 00024 m_maxEneEE = 2859.9 ; 00025 00026 }
virtual EcalCoder::~EcalCoder | ( | ) | [inline, virtual] |
void EcalCoder::analogToDigital | ( | const CaloSamples & | clf, | |
EcalDataFrame & | df | |||
) | const [virtual] |
from CaloSamples to EcalDataFrame
Definition at line 60 of file EcalCoder.cc.
References encode(), EcalDataFrame::setSize(), and CaloSamples::size().
Referenced by EcalElectronicsSim::analogToDigital().
double EcalCoder::decode | ( | const EcalMGPASample & | sample, | |
const DetId & | detId | |||
) | const [private] |
Definition at line 165 of file EcalCoder.cc.
References EcalMGPASample::adc(), findGains(), findPedestal(), fullScaleEnergy(), EcalMGPASample::gainId(), MAXADC, NGAINS, pedestal, and width.
Referenced by digitalToAnalog().
00166 { 00167 double Emax = fullScaleEnergy(id); 00168 int gainNumber = sample.gainId(); 00169 if(gainNumber==0){gainNumber=3;} 00170 assert( gainNumber >=1 && gainNumber <=3); 00171 double gains[NGAINS+1]; 00172 findGains(id, gains); 00173 double LSB = Emax/(MAXADC*gains[gainNumber]) ; 00174 double pedestal = 0.; 00175 double width = 0.; 00176 findPedestal(id, gainNumber, pedestal, width); 00177 // we shift by LSB/2 to be centered 00178 return LSB * (sample.adc() + 0.5 - pedestal) ; 00179 }
void EcalCoder::digitalToAnalog | ( | const EEDataFrame & | df, | |
CaloSamples & | lf | |||
) | const [virtual] |
from EEDataFrame to CaloSamples
Definition at line 54 of file EcalCoder.cc.
References decode(), i, EEDataFrame::id(), and EcalDataFrame::size().
00054 { 00055 for(int i = 0; i < df.size(); ++i) { 00056 lf[i] = decode(df[i], df.id()); 00057 } 00058 }
void EcalCoder::digitalToAnalog | ( | const EBDataFrame & | df, | |
CaloSamples & | lf | |||
) | const [virtual] |
from EBDataFrame to CaloSamples
Definition at line 48 of file EcalCoder.cc.
References decode(), i, EBDataFrame::id(), and EcalDataFrame::size().
00048 { 00049 for(int i = 0; i < df.size(); ++i) { 00050 lf[i] = decode(df[i], df.id()); 00051 } 00052 }
void EcalCoder::encode | ( | const CaloSamples & | caloSamples, | |
EcalDataFrame & | df | |||
) | const [private] |
produce the pulse-shape
Definition at line 66 of file EcalCoder.cc.
References ecalMGPA::adc(), ADCGAINSWITCH, addNoise_, detId, findGains(), findPedestal(), fullScaleEnergy(), ecalMGPA::gainId(), i, CaloSamples::id(), int, LogDebug, MAXADC, NGAINS, EcalDataFrame::setSample(), signal, CaloSamples::size(), funct::sqrt(), theCorrNoise_, and thePedestals.
Referenced by analogToDigital().
00067 { 00068 assert(thePedestals != 0); 00069 00070 DetId detId = caloSamples.id(); 00071 double Emax = fullScaleEnergy(detId); 00072 00073 //....initialisation 00074 if ( caloSamples[5] > 0. ) 00075 LogDebug("EcalCoder") << "Input caloSample" << "\n" << caloSamples; 00076 00077 double LSB[NGAINS+1]; 00078 double pedestals[NGAINS+1]; 00079 double widths[NGAINS+1]; 00080 double gains[NGAINS+1]; 00081 double threeSigmaADCNoise[NGAINS+1]; 00082 int maxADC[NGAINS+1]; 00083 00084 for(int igain = 0; igain <= NGAINS; ++igain) { 00085 00086 // fill in the pedestal and width 00087 findPedestal(detId, igain, pedestals[igain], widths[igain]); 00088 00089 // set nominal value first 00090 findGains(detId, gains); 00091 00092 LSB[igain] = 0.; 00093 if ( igain > 0 ) LSB[igain]= Emax/(MAXADC*gains[igain]); 00094 threeSigmaADCNoise[igain] = 0.; 00095 if ( igain > 0 ) threeSigmaADCNoise[igain] = widths[igain] * 3.; 00096 maxADC[igain] = ADCGAINSWITCH; // saturation at 4080 for middle and high gains x6 & x12 00097 if ( igain == NGAINS ) maxADC[igain] = MAXADC; // saturation at 4095 for low gain x1 00098 } 00099 00100 CaloSamples noiseframe(detId, caloSamples.size()); 00101 if (addNoise_) { 00102 theCorrNoise_->noisify(noiseframe); 00103 LogDebug("EcalCoder") << "Normalized correlated noise calo frame = " << noiseframe; 00104 } 00105 00106 int wait = 0 ; 00107 int gainId = 0 ; 00108 for (int i = 0 ; i < caloSamples.size() ; ++i) 00109 { 00110 int adc = MAXADC; 00111 if (wait == 0) gainId = 1; 00112 00113 // see which gain bin it fits in 00114 int igain = gainId-1 ; 00115 while (igain != 3) { 00116 ++igain; 00117 00118 double ped = pedestals[igain]; 00119 double signal = ped + caloSamples[i] / LSB[igain]; 00120 00121 // see if it's close enough to the boundary that we have to throw noise 00122 if(addNoise_ && (signal <= maxADC[igain]+threeSigmaADCNoise[igain]) ) { 00123 // width is the actual final noise, subtract the additional one from the trivial quantization 00124 double trueRMS = std::sqrt(widths[igain]*widths[igain]-1./12.); 00125 ped = ped + trueRMS*noiseframe[i]; 00126 signal = ped + caloSamples[i] / LSB[igain]; 00127 } 00128 int tmpadc = (signal-(int)signal <= 0.5 ? (int)signal : (int)signal + 1); 00129 // LogDebug("EcalCoder") << "DetId " << detId.rawId() << " gain " << igain << " caloSample " 00130 // << caloSamples[i] << " pededstal " << pedestals[igain] 00131 // << " noise " << widths[igain] << " conversion factor " << LSB[igain] 00132 // << " result (ped,tmpadc)= " << ped << " " << tmpadc; 00133 00134 if(tmpadc <= maxADC[igain] ) { 00135 adc = tmpadc; 00136 break ; 00137 } 00138 } 00139 00140 if (igain == 1) 00141 { 00142 wait = 0 ; 00143 gainId = igain ; 00144 } 00145 else 00146 { 00147 if (igain == gainId) --wait ; 00148 else 00149 { 00150 wait = 5 ; 00151 gainId = igain ; 00152 } 00153 } 00154 00155 00156 // change the gain for saturation 00157 int storeGainId = gainId; 00158 if ( gainId == 3 && adc == MAXADC ) storeGainId = 0; 00159 // LogDebug("EcalCoder") << " Writing out frame " << i << " ADC = " << adc << " gainId = " << gainId << " storeGainId = " << storeGainId ; 00160 00161 df.setSample(i, EcalMGPASample(adc, storeGainId)); 00162 } 00163 }
Definition at line 236 of file EcalCoder.cc.
References EcalBarrel, EcalEndcap, EcalCondObjectContainer< T >::getMap(), DetId::rawId(), DetId::subdetId(), and theGainRatios.
Referenced by decode(), and encode().
00237 { 00238 /* 00239 EcalGainRatios::EcalGainRatioMap::const_iterator grit=theGainRatios->getMap().find(detId.rawId()); 00240 EcalMGPAGainRatio mgpa; 00241 if( grit!=theGainRatios->getMap().end() ){ 00242 mgpa = grit->second; 00243 Gains[0] = 0.; 00244 Gains[3] = 1.; 00245 Gains[2] = mgpa.gain6Over1() ; 00246 Gains[1] = Gains[2]*(mgpa.gain12Over6()) ; 00247 LogDebug("EcalCoder") << "Gains for " << detId.rawId() << "\n" << " 1 = " << Gains[1] << "\n" << " 2 = " << Gains[2] << "\n" << " 3 = " << Gains[3]; 00248 } else { 00249 edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << theGainRatios->getMap().size(); 00250 } 00251 */ 00252 00253 EcalGainRatioMap::const_iterator grit = theGainRatios->getMap().find( detId ); 00254 Gains[0] = 0.; 00255 Gains[3] = 1.; 00256 Gains[2] = (*grit).gain6Over1(); 00257 Gains[1] = Gains[2]*( (*grit).gain12Over6() ); 00258 00259 00260 if ( (detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap) ) { 00261 edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << theGainRatios->getMap().size(); 00262 } 00263 00264 }
void EcalCoder::findPedestal | ( | const DetId & | detId, | |
int | gainId, | |||
double & | pedestal, | |||
double & | width | |||
) | const [private] |
look for the right pedestal according to the electronics gain
Definition at line 182 of file EcalCoder.cc.
References EcalBarrel, EcalEndcap, EcalCondObjectContainer< T >::getMap(), LogDebug, DetId::rawId(), DetId::subdetId(), and thePedestals.
Referenced by decode(), and encode().
00184 { 00185 /* 00186 EcalPedestalsMapIterator mapItr 00187 = thePedestals->m_pedestals.find(detId.rawId()); 00188 // should I care if it doesn't get found? 00189 if(mapItr == thePedestals->m_pedestals.end()) { 00190 edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << thePedestals->m_pedestals.size(); 00191 } else { 00192 EcalPedestals::Item item = mapItr->second; 00193 */ 00194 00195 /* 00196 EcalPedestals::Item const & item = (*thePedestals)(detId); 00197 ped = item.mean(gainId); 00198 width = item.rms(gainId); 00199 */ 00200 00201 EcalPedestalsMap::const_iterator itped = thePedestals->getMap().find( detId ); 00202 ped = (*itped).mean(gainId); 00203 width = (*itped).rms(gainId); 00204 00205 if ( (detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap) ) { 00206 edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << thePedestals->getMap().size(); 00207 } 00208 00209 /* 00210 switch(gainId) { 00211 case 0: 00212 ped = 0.; 00213 width = 0.; 00214 case 1: 00215 ped = item.mean_x12; 00216 width = item.rms_x12; 00217 break; 00218 case 2: 00219 ped = item.mean_x6; 00220 width = item.rms_x6; 00221 break; 00222 case 3: 00223 ped = item.mean_x1; 00224 width = item.rms_x1; 00225 break; 00226 default: 00227 edm::LogError("EcalCoder") << "Bad Pedestal " << gainId; 00228 break; 00229 } 00230 */ 00231 00232 LogDebug("EcalCoder") << "Pedestals for " << detId.rawId() << " gain range " << gainId << " : \n" << "Mean = " << ped << " rms = " << width; 00233 }
double EcalCoder::fullScaleEnergy | ( | const DetId & | detId | ) | const [private] |
limit on the energy scale due to the electronics range
Definition at line 37 of file EcalCoder.cc.
References EcalBarrel, m_maxEneEB, m_maxEneEE, and DetId::subdetId().
Referenced by decode(), and encode().
00038 { 00039 00040 if (detId.subdetId() == EcalBarrel) 00041 return m_maxEneEB ; 00042 else 00043 return m_maxEneEE ; 00044 00045 }
void EcalCoder::newEvent | ( | ) | [inline] |
void EcalCoder::setFullScaleEnergy | ( | const double | EBscale, | |
const double | EEscale | |||
) | [inline] |
Definition at line 53 of file EcalCoder.h.
References m_maxEneEB, and m_maxEneEE.
Referenced by EcalTBDigiProducer::checkCalibrations(), and EcalDigiProducer::checkCalibrations().
00053 {m_maxEneEB = EBscale; m_maxEneEE = EEscale; }
void EcalCoder::setGainRatios | ( | const EcalGainRatios * | gainRatios | ) |
Definition at line 32 of file EcalCoder.cc.
References theGainRatios.
Referenced by EcalTBDigiProducer::checkCalibrations(), and EcalDigiProducer::checkCalibrations().
00032 { 00033 theGainRatios = gainRatios; 00034 }
void EcalCoder::setPedestals | ( | const EcalPedestals * | pedestals | ) |
can be fetched every event from the EventSetup
Definition at line 28 of file EcalCoder.cc.
References thePedestals.
Referenced by EcalTBDigiProducer::checkCalibrations(), and EcalDigiProducer::checkCalibrations().
00028 { 00029 thePedestals = pedestals; 00030 }
bool EcalCoder::addNoise_ [private] |
whether add noise to the pedestals and the gains
Definition at line 96 of file EcalCoder.h.
Referenced by encode().
double EcalCoder::m_maxEneEB [private] |
max attainable energy in the ecal barrel
Definition at line 92 of file EcalCoder.h.
Referenced by EcalCoder(), fullScaleEnergy(), and setFullScaleEnergy().
double EcalCoder::m_maxEneEE [private] |
max attainable energy in the ecal endcap
Definition at line 94 of file EcalCoder.h.
Referenced by EcalCoder(), fullScaleEnergy(), and setFullScaleEnergy().
const EcalGainRatios* EcalCoder::theGainRatios [private] |
the electronics gains
Definition at line 90 of file EcalCoder.h.
Referenced by findGains(), and setGainRatios().
double EcalCoder::theGains[NGAINS+1] [private] |
Definition at line 83 of file EcalCoder.h.
const EcalPedestals* EcalCoder::thePedestals [private] |
the pedestals
Definition at line 88 of file EcalCoder.h.
Referenced by encode(), findPedestal(), and setPedestals().