CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalSimpleRecAlgo.cc
Go to the documentation of this file.
4 #include <algorithm> // for "max"
5 #include <math.h>
6 //--- temporary for printouts
7 #include<iostream>
8 
9 static double MaximumFractionalError = 0.002; // 0.2% error allowed from this source
10 
11 HcalSimpleRecAlgo::HcalSimpleRecAlgo(bool correctForTimeslew, bool correctForPulse, float phaseNS) :
12  correctForTimeslew_(correctForTimeslew),
13  correctForPulse_(correctForPulse),
14  phaseNS_(phaseNS), setForData_(false), setLeakCorrection_(false)
15 {
16 
17  pulseCorr_ = std::auto_ptr<HcalPulseContainmentManager>(
19  );
20 }
21 
22 
24  correctForTimeslew_(false), setForData_(false) { }
25 
26 
28 {
29  pulseCorr_->beginRun(es);
30 }
31 
32 
34 {
35  pulseCorr_->endRun();
36 }
37 
38 
40 }
41 
42 void HcalSimpleRecAlgo::setRecoParams(bool correctForTimeslew, bool correctForPulse, bool setLeakCorrection, int pileupCleaningID, float phaseNS){
43  correctForTimeslew_=correctForTimeslew;
44  correctForPulse_=correctForPulse;
45  phaseNS_=phaseNS;
47  pileupCleaningID_=pileupCleaningID;
48 }
49 
51 
53 
59 static float timeshift_ns_hbheho(float wpksamp);
60 
62 static float timeshift_ns_hf(float wpksamp);
63 
65 static float eCorr(int ieta, int iphi, double ampl);
66 
68 static float leakCorr(double energy);
69 
70 namespace HcalSimpleRecAlgoImpl {
71  template<class Digi, class RecHit>
72  inline RecHit reco(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
73  int ifirst, int n, bool slewCorrect, bool pulseCorrect, const HcalPulseContainmentCorrection* corr,
74  HcalTimeSlew::BiasSetting slewFlavor, bool forData, bool useLeak) {
75  CaloSamples tool;
76  coder.adc2fC(digi,tool);
77 
78  double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0;
79  double fc_ampl=0;
80  for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
81  int capid=digi[i].capid();
82  ta = (tool[i]-calibs.pedestal(capid)); // pedestal subtraction
83  fc_ampl+=ta;
84  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
85  ampl+=ta;
86  if(ta>maxA){
87  maxA=ta;
88  maxI=i;
89  }
90  }
91 
92  float time = -9999;
94  if(maxI==0 || maxI==(tool.size()-1)) {
95  LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :"
96  << " Invalid max amplitude position, "
97  << " max Amplitude: "<< maxI
98  << " first: "<<ifirst
99  << " last: "<<(tool.size()-1)
100  << std::endl;
101  } else {
102  int capid=digi[maxI-1].capid();
103  float t0 = ((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
104  capid=digi[maxI+1].capid();
105  float t2 = ((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
106 
107  // Handle negative excursions by moving "zero":
108  float minA=t0;
109  if (maxA<minA) minA=maxA;
110  if (t2<minA) minA=t2;
111  if (minA<0) { maxA-=minA; t0-=minA; t2-=minA; } // positivizes all samples
112 
113  float wpksamp = (t0 + maxA + t2);
114  if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
115  time = (maxI - digi.presamples())*25.0 + timeshift_ns_hbheho(wpksamp);
116  if (corr!=0 && pulseCorrect ) {
117  // Apply phase-based amplitude correction:
118 
119  /*
120  HcalDetId cell(digi.id());
121  int ieta = cell.ieta();
122  int iphi = cell.iphi();
123  int depth = cell.depth();
124  std::cout << "HcalSimpleRecAlgo::reco cell: ieta, iphi, depth = "
125  << ieta << ", " << iphi
126  << ", " << depth
127  << " first, toadd = " << ifirst << ", " << n << std::endl
128  << " ampl, corr, ampl_after_corr = "
129  << ampl << ", " << corr->getCorrection(fc_ampl)
130  << ", "
131  << ampl * corr->getCorrection(fc_ampl) << std::endl;
132  */
133 
134  ampl *= corr->getCorrection(fc_ampl);
135 
136  }
137  if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
138 
139  time=time-calibs.timecorr(); // time calibration
140  }
141 
142 
143  // Temoprary hack to apply energy-dependent corrections to some HB- cells
144  if(forData) {
145  HcalDetId cell(digi.id());
146  int ieta = cell.ieta();
147  int iphi = cell.iphi();
148  ampl *= eCorr(ieta,iphi,ampl);
149  }
150 
151  // Correction for a leak to pre-sample
152  if(useLeak) {
153  ampl *= leakCorr(ampl);
154  }
155 
156 
157  return RecHit(digi.id(),ampl,time);
158  }
159 }
160 
161 HBHERecHit HcalSimpleRecAlgo::reconstruct(const HBHEDataFrame& digi, int first, int toadd, const HcalCoder& coder, const HcalCalibrations& calibs) const {
162  return HcalSimpleRecAlgoImpl::reco<HBHEDataFrame,HBHERecHit>(digi,coder,calibs,
164  pulseCorr_->get(digi.id(), toadd, phaseNS_),
167 }
168 
169 HORecHit HcalSimpleRecAlgo::reconstruct(const HODataFrame& digi, int first, int toadd, const HcalCoder& coder, const HcalCalibrations& calibs) const {
170  return HcalSimpleRecAlgoImpl::reco<HODataFrame,HORecHit>(digi,coder,calibs,
172  pulseCorr_->get(digi.id(), toadd, phaseNS_),
174  setForData_, false);
175 }
176 
177 HcalCalibRecHit HcalSimpleRecAlgo::reconstruct(const HcalCalibDataFrame& digi, int first, int toadd, const HcalCoder& coder, const HcalCalibrations& calibs) const {
178  return HcalSimpleRecAlgoImpl::reco<HcalCalibDataFrame,HcalCalibRecHit>(digi,coder,calibs,
180  pulseCorr_->get(digi.id(), toadd, phaseNS_),
182  setForData_, false );
183 }
184 
185 HFRecHit HcalSimpleRecAlgo::reconstruct(const HFDataFrame& digi, int first, int toadd, const HcalCoder& coder, const HcalCalibrations& calibs) const {
186 
187  const HcalPulseContainmentCorrection* corr = pulseCorr_->get(digi.id(), toadd, phaseNS_);
188 
189  CaloSamples tool;
190  coder.adc2fC(digi,tool);
191 
192  double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0; float amp_fC=0;
193  for (int i=first; i<tool.size() && i<first+toadd; i++) {
194  int capid=digi[i].capid();
195  ta = (tool[i]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
196  ampl+=ta;
197  amp_fC += tool[i]-calibs.pedestal(capid);
198  if(ta>maxA){
199  maxA=ta;
200  maxI=i;
201  }
202  }
203 
204  float time=-9999.0;
206  if(maxI==0 || maxI==(tool.size()-1)) {
207  LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :"
208  << " Invalid max amplitude position, "
209  << " max Amplitude: "<< maxI
210  << " first: "<< first
211  << " last: "<<(tool.size()-1)
212  << std::endl;
213  } else {
214  int capid=digi[maxI-1].capid();
215  float t0 = (tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
216  capid=digi[maxI+1].capid();
217  float t2 = (tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
218 
219  // Handle negative excursions by moving "zero":
220  float zerocorr=std::min(t0,t2);
221  if (zerocorr<0.f) {
222  t0 -= zerocorr;
223  t2 -= zerocorr;
224  maxA -= zerocorr;
225  }
226 
227  // pair the peak with the larger of the two neighboring time samples
228  float wpksamp=0.f;
229  if (t0>t2) {
230  wpksamp = t0+maxA;
231  if (wpksamp != 0.f) wpksamp = maxA/wpksamp;
232  } else {
233  wpksamp = maxA+t2;
234  if (wpksamp != 0.f) wpksamp = 1.+(t2/wpksamp);
235  }
236 
237  time = (maxI - digi.presamples())*25.0 + timeshift_ns_hf(wpksamp);
238 
239  if (corr!=0 && correctForPulse_) {
240 
241  // Apply phase-based amplitude correction:
242 
243  /*
244  HcalDetId cell(digi.id());
245  int ieta = cell.ieta();
246  int iphi = cell.iphi();
247  int depth = cell.depth();
248  std::cout << "*** ieta, iphi, depth = " << ieta << ", " << iphi
249  << ", " << depth
250  << " first, toadd = " << ifirst << ", " << n << std::endl
251  << " ampl, corr, ampl_after_corr = "
252  << ampl << ", " << corr->getCorrection(fc_ampl)
253  << ", "
254  << ampl * corr->getCorrection(fc_ampl) << std::endl;
255  */
256 
257  ampl *= corr->getCorrection(amp_fC);
258  }
259 
260  if (correctForTimeslew_ && (amp_fC>0)) {
261  // -5.12327 - put in calibs.timecorr()
262  double tslew=exp(0.337681-5.94689e-4*amp_fC)+exp(2.44628-1.34888e-2*amp_fC);
263  time -= (float)tslew;
264  }
265 
266  time=time-calibs.timecorr();
267  }
268 
269  return HFRecHit(digi.id(),ampl,time);
270 }
271 
273 float eCorr(int ieta, int iphi, double energy) {
274 // return energy correction factor for HBM channels
275 // iphi=6 ieta=(-1,-15) and iphi=32 ieta=(-1,-7)
276 // I.Vodopianov 28 Feb. 2011
277  static const float low32[7] = {0.741,0.721,0.730,0.698,0.708,0.751,0.861};
278  static const float high32[7] = {0.973,0.925,0.900,0.897,0.950,0.935,1};
279  static const float low6[15] = {0.635,0.623,0.670,0.633,0.644,0.648,0.600,
280  0.570,0.595,0.554,0.505,0.513,0.515,0.561,0.579};
281  static const float high6[15] = {0.875,0.937,0.942,0.900,0.922,0.925,0.901,
282  0.850,0.852,0.818,0.731,0.717,0.782,0.853,0.778};
283 
284 
285  double slope, mid, en;
286  double corr = 1.0;
287 
288  if (!(iphi==6 && ieta<0 && ieta>-16) && !(iphi==32 && ieta<0 && ieta>-8))
289  return corr;
290 
291  int jeta = -ieta-1;
292  double xeta = (double) ieta;
293  if (energy > 0.) en=energy;
294  else en = 0.;
295 
296  if (iphi == 32) {
297  slope = 0.2272;
298  mid = 17.14 + 0.7147*xeta;
299  if (en > 100.) corr = high32[jeta];
300  else corr = low32[jeta]+(high32[jeta]-low32[jeta])/(1.0+exp(-(en-mid)*slope));
301  }
302  else if (iphi == 6) {
303  slope = 0.1956;
304  mid = 15.96 + 0.3075*xeta;
305  if (en > 100.0) corr = high6[jeta];
306  else corr = low6[jeta]+(high6[jeta]-low6[jeta])/(1.0+exp(-(en-mid)*slope));
307  }
308 
309  // std::cout << "HBHE cell: ieta, iphi = " << ieta << " " << iphi
310  // << " -> energy = " << en << " corr = " << corr << std::endl;
311 
312  return corr;
313 }
314 
315 
316 // Actual leakage (to pre-sample) correction
317 float leakCorr(double energy) {
318  double corr = 1.0;
319  return corr;
320 }
321 
322 
323 // timeshift implementation
324 
325 static const float wpksamp0_hbheho = 0.5;
326 static const int num_bins_hbheho = 61;
327 
328 static const float actual_ns_hbheho[num_bins_hbheho] = {
329 -5.44000, // 0.500, 0.000-0.017
330 -4.84250, // 0.517, 0.017-0.033
331 -4.26500, // 0.533, 0.033-0.050
332 -3.71000, // 0.550, 0.050-0.067
333 -3.18000, // 0.567, 0.067-0.083
334 -2.66250, // 0.583, 0.083-0.100
335 -2.17250, // 0.600, 0.100-0.117
336 -1.69000, // 0.617, 0.117-0.133
337 -1.23000, // 0.633, 0.133-0.150
338 -0.78000, // 0.650, 0.150-0.167
339 -0.34250, // 0.667, 0.167-0.183
340  0.08250, // 0.683, 0.183-0.200
341  0.50250, // 0.700, 0.200-0.217
342  0.90500, // 0.717, 0.217-0.233
343  1.30500, // 0.733, 0.233-0.250
344  1.69500, // 0.750, 0.250-0.267
345  2.07750, // 0.767, 0.267-0.283
346  2.45750, // 0.783, 0.283-0.300
347  2.82500, // 0.800, 0.300-0.317
348  3.19250, // 0.817, 0.317-0.333
349  3.55750, // 0.833, 0.333-0.350
350  3.91750, // 0.850, 0.350-0.367
351  4.27500, // 0.867, 0.367-0.383
352  4.63000, // 0.883, 0.383-0.400
353  4.98500, // 0.900, 0.400-0.417
354  5.33750, // 0.917, 0.417-0.433
355  5.69500, // 0.933, 0.433-0.450
356  6.05000, // 0.950, 0.450-0.467
357  6.40500, // 0.967, 0.467-0.483
358  6.77000, // 0.983, 0.483-0.500
359  7.13500, // 1.000, 0.500-0.517
360  7.50000, // 1.017, 0.517-0.533
361  7.88250, // 1.033, 0.533-0.550
362  8.26500, // 1.050, 0.550-0.567
363  8.66000, // 1.067, 0.567-0.583
364  9.07000, // 1.083, 0.583-0.600
365  9.48250, // 1.100, 0.600-0.617
366  9.92750, // 1.117, 0.617-0.633
367 10.37750, // 1.133, 0.633-0.650
368 10.87500, // 1.150, 0.650-0.667
369 11.38000, // 1.167, 0.667-0.683
370 11.95250, // 1.183, 0.683-0.700
371 12.55000, // 1.200, 0.700-0.717
372 13.22750, // 1.217, 0.717-0.733
373 13.98500, // 1.233, 0.733-0.750
374 14.81500, // 1.250, 0.750-0.767
375 15.71500, // 1.267, 0.767-0.783
376 16.63750, // 1.283, 0.783-0.800
377 17.53750, // 1.300, 0.800-0.817
378 18.38500, // 1.317, 0.817-0.833
379 19.16500, // 1.333, 0.833-0.850
380 19.89750, // 1.350, 0.850-0.867
381 20.59250, // 1.367, 0.867-0.883
382 21.24250, // 1.383, 0.883-0.900
383 21.85250, // 1.400, 0.900-0.917
384 22.44500, // 1.417, 0.917-0.933
385 22.99500, // 1.433, 0.933-0.950
386 23.53250, // 1.450, 0.950-0.967
387 24.03750, // 1.467, 0.967-0.983
388 24.53250, // 1.483, 0.983-1.000
389 25.00000 // 1.500, 1.000-1.017 - keep for interpolation
390 };
391 
392 float timeshift_ns_hbheho(float wpksamp) {
393  float flx = (num_bins_hbheho-1)*(wpksamp - wpksamp0_hbheho);
394  int index = (int)flx;
395  float yval;
396 
397  if (index < 0) return actual_ns_hbheho[0];
398  else if (index >= num_bins_hbheho-1) return actual_ns_hbheho[num_bins_hbheho-1];
399 
400  // else interpolate:
401  float y1 = actual_ns_hbheho[index];
402  float y2 = actual_ns_hbheho[index+1];
403 
404  yval = y1 + (y2-y1)*(flx-(float)index);
405 
406  return yval;
407 }
408 
409 static const int num_bins_hf = 101;
410 static const float wpksamp0_hf = 0.5;
411 
412 static const float actual_ns_hf[num_bins_hf] = {
413  0.00250, // 0.000-0.010
414  0.04500, // 0.010-0.020
415  0.08750, // 0.020-0.030
416  0.13000, // 0.030-0.040
417  0.17250, // 0.040-0.050
418  0.21500, // 0.050-0.060
419  0.26000, // 0.060-0.070
420  0.30250, // 0.070-0.080
421  0.34500, // 0.080-0.090
422  0.38750, // 0.090-0.100
423  0.42750, // 0.100-0.110
424  0.46000, // 0.110-0.120
425  0.49250, // 0.120-0.130
426  0.52500, // 0.130-0.140
427  0.55750, // 0.140-0.150
428  0.59000, // 0.150-0.160
429  0.62250, // 0.160-0.170
430  0.65500, // 0.170-0.180
431  0.68750, // 0.180-0.190
432  0.72000, // 0.190-0.200
433  0.75250, // 0.200-0.210
434  0.78500, // 0.210-0.220
435  0.81750, // 0.220-0.230
436  0.85000, // 0.230-0.240
437  0.88250, // 0.240-0.250
438  0.91500, // 0.250-0.260
439  0.95500, // 0.260-0.270
440  0.99250, // 0.270-0.280
441  1.03250, // 0.280-0.290
442  1.07000, // 0.290-0.300
443  1.10750, // 0.300-0.310
444  1.14750, // 0.310-0.320
445  1.18500, // 0.320-0.330
446  1.22500, // 0.330-0.340
447  1.26250, // 0.340-0.350
448  1.30000, // 0.350-0.360
449  1.34000, // 0.360-0.370
450  1.37750, // 0.370-0.380
451  1.41750, // 0.380-0.390
452  1.48750, // 0.390-0.400
453  1.55750, // 0.400-0.410
454  1.62750, // 0.410-0.420
455  1.69750, // 0.420-0.430
456  1.76750, // 0.430-0.440
457  1.83750, // 0.440-0.450
458  1.90750, // 0.450-0.460
459  2.06750, // 0.460-0.470
460  2.23250, // 0.470-0.480
461  2.40000, // 0.480-0.490
462  2.82250, // 0.490-0.500
463  3.81000, // 0.500-0.510
464  6.90500, // 0.510-0.520
465  8.99250, // 0.520-0.530
466 10.50000, // 0.530-0.540
467 11.68250, // 0.540-0.550
468 12.66250, // 0.550-0.560
469 13.50250, // 0.560-0.570
470 14.23750, // 0.570-0.580
471 14.89750, // 0.580-0.590
472 15.49000, // 0.590-0.600
473 16.03250, // 0.600-0.610
474 16.53250, // 0.610-0.620
475 17.00000, // 0.620-0.630
476 17.44000, // 0.630-0.640
477 17.85250, // 0.640-0.650
478 18.24000, // 0.650-0.660
479 18.61000, // 0.660-0.670
480 18.96750, // 0.670-0.680
481 19.30500, // 0.680-0.690
482 19.63000, // 0.690-0.700
483 19.94500, // 0.700-0.710
484 20.24500, // 0.710-0.720
485 20.54000, // 0.720-0.730
486 20.82250, // 0.730-0.740
487 21.09750, // 0.740-0.750
488 21.37000, // 0.750-0.760
489 21.62750, // 0.760-0.770
490 21.88500, // 0.770-0.780
491 22.13000, // 0.780-0.790
492 22.37250, // 0.790-0.800
493 22.60250, // 0.800-0.810
494 22.83000, // 0.810-0.820
495 23.04250, // 0.820-0.830
496 23.24500, // 0.830-0.840
497 23.44250, // 0.840-0.850
498 23.61000, // 0.850-0.860
499 23.77750, // 0.860-0.870
500 23.93500, // 0.870-0.880
501 24.05500, // 0.880-0.890
502 24.17250, // 0.890-0.900
503 24.29000, // 0.900-0.910
504 24.40750, // 0.910-0.920
505 24.48250, // 0.920-0.930
506 24.55500, // 0.930-0.940
507 24.62500, // 0.940-0.950
508 24.69750, // 0.950-0.960
509 24.77000, // 0.960-0.970
510 24.84000, // 0.970-0.980
511 24.91250, // 0.980-0.990
512 24.95500, // 0.990-1.000
513 24.99750, // 1.000-1.010 - keep for interpolation
514 };
515 
516 float timeshift_ns_hf(float wpksamp) {
517  float flx = (num_bins_hf-1)*(wpksamp-wpksamp0_hf);
518  int index = (int)flx;
519  float yval;
520 
521  if (index < 0) return actual_ns_hf[0];
522  else if (index >= num_bins_hf-1) return actual_ns_hf[num_bins_hf-1];
523 
524  // else interpolate:
525  float y1 = actual_ns_hf[index];
526  float y2 = actual_ns_hf[index+1];
527 
528  // float delta_x = 1/(float)num_bins_hf;
529  // yval = y1 + (y2-y1)*(flx-(float)index)/delta_x;
530 
531  yval = y1 + (y2-y1)*(flx-(float)index);
532  return yval;
533 }
#define LogDebug(id)
int i
Definition: DBlmapReader.cc:9
static const float actual_ns_hf[num_bins_hf]
HBHERecHit reconstruct(const HBHEDataFrame &digi, int first, int toadd, const HcalCoder &coder, const HcalCalibrations &calibs) const
double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
static float timeshift_ns_hf(float wpksamp)
Same as above, but for the HF PMTs.
double getCorrection(double fc_ampl) const
void beginRun(edm::EventSetup const &es)
static const double slope[3]
#define min(a, b)
Definition: mlp_lapack.h:161
double pedestal(int fCapId) const
get pedestal for capid=0..3
static const float wpksamp0_hbheho
static const float wpksamp0_hf
static const float actual_ns_hbheho[num_bins_hbheho]
const T & max(const T &a, const T &b)
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
void initPulseCorr(int toadd)
double f[11][100]
static float leakCorr(double energy)
Leak correction.
std::auto_ptr< HcalPulseContainmentManager > pulseCorr_
bool first
Definition: L1TdeRCT.cc:94
JetCorrectorParameters corr
Definition: classes.h:9
static float timeshift_ns_hbheho(float wpksamp)
static float eCorr(int ieta, int iphi, double ampl)
Ugly hack to apply energy corrections to some HB- cells.
void setRecoParams(bool correctForTimeslew, bool correctForPulse, bool setLeakCorrection, int pileupCleaningID, float phaseNS)
constexpr double MaximumFractionalError
int size() const
get the size
Definition: CaloSamples.h:24
double timecorr() const
get time correction factor
static const int num_bins_hf
static const int num_bins_hbheho
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const =0
int presamples() const
number of samples before the sample from the triggered beam crossing (according to the hardware) ...
Definition: HFDataFrame.h:28
const HcalDetId & id() const
Definition: HFDataFrame.h:22
RecHit reco(const Digi &digi, const HcalCoder &coder, const HcalCalibrations &calibs, int ifirst, int n, bool slewCorrect, bool pulseCorrect, const HcalPulseContainmentCorrection *corr, HcalTimeSlew::BiasSetting slewFlavor, bool forData, bool useLeak)
static double delay(double fC, BiasSetting bias=Medium)
Returns the amount (ns) by which a pulse of the given number of fC will be delayed by the timeslew ef...
Definition: HcalTimeSlew.cc:8