CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTauTag/RecoTau/src/RecoTauVertexAssociator.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/RecoTau/interface/RecoTauVertexAssociator.h"
00002 
00003 #include <functional>
00004 #include <boost/foreach.hpp>
00005 
00006 #include "DataFormats/TauReco/interface/PFTau.h"
00007 #include "DataFormats/VertexReco/interface/Vertex.h"
00008 #include "FWCore/Framework/interface/Event.h"
00009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00010 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00011 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00012 #include "DataFormats/TrackReco/interface/Track.h"
00013 
00014 namespace reco { namespace tau {
00015 
00016 namespace {
00017 
00018 // Get the highest pt track in a jet.
00019 // Get the KF track if it exists.  Otherwise, see if it has a GSF track.
00020 const reco::TrackBaseRef getLeadTrack(const PFJet& jet) {
00021   std::vector<PFCandidatePtr> tracks = pfChargedCands(jet, true);
00022   if (!tracks.size())
00023     return reco::TrackBaseRef();
00024   PFCandidatePtr cand = tracks[0];
00025   if (cand->trackRef().isNonnull())
00026     return reco::TrackBaseRef(cand->trackRef());
00027   else if (cand->gsfTrackRef().isNonnull()) {
00028     return reco::TrackBaseRef(cand->gsfTrackRef());
00029   }
00030   return reco::TrackBaseRef();
00031 }
00032 
00033 // Define functors which extract the relevant information from a collection of
00034 // vertices.
00035 class DZtoTrack : public std::unary_function<double, reco::VertexRef> {
00036   public:
00037     DZtoTrack(const reco::TrackBaseRef& trk):trk_(trk){}
00038     double operator()(const reco::VertexRef& vtx) const {
00039       if (!trk_ || !vtx) {
00040         return std::numeric_limits<double>::infinity();
00041       }
00042       return std::abs(trk_->dz(vtx->position()));
00043     }
00044   private:
00045     const reco::TrackBaseRef trk_;
00046 };
00047 
00048 class TrackWeightInVertex : public std::unary_function<double, reco::VertexRef>
00049 {
00050   public:
00051     TrackWeightInVertex(const reco::TrackBaseRef& trk):trk_(trk){}
00052     double operator()(const reco::VertexRef& vtx) const {
00053       if (!trk_ || !vtx) {
00054         return 0.0;
00055       }
00056       return vtx->trackWeight(trk_);
00057     }
00058   private:
00059     const reco::TrackBaseRef trk_;
00060 };
00061 
00062 }
00063 
00064 RecoTauVertexAssociator::RecoTauVertexAssociator(
00065     const edm::ParameterSet& pset) {
00066 
00067   vertexTag_ = edm::InputTag("offlinePrimaryVertices", "");
00068   std::string algorithm = "highestPtInEvent";
00069 
00070   // Sanity check, will remove once HLT module configs are updated.
00071   if (!pset.exists("primaryVertexSrc") || !pset.exists("pvFindingAlgo")) {
00072     edm::LogWarning("NoVertexFindingMethodSpecified")
00073       << "The PSet passed to the RecoTauVertexAssociator was"
00074       << " incorrectly configured. The vertex will be taken as the "
00075       << "highest Pt vertex from the offlinePrimaryVertices collection."
00076       << std::endl;
00077   } else {
00078     vertexTag_ = pset.getParameter<edm::InputTag>("primaryVertexSrc");
00079     algorithm = pset.getParameter<std::string>("pvFindingAlgo");
00080   }
00081 
00082   if (algorithm == "highestPtInEvent") {
00083     algo_ = kHighestPtInEvent;
00084   } else if (algorithm == "closestInDeltaZ") {
00085     algo_ = kClosestDeltaZ;
00086   } else if (algorithm == "highestWeightForLeadTrack") {
00087     algo_ = kHighestWeigtForLeadTrack;
00088   } else {
00089     throw cms::Exception("BadVertexAssociatorConfig")
00090       << "The algorithm specified for tau-vertex association "
00091       << algorithm << " is invalid. Options are: "  << std::endl
00092       <<  "highestPtInEvent,"
00093       <<  "closestInDeltaZ,"
00094       <<  "or highestWeightForLeadTrack." << std::endl;
00095   }
00096 }
00097 
00098 void RecoTauVertexAssociator::setEvent(const edm::Event& evt) {
00099   edm::Handle<reco::VertexCollection> verticesH_;
00100   evt.getByLabel(vertexTag_, verticesH_);
00101   vertices_.clear();
00102   vertices_.reserve(verticesH_->size());
00103   for(size_t i = 0; i < verticesH_->size(); ++i) {
00104     vertices_.push_back(reco::VertexRef(verticesH_, i));
00105   }
00106   if (!vertices_.size()) {
00107     edm::LogError("NoPV") 
00108       << "There is no primary vertex in the event!!!"
00109       << " InputTag: " << vertexTag_ << std::endl;
00110   }
00111 }
00112 
00113 reco::VertexRef
00114 RecoTauVertexAssociator::associatedVertex(const PFTau& tau) const {
00115   reco::PFJetRef jetRef = tau.jetRef();
00116 
00117   // FIXME workaround for HLT which does not use updated data format
00118   if (jetRef.isNull())
00119     jetRef = tau.pfTauTagInfoRef()->pfjetRef();
00120 
00121   return associatedVertex(*jetRef);
00122 }
00123 
00124 reco::VertexRef
00125 RecoTauVertexAssociator::associatedVertex(const PFJet& jet) const {
00126   reco::VertexRef output = vertices_.size() ? vertices_[0] : reco::VertexRef();
00127   if (algo_ == kHighestPtInEvent) {
00128     return output;
00129   } else if (algo_ == kClosestDeltaZ) {
00130     double closestDistance = std::numeric_limits<double>::infinity();
00131     DZtoTrack dzComputer(getLeadTrack(jet));
00132     // Find the vertex that has the lowest DZ to the lead track
00133     BOOST_FOREACH(const reco::VertexRef& vtx, vertices_) {
00134       double dz = dzComputer(vtx);
00135       if (dz < closestDistance) {
00136         closestDistance = dz;
00137         output = vtx;
00138       }
00139     }
00140   } else if (algo_ == kHighestWeigtForLeadTrack) {
00141     double largestWeight = 0.;
00142     // Find the vertex that gives the lead track the highest weight.
00143     TrackWeightInVertex weightComputer(getLeadTrack(jet));
00144     // Find the vertex that has the lowest DZ to the lead track
00145     BOOST_FOREACH(const reco::VertexRef& vtx, vertices_) {
00146       double weight = weightComputer(vtx);
00147       if (weight > largestWeight) {
00148         largestWeight = weight;
00149         output = vtx;
00150       }
00151     }
00152   }
00153   return output;
00154 }
00155 
00156 }}