CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoEgamma/EgammaElectronAlgos/src/ElectronMomentumCorrector.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronMomentumCorrector.h"
00002 
00003 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00004 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00005 #include "DataFormats/Math/interface/LorentzVector.h"
00006 
00007 #include "TrackingTools/GsfTools/interface/MultiGaussianState1D.h"
00008 #include "TrackingTools/GsfTools/interface/GaussianSumUtilities1D.h"
00009 #include "TrackingTools/GsfTools/interface/MultiGaussianStateTransform.h"
00010 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00011 
00012 
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 
00015 /****************************************************************************
00016  *
00017  * Class based E-p combination for the final electron momentum. It relies on
00018  * the electron classification and on the dtermination of track momentum and ecal
00019  * supercluster energy errors. The track momentum error is taken from the gsf fit.
00020  * The ecal supercluster energy error is taken from a class dependant parametrisation
00021  * of the energy resolution.
00022  *
00023  *
00024  * \author Federico Ferri - INFN Milano, Bicocca university
00025  * \author Ivica Puljak - FESB, Split
00026  * \author Stephanie Baffioni - Laboratoire Leprince-Ringuet - École polytechnique, CNRS/IN2P3
00027  *
00028  * \version $Id: ElectronMomentumCorrector.cc,v 1.15 2011/02/16 17:46:35 chamont Exp $
00029  *
00030  ****************************************************************************/
00031 
00032 
00033 void ElectronMomentumCorrector::correct( reco::GsfElectron & electron, TrajectoryStateOnSurface & vtxTsos )
00034  {
00035   if (electron.p4Error(reco::GsfElectron::P4_COMBINATION)!= 999.)
00036    {
00037     edm::LogWarning("ElectronMomentumCorrector::correct")<<"already done" ;
00038     return ;
00039    }
00040 
00041   math::XYZTLorentzVector newMomentum = electron.p4() ; // default
00042   int elClass = electron.classification() ;
00043 
00044   // irrelevant classification
00045   if ( (elClass <= reco::GsfElectron::UNKNOWN) ||
00046            (elClass>reco::GsfElectron::GAP) )
00047    {
00048     edm::LogWarning("ElectronMomentumCorrector::correct")<<"unexpected classification" ;
00049     return ;
00050    }
00051 
00052   float scEnergy = electron.ecalEnergy() ;
00053   float errorEnergy_ = electron.ecalEnergyError() ;
00054 
00055   float trackMomentum  = electron.trackMomentumAtVtx().R() ;
00056   float errorTrackMomentum = 999. ;
00057 
00058   // retreive momentum error
00059   MultiGaussianState1D qpState(MultiGaussianStateTransform::multiState1D(vtxTsos,0));
00060   GaussianSumUtilities1D qpUtils(qpState);
00061   errorTrackMomentum = trackMomentum*trackMomentum*sqrt(qpUtils.mode().variance());
00062 
00063   float finalMomentum = electron.p4().t(); // initial
00064   float finalMomentumError = 999.;
00065 
00066 
00067   // first check for large errors
00068 
00069   if (errorTrackMomentum/trackMomentum > 0.5 && errorEnergy_/scEnergy <= 0.5) {
00070     finalMomentum = scEnergy;    finalMomentumError = errorEnergy_;
00071    }
00072   else if (errorTrackMomentum/trackMomentum <= 0.5 && errorEnergy_/scEnergy > 0.5){
00073     finalMomentum = trackMomentum;  finalMomentumError = errorTrackMomentum;
00074    }
00075   else if (errorTrackMomentum/trackMomentum > 0.5 && errorEnergy_/scEnergy > 0.5){
00076     if (errorTrackMomentum/trackMomentum < errorEnergy_/scEnergy) {
00077       finalMomentum = trackMomentum; finalMomentumError = errorTrackMomentum;
00078      }
00079     else{
00080       finalMomentum = scEnergy; finalMomentumError = errorEnergy_;
00081      }
00082   }
00083 
00084   // then apply the combination algorithm
00085   else {
00086 
00087      // calculate E/p and corresponding error
00088     float eOverP = scEnergy / trackMomentum;
00089     float errorEOverP = sqrt(
00090                              (errorEnergy_/trackMomentum)*(errorEnergy_/trackMomentum) +
00091                              (scEnergy*errorTrackMomentum/trackMomentum/trackMomentum)*
00092                              (scEnergy*errorTrackMomentum/trackMomentum/trackMomentum));
00093 
00094     if ( eOverP  > 1 + 2.5*errorEOverP )
00095      {
00096       finalMomentum = scEnergy; finalMomentumError = errorEnergy_;
00097       if ((elClass==reco::GsfElectron::GOLDEN) && electron.isEB() && (eOverP<1.15))
00098         {
00099           if (scEnergy<15) {finalMomentum = trackMomentum ; finalMomentumError = errorTrackMomentum;}
00100         }
00101      }
00102     else if ( eOverP < 1 - 2.5*errorEOverP )
00103      {
00104       finalMomentum = scEnergy; finalMomentumError = errorEnergy_;
00105       if (elClass==reco::GsfElectron::SHOWERING)
00106        {
00107               if (electron.isEB())
00108                {
00109                       if (scEnergy<18)
00110                        { finalMomentum = trackMomentum; finalMomentumError = errorTrackMomentum; }
00111                }
00112               else if (electron.isEE())
00113                {
00114           if (scEnergy<13)
00115            {finalMomentum = trackMomentum; finalMomentumError = errorTrackMomentum;}
00116                }
00117               else
00118                { edm::LogWarning("ElectronMomentumCorrector::correct")<<"nor barrel neither endcap electron ?!" ; }
00119              }
00120             else if (electron.isGap())
00121              {
00122               if (scEnergy<60)
00123                { finalMomentum = trackMomentum; finalMomentumError = errorTrackMomentum ; }
00124              }
00125       }
00126     else
00127      {
00128       // combination
00129       finalMomentum = (scEnergy/errorEnergy_/errorEnergy_ + trackMomentum/errorTrackMomentum/errorTrackMomentum) /
00130         (1/errorEnergy_/errorEnergy_ + 1/errorTrackMomentum/errorTrackMomentum);
00131       float finalMomentumVariance = 1 / (1/errorEnergy_/errorEnergy_ + 1/errorTrackMomentum/errorTrackMomentum);
00132       finalMomentumError = sqrt(finalMomentumVariance);
00133      }
00134 
00135   }
00136 
00137   math::XYZTLorentzVector oldMomentum = electron.p4() ;
00138   newMomentum = math::XYZTLorentzVector
00139    ( oldMomentum.x()*finalMomentum/oldMomentum.t(),
00140      oldMomentum.y()*finalMomentum/oldMomentum.t(),
00141      oldMomentum.z()*finalMomentum/oldMomentum.t(),
00142      finalMomentum ) ;
00143 
00144 
00145   // final set
00146   electron.correctMomentum(newMomentum,errorTrackMomentum,finalMomentumError);
00147 
00148  }
00149