CMS 3D CMS Logo

PFEnergyCalibration.cc
Go to the documentation of this file.
1 
4 
6 
7 #include <TMath.h>
8 #include <cmath>
9 #include <vector>
10 #include <map>
11 #include <algorithm>
12 #include <numeric>
13 
14 using namespace std;
15 
17  //calibChrisClean.C calibration parameters bhumika Nov, 2018
18  faBarrel = std::make_unique<TF1>(
19  "faBarrel", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
20  faBarrel->SetParameter(0, -30.7141);
21  faBarrel->SetParameter(1, 31.7583);
22  faBarrel->SetParameter(2, 4.40594);
23  faBarrel->SetParameter(3, 1.70914);
24  faBarrel->SetParameter(4, 0.0613696);
25  faBarrel->SetParameter(5, 0.000104857);
26  faBarrel->SetParameter(6, -1.38927);
27  faBarrel->SetParameter(7, -0.743082);
28  fbBarrel = std::make_unique<TF1>(
29  "fbBarrel", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
30  fbBarrel->SetParameter(0, 2.25366);
31  fbBarrel->SetParameter(1, 0.537715);
32  fbBarrel->SetParameter(2, -4.81375);
33  fbBarrel->SetParameter(3, 12.109);
34  fbBarrel->SetParameter(4, 1.80577);
35  fbBarrel->SetParameter(5, 0.187919);
36  fbBarrel->SetParameter(6, -6.26234);
37  fbBarrel->SetParameter(7, -0.607392);
38  fcBarrel = std::make_unique<TF1>(
39  "fcBarrel", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
40  fcBarrel->SetParameter(0, 1.5125962);
41  fcBarrel->SetParameter(1, 0.855057);
42  fcBarrel->SetParameter(2, -6.04199);
43  fcBarrel->SetParameter(3, 2.08229);
44  fcBarrel->SetParameter(4, 0.592266);
45  fcBarrel->SetParameter(5, 0.0291232);
46  fcBarrel->SetParameter(6, 0.364802);
47  fcBarrel->SetParameter(7, -1.50142);
48  faEtaBarrelEH = std::make_unique<TF1>("faEtaBarrelEH", "[0]+[1]*exp(-x/[2])", 0., 1000.);
49  faEtaBarrelEH->SetParameter(0, 0.0185555);
50  faEtaBarrelEH->SetParameter(1, -0.0470674);
51  faEtaBarrelEH->SetParameter(2, 396.959);
52  fbEtaBarrelEH = std::make_unique<TF1>("fbEtaBarrelEH", "[0]+[1]*exp(-x/[2])", 0., 1000.);
53  fbEtaBarrelEH->SetParameter(0, 0.0396458);
54  fbEtaBarrelEH->SetParameter(1, 0.114128);
55  fbEtaBarrelEH->SetParameter(2, 251.405);
56  faEtaBarrelH = std::make_unique<TF1>("faEtaBarrelH", "[0]+[1]*x", 0., 1000.);
57  faEtaBarrelH->SetParameter(0, 0.00434994);
58  faEtaBarrelH->SetParameter(1, -5.16564e-06);
59  fbEtaBarrelH = std::make_unique<TF1>("fbEtaBarrelH", "[0]+[1]*exp(-x/[2])", 0., 1000.);
60  fbEtaBarrelH->SetParameter(0, -0.0232604);
61  fbEtaBarrelH->SetParameter(1, 0.0937525);
62  fbEtaBarrelH->SetParameter(2, 34.9935);
63 
64  faEndcap = std::make_unique<TF1>(
65  "faEndcap", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
66  faEndcap->SetParameter(0, 1.17227);
67  faEndcap->SetParameter(1, 13.1489);
68  faEndcap->SetParameter(2, -29.1672);
69  faEndcap->SetParameter(3, 0.604223);
70  faEndcap->SetParameter(4, 0.0426363);
71  faEndcap->SetParameter(5, 3.30898e-15);
72  faEndcap->SetParameter(6, 0.165293);
73  faEndcap->SetParameter(7, -7.56786);
74  fbEndcap = std::make_unique<TF1>(
75  "fbEndcap", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
76  fbEndcap->SetParameter(0, -0.974251);
77  fbEndcap->SetParameter(1, 1.61733);
78  fbEndcap->SetParameter(2, 0.0629183);
79  fbEndcap->SetParameter(3, 7.78495);
80  fbEndcap->SetParameter(4, -0.774289);
81  fbEndcap->SetParameter(5, 7.81399e-05);
82  fbEndcap->SetParameter(6, 0.139116);
83  fbEndcap->SetParameter(7, -4.25551);
84  fcEndcap = std::make_unique<TF1>(
85  "fcEndcap", "[0]+((([1]+([2]/sqrt(x)))*exp(-(x^[6]/[3])))-([4]*exp(-(x^[7]/[5]))))", 0., 1000.);
86  fcEndcap->SetParameter(0, 1.01863);
87  fcEndcap->SetParameter(1, 1.29787);
88  fcEndcap->SetParameter(2, -3.97293);
89  fcEndcap->SetParameter(3, 21.7805);
90  fcEndcap->SetParameter(4, 0.810195);
91  fcEndcap->SetParameter(5, 0.234134);
92  fcEndcap->SetParameter(6, 1.42226);
93  fcEndcap->SetParameter(7, -0.0997326);
94  faEtaEndcapEH = std::make_unique<TF1>("faEtaEndcapEH", "[0]+[1]*exp(-x/[2])", 0., 1000.);
95  faEtaEndcapEH->SetParameter(0, 0.0112692);
96  faEtaEndcapEH->SetParameter(1, -2.68063);
97  faEtaEndcapEH->SetParameter(2, 2.90973);
98  fbEtaEndcapEH = std::make_unique<TF1>("fbEtaEndcapEH", "[0]+[1]*exp(-x/[2])", 0., 1000.);
99  fbEtaEndcapEH->SetParameter(0, -0.0192991);
100  fbEtaEndcapEH->SetParameter(1, -0.265);
101  fbEtaEndcapEH->SetParameter(2, 80.5502);
102  faEtaEndcapH = std::make_unique<TF1>("faEtaEndcapH", "[0]+[1]*exp(-x/[2])+[3]*[3]*exp(-x*x/([4]*[4]))", 0., 1000.);
103  faEtaEndcapH->SetParameter(0, -0.0106029);
104  faEtaEndcapH->SetParameter(1, -0.692207);
105  faEtaEndcapH->SetParameter(2, 0.0542991);
106  faEtaEndcapH->SetParameter(3, -0.171435);
107  faEtaEndcapH->SetParameter(4, -61.2277);
108  fbEtaEndcapH = std::make_unique<TF1>("fbEtaEndcapH", "[0]+[1]*exp(-x/[2])+[3]*[3]*exp(-x*x/([4]*[4]))", 0., 1000.);
109  fbEtaEndcapH->SetParameter(0, 0.0214894);
110  fbEtaEndcapH->SetParameter(1, -0.266704);
111  fbEtaEndcapH->SetParameter(2, 5.2112);
112  fbEtaEndcapH->SetParameter(3, 0.303578);
113  fbEtaEndcapH->SetParameter(4, -104.367);
114 
115  //added by Bhumika on 2 august 2018
116 
117  fcEtaBarrelH = std::make_unique<TF1>("fcEtaBarrelH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
118  fcEtaBarrelH->SetParameter(0, 0);
119  fcEtaBarrelH->SetParameter(1, 2);
120  fcEtaBarrelH->SetParameter(2, 0);
121  fcEtaBarrelH->SetParameter(3, 1);
122 
123  fcEtaEndcapH = std::make_unique<TF1>("fcEtaEndcapH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
124  fcEtaEndcapH->SetParameter(0, 0);
125  fcEtaEndcapH->SetParameter(1, 0);
126  fcEtaEndcapH->SetParameter(2, 0.05);
127  fcEtaEndcapH->SetParameter(3, 0);
128 
129  fdEtaEndcapH = std::make_unique<TF1>("fdEtaEndcapH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
130  fdEtaEndcapH->SetParameter(0, 1.5);
131  fdEtaEndcapH->SetParameter(1, 4);
132  fdEtaEndcapH->SetParameter(2, -1.1);
133  fdEtaEndcapH->SetParameter(3, 1.0);
134 
135  fcEtaBarrelEH = std::make_unique<TF1>("fcEtaBarrelEH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
136  fcEtaBarrelEH->SetParameter(0, 0);
137  fcEtaBarrelEH->SetParameter(1, 2);
138  fcEtaBarrelEH->SetParameter(2, 0);
139  fcEtaBarrelEH->SetParameter(3, 1);
140 
141  fcEtaEndcapEH = std::make_unique<TF1>("fcEtaEndcapEH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
142  fcEtaEndcapEH->SetParameter(0, 0);
143  fcEtaEndcapEH->SetParameter(1, 0);
144  fcEtaEndcapEH->SetParameter(2, 0);
145  fcEtaEndcapEH->SetParameter(3, 0);
146 
147  fdEtaEndcapEH = std::make_unique<TF1>("fdEtaEndcapEH", "[3]*((x-[0])^[1])+[2]", 0., 1000.);
148  fdEtaEndcapEH->SetParameter(0, 1.5);
149  fdEtaEndcapEH->SetParameter(1, 2.0);
150  fdEtaEndcapEH->SetParameter(2, 0.6);
151  fdEtaEndcapEH->SetParameter(3, 1.0);
152 }
153 
155  reco::PFCluster const& eeCluster,
156  std::vector<reco::PFCluster const*> const& psClusterPointers,
157  ESChannelStatus const& channelStatus,
158  bool applyCrackCorrections) const {
159  double ps1_energy_sum = 0.;
160  double ps2_energy_sum = 0.;
161  bool condP1 = true;
162  bool condP2 = true;
163 
164  for (auto const& psclus : psClusterPointers) {
165  bool cond = true;
166  for (auto const& recH : psclus->recHitFractions()) {
167  auto strip = recH.recHitRef()->detId();
168  if (strip != ESDetId(0)) {
169  //getStatusCode() == 0 => active channel
170  // apply correction if all recHits are dead
171  if (channelStatus.getMap().find(strip)->getStatusCode() == 0) {
172  cond = false;
173  break;
174  }
175  }
176  }
177 
178  if (psclus->layer() == PFLayer::PS1) {
179  ps1_energy_sum += psclus->energy();
180  condP1 &= cond;
181  } else if (psclus->layer() == PFLayer::PS2) {
182  ps2_energy_sum += psclus->energy();
183  condP2 &= cond;
184  }
185  }
186 
187  double ePS1 = condP1 ? -1. : 0.;
188  double ePS2 = condP2 ? -1. : 0.;
189 
190  double cluscalibe = energyEm(eeCluster, ps1_energy_sum, ps2_energy_sum, ePS1, ePS2, applyCrackCorrections);
191 
192  return {cluscalibe, ePS1, ePS2};
193 }
194 
195 void PFEnergyCalibration::energyEmHad(double t, double& e, double& h, double eta, double phi) const {
196  // Use calorimetric energy as true energy for neutral particles
197  const double tt = t;
198  const double ee = e;
199  const double hh = h;
200  double etaCorrE = 1.;
201  double etaCorrH = 1.;
202  auto absEta = std::abs(eta);
203  t = min(999.9, max(tt, e + h));
204  if (t < 1.)
205  return;
206 
207  // Barrel calibration
208  if (absEta < 1.48) {
209  // The energy correction
210  double a = e > 0. ? aBarrel(t) : 1.;
211  double b = e > 0. ? bBarrel(t) : cBarrel(t);
212  double thresh = e > 0. ? threshE : threshH;
213 
214  // Protection against negative calibration
215  if (a < -0.25 || b < -0.25) {
216  a = 1.;
217  b = 1.;
218  thresh = 0.;
219  }
220 
221  // The new estimate of the true energy
222  t = min(999.9, max(tt, thresh + a * e + b * h));
223 
224  // The angular correction
225  if (e > 0. && thresh > 0.) {
226  etaCorrE = 1.0 + aEtaBarrelEH(t) + 1.3 * bEtaBarrelEH(t) * cEtaBarrelEH(absEta);
227  etaCorrH = 1.0;
228  } else {
229  etaCorrE = 1.0 + aEtaBarrelH(t) + 1.3 * bEtaBarrelH(t) * cEtaBarrelH(absEta);
230  etaCorrH = 1.0 + aEtaBarrelH(t) + bEtaBarrelH(t) * cEtaBarrelH(absEta);
231  }
232  if (e > 0. && thresh > 0.)
233  e = h > 0. ? threshE - threshH + etaCorrE * a * e : threshE + etaCorrE * a * e;
234  if (h > 0. && thresh > 0.) {
235  h = threshH + etaCorrH * b * h;
236  }
237 
238  // Endcap calibration
239  } else {
240  // The energy correction
241  double a = e > 0. ? aEndcap(t) : 1.;
242  double b = e > 0. ? bEndcap(t) : cEndcap(t);
243  double thresh = e > 0. ? threshE : threshH;
244 
245  // Protection against negative calibration
246  if (a < -0.25 || b < -0.25) {
247  a = 1.;
248  b = 1.;
249  thresh = 0.;
250  }
251 
252  // The new estimate of the true energy
253  t = min(999.9, max(tt, thresh + a * e + b * h));
254 
255  // The angular correction
256  const double dEta = std::abs(absEta - 1.5);
257  const double etaPow = dEta * dEta * dEta * dEta;
258 
259  if (e > 0. && thresh > 0.) {
260  if (absEta < 2.5) {
261  etaCorrE = 1. + aEtaEndcapEH(t) + bEtaEndcapEH(t) * cEtaEndcapEH(absEta);
262  } else {
263  etaCorrE = 1. + aEtaEndcapEH(t) + 1.3 * bEtaEndcapEH(t) * dEtaEndcapEH(absEta);
264  }
265 
266  etaCorrH = 1. + aEtaEndcapEH(t) + bEtaEndcapEH(t) * (0.04 + etaPow);
267  } else {
268  etaCorrE = 1.;
269  if (absEta < 2.5) {
270  etaCorrH = 1. + aEtaEndcapH(t) + bEtaEndcapH(t) * cEtaEndcapH(absEta);
271  } else {
272  etaCorrH = 1. + aEtaEndcapH(t) + bEtaEndcapH(t) * dEtaEndcapH(absEta);
273  }
274  }
275 
276  //t = min(999.9,max(tt, thresh + etaCorrE*a*e + etaCorrH*b*h));
277 
278  if (e > 0. && thresh > 0.)
279  e = h > 0. ? threshE - threshH + etaCorrE * a * e : threshE + etaCorrE * a * e;
280  if (h > 0. && thresh > 0.) {
281  h = threshH + etaCorrH * b * h;
282  }
283  }
284 
285  // Protection
286  if (e < 0. || h < 0.) {
287  // Some protection against crazy calibration
288  if (e < 0.)
289  e = ee;
290  if (h < 0.)
291  h = hh;
292  }
293 
294  // And that's it !
295 }
296 
297 // The calibration functions
298 double PFEnergyCalibration::aBarrel(double x) const {
299  if (pfCalibrations) {
302  return pfCalibrations->getResult(PerformanceResult::PFfa_BARREL, point);
303 
304  } else {
305  return faBarrel->Eval(x);
306  }
307 }
308 
309 double PFEnergyCalibration::bBarrel(double x) const {
310  if (pfCalibrations) {
313  return pfCalibrations->getResult(PerformanceResult::PFfb_BARREL, point);
314 
315  } else {
316  return fbBarrel->Eval(x);
317  }
318 }
319 
320 double PFEnergyCalibration::cBarrel(double x) const {
321  if (pfCalibrations) {
324  return pfCalibrations->getResult(PerformanceResult::PFfc_BARREL, point);
325 
326  } else {
327  return fcBarrel->Eval(x);
328  }
329 }
330 
331 double PFEnergyCalibration::aEtaBarrelEH(double x) const {
332  if (pfCalibrations) {
335  return pfCalibrations->getResult(PerformanceResult::PFfaEta_BARRELEH, point);
336 
337  } else {
338  return faEtaBarrelEH->Eval(x);
339  }
340 }
341 
342 double PFEnergyCalibration::bEtaBarrelEH(double x) const {
343  if (pfCalibrations) {
346  return pfCalibrations->getResult(PerformanceResult::PFfbEta_BARRELEH, point);
347 
348  } else {
349  return fbEtaBarrelEH->Eval(x);
350  }
351 }
352 
353 double PFEnergyCalibration::aEtaBarrelH(double x) const {
354  if (pfCalibrations) {
357  return pfCalibrations->getResult(PerformanceResult::PFfaEta_BARRELH, point);
358 
359  } else {
360  return faEtaBarrelH->Eval(x);
361  }
362 }
363 
364 double PFEnergyCalibration::bEtaBarrelH(double x) const {
365  if (pfCalibrations) {
368  return pfCalibrations->getResult(PerformanceResult::PFfbEta_BARRELH, point);
369 
370  } else {
371  return fbEtaBarrelH->Eval(x);
372  }
373 }
374 
375 double PFEnergyCalibration::aEndcap(double x) const {
376  if (pfCalibrations) {
379  return pfCalibrations->getResult(PerformanceResult::PFfa_ENDCAP, point);
380 
381  } else {
382  return faEndcap->Eval(x);
383  }
384 }
385 
386 double PFEnergyCalibration::bEndcap(double x) const {
387  if (pfCalibrations) {
390  return pfCalibrations->getResult(PerformanceResult::PFfb_ENDCAP, point);
391 
392  } else {
393  return fbEndcap->Eval(x);
394  }
395 }
396 
397 double PFEnergyCalibration::cEndcap(double x) const {
398  if (pfCalibrations) {
401  return pfCalibrations->getResult(PerformanceResult::PFfc_ENDCAP, point);
402 
403  } else {
404  return fcEndcap->Eval(x);
405  }
406 }
407 
408 double PFEnergyCalibration::aEtaEndcapEH(double x) const {
409  if (pfCalibrations) {
412  return pfCalibrations->getResult(PerformanceResult::PFfaEta_ENDCAPEH, point);
413 
414  } else {
415  return faEtaEndcapEH->Eval(x);
416  }
417 }
418 
419 double PFEnergyCalibration::bEtaEndcapEH(double x) const {
420  if (pfCalibrations) {
423  return pfCalibrations->getResult(PerformanceResult::PFfbEta_ENDCAPEH, point);
424 
425  } else {
426  return fbEtaEndcapEH->Eval(x);
427  }
428 }
429 
430 double PFEnergyCalibration::aEtaEndcapH(double x) const {
431  if (pfCalibrations) {
434  return pfCalibrations->getResult(PerformanceResult::PFfaEta_ENDCAPH, point);
435 
436  } else {
437  return faEtaEndcapH->Eval(x);
438  }
439 }
440 
441 double PFEnergyCalibration::bEtaEndcapH(double x) const {
442  if (pfCalibrations) {
445  return pfCalibrations->getResult(PerformanceResult::PFfbEta_ENDCAPH, point);
446  } else {
447  return fbEtaEndcapH->Eval(x);
448  }
449 }
450 
451 //added by Bhumika Kansal on 3 august 2018
452 
453 double PFEnergyCalibration::cEtaBarrelH(double x) const {
454  if (pfCalibrations) {
457  return pfCalibrations->getResult(PerformanceResult::PFfcEta_BARRELH, point);
458 
459  } else {
460  return fcEtaBarrelH->Eval(x);
461  }
462 }
463 double PFEnergyCalibration::cEtaEndcapH(double x) const {
464  if (pfCalibrations) {
467  return pfCalibrations->getResult(PerformanceResult::PFfcEta_ENDCAPH, point);
468 
469  } else {
470  return fcEtaEndcapH->Eval(x);
471  }
472 }
473 
474 double PFEnergyCalibration::dEtaEndcapH(double x) const {
475  if (pfCalibrations) {
478  return pfCalibrations->getResult(PerformanceResult::PFfdEta_ENDCAPH, point);
479 
480  } else {
481  return fdEtaEndcapH->Eval(x);
482  }
483 }
484 
485 double PFEnergyCalibration::cEtaBarrelEH(double x) const {
486  if (pfCalibrations) {
489  return pfCalibrations->getResult(PerformanceResult::PFfcEta_BARRELEH, point);
490 
491  } else {
492  return fcEtaBarrelEH->Eval(x);
493  }
494 }
495 
496 double PFEnergyCalibration::cEtaEndcapEH(double x) const {
497  if (pfCalibrations) {
500  return pfCalibrations->getResult(PerformanceResult::PFfcEta_ENDCAPEH, point);
501 
502  } else {
503  return fcEtaEndcapEH->Eval(x);
504  }
505 }
506 
507 double PFEnergyCalibration::dEtaEndcapEH(double x) const {
508  if (pfCalibrations) {
511  return pfCalibrations->getResult(PerformanceResult::PFfdEta_ENDCAPEH, point);
512 
513  } else {
514  return fdEtaEndcapEH->Eval(x);
515  }
516 }
517 
519  double ePS1,
520  double ePS2,
521  bool crackCorrection) const {
522  return Ecorr(clusterEcal.energy(), ePS1, ePS2, clusterEcal.eta(), clusterEcal.phi(), crackCorrection);
523 }
524 
526  double ePS1,
527  double ePS2,
528  double& ps1,
529  double& ps2,
530  bool crackCorrection) const {
531  return Ecorr(clusterEcal.energy(), ePS1, ePS2, clusterEcal.eta(), clusterEcal.phi(), ps1, ps2, crackCorrection);
532 }
533 
534 std::ostream& operator<<(std::ostream& out, const PFEnergyCalibration& calib) {
535  if (!out)
536  return out;
537 
538  out << "PFEnergyCalibration -- " << endl;
539 
540  if (calib.pfCalibrations) {
541  static const std::map<std::string, PerformanceResult::ResultType> functType = {
542  {"PFfa_BARREL", PerformanceResult::PFfa_BARREL},
543  {"PFfa_ENDCAP", PerformanceResult::PFfa_ENDCAP},
544  {"PFfb_BARREL", PerformanceResult::PFfb_BARREL},
545  {"PFfb_ENDCAP", PerformanceResult::PFfb_ENDCAP},
546  {"PFfc_BARREL", PerformanceResult::PFfc_BARREL},
547  {"PFfc_ENDCAP", PerformanceResult::PFfc_ENDCAP},
548  {"PFfaEta_BARRELH", PerformanceResult::PFfaEta_BARRELH},
549  {"PFfaEta_ENDCAPH", PerformanceResult::PFfaEta_ENDCAPH},
550  {"PFfbEta_BARRELH", PerformanceResult::PFfbEta_BARRELH},
551  {"PFfbEta_ENDCAPH", PerformanceResult::PFfbEta_ENDCAPH},
552  {"PFfaEta_BARRELEH", PerformanceResult::PFfaEta_BARRELEH},
553  {"PFfaEta_ENDCAPEH", PerformanceResult::PFfaEta_ENDCAPEH},
554  {"PFfbEta_BARRELEH", PerformanceResult::PFfbEta_BARRELEH},
555  {"PFfbEta_ENDCAPEH", PerformanceResult::PFfbEta_ENDCAPEH},
556  {"PFfcEta_BARRELH", PerformanceResult::PFfcEta_BARRELH},
557  {"PFfcEta_ENDCAPH", PerformanceResult::PFfcEta_ENDCAPH},
558  {"PFfdEta_ENDCAPH", PerformanceResult::PFfdEta_ENDCAPH},
559  {"PFfcEta_BARRELEH", PerformanceResult::PFfcEta_BARRELEH},
560  {"PFfcEta_ENDCAPEH", PerformanceResult::PFfcEta_ENDCAPEH},
561  {"PFfdEta_ENDCAPEH", PerformanceResult::PFfdEta_ENDCAPEH}
562 
563  };
564 
565  for (std::map<std::string, PerformanceResult::ResultType>::const_iterator func = functType.begin();
566  func != functType.end();
567  ++func) {
568  cout << "Function: " << func->first << endl;
569  PerformanceResult::ResultType fType = func->second;
570  calib.pfCalibrations->printFormula(fType);
571  }
572 
573  } else {
574  std::cout << "Default calibration functions : " << std::endl;
575 
576  calib.faBarrel->Print();
577  calib.fbBarrel->Print();
578  calib.fcBarrel->Print();
579  calib.faEtaBarrelEH->Print();
580  calib.fbEtaBarrelEH->Print();
581  calib.faEtaBarrelH->Print();
582  calib.fbEtaBarrelH->Print();
583  calib.faEndcap->Print();
584  calib.fbEndcap->Print();
585  calib.fcEndcap->Print();
586  calib.faEtaEndcapEH->Print();
587  calib.fbEtaEndcapEH->Print();
588  calib.faEtaEndcapH->Print();
589  calib.fbEtaEndcapH->Print();
590  //
591  }
592 
593  return out;
594 }
595 
608 
614 
615 //useful to compute the signed distance to the closest crack in the barrel
616 double PFEnergyCalibration::minimum(double a, double b) const {
617  if (std::abs(b) < std::abs(a))
618  a = b;
619  return a;
620 }
621 
622 namespace {
623  constexpr double pi = M_PI; // 3.14159265358979323846;
624 
625  std::vector<double> fillcPhi() {
626  std::vector<double> retValue;
627  retValue.resize(18, 0);
628  retValue[0] = 2.97025;
629  for (unsigned i = 1; i <= 17; ++i)
630  retValue[i] = retValue[0] - 2 * i * pi / 18;
631 
632  return retValue;
633  }
634 
635  //Location of the 18 phi-cracks
636  const std::vector<double> cPhi = fillcPhi();
637 } // namespace
638 
639 //compute the unsigned distance to the closest phi-crack in the barrel
640 double PFEnergyCalibration::dCrackPhi(double phi, double eta) const {
641  //Shift of this location if eta<0
642  constexpr double delta_cPhi = 0.00638;
643 
644  double m; //the result
645 
646  //the location is shifted
647  if (eta < 0)
648  phi += delta_cPhi;
649 
650  if (phi >= -pi && phi <= pi) {
651  //the problem of the extrema
652  if (phi < cPhi[17] || phi >= cPhi[0]) {
653  if (phi < 0)
654  phi += 2 * pi;
655  m = minimum(phi - cPhi[0], phi - cPhi[17] - 2 * pi);
656  }
657 
658  //between these extrema...
659  else {
660  bool OK = false;
661  unsigned i = 16;
662  while (!OK) {
663  if (phi < cPhi[i]) {
664  m = minimum(phi - cPhi[i + 1], phi - cPhi[i]);
665  OK = true;
666  } else
667  i -= 1;
668  }
669  }
670  } else {
671  m = 0.; //if there is a problem, we assum that we are in a crack
672  std::cout << "Problem in dminphi" << std::endl;
673  }
674  if (eta < 0)
675  m = -m; //because of the disymetry
676  return m;
677 }
678 
679 // corrects the effect of phi-cracks
680 double PFEnergyCalibration::CorrPhi(double phi, double eta) const {
681  // we use 3 gaussians to correct the phi-cracks effect
682  constexpr double p1 = 5.59379e-01;
683  constexpr double p2 = -1.26607e-03;
684  constexpr double p3 = 9.61133e-04;
685 
686  constexpr double p4 = 1.81691e-01;
687  constexpr double p5 = -4.97535e-03;
688  constexpr double p6 = 1.31006e-03;
689 
690  constexpr double p7 = 1.38498e-01;
691  constexpr double p8 = 1.18599e-04;
692  constexpr double p9 = 2.01858e-03;
693 
694  double dminphi = dCrackPhi(phi, eta);
695 
696  double result =
697  (1 + p1 * TMath::Gaus(dminphi, p2, p3) + p4 * TMath::Gaus(dminphi, p5, p6) + p7 * TMath::Gaus(dminphi, p8, p9));
698 
699  return result;
700 }
701 
702 // corrects the effect of |eta|-cracks
703 double PFEnergyCalibration::CorrEta(double eta) const {
704  // we use a gaussian with a screwness for each of the 5 |eta|-cracks
705  constexpr double a[] = {6.13349e-01, 5.08146e-01, 4.44480e-01, 3.3487e-01, 7.65627e-01}; // amplitude
706  constexpr double m[] = {-1.79514e-02, 4.44747e-01, 7.92824e-01, 1.14090e+00, 1.47464e+00}; // mean
707  constexpr double s[] = {7.92382e-03, 3.06028e-03, 3.36139e-03, 3.94521e-03, 8.63950e-04}; // sigma
708  constexpr double sa[] = {1.27228e+01, 3.81517e-02, 1.63507e-01, -6.56480e-02, 1.87160e-01}; // screwness amplitude
709  constexpr double ss[] = {5.48753e-02, -1.00223e-02, 2.22866e-03, 4.26288e-04, 2.67937e-03}; // screwness sigma
710  double result = 1;
711 
712  for (unsigned i = 0; i <= 4; i++)
713  result += a[i] * TMath::Gaus(eta, m[i], s[i]) *
714  (1 + sa[i] * TMath::Sign(1., eta - m[i]) * TMath::Exp(-std::abs(eta - m[i]) / ss[i]));
715 
716  return result;
717 }
718 
719 //corrects the global behaviour in the barrel
720 double PFEnergyCalibration::CorrBarrel(double E, double eta) const {
721  //Energy dependency
722  /*
723  //YM Parameters 52XX:
724  constexpr double p0=1.00000e+00;
725  constexpr double p1=3.27753e+01;
726  constexpr double p2=2.28552e-02;
727  constexpr double p3=3.06139e+00;
728  constexpr double p4=2.25135e-01;
729  constexpr double p5=1.47824e+00;
730  constexpr double p6=1.09e-02;
731  constexpr double p7=4.19343e+01;
732  */
733  constexpr double p0 = 0.9944;
734  constexpr double p1 = 9.827;
735  constexpr double p2 = 1.503;
736  constexpr double p3 = 1.196;
737  constexpr double p4 = 0.3349;
738  constexpr double p5 = 0.89;
739  constexpr double p6 = 0.004361;
740  constexpr double p7 = 51.51;
741  //Eta dependency
742  constexpr double p8 = 2.705593e-03;
743 
744  double result =
745  (p0 + 1 / (p1 + p2 * TMath::Power(E, p3)) + p4 * TMath::Exp(-E / p5) + p6 * TMath::Exp(-E * E / (p7 * p7))) *
746  (1 + p8 * eta * eta);
747 
748  return result;
749 }
750 
759 
760 //Alpha, Beta, Gamma give the weight of each sub-detector (PS layer1, PS layer2 and Ecal) in the areas of the endcaps where there is a PS
761 // Etot = Beta*eEcal + Gamma*(ePS1 + Alpha*ePS2)
762 
763 double PFEnergyCalibration::Alpha(double eta) const {
764  //Energy dependency
765  constexpr double p0 = 5.97621e-01;
766 
767  //Eta dependency
768  constexpr double p1 = -1.86407e-01;
769  constexpr double p2 = 3.85197e-01;
770 
771  //so that <feta()> = 1
772  constexpr double norm = (p1 + p2 * (2.6 + 1.656) / 2);
773 
774  double result = p0 * (p1 + p2 * eta) / norm;
775 
776  return result;
777 }
778 
779 double PFEnergyCalibration::Beta(double E, double eta) const {
780  //Energy dependency
781  constexpr double p0 = 0.032;
782  constexpr double p1 = 9.70394e-02;
783  constexpr double p2 = 2.23072e+01;
784  constexpr double p3 = 100;
785 
786  //Eta dependency
787  constexpr double p4 = 1.02496e+00;
788  constexpr double p5 = -4.40176e-03;
789 
790  //so that <feta()> = 1
791  constexpr double norm = (p4 + p5 * (2.6 + 1.656) / 2);
792 
793  double result = (1.0012 + p0 * TMath::Exp(-E / p3) + p1 * TMath::Exp(-E / p2)) * (p4 + p5 * eta) / norm;
794  return result;
795 }
796 
797 double PFEnergyCalibration::Gamma(double etaEcal) const {
798  //Energy dependency
799  constexpr double p0 = 2.49752e-02;
800 
801  //Eta dependency
802  constexpr double p1 = 6.48816e-02;
803  constexpr double p2 = -1.59517e-02;
804 
805  //so that <feta()> = 1
806  constexpr double norm = (p1 + p2 * (2.6 + 1.656) / 2);
807 
808  double result = p0 * (p1 + p2 * etaEcal) / norm;
809 
810  return result;
811 }
812 
818 
819 // returns the corrected energy in the barrel (0,1.48)
820 // Global Behaviour, phi and eta cracks are taken into account
821 double PFEnergyCalibration::EcorrBarrel(double E, double eta, double phi, bool crackCorrection) const {
822  // double result = E*CorrBarrel(E,eta)*CorrEta(eta)*CorrPhi(phi,eta);
823  double correction = crackCorrection ? std::max(CorrEta(eta), CorrPhi(phi, eta)) : 1.;
824  double result = E * CorrBarrel(E, eta) * correction;
825 
826  return result;
827 }
828 
829 // returns the corrected energy in the area between the barrel and the PS (1.48,1.65)
830 double PFEnergyCalibration::EcorrZoneBeforePS(double E, double eta) const {
831  //Energy dependency
832  constexpr double p0 = 1;
833  constexpr double p1 = 0.18;
834  constexpr double p2 = 8.;
835 
836  //Eta dependency
837  constexpr double p3 = 0.3;
838  constexpr double p4 = 1.11;
839  constexpr double p5 = 0.025;
840  constexpr double p6 = 1.49;
841  constexpr double p7 = 0.6;
842 
843  //so that <feta()> = 1
844  constexpr double norm = 1.21;
845 
846  double result = E * (p0 + p1 * TMath::Exp(-E / p2)) * (p3 + p4 * TMath::Gaus(eta, p6, p5) + p7 * eta) / norm;
847 
848  return result;
849 }
850 
851 // returns the corrected energy in the PS (1.65,2.6)
852 // only when (ePS1>0)||(ePS2>0)
853 double PFEnergyCalibration::EcorrPS(double eEcal, double ePS1, double ePS2, double etaEcal) const {
854  // gives the good weights to each subdetector
855  double E = Beta(1.0155 * eEcal + 0.025 * (ePS1 + 0.5976 * ePS2) / 9e-5, etaEcal) * eEcal +
856  Gamma(etaEcal) * (ePS1 + Alpha(etaEcal) * ePS2) / 9e-5;
857 
858  //Correction of the residual energy dependency
859  constexpr double p0 = 1.00;
860  constexpr double p1 = 2.18;
861  constexpr double p2 = 1.94;
862  constexpr double p3 = 4.13;
863  constexpr double p4 = 1.127;
864 
865  double result = E * (p0 + p1 * TMath::Exp(-E / p2) - p3 * TMath::Exp(-E / p4));
866 
867  return result;
868 }
869 
870 // returns the corrected energy in the PS (1.65,2.6)
871 // only when (ePS1>0)||(ePS2>0)
873  double eEcal, double ePS1, double ePS2, double etaEcal, double& outputPS1, double& outputPS2) const {
874  // gives the good weights to each subdetector
875  double gammaprime = Gamma(etaEcal) / 9e-5;
876 
877  if (outputPS1 == 0 && outputPS2 == 0 && esEEInterCalib_ != nullptr) {
878  // both ES planes working
879  // scaling factor accounting for data-mc
880  outputPS1 = gammaprime * ePS1 * esEEInterCalib_->getGammaLow0();
881  outputPS2 = gammaprime * Alpha(etaEcal) * ePS2 * esEEInterCalib_->getGammaLow3();
882  } else if (outputPS1 == 0 && outputPS2 == -1 && esEEInterCalib_ != nullptr) {
883  // ESP1 only working
884  double corrTotES = gammaprime * ePS1 * esEEInterCalib_->getGammaLow0() * esEEInterCalib_->getGammaLow1();
885  outputPS1 = gammaprime * ePS1 * esEEInterCalib_->getGammaLow0();
886  outputPS2 = corrTotES - outputPS1;
887  } else if (outputPS1 == -1 && outputPS2 == 0 && esEEInterCalib_ != nullptr) {
888  // ESP2 only working
889  double corrTotES =
890  gammaprime * Alpha(etaEcal) * ePS2 * esEEInterCalib_->getGammaLow3() * esEEInterCalib_->getGammaLow2();
891  outputPS2 = gammaprime * Alpha(etaEcal) * ePS2 * esEEInterCalib_->getGammaLow3();
892  outputPS1 = corrTotES - outputPS2;
893  } else {
894  // none working
895  outputPS1 = gammaprime * ePS1;
896  outputPS2 = gammaprime * Alpha(etaEcal) * ePS2;
897  }
898 
899  double E = Beta(1.0155 * eEcal + 0.025 * (ePS1 + 0.5976 * ePS2) / 9e-5, etaEcal) * eEcal + outputPS1 + outputPS2;
900 
901  //Correction of the residual energy dependency
902  constexpr double p0 = 1.00;
903  constexpr double p1 = 2.18;
904  constexpr double p2 = 1.94;
905  constexpr double p3 = 4.13;
906  constexpr double p4 = 1.127;
907 
908  double corrfac = (p0 + p1 * TMath::Exp(-E / p2) - p3 * TMath::Exp(-E / p4));
909  outputPS1 *= corrfac;
910  outputPS2 *= corrfac;
911  double result = E * corrfac;
912 
913  return result;
914 }
915 
916 // returns the corrected energy in the PS (1.65,2.6)
917 // only when (ePS1=0)&&(ePS2=0)
918 double PFEnergyCalibration::EcorrPS_ePSNil(double eEcal, double eta) const {
919  //Energy dependency
920  constexpr double p0 = 1.02;
921  constexpr double p1 = 0.165;
922  constexpr double p2 = 6.5;
923  constexpr double p3 = 2.1;
924 
925  //Eta dependency
926  constexpr double p4 = 1.02496e+00;
927  constexpr double p5 = -4.40176e-03;
928 
929  //so that <feta()> = 1
930  constexpr double norm = (p4 + p5 * (2.6 + 1.656) / 2);
931 
932  double result = eEcal * (p0 + p1 * TMath::Exp(-std::abs(eEcal - p3) / p2)) * (p4 + p5 * eta) / norm;
933 
934  return result;
935 }
936 
937 // returns the corrected energy in the area between the end of the PS and the end of the endcap (2.6,2.98)
938 double PFEnergyCalibration::EcorrZoneAfterPS(double E, double eta) const {
939  //Energy dependency
940  constexpr double p0 = 1;
941  constexpr double p1 = 0.058;
942  constexpr double p2 = 12.5;
943  constexpr double p3 = -1.05444e+00;
944  constexpr double p4 = -5.39557e+00;
945  constexpr double p5 = 8.38444e+00;
946  constexpr double p6 = 6.10998e-01;
947 
948  //Eta dependency
949  constexpr double p7 = 1.06161e+00;
950  constexpr double p8 = 0.41;
951  constexpr double p9 = 2.918;
952  constexpr double p10 = 0.0181;
953  constexpr double p11 = 2.05;
954  constexpr double p12 = 2.99;
955  constexpr double p13 = 0.0287;
956 
957  //so that <feta()> = 1
958  constexpr double norm = 1.045;
959 
960  double result = E * (p0 + p1 * TMath::Exp(-(E - p3) / p2) + 1 / (p4 + p5 * TMath::Power(E, p6))) *
961  (p7 + p8 * TMath::Gaus(eta, p9, p10) + p11 * TMath::Gaus(eta, p12, p13)) / norm;
962  return result;
963 }
964 
965 // returns the corrected energy everywhere
966 // this work should be improved between 1.479 and 1.52 (junction barrel-endcap)
968  double eEcal, double ePS1, double ePS2, double eta, double phi, bool crackCorrection) const {
969  constexpr double endBarrel = 1.48;
970  constexpr double beginingPS = 1.65;
971  constexpr double endPS = 2.6;
972  constexpr double endEndCap = 2.98;
973 
974  double result = 0;
975 
976  eta = std::abs(eta);
977 
978  if (eEcal > 0) {
979  if (eta <= endBarrel)
980  result = EcorrBarrel(eEcal, eta, phi, crackCorrection);
981  else if (eta <= beginingPS)
982  result = EcorrZoneBeforePS(eEcal, eta);
983  else if ((eta < endPS) && ePS1 == 0 && ePS2 == 0)
984  result = EcorrPS_ePSNil(eEcal, eta);
985  else if (eta < endPS)
986  result = EcorrPS(eEcal, ePS1, ePS2, eta);
987  else if (eta < endEndCap)
988  result = EcorrZoneAfterPS(eEcal, eta);
989  else
990  result = eEcal;
991  } else
992  result = eEcal; // useful if eEcal=0 or eta>2.98
993  //protection
994  if (result < eEcal)
995  result = eEcal;
996  return result;
997 }
998 
999 // returns the corrected energy everywhere
1000 // this work should be improved between 1.479 and 1.52 (junction barrel-endcap)
1001 double PFEnergyCalibration::Ecorr(double eEcal,
1002  double ePS1,
1003  double ePS2,
1004  double eta,
1005  double phi,
1006  double& ps1,
1007  double& ps2,
1008  bool crackCorrection) const {
1009  constexpr double endBarrel = 1.48;
1010  constexpr double beginingPS = 1.65;
1011  constexpr double endPS = 2.6;
1012  constexpr double endEndCap = 2.98;
1013 
1014  double result = 0;
1015 
1016  eta = std::abs(eta);
1017 
1018  if (eEcal > 0) {
1019  if (eta <= endBarrel)
1020  result = EcorrBarrel(eEcal, eta, phi, crackCorrection);
1021  else if (eta <= beginingPS)
1022  result = EcorrZoneBeforePS(eEcal, eta);
1023  else if ((eta < endPS) && ePS1 == 0 && ePS2 == 0)
1024  result = EcorrPS_ePSNil(eEcal, eta);
1025  else if (eta < endPS)
1026  result = EcorrPS(eEcal, ePS1, ePS2, eta, ps1, ps2);
1027  else if (eta < endEndCap)
1028  result = EcorrZoneAfterPS(eEcal, eta);
1029  else
1030  result = eEcal;
1031  } else
1032  result = eEcal; // useful if eEcal=0 or eta>2.98
1033  // protection
1034  if (result < eEcal)
1035  result = eEcal;
1036  return result;
1037 }
double dEtaEndcapH(double x) const
double Beta(double E, double eta) const
double EcorrZoneBeforePS(double E, double eta) const
double Gamma(double etaEcal) const
double cEtaBarrelEH(double x) const
double aEtaBarrelH(double x) const
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
double bEtaBarrelH(double x) const
double cEtaEndcapH(double x) const
double bEtaEndcapH(double x) const
double cEtaEndcapEH(double x) const
CalibratedEndcapPFClusterEnergies calibrateEndcapClusterEnergies(reco::PFCluster const &eeCluster, std::vector< reco::PFCluster const *> const &psClusterPointers, ESChannelStatus const &channelStatus, bool applyCrackCorrections) const
const_iterator find(uint32_t rawId) const
double phi() const
azimuthal angle of cluster centroid
Definition: CaloCluster.h:183
const Double_t pi
Definition: TTTypes.h:54
double cBarrel(double x) const
double EcorrPS(double eEcal, double ePS1, double ePS2, double etaEcal) const
double cEndcap(double x) const
double EcorrZoneAfterPS(double E, double eta) const
double energy() const
cluster energy
Definition: PFCluster.h:74
double cEtaBarrelH(double x) const
double EcorrBarrel(double E, double eta, double phi, bool crackCorrection=true) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double aEtaBarrelEH(double x) const
double dCrackPhi(double phi, double eta) const
double bEtaEndcapEH(double x) const
double Ecorr(double eEcal, double ePS1, double ePS2, double eta, double phi, bool crackCorrection=true) const
void energyEmHad(double t, double &e, double &h, double eta, double phi) const
double aEndcap(double x) const
std::ostream & operator<<(std::ostream &out, const std::tuple< Types... > &value)
Definition: Utilities.h:32
double CorrPhi(double phi, double eta) const
#define M_PI
std::pair< int, edm::FunctionWithDict > OK
Definition: findMethod.cc:126
double aEtaEndcapEH(double x) const
double minimum(double a, double b) const
double bEndcap(double x) const
double bBarrel(double x) const
double Alpha(double eta) const
double b
Definition: hdecay.h:120
double CorrEta(double eta) const
double aBarrel(double x) const
double EcorrPS_ePSNil(double eEcal, double eta) const
Definition: plugin.cc:23
double aEtaEndcapH(double x) const
double a
Definition: hdecay.h:121
float x
double CorrBarrel(double E, double eta) const
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:180
TupleMultiplicity< TrackerTraits > const *__restrict__ TrackingRecHitSoAConstView< TrackerTraits > hh
const self & getMap() const
double dEtaEndcapEH(double x) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
static std::map< PerformanceResult::ResultType, std::string > functType
double energyEm(const reco::PFCluster &clusterEcal, double ePS1, double ePS2, bool crackCorrection=true) const
double bEtaBarrelEH(double x) const
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5