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
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
00086 if (uniquePVTracks.size() != pvTrackRefs.size()) {
00087 std::vector<reco::TransientTrack> pvTransTracks;
00088
00089 BOOST_FOREACH(const reco::TrackRef& track, pvTrackRefs) {
00090 pvTransTracks.push_back(builder_->build(track));
00091 }
00092
00093 TransientVertex newPV = kvf.vertex(pvTransTracks, *beamspot_);
00094 pv = newPV;
00095 }
00096 }
00097
00098
00099
00100
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
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
00117 TransientVertex sv = kvf.vertex(signalTransTracks);
00118
00119 Measurement1D svDist = reco::SecondaryVertex::computeDist2d(
00120 pv, sv, direction, true);
00121 double significance = svDist.significance();
00122
00123 if (significance > 40)
00124 significance = 40;
00125 if (significance < -20)
00126 significance = -20;
00127 return significance;
00128 } else {
00129
00130 return prediscriminantFailValue_;
00131 }
00132 }
00133
00134 #include "FWCore/Framework/interface/MakerMacros.h"
00135 DEFINE_FWK_MODULE(PFRecoTauDiscriminationByFlight);