CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/PatCandidates/src/ResolutionHelper.cc

Go to the documentation of this file.
00001 #include "DataFormats/PatCandidates/interface/ResolutionHelper.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 using namespace std;  // faster sqrt, sqrt, pow(x,2)....
00007 
00008 void
00009 pat::helper::ResolutionHelper::rescaleForKinFitter(pat::CandKinResolution::Parametrization parametrization, 
00010         AlgebraicSymMatrix44 &covariance, 
00011         const math::XYZTLorentzVector &initialP4)
00012 {
00013     double inv;
00014     switch (parametrization) {
00015         case pat::CandKinResolution::Cart:         
00016         case pat::CandKinResolution::Spher:  
00017             // for us parameter[3] = mass, for KinFitter parameter[3] = mass/initialP4.mass();
00018             inv = 1.0/initialP4.mass();
00019             for (int i = 0; i < 4; i++) {
00020                 covariance(3,i) *= inv;
00021             }
00022             covariance(3,3) *= inv; 
00023             break;
00024         case pat::CandKinResolution::ESpher:       
00025              // for us parameter[3] = energy, for KinFitter parameter[3] = energy/initialP4.energy();
00026             inv = 1.0/initialP4.energy();
00027             for (int i = 0; i < 4; i++) {
00028                 covariance(3,i) *= inv;
00029             }
00030             covariance(3,3) *= inv; 
00031             break;
00032        default:
00033             ;// nothing to do
00034     }
00035 }
00036 
00037 double pat::helper::ResolutionHelper::getResolP(pat::CandKinResolution::Parametrization parametrization,
00038         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)
00039 {
00040     switch (parametrization) {
00041         // ==== CARTESIAN ====
00042         case pat::CandKinResolution::Cart:
00043         case pat::CandKinResolution::ECart:
00044         case pat::CandKinResolution::MCCart:
00045             {
00046                 // p2 = px^2 + py^2 + pz^2
00047                 // dp/dp_i = p_i/p ==> it is a unit vector!
00048                 AlgebraicVector3 derivs(p4.X(), p4.Y(), p4.Z());
00049                 derivs.Unit(); 
00050                 return sqrt(ROOT::Math::Similarity(derivs, covariance.Sub<AlgebraicSymMatrix33>(0,0)));
00051             }
00052         // ==== SPHERICAL (P)  ====
00053         case pat::CandKinResolution::Spher:  
00054         case pat::CandKinResolution::ESpher:
00055         case pat::CandKinResolution::MCSpher:      
00056             return sqrt(covariance(0,0));
00057         // ==== SPHERICAL (1/P)  ====
00058         case pat::CandKinResolution::MCPInvSpher:
00059             return sqrt(covariance(0,0)) * (p4.P2());
00060         // ==== HEP CYLINDRICAL (with Pt = Et, P = E) ====
00061         case pat::CandKinResolution::EtThetaPhi: 
00062         case pat::CandKinResolution::EtEtaPhi:     
00063             return  getResolE(parametrization,covariance,p4);
00064         // ==== OTHER ====
00065         case pat::CandKinResolution::Invalid:
00066             throw cms::Exception("Invalid parametrization") << parametrization;
00067         default:
00068             throw cms::Exception("Not Implemented") << "getResolP not yet implemented for parametrization " << parametrization ;
00069     }
00070 }
00071 double pat::helper::ResolutionHelper::getResolPt(pat::CandKinResolution::Parametrization parametrization,
00072         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00073 {
00074      switch (parametrization) {
00075         // ==== CARTESIAN ====
00076         case pat::CandKinResolution::Cart:
00077         case pat::CandKinResolution::ECart:
00078         case pat::CandKinResolution::MCCart:
00079             {
00080                 double pti2 = 1.0/(p4.Perp2());
00081                 return sqrt(   (  covariance(0,0) * p4.Px()*p4.Px() +
00082                                   covariance(1,1) * p4.Py()*p4.Py() +
00083                                 2*covariance(0,1) * p4.Px()*p4.Py()) * pti2 );
00084             }
00085         // ==== SPHERICAL (P, Theta)  ====
00086         case pat::CandKinResolution::Spher:  
00087         case pat::CandKinResolution::ESpher:
00088         case pat::CandKinResolution::MCSpher:      
00089             {
00090                 // pt = p * sin(theta)
00091                 double a = sin(p4.Theta());
00092                 double b = p4.P() * cos(p4.Theta());
00093                 return sqrt(a*a*covariance(0,0)  + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00094             }
00095         // ==== SPHERICAL (1/P)  ====
00096         case pat::CandKinResolution::MCPInvSpher:
00097             {
00098                 // pt = (1/pi) * sin(theta)
00099                 double p = p4.P(); 
00100                 double a = - (p*p) * sin(p4.Theta());
00101                 double b = p * cos(p4.Theta());
00102                 return sqrt(a*a*covariance(0,0)  + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00103             }
00104         // ==== HEP CYLINDRICAL (with Pt = Et) ====
00105         case pat::CandKinResolution::EtThetaPhi: 
00106         case pat::CandKinResolution::EtEtaPhi:
00107             return sqrt(covariance(0,0));
00108         case pat::CandKinResolution::Invalid:
00109             throw cms::Exception("Invalid parametrization") << parametrization;
00110         default:
00111             throw cms::Exception("Not Implemented") << "getResolPt not yet implemented for parametrization " << parametrization ;
00112     }
00113 }
00114 
00115 double pat::helper::ResolutionHelper::getResolPInv(pat::CandKinResolution::Parametrization parametrization,
00116         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00117 {
00118      switch (parametrization) {
00119         // ==== SPHERICAL (P)  ====
00120         case pat::CandKinResolution::Spher:  
00121         case pat::CandKinResolution::ESpher:
00122         case pat::CandKinResolution::MCSpher:      
00123             return 1.0/p4.P2() * sqrt(covariance(0,0));
00124         // ==== SPHERICAL (1/P)  ====
00125         case pat::CandKinResolution::MCPInvSpher:
00126             return sqrt(covariance(0,0));
00127         // ==== OTHER ====
00128         case pat::CandKinResolution::Cart:
00129         case pat::CandKinResolution::ECart:
00130         case pat::CandKinResolution::MCCart:
00131         case pat::CandKinResolution::EtThetaPhi: 
00132         case pat::CandKinResolution::EtEtaPhi:
00133             return 1.0/p4.P2() * getResolP(parametrization, covariance, p4);
00134         case pat::CandKinResolution::Invalid:
00135             throw cms::Exception("Invalid parametrization") << parametrization;
00136         default:
00137             throw cms::Exception("Not Implemented") << "getResolPInv not yet implemented for parametrization " << parametrization ;
00138     }
00139 }
00140 
00141 double pat::helper::ResolutionHelper::getResolPx(pat::CandKinResolution::Parametrization parametrization,
00142         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00143 {
00144      switch (parametrization) {
00145         // ==== CARTESIAN ====
00146         case pat::CandKinResolution::Cart:
00147         case pat::CandKinResolution::ECart:
00148         case pat::CandKinResolution::MCCart:
00149             return sqrt(covariance(0,0));
00150         // ==== SPHERICAL (P)  ====
00151         case pat::CandKinResolution::Spher:  
00152         case pat::CandKinResolution::ESpher:
00153         case pat::CandKinResolution::MCSpher:      
00154         case pat::CandKinResolution::MCPInvSpher:
00155             {
00156                 // Px = P * sin(theta) * cos(phi)
00157                 double p = p4.P();
00158                 AlgebraicVector3 derivs; 
00159                 derivs[0] = sin(p4.Theta()) * cos(p4.Phi()); // now let's hope gcc does common subexpr optimiz.
00160                 if (parametrization == pat::CandKinResolution::MCPInvSpher) {
00161                     derivs[0] *= -(p*p);
00162                 } 
00163                 derivs[1] = p *  cos(p4.Theta()) * cos(p4.Phi()); 
00164                 derivs[2] = p *  sin(p4.Theta()) * -sin(p4.Phi()); 
00165                 return sqrt(ROOT::Math::Similarity(derivs, covariance.Sub<AlgebraicSymMatrix33>(0,0)));
00166             }
00167         // ==== HEP CYLINDRICAL (with Pt = Et) ====
00168         case pat::CandKinResolution::EtThetaPhi: 
00169         case pat::CandKinResolution::EtEtaPhi:
00170             {
00171                 // Px = Pt * cos(phi)
00172                 double a = cos(p4.Phi());
00173                 double b = - p4.Pt() * sin(p4.Phi());
00174                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(2,0) + b*b*covariance(2,2));
00175             }
00176         // ==== OTHERS ====
00177         case pat::CandKinResolution::Invalid:
00178             throw cms::Exception("Invalid parametrization") << parametrization;
00179         default:
00180             throw cms::Exception("Not Implemented") << "getResolPx not yet implemented for parametrization " << parametrization ;
00181     }
00182 }
00183 double pat::helper::ResolutionHelper::getResolPy(pat::CandKinResolution::Parametrization parametrization,
00184         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00185 {
00186      switch (parametrization) {
00187         // ==== CARTESIAN ====
00188         case pat::CandKinResolution::Cart:
00189         case pat::CandKinResolution::ECart:
00190         case pat::CandKinResolution::MCCart:
00191             return sqrt(covariance(1,1));
00192         // ==== SPHERICAL (P)  ====
00193         case pat::CandKinResolution::Spher:  
00194         case pat::CandKinResolution::ESpher:
00195         case pat::CandKinResolution::MCSpher:      
00196         case pat::CandKinResolution::MCPInvSpher:
00197             {
00198                 // Py = P * sin(theta) * sin(phi)
00199                 double p = p4.P();
00200                 AlgebraicVector3 derivs; 
00201                 derivs[0] = sin(p4.Theta()) * sin(p4.Phi()); // now let's hope gcc does common subexpr optimiz.
00202                 if (parametrization == pat::CandKinResolution::MCPInvSpher) {
00203                     derivs[0] *= -(p*p);
00204                 }
00205                 derivs[1] = p *  cos(p4.Theta()) * sin(p4.Phi()); 
00206                 derivs[2] = p *  sin(p4.Theta()) * cos(p4.Phi()); 
00207                 return sqrt(ROOT::Math::Similarity(derivs, covariance.Sub<AlgebraicSymMatrix33>(0,0)));
00208             }
00209         // ==== HEP CYLINDRICAL (with Pt = Et) ====
00210         case pat::CandKinResolution::EtThetaPhi: 
00211         case pat::CandKinResolution::EtEtaPhi:
00212             {
00213                 // Py = Pt * sin(phi)
00214                 double a = sin(p4.Phi());
00215                 double b = p4.Pt() * cos(p4.Phi());
00216                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(2,0) + b*b*covariance(2,2));
00217             }
00218         // ==== OTHERS ====
00219         case pat::CandKinResolution::Invalid:
00220             throw cms::Exception("Invalid parametrization") << parametrization;
00221         default:
00222             throw cms::Exception("Not Implemented") << "getResolPy not yet implemented for parametrization " << parametrization ;
00223     }
00224 }
00225 double pat::helper::ResolutionHelper::getResolPz(pat::CandKinResolution::Parametrization parametrization,
00226         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00227 {
00228      switch (parametrization) {
00229         // ==== CARTESIAN ====
00230         case pat::CandKinResolution::Cart:
00231         case pat::CandKinResolution::ECart:
00232         case pat::CandKinResolution::MCCart:
00233             return sqrt(covariance(2,2));
00234         // ==== SPHERICAL (P)  ====
00235         case pat::CandKinResolution::Spher:  
00236         case pat::CandKinResolution::ESpher:
00237         case pat::CandKinResolution::MCSpher:      
00238             {
00239                 // Pz = P * cos(theta) 
00240                 double a = cos(p4.Theta());
00241                 double b = -p4.P() * sin(p4.Theta());
00242                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(1,0) + b*b*covariance(1,1));
00243             }
00244         case pat::CandKinResolution::MCPInvSpher:
00245             {
00246                 // Pz = P * cos(theta) 
00247                 double p = p4.P(); 
00248                 double a = -p*p*cos(p4.Theta());
00249                 double b = -p * sin(p4.Theta());
00250                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(1,0) + b*b*covariance(1,1));
00251             }
00252         // ==== HEP CYLINDRICAL (with Pt = Et) ====
00253         case pat::CandKinResolution::EtThetaPhi: 
00254             {
00255                 // Pz = Pt * ctg(theta)    d ctg(x) = -1/sin^2(x)    
00256                 double s = sin(p4.Theta()), c = cos(p4.Theta());
00257                 double a = c/s;
00258                 double b = - p4.Pt() / (s*s);
00259                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(1,0) + b*b*covariance(1,1));
00260             }
00261         case pat::CandKinResolution::EtEtaPhi:
00262             {
00263                 // Pz = Pt * sinh(eta)
00264                 double a = sinh(p4.Eta());
00265                 double b = p4.Et() * cosh(p4.Eta());
00266                 return sqrt(a*a*covariance(0,0) + 2*a*b*covariance(1,0) + b*b*covariance(1,1));
00267             }
00268         // ==== OTHERS ====
00269         case pat::CandKinResolution::Invalid:
00270             throw cms::Exception("Invalid parametrization") << parametrization;
00271         default:
00272             throw cms::Exception("Not Implemented") << "getResolPz not yet implemented for parametrization " << parametrization ;
00273     }
00274 }
00275 
00276 double pat::helper::ResolutionHelper::getResolE(pat::CandKinResolution::Parametrization parametrization,
00277         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)
00278 {
00279     switch (parametrization) {
00280         // ======= ENERGY BASED ==========
00281         case pat::CandKinResolution::ECart:    
00282         case pat::CandKinResolution::ESpher:
00283             return sqrt(covariance(3,3));
00284             // ======= ET BASED ==========
00285         case pat::CandKinResolution::EtThetaPhi: 
00286             {
00287                 // E = Et/Sin(theta)
00288                 double a = 1.0/sin(p4.Theta()); // dE/dEt
00289                 double b = - a*a* p4.Et() * cos(p4.Theta()); // dE/dTh
00290                 return sqrt(a*a*covariance(0,0) + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00291             }
00292         case pat::CandKinResolution::EtEtaPhi: 
00293             {
00294                 // E = Et/Sin(Theta(eta))
00295                 double th = p4.Theta();
00296                 double a = 1.0/sin(th); // dE/dEt
00297                 double b =  a* p4.Et() * cos(th);   // dE/dEta: dTh/dEta = - 1.0/sin(theta) = - dE/dEt
00298                 return sqrt(a*a*covariance(0,0) + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00299             }
00300             // ======= MASS BASED ==========
00301         case pat::CandKinResolution::Cart:
00302             {
00303                 AlgebraicVector4 xoE(p4.X(), p4.Y(), p4.Z(), p4.M()); 
00304                 xoE *= 1/p4.E();
00305                 return sqrt(ROOT::Math::Similarity(xoE, covariance));
00306             }
00307         case pat::CandKinResolution::MCCart:
00308             {
00309                 AlgebraicVector4 xoE(p4.X(), p4.Y(), p4.Z(), 0);
00310                 xoE *= 1/p4.E();
00311                 return sqrt(ROOT::Math::Similarity(xoE, covariance));
00312             }
00313         case pat::CandKinResolution::Spher:  
00314             {
00315                 // E = sqrt(P^2 + m^2)
00316                 double einv = 1.0/p4.E();
00317                 double a  = p4.P()*einv; // dE/dP
00318                 double b  = p4.M()*einv; // dE/dm
00319                 return sqrt(a*a*covariance(0,0) + b*b*covariance(3,3) + 2*a*b*covariance(0,3));
00320             }
00321         case pat::CandKinResolution::MCSpher:  
00322             {
00323                 // E = sqrt(P^2 + m^2); |dE/dP| = |P/E| = P/E
00324                 return p4.P()/p4.E() * sqrt(covariance(0,0));
00325             }
00326         case pat::CandKinResolution::MCPInvSpher:   //  
00327             {
00328                 // E = sqrt(P^2 + m^2); |dE/d(1/P)| = P^2 |dE/dP| = P^3/E
00329                 double p = p4.P();
00330                 return p*p*p/p4.E()*sqrt(covariance(0,0));
00331             }
00332             // ======= OTHER ==========
00333         case pat::CandKinResolution::Invalid:
00334             throw cms::Exception("Invalid parametrization") << parametrization;
00335         default:
00336             throw cms::Exception("Not Implemented") << "getResolE not yet implemented for parametrization " << parametrization ;
00337     }
00338 }
00339 
00340 double pat::helper::ResolutionHelper::getResolEt(pat::CandKinResolution::Parametrization parametrization,
00341         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00342 {
00343     switch (parametrization) {
00344         // ======= ENERGY BASED ==========
00345         case pat::CandKinResolution::ECart:    
00346             {
00347                 // Et^2 = E^2 * (Pt^2/P^2)  
00348                 double pt2 = p4.Perp2();
00349                 double pz2 = ROOT::Math::Square(p4.Pz()), p2 = pt2 + pz2;
00350                 double e2OverP4 = ROOT::Math::Square(p4.E()/p2);
00351                 AlgebraicVector4 derivs(p4.Px(), p4.Py(), p4.Pz(), p4.E());
00352                 derivs    *= (1.0/p4.Et());
00353                 derivs[0] *=  pz2 * e2OverP4;
00354                 derivs[1] *=  pz2 * e2OverP4;
00355                 derivs[2] *= -pt2 * e2OverP4;
00356                 derivs[3] *=  pt2/p2;
00357                 return sqrt(ROOT::Math::Similarity(derivs, covariance));
00358             }
00359         case pat::CandKinResolution::ESpher:
00360             {
00361                 // Et = E * Sin(Theta)
00362                 double st = sin(p4.Theta()), ct = cos(p4.Theta());
00363                 return sqrt(  st*st                         * covariance(3,3) +
00364                               ROOT::Math::Square(ct*p4.E()) * covariance(1,1) + 
00365                               2*st*ct*p4.E()                * covariance(1,3)
00366                         );
00367             }
00368             // ======= ET BASED ==========
00369         case pat::CandKinResolution::EtThetaPhi: 
00370         case pat::CandKinResolution::EtEtaPhi: 
00371             return sqrt(covariance(0,0));
00372             // ======= MASS BASED ==========
00373         case pat::CandKinResolution::Cart:
00374         case pat::CandKinResolution::MCCart:
00375             {
00376                 // Et^2 = E^2 Sin^2(th) = (p^2 + m^2) * (pt^2) / p^2
00377                 double pt2 = p4.Perp2();
00378                 double p2  = pt2 + ROOT::Math::Square(p4.Pz());
00379                 double e2  = p2 + p4.M2();
00380                 double s2  = pt2/p2, pi2 = 1.0/p2;
00381                 double et  = sqrt(e2 * s2);
00382                 AlgebraicVector4 derivs(p4.Px(), p4.Py(), p4.Pz(), p4.M());
00383                 derivs *= 1.0/et;
00384                 derivs[0] *= (s2 + e2*pi2*(1.0 - pt2*pi2) );   
00385                 derivs[1] *= (s2 + e2*pi2*(1.0 - pt2*pi2) );   
00386                 derivs[2] *= (s2 - e2*pt2*pi2*pi2);    
00387                 if (parametrization == pat::CandKinResolution::Cart) {
00388                     derivs[3] *= s2;
00389                     return sqrt(ROOT::Math::Similarity(derivs, covariance));
00390                 } else {
00391                     derivs[3] = 0;
00392                     return sqrt(ROOT::Math::Similarity(derivs, covariance)); // test if Sub<33> is faster
00393                 }
00394             }
00395         case pat::CandKinResolution::Spher:  
00396             {
00397                 // Et = E sin(theta); dE/dM = M/E, dE/dP = P/E
00398                 double s = sin(p4.Theta()), c = cos(p4.Theta());
00399                 double e = p4.E(); 
00400                 AlgebraicVector4 derivs( p4.P()/e * s, e * c, 0, p4.M()/e * s);
00401                 return sqrt(ROOT::Math::Similarity(derivs, covariance));
00402             }
00403         case pat::CandKinResolution::MCSpher:
00404             {
00405                 // Et = E sin(theta); dE/dP = P/E
00406                 double s = sin(p4.Theta()), c = cos(p4.Theta());
00407                 double e = p4.E(); 
00408                 double a = p4.P()* s / e;
00409                 double b = e * c;
00410                 return sqrt(a*a*covariance(0,0) + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00411             }
00412         case pat::CandKinResolution::MCPInvSpher:   
00413             {
00414                 // Et = E sin(theta); dE/dP = P/E -> dE/d(1/P) = - P^2 dE/dP = - P^3 / E
00415                 double s = sin(p4.Theta()), c = cos(p4.Theta());
00416                 double p = p4.P(), e = p4.E(); 
00417                 double a = ( - p * p * p / e ) * s;
00418                 double b = e * c;
00419                 return sqrt(a*a*covariance(0,0) + b*b*covariance(1,1) + 2*a*b*covariance(0,1));
00420             }
00421             // ======= OTHER ==========
00422         case pat::CandKinResolution::Invalid:
00423             throw cms::Exception("Invalid parametrization") << parametrization;
00424         default:
00425             throw cms::Exception("Not Implemented") << "getResolEt not yet implemented for parametrization " << parametrization ;
00426     }
00427 }
00428 
00429 
00430 double pat::helper::ResolutionHelper::getResolM(pat::CandKinResolution::Parametrization parametrization,
00431         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00432 {
00433     switch (parametrization) {
00434         // ====== MASS CONSTRAINED =====
00435         case pat::CandKinResolution::MCSpher:
00436         case pat::CandKinResolution::MCPInvSpher:   
00437         case pat::CandKinResolution::MCCart:
00438         case pat::CandKinResolution::EtThetaPhi: 
00439         case pat::CandKinResolution::EtEtaPhi: 
00440             return 0;
00441         // ======= MASS BASED ==========
00442         case pat::CandKinResolution::Cart:
00443         case pat::CandKinResolution::Spher:  
00444             return sqrt(covariance(3,3));
00445         // ======= ENERGY BASED ==========
00446         case pat::CandKinResolution::ESpher:
00447             { // M^2 = E^2 - P^2
00448               double dMdE = p4.E()/p4.M(), dMdP = - p4.P()/p4.M();
00449               return sqrt(  dMdP*dMdP*covariance(0,0) +
00450                           2*dMdP*dMdE*covariance(0,3) +
00451                             dMdE*dMdE*covariance(3,3));
00452             }
00453         case pat::CandKinResolution::ECart:    
00454             { // M^2 = E^2 - sum_i P_i^2
00455                 AlgebraicVector4 derivs(-p4.Px(), -p4.Py(), -p4.Pz(), p4.E());
00456                 derivs *= 1.0/p4.M();
00457                 return sqrt(ROOT::Math::Similarity(derivs, covariance));
00458             }
00459             throw cms::Exception("Not Implemented") << "getResolM not yet implemented for parametrization " << parametrization ;
00460         case pat::CandKinResolution::Invalid:
00461             throw cms::Exception("Invalid parametrization") << parametrization;
00462         default:
00463             throw cms::Exception("Not Implemented") << "getResolM not yet implemented for parametrization " << parametrization ;
00464     }
00465 }
00466 
00467 inline double DetaDtheta(double theta) { 
00468     // y  = -ln(tg(x/2)) =>
00469     // y' = - 1/tg(x/2) * 1/(cos(x/2))^2 * 1/2 = - 1 / (2 * sin(x/2) * cos(x/2)) = -1/sin(x) 
00470     return -1.0/sin(theta);
00471 }
00472 inline double DthetaDeta(double eta) { 
00473     // y = 2 atan(exp(-x))
00474     // y' = 2 * 1/(1+exp^2) * exp(-x) * (-1) = - 2 * exp/(1+exp^2) = - 2 / (exp + 1/exp)
00475     double e = exp(-eta);
00476     return -2.0/(e + 1.0/e);
00477 }
00478 
00479 double pat::helper::ResolutionHelper::getResolEta(pat::CandKinResolution::Parametrization parametrization,
00480         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)
00481 {
00482     switch (parametrization) {
00483         case pat::CandKinResolution::Cart:
00484         case pat::CandKinResolution::ECart:
00485         case pat::CandKinResolution::MCCart:
00486             // dEta = dTheta * dEta/dTheta 
00487             return abs(DetaDtheta(p4.Theta())) * getResolTheta(parametrization, covariance, p4);
00488         case pat::CandKinResolution::ESpher:        //  all the ones which have
00489         case pat::CandKinResolution::MCPInvSpher:   //  theta as parameter 1
00490         case pat::CandKinResolution::MCSpher:      
00491         case pat::CandKinResolution::EtThetaPhi: 
00492         case pat::CandKinResolution::Spher:  
00493             return sqrt(covariance(1,1))*abs(DetaDtheta(p4.Theta()));
00494         case pat::CandKinResolution::EtEtaPhi:      // as simple as that
00495             return sqrt(covariance(1,1));
00496         case pat::CandKinResolution::Invalid:
00497             throw cms::Exception("Invalid parametrization") << parametrization;
00498         default:
00499             throw cms::Exception("Not Implemented") << "getResolEta not yet implemented for parametrization " << parametrization ;
00500     }
00501 }
00502 double pat::helper::ResolutionHelper::getResolTheta(pat::CandKinResolution::Parametrization parametrization,
00503         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00504 {
00505     switch (parametrization) {
00506         case pat::CandKinResolution::Cart:
00507         case pat::CandKinResolution::ECart:
00508         case pat::CandKinResolution::MCCart:
00509             {
00510                 // theta = acos( pz / p )        ; d acos(x) = - 1 / sqrt( 1 - x*x) dx = - p/pt dx
00511                 double pt2 = p4.Perp2();
00512                 double p   = p4.P(), pi = 1.0/p, pi3 = pi*pi*pi;
00513                 double dacos = - p/sqrt(pt2);
00514                 AlgebraicVector3 derivs;
00515                 derivs[0] = -p4.Px() * p4.Pz() * dacos * pi3;
00516                 derivs[1] = -p4.Py() * p4.Pz() * dacos * pi3;
00517                 derivs[2] =  pt2 * dacos * pi3;
00518                 return sqrt(ROOT::Math::Similarity(derivs, covariance.Sub<AlgebraicSymMatrix33>(0,0)));
00519             }
00520         case pat::CandKinResolution::ESpher:        //  all the ones which have
00521         case pat::CandKinResolution::MCPInvSpher:   //  theta as parameter 1
00522         case pat::CandKinResolution::MCSpher:      
00523         case pat::CandKinResolution::EtThetaPhi: 
00524         case pat::CandKinResolution::Spher:  
00525             return sqrt(covariance(1,1)); 
00526         case pat::CandKinResolution::EtEtaPhi:      
00527             return sqrt(covariance(1,1))*abs(DthetaDeta(p4.Eta())); 
00528         case pat::CandKinResolution::Invalid:
00529             throw cms::Exception("Invalid parametrization") << parametrization;
00530         default:
00531             throw cms::Exception("Not Implemented") << "getResolTheta not yet implemented for parametrization " << parametrization ;
00532     }
00533 }
00534 double pat::helper::ResolutionHelper::getResolPhi(pat::CandKinResolution::Parametrization parametrization,
00535         const AlgebraicSymMatrix44 &covariance, const pat::CandKinResolution::LorentzVector &p4)  
00536 {
00537     double pt2 = p4.Perp2();
00538     switch (parametrization) {
00539         case pat::CandKinResolution::Cart:         
00540         case pat::CandKinResolution::ECart:        
00541         case pat::CandKinResolution::MCCart:
00542             return sqrt( ROOT::Math::Square(p4.Px()) * covariance(1,1) +
00543                          ROOT::Math::Square(p4.Py()) * covariance(0,0) +
00544                          -2*p4.Px()*p4.Py()          * covariance(0,1)
00545                     )/pt2;
00546         case pat::CandKinResolution::ESpher:        //  all the ones which have
00547         case pat::CandKinResolution::MCPInvSpher:   //  phi as parameter 2
00548         case pat::CandKinResolution::MCSpher:      
00549         case pat::CandKinResolution::EtThetaPhi: 
00550         case pat::CandKinResolution::Spher:  
00551         case pat::CandKinResolution::EtEtaPhi:      
00552             return sqrt(covariance(2,2)); 
00553         case pat::CandKinResolution::Invalid:
00554             throw cms::Exception("Invalid parametrization") << parametrization;
00555         default:
00556             throw cms::Exception("Not Implemented") << "getResolPhi not yet implemented for parametrization " << parametrization ;
00557     }
00558 }