00001 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00002 #include "CondFormats/PhysicsToolsObjects/interface/PerformancePayloadFromTFormula.h"
00003 #include <TMath.h>
00004 #include <math.h>
00005 #include <vector>
00006 #include <TF1.h>
00007 #include <map>
00008 #include <algorithm>
00009
00010 using namespace std;
00011
00012 PFEnergyCalibration::PFEnergyCalibration() : pfCalibrations(0)
00013 {
00014 initializeCalibrationFunctions();
00015 }
00016
00017 PFEnergyCalibration::~PFEnergyCalibration()
00018 {
00019
00020 delete faBarrel;
00021 delete fbBarrel;
00022 delete fcBarrel;
00023 delete faEtaBarrel;
00024 delete fbEtaBarrel;
00025 delete faEndcap;
00026 delete fbEndcap;
00027 delete fcEndcap;
00028 delete faEtaEndcap;
00029 delete fbEtaEndcap;
00030
00031 }
00032
00033 void
00034 PFEnergyCalibration::initializeCalibrationFunctions() {
00035
00036
00037
00038 threshE = 3.5;
00039 threshH = 2.5;
00040
00041
00042 faBarrel = new TF1("faBarrel","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00043 fbBarrel = new TF1("fbBarrel","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00044 fcBarrel = new TF1("fcBarrel","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00045 faEtaBarrel = new TF1("faEtaBarrel","[0]+[1]*exp(-x/[2])",1.,1000.);
00046 fbEtaBarrel = new TF1("fbEtaBarrel","[0]+[1]*exp(-x/[2])+[3]*[3]*exp(-x*x/([4]*[4]))",1.,1000.);
00047 faBarrel->SetParameter(0,1.15665);
00048 fbBarrel->SetParameter(0,0.994603);
00049 fcBarrel->SetParameter(0,0.956544);
00050 faEtaBarrel->SetParameter(0,0.014664);
00051 fbEtaBarrel->SetParameter(0,0.00975451);
00052 faBarrel->SetParameter(1,0.165627);
00053 fbBarrel->SetParameter(1,0.13632);
00054 fcBarrel->SetParameter(1,0.0857207);
00055 faEtaBarrel->SetParameter(1,-0.0426776);
00056 fbEtaBarrel->SetParameter(1,0.102247);
00057 faBarrel->SetParameter(2,0.827718);
00058 fbBarrel->SetParameter(2,-0.758013);
00059 fcBarrel->SetParameter(2,-0.44347);
00060 faEtaBarrel->SetParameter(2,431.054);
00061 fbEtaBarrel->SetParameter(2,436.21);
00062 faBarrel->SetParameter(3,231.339);
00063 fbBarrel->SetParameter(3,183.627);
00064 fcBarrel->SetParameter(3,63.3479);
00065 faBarrel->SetParameter(4,2.45332);
00066 fbBarrel->SetParameter(4,1);
00067 fcBarrel->SetParameter(4,1.24174);
00068 faBarrel->SetParameter(5,29.6603);
00069 fbBarrel->SetParameter(5,39.6784);
00070 fcBarrel->SetParameter(5,12.322);
00071
00072
00073 faEndcap = new TF1("faEndcap","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00074 fbEndcap = new TF1("fbEndcap","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00075 fcEndcap = new TF1("fcEndcap","[0]+([1]+[2]/sqrt(x))*exp(-x/[3])-[4]*exp(-x*x/[5])",1.,1000.);
00076 faEtaEndcap = new TF1("faEtaEndcap","[0]+[1]*exp(-x/[2])",1.,1000.);
00077 fbEtaEndcap = new TF1("fbEtaEndcap","[0]+[1]*exp(-x/[2])+[3]*[3]*exp(-x*x/([4]*[4]))",1.,1000.);
00078 faEndcap->SetParameter(0,1.1272);
00079 fbEndcap->SetParameter(0,0.982824);
00080 fcEndcap->SetParameter(0,0.950244);
00081 faEtaEndcap->SetParameter(0,-0.000582903);
00082 fbEtaEndcap->SetParameter(0,0.0267319);
00083 faEndcap->SetParameter(1,0.258536);
00084 fbEndcap->SetParameter(1,0.0977533);
00085 fcEndcap->SetParameter(1,0.00564779);
00086 faEtaEndcap->SetParameter(1,-0.000482148);
00087 fbEtaEndcap->SetParameter(1,-0.554552);
00088 faEndcap->SetParameter(2,0.808071);
00089 fbEndcap->SetParameter(2,0.155416);
00090 fcEndcap->SetParameter(2,0.227162);
00091 faEtaEndcap->SetParameter(2,209.466);
00092 fbEtaEndcap->SetParameter(2,1.71188);
00093 faEndcap->SetParameter(3,214.039);
00094 fbEndcap->SetParameter(3,240.379);
00095 fcEndcap->SetParameter(3,207.786);
00096 fbEtaEndcap->SetParameter(3,0.235834);
00097 faEndcap->SetParameter(4,2);
00098 fbEndcap->SetParameter(4,1.2);
00099 fcEndcap->SetParameter(4,1.32824);
00100 fbEtaEndcap->SetParameter(4,-135.431);
00101 faEndcap->SetParameter(5,47.2602);
00102 fbEndcap->SetParameter(5,78.3083);
00103 fcEndcap->SetParameter(5,22.1825);
00104
00105 }
00106
00107 void
00108 PFEnergyCalibration::energyEmHad(double t, double& e, double&h, double eta, double phi) const {
00109
00110
00111
00112 double tt = t;
00113 double ee = e;
00114 double hh = h;
00115 double a = 1.;
00116 double b = 1.;
00117 double etaCorrE = 1.;
00118 double etaCorrH = 1.;
00119 t = min(999.9,max(tt,e+h));
00120 if ( t < 1. ) return;
00121
00122
00123 if ( fabs(eta) < 1.48 ) {
00124
00125
00126 a = e>0. ? aBarrel(t) : 1.;
00127 b = e>0. ? bBarrel(t) : cBarrel(t);
00128 double thresh = e > 0. ? threshE : threshH;
00129
00130
00131 if ( a < -0.25 || b < -0.25 ) {
00132 a = 1.;
00133 b = 1.;
00134 thresh = 0.;
00135 }
00136
00137
00138 t = min(999.9,max(tt, thresh+a*e+b*h));
00139
00140
00141 etaCorrE = 1. + aEtaBarrel(t) + bEtaBarrel(t)*fabs(eta)*fabs(eta);
00142 etaCorrH = 1.;
00143
00144 t = max(tt, thresh+etaCorrE*a*e+etaCorrH*b*h);
00145
00146 if ( e > 0. && thresh > 0. )
00147 e = h > 0. ? threshE-threshH + etaCorrE * a * e : threshE + etaCorrE * a * e;
00148 if ( h > 0. && thresh > 0. )
00149 h = threshH + etaCorrH * b * h;
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 } else {
00167
00168
00169 a = e>0. ? aEndcap(t) : 1.;
00170 b = e>0. ? bEndcap(t) : cEndcap(t);
00171 double thresh = e > 0. ? threshE : threshH;
00172
00173 if ( a < -0.25 || b < -0.25 ) {
00174 a = 1.;
00175 b = 1.;
00176 thresh = 0.;
00177 }
00178
00179
00180 t = min(999.9,max(tt, thresh+a*e+b*h));
00181
00182
00183 double dEta = fabs ( fabs(eta) - 1.5 );
00184 double etaPow = dEta * dEta * dEta * dEta;
00185
00186 etaCorrE = 1. + aEtaEndcap(t) + bEtaEndcap(t)*etaPow;
00187 etaCorrH = 1. + aEtaEndcap(t) + bEtaEndcap(t)*etaPow;
00188
00189
00190
00191
00192
00193
00194
00195
00196 t = min(999.9,max(tt, thresh + etaCorrE*a*e + etaCorrH*b*h));
00197
00198 if ( e > 0. && thresh > 0. )
00199 e = h > 0. ? threshE-threshH + etaCorrE * a * e : threshE + etaCorrE * a * e;
00200 if ( h > 0. && thresh > 0. )
00201 h = threshH + b * etaCorrH * h;
00202
00203
00204 }
00205
00206
00207 if ( e < 0. || h < 0. ) {
00208
00209
00210
00211
00212
00213
00214 if ( e < 0. ) e = ee;
00215 if ( h < 0. ) h = hh;
00216 }
00217
00218
00219
00220
00221 }
00222
00223
00224 double
00225 PFEnergyCalibration::aBarrel(double x) const {
00226
00227 if ( pfCalibrations ) {
00228
00229 BinningPointByMap point;
00230 point.insert(BinningVariables::JetEt, x);
00231 return pfCalibrations->getResult(PerformanceResult::PFfa_BARREL,point);
00232
00233 } else {
00234
00235 return faBarrel->Eval(x);
00236
00237 }
00238 }
00239
00240 double
00241 PFEnergyCalibration::bBarrel(double x) const {
00242
00243 if ( pfCalibrations ) {
00244
00245 BinningPointByMap point;
00246 point.insert(BinningVariables::JetEt, x);
00247 return pfCalibrations->getResult(PerformanceResult::PFfb_BARREL,point);
00248
00249 } else {
00250
00251 return fbBarrel->Eval(x);
00252
00253 }
00254 }
00255
00256 double
00257 PFEnergyCalibration::cBarrel(double x) const {
00258
00259 if ( pfCalibrations ) {
00260
00261 BinningPointByMap point;
00262 point.insert(BinningVariables::JetEt, x);
00263 return pfCalibrations->getResult(PerformanceResult::PFfc_BARREL,point);
00264
00265 } else {
00266
00267 return fcBarrel->Eval(x);
00268
00269 }
00270 }
00271
00272 double
00273 PFEnergyCalibration::aEtaBarrel(double x) const {
00274
00275 if ( pfCalibrations ) {
00276
00277 BinningPointByMap point;
00278 point.insert(BinningVariables::JetEt, x);
00279 return pfCalibrations->getResult(PerformanceResult::PFfaEta_BARREL,point);
00280
00281 } else {
00282
00283 return faEtaBarrel->Eval(x);
00284
00285 }
00286 }
00287
00288 double
00289 PFEnergyCalibration::bEtaBarrel(double x) const {
00290
00291 if ( pfCalibrations ) {
00292
00293 BinningPointByMap point;
00294 point.insert(BinningVariables::JetEt, x);
00295 return pfCalibrations->getResult(PerformanceResult::PFfbEta_BARREL,point);
00296
00297 } else {
00298
00299 return fbEtaBarrel->Eval(x);
00300
00301 }
00302 }
00303
00304 double
00305 PFEnergyCalibration::aEndcap(double x) const {
00306
00307 if ( pfCalibrations ) {
00308
00309 BinningPointByMap point;
00310 point.insert(BinningVariables::JetEt, x);
00311 return pfCalibrations->getResult(PerformanceResult::PFfa_ENDCAP,point);
00312
00313 } else {
00314
00315 return faEndcap->Eval(x);
00316
00317 }
00318 }
00319
00320 double
00321 PFEnergyCalibration::bEndcap(double x) const {
00322
00323 if ( pfCalibrations ) {
00324
00325 BinningPointByMap point;
00326 point.insert(BinningVariables::JetEt, x);
00327 return pfCalibrations->getResult(PerformanceResult::PFfb_ENDCAP,point);
00328
00329 } else {
00330
00331 return fbEndcap->Eval(x);
00332
00333 }
00334 }
00335
00336 double
00337 PFEnergyCalibration::cEndcap(double x) const {
00338
00339 if ( pfCalibrations ) {
00340
00341 BinningPointByMap point;
00342 point.insert(BinningVariables::JetEt, x);
00343 return pfCalibrations->getResult(PerformanceResult::PFfc_ENDCAP,point);
00344
00345 } else {
00346
00347 return fcEndcap->Eval(x);
00348
00349 }
00350 }
00351
00352 double
00353 PFEnergyCalibration::aEtaEndcap(double x) const {
00354
00355 if ( pfCalibrations ) {
00356
00357 BinningPointByMap point;
00358 point.insert(BinningVariables::JetEt, x);
00359 return pfCalibrations->getResult(PerformanceResult::PFfaEta_ENDCAP,point);
00360
00361 } else {
00362
00363 return faEtaEndcap->Eval(x);
00364
00365 }
00366 }
00367
00368 double
00369 PFEnergyCalibration::bEtaEndcap(double x) const {
00370
00371 if ( pfCalibrations ) {
00372
00373 BinningPointByMap point;
00374 point.insert(BinningVariables::JetEt, x);
00375 return pfCalibrations->getResult(PerformanceResult::PFfbEta_ENDCAP,point);
00376
00377 } else {
00378
00379 return fbEtaEndcap->Eval(x);
00380
00381 }
00382 }
00383
00384
00385 double
00386 PFEnergyCalibration::energyEm(const reco::PFCluster& clusterEcal,
00387 std::vector<double> &EclustersPS1,
00388 std::vector<double> &EclustersPS2,
00389 bool crackCorrection ){
00390 double ePS1(std::accumulate(EclustersPS1.begin(), EclustersPS1.end(), 0.0));
00391 double ePS2(std::accumulate(EclustersPS2.begin(), EclustersPS2.end(), 0.0));
00392 return energyEm(clusterEcal, ePS1, ePS2, crackCorrection);
00393 }
00394
00395 double
00396 PFEnergyCalibration::energyEm(const reco::PFCluster& clusterEcal,
00397 double ePS1,
00398 double ePS2,
00399 bool crackCorrection ){
00400 double eEcal = clusterEcal.energy();
00401
00402 reco::PFCluster myPFCluster=clusterEcal;
00403 myPFCluster.calculatePositionREP();
00404 double eta = myPFCluster.positionREP().eta();
00405 double phi = myPFCluster.positionREP().phi();
00406
00407 double calibrated = Ecorr(eEcal,ePS1,ePS2,eta,phi, crackCorrection);
00408 if(eEcal!=0 && calibrated==0) std::cout<<"Eecal = "<<eEcal<<" eta = "<<eta<<" phi = "<<phi<<std::endl;
00409 return calibrated;
00410 }
00411
00412 double PFEnergyCalibration::energyEm(const reco::PFCluster& clusterEcal,
00413 std::vector<double> &EclustersPS1,
00414 std::vector<double> &EclustersPS2,
00415 double& ps1,double& ps2,
00416 bool crackCorrection){
00417 double ePS1(std::accumulate(EclustersPS1.begin(), EclustersPS1.end(), 0.0));
00418 double ePS2(std::accumulate(EclustersPS2.begin(), EclustersPS2.end(), 0.0));
00419 return energyEm(clusterEcal, ePS1, ePS2, ps1, ps2, crackCorrection);
00420 }
00421 double PFEnergyCalibration::energyEm(const reco::PFCluster& clusterEcal,
00422 double ePS1, double ePS2,
00423 double& ps1,double& ps2,
00424 bool crackCorrection){
00425 double eEcal = clusterEcal.energy();
00426
00427 reco::PFCluster myPFCluster=clusterEcal;
00428 myPFCluster.calculatePositionREP();
00429 double eta = myPFCluster.positionREP().eta();
00430 double phi = myPFCluster.positionREP().phi();
00431
00432 double calibrated = Ecorr(eEcal,ePS1,ePS2,eta,phi,ps1,ps2,crackCorrection);
00433 if(eEcal!=0 && calibrated==0) std::cout<<"Eecal = "<<eEcal<<" eta = "<<eta<<" phi = "<<phi<<std::endl;
00434 return calibrated;
00435 }
00436
00437
00438 std::ostream& operator<<(std::ostream& out,
00439 const PFEnergyCalibration& calib) {
00440
00441 if(!out ) return out;
00442
00443 out<<"PFEnergyCalibration -- "<<endl;
00444
00445 if ( calib.pfCalibrations ) {
00446
00447 std::cout << "Functions taken from the global tags : " << std::endl;
00448
00449 static std::map<std::string, PerformanceResult::ResultType> functType;
00450
00451 functType["PFfa_BARREL"] = PerformanceResult::PFfa_BARREL;
00452 functType["PFfa_ENDCAP"] = PerformanceResult::PFfa_ENDCAP;
00453 functType["PFfb_BARREL"] = PerformanceResult::PFfb_BARREL;
00454 functType["PFfb_ENDCAP"] = PerformanceResult::PFfb_ENDCAP;
00455 functType["PFfc_BARREL"] = PerformanceResult::PFfc_BARREL;
00456 functType["PFfc_ENDCAP"] = PerformanceResult::PFfc_ENDCAP;
00457 functType["PFfaEta_BARREL"] = PerformanceResult::PFfaEta_BARREL;
00458 functType["PFfaEta_ENDCAP"] = PerformanceResult::PFfaEta_ENDCAP;
00459 functType["PFfbEta_BARREL"] = PerformanceResult::PFfbEta_BARREL;
00460 functType["PFfbEta_ENDCAP"] = PerformanceResult::PFfbEta_ENDCAP;
00461
00462 for(std::map<std::string,PerformanceResult::ResultType>::const_iterator
00463 func = functType.begin();
00464 func != functType.end();
00465 ++func) {
00466
00467 cout << "Function: " << func->first << endl;
00468 PerformanceResult::ResultType fType = func->second;
00469 calib.pfCalibrations->printFormula(fType);
00470 }
00471
00472 } else {
00473
00474 std::cout << "Default calibration functions : " << std::endl;
00475
00476 calib.faBarrel->Print();
00477 calib.fbBarrel->Print();
00478 calib.fcBarrel->Print();
00479 calib.faEtaBarrel->Print();
00480 calib.fbEtaBarrel->Print();
00481 calib.faEndcap->Print();
00482 calib.fbEndcap->Print();
00483 calib.fcEndcap->Print();
00484 calib.faEtaEndcap->Print();
00485 calib.fbEtaEndcap->Print();
00486 }
00487
00488 return out;
00489 }
00490
00491
00492
00493
00506
00507
00508
00514
00515
00516
00517 double
00518 PFEnergyCalibration::minimum(double a,double b){
00519 if(TMath::Abs(b)<TMath::Abs(a)) a=b;
00520 return a;
00521 }
00522
00523
00524
00525 double
00526 PFEnergyCalibration::dCrackPhi(double phi, double eta){
00527
00528 constexpr double pi= M_PI;
00529
00530
00531 static std::vector<double> cPhi;
00532 if(cPhi.size()==0)
00533 {
00534 cPhi.resize(18,0);
00535 cPhi[0]=2.97025;
00536 for(unsigned i=1;i<=17;++i) cPhi[i]=cPhi[0]-2*i*pi/18;
00537 }
00538
00539
00540 constexpr double delta_cPhi=0.00638;
00541
00542 double m;
00543
00544
00545 if(eta<0) phi +=delta_cPhi;
00546
00547 if (phi>=-pi && phi<=pi){
00548
00549
00550 if (phi<cPhi[17] || phi>=cPhi[0]){
00551 if (phi<0) phi+= 2*pi;
00552 m = minimum(phi -cPhi[0],phi-cPhi[17]-2*pi);
00553 }
00554
00555
00556 else{
00557 bool OK = false;
00558 unsigned i=16;
00559 while(!OK){
00560 if (phi<cPhi[i]){
00561 m=minimum(phi-cPhi[i+1],phi-cPhi[i]);
00562 OK=true;
00563 }
00564 else i-=1;
00565 }
00566 }
00567 }
00568 else{
00569 m=0.;
00570 std::cout<<"Problem in dminphi"<<std::endl;
00571 }
00572 if(eta<0) m=-m;
00573 return m;
00574 }
00575
00576
00577 double
00578 PFEnergyCalibration::CorrPhi(double phi, double eta) {
00579
00580
00581 constexpr double p1= 5.59379e-01;
00582 constexpr double p2= -1.26607e-03;
00583 constexpr double p3= 9.61133e-04;
00584
00585 constexpr double p4= 1.81691e-01;
00586 constexpr double p5= -4.97535e-03;
00587 constexpr double p6= 1.31006e-03;
00588
00589 constexpr double p7= 1.38498e-01;
00590 constexpr double p8= 1.18599e-04;
00591 constexpr double p9= 2.01858e-03;
00592
00593
00594 double dminphi = dCrackPhi(phi,eta);
00595
00596 double result = (1+p1*TMath::Gaus(dminphi,p2,p3)+p4*TMath::Gaus(dminphi,p5,p6)+p7*TMath::Gaus(dminphi,p8,p9));
00597
00598 return result;
00599 }
00600
00601
00602
00603 double
00604 PFEnergyCalibration::CorrEta(double eta){
00605
00606
00607 constexpr double a[] = {6.13349e-01, 5.08146e-01, 4.44480e-01, 3.3487e-01, 7.65627e-01};
00608 constexpr double m[] = {-1.79514e-02, 4.44747e-01, 7.92824e-01, 1.14090e+00, 1.47464e+00};
00609 constexpr double s[] = {7.92382e-03, 3.06028e-03, 3.36139e-03, 3.94521e-03, 8.63950e-04};
00610 constexpr double sa[] = {1.27228e+01, 3.81517e-02, 1.63507e-01, -6.56480e-02, 1.87160e-01};
00611 constexpr double ss[] = {5.48753e-02, -1.00223e-02, 2.22866e-03, 4.26288e-04, 2.67937e-03};
00612 double result = 1;
00613
00614 for(unsigned i=0;i<=4;i++) result+=a[i]*TMath::Gaus(eta,m[i],s[i])*(1+sa[i]*TMath::Sign(1.,eta-m[i])*TMath::Exp(-TMath::Abs(eta-m[i])/ss[i]));
00615
00616 return result;
00617 }
00618
00619
00620
00621 double
00622 PFEnergyCalibration::CorrBarrel(double E, double eta) {
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 constexpr double p0 = 0.9944;
00637 constexpr double p1 = 9.827;
00638 constexpr double p2 = 1.503;
00639 constexpr double p3 = 1.196;
00640 constexpr double p4 = 0.3349;
00641 constexpr double p5 = 0.89;
00642 constexpr double p6 = 0.004361;
00643 constexpr double p7 = 51.51;
00644
00645 constexpr double p8=2.705593e-03;
00646
00647 double result = (p0+1/(p1+p2*TMath::Power(E,p3))+p4*TMath::Exp(-E/p5)+p6*TMath::Exp(-E*E/(p7*p7)))*(1+p8*eta*eta);
00648
00649 return result;
00650 }
00651
00652
00653
00662
00663
00664
00665
00666
00667 double
00668 PFEnergyCalibration::Alpha(double eta) {
00669
00670
00671 constexpr double p0 = 5.97621e-01;
00672
00673
00674 constexpr double p1 =-1.86407e-01;
00675 constexpr double p2 = 3.85197e-01;
00676
00677
00678 constexpr double norm = (p1+p2*(2.6+1.656)/2);
00679
00680 double result = p0*(p1+p2*eta)/norm;
00681
00682 return result;
00683 }
00684
00685 double
00686 PFEnergyCalibration::Beta(double E, double eta) {
00687
00688
00689 constexpr double p0 = 0.032;
00690 constexpr double p1 = 9.70394e-02;
00691 constexpr double p2 = 2.23072e+01;
00692 constexpr double p3 = 100;
00693
00694
00695 constexpr double p4 = 1.02496e+00 ;
00696 constexpr double p5 = -4.40176e-03 ;
00697
00698
00699 constexpr double norm = (p4+p5*(2.6+1.656)/2);
00700
00701 double result = (1.0012+p0*TMath::Exp(-E/p3)+p1*TMath::Exp(-E/p2))*(p4+p5*eta)/norm;
00702 return result;
00703 }
00704
00705
00706 double
00707 PFEnergyCalibration::Gamma(double etaEcal) {
00708
00709
00710 constexpr double p0 = 2.49752e-02;
00711
00712
00713 constexpr double p1 = 6.48816e-02;
00714 constexpr double p2 = -1.59517e-02;
00715
00716
00717 constexpr double norm = (p1+p2*(2.6+1.656)/2);
00718
00719 double result = p0*(p1+p2*etaEcal)/norm;
00720
00721 return result;
00722 }
00723
00724
00725
00731
00732
00733
00734
00735 double
00736 PFEnergyCalibration::EcorrBarrel(double E, double eta, double phi,
00737 bool crackCorrection ){
00738
00739
00740 double correction = crackCorrection ? std::max(CorrEta(eta),CorrPhi(phi,eta)) : 1.;
00741 double result = E * CorrBarrel(E,eta) * correction;
00742
00743 return result;
00744 }
00745
00746
00747
00748 double
00749 PFEnergyCalibration::EcorrZoneBeforePS(double E, double eta){
00750
00751
00752 constexpr double p0 =1;
00753 constexpr double p1 =0.18;
00754 constexpr double p2 =8.;
00755
00756
00757 constexpr double p3 =0.3;
00758 constexpr double p4 =1.11;
00759 constexpr double p5 =0.025;
00760 constexpr double p6 =1.49;
00761 constexpr double p7 =0.6;
00762
00763
00764 constexpr double norm = 1.21;
00765
00766 double result = E*(p0+p1*TMath::Exp(-E/p2))*(p3+p4*TMath::Gaus(eta,p6,p5)+p7*eta)/norm;
00767
00768 return result;
00769 }
00770
00771
00772
00773
00774 double
00775 PFEnergyCalibration::EcorrPS(double eEcal,double ePS1,double ePS2,double etaEcal) {
00776
00777
00778 double E = Beta(1.0155*eEcal+0.025*(ePS1+0.5976*ePS2)/9e-5,etaEcal)*eEcal+Gamma(etaEcal)*(ePS1+Alpha(etaEcal)*ePS2)/9e-5 ;
00779
00780
00781 constexpr double p0 = 1.00;
00782 constexpr double p1 = 2.18;
00783 constexpr double p2 =1.94;
00784 constexpr double p3 =4.13;
00785 constexpr double p4 =1.127;
00786
00787 double result = E*(p0+p1*TMath::Exp(-E/p2)-p3*TMath::Exp(-E/p4));
00788
00789 return result;
00790 }
00791
00792
00793
00794 double
00795 PFEnergyCalibration::EcorrPS(double eEcal,double ePS1,double ePS2,double etaEcal,double & outputPS1, double & outputPS2) {
00796
00797
00798 double gammaprime=Gamma(etaEcal)/9e-5;
00799 outputPS1=gammaprime*ePS1;
00800 outputPS2=gammaprime*Alpha(etaEcal)*ePS2;
00801 double E = Beta(1.0155*eEcal+0.025*(ePS1+0.5976*ePS2)/9e-5,etaEcal)*eEcal+outputPS1+outputPS2;
00802
00803
00804 constexpr double p0 = 1.00;
00805 constexpr double p1 = 2.18;
00806 constexpr double p2 =1.94;
00807 constexpr double p3 =4.13;
00808 constexpr double p4 =1.127;
00809
00810 double corrfac=(p0+p1*TMath::Exp(-E/p2)-p3*TMath::Exp(-E/p4));
00811 outputPS1*=corrfac;
00812 outputPS2*=corrfac;
00813 double result = E*corrfac;
00814
00815 return result;
00816 }
00817
00818
00819
00820
00821 double
00822 PFEnergyCalibration::EcorrPS_ePSNil(double eEcal,double eta){
00823
00824
00825 constexpr double p0= 1.02;
00826 constexpr double p1= 0.165;
00827 constexpr double p2= 6.5 ;
00828 constexpr double p3= 2.1 ;
00829
00830
00831 constexpr double p4 = 1.02496e+00 ;
00832 constexpr double p5 = -4.40176e-03 ;
00833
00834
00835 constexpr double norm = (p4+p5*(2.6+1.656)/2);
00836
00837 double result = eEcal*(p0+p1*TMath::Exp(-TMath::Abs(eEcal-p3)/p2))*(p4+p5*eta)/norm;
00838
00839 return result;
00840 }
00841
00842
00843
00844 double
00845 PFEnergyCalibration::EcorrZoneAfterPS(double E, double eta){
00846
00847
00848 constexpr double p0 =1;
00849 constexpr double p1 = 0.058;
00850 constexpr double p2 =12.5;
00851 constexpr double p3 =-1.05444e+00;
00852 constexpr double p4 =-5.39557e+00;
00853 constexpr double p5 =8.38444e+00;
00854 constexpr double p6 = 6.10998e-01 ;
00855
00856
00857 constexpr double p7 =1.06161e+00;
00858 constexpr double p8 = 0.41;
00859 constexpr double p9 =2.918;
00860 constexpr double p10 =0.0181;
00861 constexpr double p11= 2.05;
00862 constexpr double p12 =2.99;
00863 constexpr double p13=0.0287;
00864
00865
00866 constexpr double norm=1.045;
00867
00868 double result = E*(p0+p1*TMath::Exp(-(E-p3)/p2)+1/(p4+p5*TMath::Power(E,p6)))*(p7+p8*TMath::Gaus(eta,p9,p10)+p11*TMath::Gaus(eta,p12,p13))/norm;
00869 return result;
00870 }
00871
00872
00873
00874
00875
00876
00877 double
00878 PFEnergyCalibration::Ecorr(double eEcal,double ePS1,double ePS2,
00879 double eta,double phi,
00880 bool crackCorrection ) {
00881
00882 constexpr double endBarrel=1.48;
00883 constexpr double beginingPS=1.65;
00884 constexpr double endPS=2.6;
00885 constexpr double endEndCap=2.98;
00886
00887 double result=0;
00888
00889 eta=TMath::Abs(eta);
00890
00891 if(eEcal>0){
00892 if(eta <= endBarrel) result = EcorrBarrel(eEcal,eta,phi,crackCorrection);
00893 else if(eta <= beginingPS) result = EcorrZoneBeforePS(eEcal,eta);
00894 else if((eta < endPS) && ePS1==0 && ePS2==0) result = EcorrPS_ePSNil(eEcal,eta);
00895 else if(eta < endPS) result = EcorrPS(eEcal,ePS1,ePS2,eta);
00896 else if(eta < endEndCap) result = EcorrZoneAfterPS(eEcal,eta);
00897 else result =eEcal;
00898 }
00899 else result = eEcal;
00900
00901 if(result<eEcal) result=eEcal;
00902 return result;
00903 }
00904
00905
00906
00907 double
00908 PFEnergyCalibration::Ecorr(double eEcal,double ePS1,double ePS2,double eta,double phi,double& ps1,double&ps2,bool crackCorrection) {
00909
00910 constexpr double endBarrel=1.48;
00911 constexpr double beginingPS=1.65;
00912 constexpr double endPS=2.6;
00913 constexpr double endEndCap=2.98;
00914
00915 double result=0;
00916
00917 eta=TMath::Abs(eta);
00918
00919 if(eEcal>0){
00920 if(eta <= endBarrel) result = EcorrBarrel(eEcal,eta,phi,crackCorrection);
00921 else if(eta <= beginingPS) result = EcorrZoneBeforePS(eEcal,eta);
00922 else if((eta < endPS) && ePS1==0 && ePS2==0) result = EcorrPS_ePSNil(eEcal,eta);
00923 else if(eta < endPS) result = EcorrPS(eEcal,ePS1,ePS2,eta,ps1,ps2);
00924 else if(eta < endEndCap) result = EcorrZoneAfterPS(eEcal,eta);
00925 else result =eEcal;
00926 }
00927 else result = eEcal;
00928
00929 if(result<eEcal) result=eEcal;
00930 return result;
00931 }