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 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
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
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
00143 TrackWeightInVertex weightComputer(getLeadTrack(jet));
00144
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 }}