CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoTauTag/RecoTau/plugins/RecoTauDiscriminationByFlight.cc

Go to the documentation of this file.
00001 #include <boost/foreach.hpp>
00002 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
00003 #include "DataFormats/VertexReco/interface/Vertex.h"
00004 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00005 
00006 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00007 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00008 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00009 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h"
00010 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
00011 #include "RecoBTag/SecondaryVertex/interface/SecondaryVertex.h"
00012 #include "TrackingTools/IPTools/interface/IPTools.h"
00013 
00014 class PFRecoTauDiscriminationByFlight : public PFTauDiscriminationProducerBase {
00015   public:
00016     PFRecoTauDiscriminationByFlight(const edm::ParameterSet& pset);
00017     virtual ~PFRecoTauDiscriminationByFlight(){}
00018     void beginEvent(const edm::Event& evt, const edm::EventSetup& es);
00019     double discriminate(const reco::PFTauRef&);
00020   private:
00021     edm::InputTag vertexSource_;
00022     edm::InputTag bsSource_;
00023     edm::Handle<reco::VertexCollection> vertices_;
00024     edm::Handle<reco::BeamSpot> beamspot_;
00025     const TransientTrackBuilder* builder_;
00026     double oneProngSig_;
00027     double threeProngSig_;
00028     bool refitPV_;
00029 };
00030 
00031 PFRecoTauDiscriminationByFlight::PFRecoTauDiscriminationByFlight(
00032     const edm::ParameterSet& pset):PFTauDiscriminationProducerBase(pset) {
00033   vertexSource_ = pset.getParameter<edm::InputTag>("vertexSource");
00034   oneProngSig_ = pset.exists("oneProngSigCut") ?
00035     pset.getParameter<double>("oneProngSigCut") : -1.;
00036   threeProngSig_ = pset.exists("threeProngSigCut") ?
00037     pset.getParameter<double>("threeProngSigCut") : -1.;
00038   refitPV_ = pset.getParameter<bool>("refitPV");
00039   if (refitPV_)
00040     bsSource_ = pset.getParameter<edm::InputTag>("beamspot");
00041 }
00042 
00043 void PFRecoTauDiscriminationByFlight::beginEvent(
00044     const edm::Event& evt, const edm::EventSetup& es) {
00045   evt.getByLabel(vertexSource_, vertices_);
00046   if (refitPV_)
00047     evt.getByLabel(bsSource_, beamspot_);
00048   edm::ESHandle<TransientTrackBuilder> transTrackBuilder;
00049   es.get<TransientTrackRecord>().get("TransientTrackBuilder",transTrackBuilder);
00050   builder_ = transTrackBuilder.product();
00051 }
00052 
00053 double PFRecoTauDiscriminationByFlight::discriminate(
00054     const reco::PFTauRef& tau) {
00055 
00056   KalmanVertexFitter kvf(true);
00057   const reco::PFCandidateRefVector& signalTracks =
00058     tau->signalPFChargedHadrCands();
00059   std::vector<reco::TransientTrack> signalTransTracks;
00060   std::vector<reco::TrackRef> signalTrackRefs;
00061   BOOST_FOREACH(const reco::PFCandidateRef& pftrack, signalTracks) {
00062     if (pftrack->trackRef().isNonnull()) {
00063       signalTransTracks.push_back(
00064           builder_->build(pftrack->trackRef()));
00065       signalTrackRefs.push_back(pftrack->trackRef());
00066     }
00067   }
00068 
00069   reco::Vertex pv = (*vertices_)[0];
00070 
00071   if (refitPV_) {
00072     std::vector<reco::TrackRef> pvTrackRefs;
00073     for (reco::Vertex::trackRef_iterator pvTrack = pv.tracks_begin();
00074         pvTrack != pv.tracks_end(); ++pvTrack ) {
00075       pvTrackRefs.push_back(pvTrack->castTo<reco::TrackRef>());
00076     }
00077     // Get PV tracks not associated to the tau
00078     std::sort(signalTrackRefs.begin(), signalTrackRefs.end());
00079     std::sort(pvTrackRefs.begin(), pvTrackRefs.end());
00080     std::vector<reco::TrackRef> uniquePVTracks;
00081     uniquePVTracks.reserve(pvTrackRefs.size());
00082     std::set_difference(pvTrackRefs.begin(), pvTrackRefs.end(),
00083         signalTrackRefs.begin(), signalTrackRefs.end(),
00084         std::back_inserter(uniquePVTracks));
00085     // Check if we need to refit
00086     if (uniquePVTracks.size() != pvTrackRefs.size()) {
00087       std::vector<reco::TransientTrack> pvTransTracks;
00088       // Build all our unique transient tracks in the PV
00089       BOOST_FOREACH(const reco::TrackRef& track, pvTrackRefs) {
00090         pvTransTracks.push_back(builder_->build(track));
00091       }
00092       // Refit our PV
00093       TransientVertex newPV = kvf.vertex(pvTransTracks, *beamspot_);
00094       pv = newPV;
00095     }
00096   }
00097 
00098   // The tau direction, to determine the sign of the IP.
00099   // In the case that it is a one prong, take the jet direction.
00100   // This may give better result due to out-of-cone stuff.
00101   GlobalVector direction = (tau->signalPFCands().size() == 1 ?
00102       GlobalVector(
00103           tau->jetRef()->px(), tau->jetRef()->py(), tau->jetRef()->pz()) :
00104       GlobalVector(tau->px(), tau->py(), tau->pz()));
00105 
00106   // Now figure out of we are doing a SV fit or an IP significance
00107   if (signalTransTracks.size() == 1) {
00108     reco::TransientTrack track = signalTransTracks.front();
00109     std::pair<bool,Measurement1D> ipsig =
00110       IPTools::signedTransverseImpactParameter(track, direction, pv);
00111     if (ipsig.first)
00112       return ipsig.second.significance();
00113     else
00114       return prediscriminantFailValue_;
00115   } else if (signalTransTracks.size() == 3) {
00116     // Fit the decay vertex of the three prong
00117     TransientVertex sv = kvf.vertex(signalTransTracks);
00118     // the true parameter indicates include PV errors
00119     Measurement1D svDist = reco::SecondaryVertex::computeDist2d(
00120         pv, sv, direction, true);
00121     double significance = svDist.significance();
00122     // Make sure it is a sane value
00123     if (significance > 40)
00124       significance = 40;
00125     if (significance < -20)
00126       significance = -20;
00127     return significance;
00128   } else  {
00129     // Weird two prong or something
00130     return prediscriminantFailValue_;
00131   }
00132 }
00133 
00134 #include "FWCore/Framework/interface/MakerMacros.h"
00135 DEFINE_FWK_MODULE(PFRecoTauDiscriminationByFlight);