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