CMS 3D CMS Logo

EcalCoder.cc
Go to the documentation of this file.
6 
7 #include <iostream>
8 
9 //#include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
10 
11 EcalCoder::EcalCoder(bool addNoise,
12  bool PreMix1,
13  EcalCoder::Noisifier* ebCorrNoise0,
14  EcalCoder::Noisifier* eeCorrNoise0,
15  EcalCoder::Noisifier* ebCorrNoise1,
16  EcalCoder::Noisifier* eeCorrNoise1,
17  EcalCoder::Noisifier* ebCorrNoise2,
18  EcalCoder::Noisifier* eeCorrNoise2)
19  : m_peds(nullptr),
20  m_gainRatios(nullptr),
21  m_intercals(nullptr),
22  m_maxEneEB(1668.3), // 4095(MAXADC)*12(gain 2)*0.035(GeVtoADC)*0.97
23  m_maxEneEE(2859.9), // 4095(MAXADC)*12(gain 2)*0.060(GeVtoADC)*0.97
24  m_addNoise(addNoise),
25  m_PreMix1(PreMix1) {
26  m_ebCorrNoise[0] = ebCorrNoise0;
27  assert(nullptr != m_ebCorrNoise[0]);
28  m_eeCorrNoise[0] = eeCorrNoise0;
29  m_ebCorrNoise[1] = ebCorrNoise1;
30  m_eeCorrNoise[1] = eeCorrNoise1;
31  m_ebCorrNoise[2] = ebCorrNoise2;
32  m_eeCorrNoise[2] = eeCorrNoise2;
33 }
34 
36 
37 void EcalCoder::setFullScaleEnergy(double EBscale, double EEscale) {
38  m_maxEneEB = EBscale;
39  m_maxEneEE = EEscale;
40 }
41 
42 void EcalCoder::setPedestals(const EcalPedestals* pedestals) { m_peds = pedestals; }
43 
44 void EcalCoder::setGainRatios(const EcalGainRatios* gainRatios) { m_gainRatios = gainRatios; }
45 
47 
48 double EcalCoder::fullScaleEnergy(const DetId& detId) const {
49  return detId.subdetId() == EcalBarrel ? m_maxEneEB : m_maxEneEE;
50 }
51 
52 void EcalCoder::analogToDigital(CLHEP::HepRandomEngine* engine, const EcalSamples& clf, EcalDataFrame& df) const {
53  df.setSize(clf.size());
54  encode(clf, df, engine);
55  /* std::cout<<" **Id=" ;
56  if( CaloGenericDetId( clf.id() ).isEB() )
57  {
58  std::cout<<EBDetId( clf.id() ) ;
59  }
60  else
61  {
62  std::cout<<EEDetId( clf.id() ) ;
63  }
64  std::cout<<", size="<<df.size();
65  for( int i ( 0 ) ; i != df.size() ; ++i )
66  {
67  std::cout<<", "<<df[i];
68  }
69  std::cout<<std::endl ;*/
70 }
71 
72 void EcalCoder::encode(const EcalSamples& ecalSamples, EcalDataFrame& df, CLHEP::HepRandomEngine* engine) const {
73  assert(nullptr != m_peds);
74 
75  const unsigned int csize(ecalSamples.size());
76 
77  DetId detId = ecalSamples.id();
78  double Emax = fullScaleEnergy(detId);
79 
80  //....initialisation
81  if (ecalSamples[5] > 0.)
82  LogDebug("EcalCoder") << "Input caloSample"
83  << "\n"
84  << ecalSamples;
85 
86  double LSB[NGAINS + 1];
87  double pedestals[NGAINS + 1];
88  double widths[NGAINS + 1];
89  double gains[NGAINS + 1];
90  int maxADC[NGAINS + 1];
91  double trueRMS[NGAINS + 1];
92 
93  double icalconst = 1.;
94  findIntercalibConstant(detId, icalconst);
95 
96  for (unsigned int igain(0); igain <= NGAINS; ++igain) {
97  // fill in the pedestal and width
98  findPedestal(detId, igain, pedestals[igain], widths[igain]);
99 
100  if (0 < igain)
101  trueRMS[igain] = std::sqrt(widths[igain] * widths[igain] - 1. / 12.);
102 
103  // set nominal value first
104  findGains(detId, gains);
105 
106  LSB[igain] = 0.;
107  if (igain > 0)
108  LSB[igain] = Emax / (MAXADC * gains[igain]);
109  maxADC[igain] = ADCGAINSWITCH; // saturation at 4080 for middle and high gains x6 & x12
110  if (igain == NGAINS)
111  maxADC[igain] = MAXADC; // saturation at 4095 for low gain x1
112  }
113 
114  CaloSamples noiseframe[] = {CaloSamples(detId, csize), CaloSamples(detId, csize), CaloSamples(detId, csize)};
115 
116  const Noisifier* noisy[3] = {
117  (nullptr == m_eeCorrNoise[0] || EcalBarrel == detId.subdetId() ? m_ebCorrNoise[0] : m_eeCorrNoise[0]),
118  (EcalBarrel == detId.subdetId() ? m_ebCorrNoise[1] : m_eeCorrNoise[1]),
119  (EcalBarrel == detId.subdetId() ? m_ebCorrNoise[2] : m_eeCorrNoise[2])};
120 
121  if (m_addNoise) {
122  noisy[0]->noisify(noiseframe[0], engine); // high gain
123  if (nullptr == noisy[1])
124  noisy[0]->noisify(noiseframe[1], engine,
125  &noisy[0]->vecgau()); // med
126  if (nullptr == noisy[2])
127  noisy[0]->noisify(noiseframe[2], engine,
128  &noisy[0]->vecgau()); // low
129  }
130 
131  // std::cout << " intercal, LSBs, gains " << icalconst << " " << LSB[0] << " " << LSB[1] << " " << gains[0] << " " << gains[1] << " " << Emax << std::endl;
132 
133  int wait = 0;
134  int gainId = 0;
135  bool isSaturated = false;
136 
137  for (unsigned int i(0); i != csize; ++i) {
138  bool done(false);
139  int adc = MAXADC;
140  if (0 == wait)
141  gainId = 1;
142 
143  // see which gain bin it fits in
144  int igain(gainId - 1);
145  do {
146  ++igain;
147 
148  // if( igain != gainId ) std::cout <<"$$$$ Gain switch from " << gainId
149  // <<" to "<< igain << std::endl ;
150 
151  if (1 != igain && // not high gain
152  m_addNoise && // want to add noise
153  nullptr != noisy[igain - 1] && // exists
154  noiseframe[igain - 1].isBlank()) // not already done
155  {
156  noisy[igain - 1]->noisify(noiseframe[igain - 1], engine, &noisy[0]->vecgau());
157  //std::cout<<"....noisifying gain level = "<<igain<<std::endl ;
158  }
159 
160  double signal;
161 
162  if (!m_PreMix1) {
163  // noiseframe filled with zeros if !m_addNoise
164  const double asignal(pedestals[igain] + ecalSamples[i] / (LSB[igain] * icalconst) +
165  trueRMS[igain] * noiseframe[igain - 1][i]);
166  signal = asignal;
167  } else { // Any changes made here must be reverse-engineered in EcalSignalGenerator!
168 
169  if (igain == 1) {
170  const double asignal(ecalSamples[i] * 1000.); // save low level info
171  signal = asignal;
172  } else if (igain == 2) {
173  const double asignal(ecalSamples[i] / (LSB[1] * icalconst));
174  signal = asignal;
175  } else if (igain == 3) { // bet that no pileup hit has an energy over Emax/2
176  const double asignal(ecalSamples[i] / (LSB[2] * icalconst));
177  signal = asignal;
178  } else { //not sure we ever get here at gain=0, but hit wil be saturated anyway
179  const double asignal(ecalSamples[i] / (LSB[3] * icalconst)); // just calculate something
180  signal = asignal;
181  }
182  // old version
183  //const double asignal ( // no pedestals for pre-mixing
184  // ecalSamples[i] /( LSB[igain]*icalconst ) );
185  //signal = asignal;
186  }
187 
188  // std::cout << " " << ecalSamples[i] << " " << noiseframe[igain-1][i] << std::endl;
189 
190  const int isignal(signal);
191  const int tmpadc(signal - (double)isignal < 0.5 ? isignal : isignal + 1);
192  // LogDebug("EcalCoder") << "DetId " << detId.rawId() << " gain " << igain << " caloSample "
193  // << ecalSamples[i] << " pededstal " << pedestals[igain]
194  // << " noise " << widths[igain] << " conversion factor " << LSB[igain]
195  // << " result (ped,tmpadc)= " << ped << " " << tmpadc;
196 
197  if (tmpadc <= maxADC[igain]) {
198  adc = tmpadc;
199  done = true;
200  }
201  } while (!done && igain < 3);
202 
203  if (igain == 1) {
204  wait = 0;
205  gainId = igain;
206  } else {
207  if (igain == gainId)
208  --wait;
209  else {
210  wait = 5;
211  gainId = igain;
212  }
213  }
214 
215  // change the gain for saturation
216  int storeGainId = gainId;
217  if (gainId == 3 && adc == MAXADC) {
218  storeGainId = 0;
219  isSaturated = true;
220  }
221  // LogDebug("EcalCoder") << " Writing out frame " << i << " ADC = " << adc << " gainId = " << gainId << " storeGainId = " << storeGainId ;
222 
223  df.setSample(i, EcalMGPASample(adc, storeGainId));
224  }
225  // handle saturation properly according to IN-2007/056
226  // N.B. - FIXME
227  // still missing the possibility for a signal to pass the saturation threshold
228  // again within the 5 subsequent samples (higher order effect).
229 
230  if (isSaturated) {
231  for (unsigned int i = 0; i < ecalSamples.size(); ++i) {
232  if (df.sample(i).gainId() == 0) {
233  unsigned int hyst = i + 1 + 2;
234  for (unsigned int j = i + 1; j < hyst && j < ecalSamples.size(); ++j) {
235  df.setSample(j, EcalMGPASample(MAXADC, 0));
236  }
237  }
238  }
239  }
240 }
241 
242 void EcalCoder::findPedestal(const DetId& detId, int gainId, double& ped, double& width) const {
243  /*
244  EcalPedestalsMapIterator mapItr
245  = m_peds->m_pedestals.find(detId.rawId());
246  // should I care if it doesn't get found?
247  if(mapItr == m_peds->m_pedestals.end()) {
248  edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the " << m_peds->m_pedestals.size();
249  } else {
250  EcalPedestals::Item item = mapItr->second;
251  */
252 
253  /*
254  EcalPedestals::Item const & item = (*m_peds)(detId);
255  ped = item.mean(gainId);
256  width = item.rms(gainId);
257  */
258 
260  ped = (*itped).mean(gainId);
261  width = (*itped).rms(gainId);
262 
263  if ((detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap)) {
264  edm::LogError("EcalCoder") << "Could not find pedestal for " << detId.rawId() << " among the "
265  << m_peds->getMap().size();
266  }
267 
268  /*
269  switch(gainId) {
270  case 0:
271  ped = 0.;
272  width = 0.;
273  case 1:
274  ped = item.mean_x12;
275  width = item.rms_x12;
276  break;
277  case 2:
278  ped = item.mean_x6;
279  width = item.rms_x6;
280  break;
281  case 3:
282  ped = item.mean_x1;
283  width = item.rms_x1;
284  break;
285  default:
286  edm::LogError("EcalCoder") << "Bad Pedestal " << gainId;
287  break;
288  }
289  */
290 
291  LogDebug("EcalCoder") << "Pedestals for " << detId.rawId() << " gain range " << gainId << " : \n"
292  << "Mean = " << ped << " rms = " << width;
293 }
294 
295 void EcalCoder::findGains(const DetId& detId, double Gains[]) const {
296  /*
297  EcalGainRatios::EcalGainRatioMap::const_iterator grit=m_gainRatios->getMap().find(detId.rawId());
298  EcalMGPAGainRatio mgpa;
299  if( grit!=m_gainRatios->getMap().end() ){
300  mgpa = grit->second;
301  Gains[0] = 0.;
302  Gains[3] = 1.;
303  Gains[2] = mgpa.gain6Over1() ;
304  Gains[1] = Gains[2]*(mgpa.gain12Over6()) ;
305  LogDebug("EcalCoder") << "Gains for " << detId.rawId() << "\n" << " 1 = " << Gains[1] << "\n" << " 2 = " << Gains[2] << "\n" << " 3 = " << Gains[3];
306  } else {
307  edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the " << m_gainRatios->getMap().size();
308  }
309  */
310 
312  Gains[0] = 0.;
313  Gains[3] = 1.;
314  Gains[2] = (*grit).gain6Over1();
315  Gains[1] = Gains[2] * ((*grit).gain12Over6());
316 
317  if ((detId.subdetId() != EcalBarrel) && (detId.subdetId() != EcalEndcap)) {
318  edm::LogError("EcalCoder") << "Could not find gain ratios for " << detId.rawId() << " among the "
319  << m_gainRatios->getMap().size();
320  }
321 }
322 
323 void EcalCoder::findIntercalibConstant(const DetId& detId, double& icalconst) const {
324  EcalIntercalibConstantMC thisconst = 1.;
325  // find intercalib constant for this xtal
326  const EcalIntercalibConstantMCMap& icalMap = m_intercals->getMap();
327  EcalIntercalibConstantMCMap::const_iterator icalit = icalMap.find(detId);
328  if (icalit != icalMap.end()) {
329  thisconst = (*icalit);
330  if (icalconst == 0.) {
331  thisconst = 1.;
332  }
333  } else {
334  edm::LogError("EcalCoder") << "No intercalib const found for xtal " << detId.rawId()
335  << "! something wrong with EcalIntercalibConstants in your DB? ";
336  }
337  icalconst = thisconst;
338 }
#define LogDebug(id)
bool m_addNoise
Definition: EcalCoder.h:93
const EcalGainRatios * m_gainRatios
Definition: EcalCoder.h:86
adds noise to the given frame.
Definition: EcalCoder.h:12
const self & getMap() const
#define nullptr
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
EcalMGPASample sample(int i) const
Definition: EcalDataFrame.h:29
void setIntercalibConstants(const EcalIntercalibConstantsMC *ical)
Definition: EcalCoder.cc:46
virtual void analogToDigital(CLHEP::HepRandomEngine *, const EcalSamples &clf, EcalDataFrame &df) const
from EcalSamples to EcalDataFrame
Definition: EcalCoder.cc:52
void noisify(T &frame, CLHEP::HepRandomEngine *, const VecDou *rangau=nullptr) const
int gainId() const
get the gainId (2 bits)
double fullScaleEnergy(const DetId &did) const
limit on the energy scale due to the electronics range
Definition: EcalCoder.cc:48
const EcalIntercalibConstantsMC * m_intercals
Definition: EcalCoder.h:88
double m_maxEneEE
Definition: EcalCoder.h:91
const Noisifier * m_ebCorrNoise[3]
Definition: EcalCoder.h:96
void setSize(int)
Definition: EcalDataFrame.h:41
const Noisifier * m_eeCorrNoise[3]
Definition: EcalCoder.h:97
DetId id() const
T sqrt(T t)
Definition: SSEVec.h:18
void setPedestals(const EcalPedestals *pedestals)
can be fetched every event from the EventSetup
Definition: EcalCoder.cc:42
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
void findGains(const DetId &detId, double theGains[]) const
Definition: EcalCoder.cc:295
void encode(const EcalSamples &ecalSamples, EcalDataFrame &df, CLHEP::HepRandomEngine *) const
produce the pulse-shape
Definition: EcalCoder.cc:72
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
bool m_PreMix1
Definition: EcalCoder.h:94
const EcalPedestals * m_peds
Definition: EcalCoder.h:84
void setGainRatios(const EcalGainRatios *gainRatios)
Definition: EcalCoder.cc:44
Definition: DetId.h:18
void setFullScaleEnergy(double EBscale, double EEscale)
Definition: EcalCoder.cc:37
std::vector< Item >::const_iterator const_iterator
constexpr int gainId(sample_type sample)
get the gainId (2 bits)
bool isSaturated(const Digi &digi, const int &maxADCvalue, int ifirst, int n)
uint32_t size() const
void setSample(int i, EcalMGPASample sam)
Definition: EcalDataFrame.h:43
virtual ~EcalCoder()
dtor
Definition: EcalCoder.cc:35
double m_maxEneEB
Definition: EcalCoder.h:90
const_iterator find(uint32_t rawId) const
const_iterator end() const
float EcalIntercalibConstantMC
void findIntercalibConstant(const DetId &detId, double &icalconst) const
Definition: EcalCoder.cc:323
void findPedestal(const DetId &detId, int gainId, double &pedestal, double &width) const
not yet implemented
Definition: EcalCoder.cc:242
EcalCoder(bool addNoise, bool PreMix1, Noisifier *ebCorrNoise0, Noisifier *eeCorrNoise0=nullptr, Noisifier *ebCorrNoise1=nullptr, Noisifier *eeCorrNoise1=nullptr, Noisifier *ebCorrNoise2=nullptr, Noisifier *eeCorrNoise2=nullptr)
ctor
Definition: EcalCoder.cc:11