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
00019
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
00034
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
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 }
00107
00108 reco::VertexRef
00109 RecoTauVertexAssociator::associatedVertex(const PFTau& tau) const {
00110 reco::PFJetRef jetRef = tau.jetRef();
00111
00112
00113 if (jetRef.isNull())
00114 jetRef = tau.pfTauTagInfoRef()->pfjetRef();
00115
00116 return associatedVertex(*jetRef);
00117 }
00118
00119 reco::VertexRef
00120 RecoTauVertexAssociator::associatedVertex(const PFJet& jet) const {
00121 reco::VertexRef output = vertices_.size() ? vertices_[0] : reco::VertexRef();
00122 if (algo_ == kHighestPtInEvent) {
00123 return output;
00124 } else if (algo_ == kClosestDeltaZ) {
00125 double closestDistance = std::numeric_limits<double>::infinity();
00126 DZtoTrack dzComputer(getLeadTrack(jet));
00127
00128 BOOST_FOREACH(const reco::VertexRef& vtx, vertices_) {
00129 double dz = dzComputer(vtx);
00130 if (dz < closestDistance) {
00131 closestDistance = dz;
00132 output = vtx;
00133 }
00134 }
00135 } else if (algo_ == kHighestWeigtForLeadTrack) {
00136 double largestWeight = 0.;
00137
00138 TrackWeightInVertex weightComputer(getLeadTrack(jet));
00139
00140 BOOST_FOREACH(const reco::VertexRef& vtx, vertices_) {
00141 double weight = weightComputer(vtx);
00142 if (weight > largestWeight) {
00143 largestWeight = weight;
00144 output = vtx;
00145 }
00146 }
00147 }
00148 return output;
00149 }
00150
00151 }}