CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationByIsolation.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
00002 #include "DataFormats/Candidate/interface/LeafCandidate.h"
00003 #include "RecoTauTag/TauTagTools/interface/PFTauQualityCutWrapper.h"
00004 
00005 /* class PFRecoTauDiscriminationByIsolation
00006  * created : Jul 23 2007,
00007  * revised : Thu Aug 13 14:44:40 PDT 2009
00008  * contributors : Ludovic Houchu (Ludovic.Houchu@cern.ch ; IPHC, Strasbourg), Christian Veelken (veelken@fnal.gov ; UC Davis), 
00009  *                Evan K. Friis (friis@physics.ucdavis.edu ; UC Davis)
00010  */
00011 
00012 using namespace reco;
00013 using namespace std;
00014 
00015 class PFRecoTauDiscriminationByIsolation : public PFTauDiscriminationProducerBase  {
00016    public:
00017       explicit PFRecoTauDiscriminationByIsolation(const edm::ParameterSet& iConfig):PFTauDiscriminationProducerBase(iConfig), 
00018                                                                                qualityCuts_(iConfig.getParameter<edm::ParameterSet>("qualityCuts"))  // retrieve quality cuts 
00019       {   
00020          includeTracks_         = iConfig.getParameter<bool>("ApplyDiscriminationByTrackerIsolation");
00021          includeGammas_         = iConfig.getParameter<bool>("ApplyDiscriminationByECALIsolation");
00022 
00023          applyOccupancyCut_     = iConfig.getParameter<bool>("applyOccupancyCut");
00024          maximumOccupancy_      = iConfig.getParameter<uint32_t>("maximumOccupancy");
00025 
00026          applySumPtCut_         = iConfig.getParameter<bool>("applySumPtCut");
00027          maximumSumPt_          = iConfig.getParameter<double>("maximumSumPtCut");
00028 
00029          applyRelativeSumPtCut_ = iConfig.getParameter<bool>("applyRelativeSumPtCut");
00030          maximumRelativeSumPt_  = iConfig.getParameter<double>("relativeSumPtCut");
00031 
00032          pvProducer_            = iConfig.getParameter<edm::InputTag>("PVProducer");
00033       }
00034 
00035       ~PFRecoTauDiscriminationByIsolation(){}
00036 
00037       void beginEvent(const edm::Event& evt, const edm::EventSetup& evtSetup);
00038       double discriminate(const PFTauRef& pfTau);
00039 
00040    private:
00041       PFTauQualityCutWrapper qualityCuts_;
00042 
00043       bool includeTracks_;
00044       bool includeGammas_;
00045       
00046       bool applyOccupancyCut_;
00047       uint32_t maximumOccupancy_;
00048 
00049       bool applySumPtCut_;
00050       double maximumSumPt_;
00051 
00052       bool applyRelativeSumPtCut_;
00053       double maximumRelativeSumPt_;
00054 
00055       edm::InputTag pvProducer_;
00056 
00057       Vertex currentPV_;
00058 };
00059 
00060 void PFRecoTauDiscriminationByIsolation::beginEvent(const edm::Event& event, const edm::EventSetup& eventSetup)
00061 {
00062    // NB: The use of the PV in this context is necessitated by its use in applying quality cuts to the
00063    // different objects in the isolation cone
00064    
00065    // get the PV for this event
00066    edm::Handle<VertexCollection> primaryVertices;
00067    event.getByLabel(pvProducer_, primaryVertices);
00068 
00069    // take the highest pt primary vertex in the event
00070    if( primaryVertices->size() ) 
00071    {
00072       currentPV_ = *(primaryVertices->begin());
00073    } else // no PV exists, so simulate it ala PFRecoTauProducer.cc
00074    {
00075       const double smearedPVsigmaY = 0.0015;
00076       const double smearedPVsigmaX = 0.0015;
00077       const double smearedPVsigmaZ = 0.005;
00078       Vertex::Error SimPVError;
00079       SimPVError(0,0) = smearedPVsigmaX*smearedPVsigmaX;
00080       SimPVError(1,1) = smearedPVsigmaY*smearedPVsigmaY;
00081       SimPVError(2,2) = smearedPVsigmaZ*smearedPVsigmaZ;
00082       Vertex::Point blankVertex(0, 0, 0);
00083       // note that the PFTau has its vertex set as the associated PV.  So if it doesn't exist,
00084       // a fake vertex has already been created (about 0, 0, 0) w/ the above width (gaussian)
00085       currentPV_ = Vertex(blankVertex, SimPVError,1,1,1);    
00086    }
00087 }
00088 
00089 double PFRecoTauDiscriminationByIsolation::discriminate(const PFTauRef& pfTau)
00090 {
00091    // collect the objects we are working with (ie tracks, tracks+gammas, etc)
00092    std::vector<LeafCandidate> isoObjects;
00093 
00094    if( includeTracks_ )
00095    {
00096       qualityCuts_.isolationChargedObjects(*pfTau, currentPV_, isoObjects);
00097    }
00098 
00099    if( includeGammas_ )
00100    {
00101       qualityCuts_.isolationGammaObjects(*pfTau, isoObjects);
00102    }
00103 
00104    bool failsOccupancyCut     = false;
00105    bool failsSumPtCut         = false;
00106    bool failsRelativeSumPtCut = false;
00107 
00108    //--- nObjects requirement
00109    failsOccupancyCut = ( isoObjects.size() > maximumOccupancy_ );
00110 
00111    //--- Sum PT requirement
00112    if( applySumPtCut_ || applyRelativeSumPtCut_ )
00113    {
00114       reco::Particle::LorentzVector totalP4;
00115       for(std::vector<LeafCandidate>::const_iterator iIsoObject  = isoObjects.begin();
00116             iIsoObject != isoObjects.end(); 
00117             ++iIsoObject)
00118       {
00119          totalP4 += iIsoObject->p4();
00120       }
00121 
00122       failsSumPtCut = ( totalP4.pt() > maximumSumPt_ );
00123 
00124       //--- Relative Sum PT requirement
00125       failsRelativeSumPtCut = ( ( pfTau->pt() > 0 ? totalP4.pt()/pfTau->pt() : 0 ) > maximumRelativeSumPt_ );
00126    }
00127 
00128    bool fails = ( applyOccupancyCut_     && failsOccupancyCut     )   || 
00129                 ( applySumPtCut_         && failsSumPtCut         )   || 
00130                 ( applyRelativeSumPtCut_ && failsRelativeSumPtCut ) ;
00131 
00132    return ( fails ? 0. : 1. );
00133 }
00134 
00135 DEFINE_FWK_MODULE(PFRecoTauDiscriminationByIsolation);
00136 
00137 /*
00138 void PFRecoTauDiscriminationByIsolation::produce(edm::Event& iEvent,const edm::EventSetup& iEventSetup){
00139   edm::Handle<PFTauCollection> thePFTauCollection;
00140   iEvent.getByLabel(PFTauProducer_,thePFTauCollection);
00141   
00142   // fill the AssociationVector object
00143   auto_ptr<PFTauDiscriminator> thePFTauDiscriminatorByIsolation(new PFTauDiscriminator(PFTauRefProd(thePFTauCollection)));
00144   
00145   for(size_t iPFTau=0;iPFTau<thePFTauCollection->size();++iPFTau) {
00146     PFTauRef thePFTauRef(thePFTauCollection,iPFTau);
00147     PFTau thePFTau=*thePFTauRef;
00148     math::XYZVector thePFTau_XYZVector=thePFTau.momentum();   
00149     PFTauElementsOperators thePFTauElementsOperators(thePFTau);
00150     if (ApplyDiscriminationByTrackerIsolation_){  
00151       // optional selection by a tracker isolation : ask for 0 charged hadron PFCand / reco::Track in an isolation annulus around a leading PFCand / reco::Track axis
00152       float TrackPtSum=0;
00153       double theTrackerIsolationDiscriminator = 1.;
00154       if (ManipulateTracks_insteadofChargedHadrCands_){
00155          const TrackRefVector& isolationTracks = thePFTau.isolationTracks();
00156          unsigned int tracksAboveThreshold = 0;
00157 
00158          for(size_t iTrack = 0; iTrack < isolationTracks.size(); ++iTrack)
00159          {
00160 
00161            if (SumOverCandidates_){
00162              TrackPtSum+=isolationTracks[iTrack]->pt();
00163              if ((TrackPtSum>maxChargedPt_)&&(!TrackIsolationOverTauPt_)){
00164                theTrackerIsolationDiscriminator = 0.;
00165                break;
00166              }
00167              if ((TrackPtSum/thePFTau.pt()>maxChargedPt_)&&(TrackIsolationOverTauPt_)){
00168                theTrackerIsolationDiscriminator = 0.;
00169                break;
00170              }       
00171            }
00172            else{
00173              if(isolationTracks[iTrack]->pt() > maxChargedPt_) {
00174                if(++tracksAboveThreshold > TrackerIsolAnnulus_Tracksmaxn_)
00175                  {
00176                    theTrackerIsolationDiscriminator = 0.;
00177                    break;
00178                  }
00179              }
00180            }
00181          }
00182 
00183       } else { //use pf candidates instead
00184          const PFCandidateRefVector& pfIsoChargedCands = thePFTau.isolationPFChargedHadrCands();
00185          unsigned int tracksAboveThreshold = 0;
00186          for(size_t iIsoCand = 0; iIsoCand < pfIsoChargedCands.size(); ++iIsoCand)
00187          {
00188            if (SumOverCandidates_){
00189              TrackPtSum+=pfIsoChargedCands[iIsoCand]->pt();
00190              if ((TrackPtSum>maxChargedPt_)&&(!TrackIsolationOverTauPt_)){
00191                theTrackerIsolationDiscriminator = 0.;
00192                break;
00193              }
00194              if ((TrackPtSum/thePFTau.pt()>maxChargedPt_)&&(TrackIsolationOverTauPt_)){
00195                theTrackerIsolationDiscriminator = 0.;
00196                break;
00197              }       
00198            } 
00199            else{
00200              if(pfIsoChargedCands[iIsoCand]->pt() > maxChargedPt_) {
00201                if(++tracksAboveThreshold > TrackerIsolAnnulus_Candsmaxn_) {
00202                  theTrackerIsolationDiscriminator = 0.;
00203                  break;
00204                }
00205              }
00206            }
00207          }
00208       }
00209 
00210       if (theTrackerIsolationDiscriminator == 0.){
00211         thePFTauDiscriminatorByIsolation->setValue(iPFTau,0.);
00212         continue;
00213       }
00214     }    
00215     
00216     if (ApplyDiscriminationByECALIsolation_){
00217       
00218       // optional selection by an ECAL isolation : ask for 0 gamma PFCand in an isolation annulus around a leading PFCand
00219       double theECALIsolationDiscriminator =1.;
00220       const PFCandidateRefVector& pfIsoGammaCands = thePFTau.isolationPFGammaCands();
00221       unsigned int gammasAboveThreshold = 0;
00222       float PhotonSum=0;
00223       for(size_t iIsoGamma = 0; iIsoGamma < pfIsoGammaCands.size(); ++iIsoGamma)
00224       {
00225         if (SumOverCandidates_){
00226           PhotonSum+=pfIsoGammaCands[iIsoGamma]->pt();
00227           if ((PhotonSum>maxGammaPt_)&&(!TrackIsolationOverTauPt_)){
00228              theECALIsolationDiscriminator = 0.;
00229             break;
00230           }
00231           if ((PhotonSum/thePFTau.pt()>maxGammaPt_)&&(TrackIsolationOverTauPt_)){
00232                theECALIsolationDiscriminator = 0.;
00233                break;
00234           }          
00235         } 
00236         else{
00237           if(pfIsoGammaCands[iIsoGamma]->pt() > maxGammaPt_) {
00238             if(++gammasAboveThreshold > ECALIsolAnnulus_Candsmaxn_) {
00239               theECALIsolationDiscriminator = 0;
00240               break;
00241             }
00242           }
00243         }
00244       }
00245       if (theECALIsolationDiscriminator==0.){
00246         thePFTauDiscriminatorByIsolation->setValue(iPFTau,0);
00247         continue;
00248       }
00249     }
00250     
00251     // not optional selection : ask for a leading (Pt>minPt) PFCand / reco::Track in a matching cone around the PFJet axis
00252     bool theleadElementDiscriminator = true;
00253     if (ManipulateTracks_insteadofChargedHadrCands_) {
00254       if (!thePFTau.leadTrack()) theleadElementDiscriminator = false;
00255     } else if (!thePFTau.leadPFChargedHadrCand()) theleadElementDiscriminator = false;
00256 
00257     if (!theleadElementDiscriminator) thePFTauDiscriminatorByIsolation->setValue(iPFTau,0);
00258     else thePFTauDiscriminatorByIsolation->setValue(iPFTau,1); //passes everything
00259   }    
00260 
00261   iEvent.put(thePFTauDiscriminatorByIsolation);
00262   
00263 }
00264 
00265 */