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