CMS 3D CMS Logo

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