CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RecoTauVertexAssociator.cc
Go to the documentation of this file.
2 
3 #include <functional>
4 #include <boost/foreach.hpp>
5 
13 
14 namespace reco { namespace tau {
15 
16 // Get the highest pt track in a jet.
17 // Get the KF track if it exists. Otherwise, see if it has a GSF track.
19 {
20  std::vector<PFCandidatePtr> chargedPFCands = pfChargedCands(jet, true);
21  if ( verbosity_ >= 1 ) {
22  std::cout << "<RecoTauVertexAssociator::getLeadTrack>:" << std::endl;
23  std::cout << " jet: Pt = " << jet.pt() << ", eta = " << jet.eta() << ", phi = " << jet.phi() << std::endl;
24  std::cout << " num. chargedPFCands = " << chargedPFCands.size() << std::endl;
25  std::cout << " vxTrkFiltering = " << vxTrkFiltering_ << std::endl;
26  }
27 
28  if ( chargedPFCands.size() == 0 ) {
29  return reco::TrackBaseRef();
30  }
31 
32  std::vector<PFCandidatePtr> selectedPFCands;
33  if ( vxTrkFiltering_ ) {
34  selectedPFCands = qcuts_->filterCandRefs(chargedPFCands);
35  } else {
36  selectedPFCands = chargedPFCands;
37  }
38  if ( verbosity_ >= 1 ) {
39  std::cout << " num. selectedPFCands = " << selectedPFCands.size() << std::endl;
40  }
41 
43  if ( selectedPFCands.size() >= 1 ) {
44  double leadTrackPt = 0.;
45  if ( leadingTrkOrPFCandOption_ == kFirstTrack){ leadPFCand=selectedPFCands[0];}
46  else
47  {
48  for ( std::vector<PFCandidatePtr>::const_iterator pfCand = selectedPFCands.begin();
49  pfCand != selectedPFCands.end(); ++pfCand ) {
50  const reco::Track* track = 0;
51  if ( (*pfCand)->trackRef().isNonnull() ) track = (*pfCand)->trackRef().get();
52  else if ( (*pfCand)->gsfTrackRef().isNonnull() ) track = (*pfCand)->gsfTrackRef().get();
53  if ( !track ) continue;
54  double trackPt = 0.;
56  //double trackPt = track->pt();
57  trackPt = track->pt() - 2.*track->ptError();
58  } else if ( leadingTrkOrPFCandOption_ == kLeadPFCand ) {
59  trackPt = (*pfCand)->pt();
60  } else assert(0);
61  if ( trackPt > leadTrackPt ) {
62  leadPFCand = (*pfCand);
63  leadTrackPt = trackPt;
64  }
65  }
66  }
67  }
68  if ( leadPFCand.isNull() ) {
69  if ( recoverLeadingTrk_ ) {
70  leadPFCand = chargedPFCands[0];
71  } else {
72  return reco::TrackBaseRef();
73  }
74  }
75  if ( verbosity_ >= 1 ) {
76  std::cout << "leadPFCand: Pt = " << leadPFCand->pt() << ", eta = " << leadPFCand->eta() << ", phi = " << leadPFCand->phi() << std::endl;
77  }
78 
79  if ( leadPFCand->trackRef().isNonnull() ) {
80  return reco::TrackBaseRef(leadPFCand->trackRef());
81  } else if ( leadPFCand->gsfTrackRef().isNonnull() ) {
82  return reco::TrackBaseRef(leadPFCand->gsfTrackRef());
83  }
84  return reco::TrackBaseRef();
85 }
86 
87 namespace {
88  // Define functors which extract the relevant information from a collection of
89  // vertices.
90  class DZtoTrack : public std::unary_function<double, reco::VertexRef>
91  {
92  public:
93  DZtoTrack(const reco::TrackBaseRef& trk)
94  : trk_(trk)
95  {}
96  double operator()(const reco::VertexRef& vtx) const
97  {
98  if ( !trk_ || !vtx ) {
100  }
101  return std::abs(trk_->dz(vtx->position()));
102  }
103  private:
105  };
106 
107  class TrackWeightInVertex : public std::unary_function<double, reco::VertexRef>
108  {
109  public:
110  TrackWeightInVertex(const reco::TrackBaseRef& trk)
111  : trk_(trk)
112  {}
113  double operator()(const reco::VertexRef& vtx) const
114  {
115  if ( !trk_ || !vtx ) {
116  return 0.0;
117  }
118  return vtx->trackWeight(trk_);
119  }
120  private:
121  const reco::TrackBaseRef trk_;
122  };
123 }
124 
126  : vertexSelector_(0),
127  qcuts_(0),
128  jetToVertexAssociation_(0),
129  lastEvent_(-1)
130 {
131  //std::cout << "<RecoTauVertexAssociator::RecoTauVertexAssociator>:" << std::endl;
132 
133  vertexTag_ = edm::InputTag("offlinePrimaryVertices", "");
134  algorithm_ = "highestPtInEvent";
135  // Sanity check, will remove once HLT module configs are updated.
136  if ( !pset.exists("primaryVertexSrc") || !pset.exists("pvFindingAlgo") ) {
137  edm::LogWarning("NoVertexFindingMethodSpecified")
138  << "The PSet passed to the RecoTauVertexAssociator was incorrectly configured."
139  << " The vertex will be taken as the highest Pt vertex from the 'offlinePrimaryVertices' collection."
140  << std::endl;
141  } else {
142  vertexTag_ = pset.getParameter<edm::InputTag>("primaryVertexSrc");
143  algorithm_ = pset.getParameter<std::string>("pvFindingAlgo");
144  }
145 
146  if ( pset.exists("vxAssocQualityCuts") ) {
147  //std::cout << " reading 'vxAssocQualityCuts'" << std::endl;
148  qcuts_ = new RecoTauQualityCuts(pset.getParameterSet("vxAssocQualityCuts"));
149  } else {
150  //std::cout << " reading 'signalQualityCuts'" << std::endl;
151  qcuts_ = new RecoTauQualityCuts(pset.getParameterSet("signalQualityCuts"));
152  }
153  assert(qcuts_);
154 
155  vxTrkFiltering_ = false;
156  if ( !pset.exists("vertexTrackFiltering") && pset.exists("vxAssocQualityCuts") ) {
157  edm::LogWarning("NoVertexTrackFilteringSpecified")
158  << "The PSet passed to the RecoTauVertexAssociator was incorrectly configured."
159  << " Please define vertexTrackFiltering in config file."
160  << " No filtering of tracks to vertices will be applied."
161  << std::endl;
162  } else {
163  vxTrkFiltering_ = pset.exists("vertexTrackFiltering") ?
164  pset.getParameter<bool>("vertexTrackFiltering") : false;
165  }
166  if ( pset.exists("vertexSelection") ) {
167  std::string vertexSelection = pset.getParameter<std::string>("vertexSelection");
168  if ( vertexSelection != "" ) {
170  }
171  }
172 
173  if ( algorithm_ == "highestPtInEvent" ) {
175  } else if ( algorithm_ == "closestInDeltaZ" ) {
177  } else if ( algorithm_ == "highestWeightForLeadTrack" ) {
179  } else if ( algorithm_ == "combined" ) {
180  algo_ = kCombined;
181  } else {
182  throw cms::Exception("BadVertexAssociatorConfig")
183  << "Invalid Configuration parameter 'algorithm' " << algorithm_ << "."
184  << " Valid options are: 'highestPtInEvent', 'closestInDeltaZ', 'highestWeightForLeadTrack' and 'combined'.\n";
185  }
186 
188 
189  recoverLeadingTrk_ = pset.exists("recoverLeadingTrk") ?
190  pset.getParameter<bool>("recoverLeadingTrk") : false;
191 
192  std::string leadingTrkOrPFCandOption_string = pset.exists("leadingTrkOrPFCandOption") ? pset.getParameter<std::string>("leadingTrkOrPFCandOption") : "firstTrack" ;
193  if ( leadingTrkOrPFCandOption_string == "leadTrack" ) leadingTrkOrPFCandOption_ = kLeadTrack;
194  else if ( leadingTrkOrPFCandOption_string == "leadPFCand" ) leadingTrkOrPFCandOption_ = kLeadPFCand;
195  else if ( leadingTrkOrPFCandOption_string == "firstTrack" ) leadingTrkOrPFCandOption_ = kFirstTrack;
196  else throw cms::Exception("BadVertexAssociatorConfig")
197  << "Invalid Configuration parameter 'leadingTrkOrPFCandOption' " << leadingTrkOrPFCandOption_string << "."
198  << " Valid options are: 'leadTrack', 'leadPFCand', 'firstTrack'.\n";
199 
200  verbosity_ = ( pset.exists("verbosity") ) ?
201  pset.getParameter<int>("verbosity") : 0;
202 }
203 
205 {
206  delete vertexSelector_;
207  delete qcuts_;
209 }
210 
212 {
214  evt.getByToken(vxToken_, vertices);
215  selectedVertices_.clear();
216  selectedVertices_.reserve(vertices->size());
217  for ( size_t idxVertex = 0; idxVertex < vertices->size(); ++idxVertex ) {
218  reco::VertexRef vertex(vertices, idxVertex);
219  if ( vertexSelector_ && !(*vertexSelector_)(*vertex) ) continue;
220  selectedVertices_.push_back(vertex);
221  }
222  if ( selectedVertices_.size() > 0 ) {
224  }
225  int currentEvent = evt.id().event();
226  if ( currentEvent != lastEvent_ || !jetToVertexAssociation_ ) {
227  if ( !jetToVertexAssociation_ ) jetToVertexAssociation_ = new std::map<const reco::PFJet*, reco::VertexRef>;
228  else jetToVertexAssociation_->clear();
229  lastEvent_ = currentEvent;
230  }
231 }
232 
235 {
236  reco::PFJetRef jetRef = tau.jetRef();
237  // FIXME workaround for HLT which does not use updated data format
238  if ( jetRef.isNull() ) jetRef = tau.pfTauTagInfoRef()->pfjetRef();
239  return associatedVertex(*jetRef);
240 }
241 
244 {
245  if ( verbosity_ >= 1 ) {
246  std::cout << "<RecoTauVertexAssociator::associatedVertex>:" << std::endl;
247  std::cout << " jet: Pt = " << jet.pt() << ", eta = " << jet.eta() << ", phi = " << jet.phi() << std::endl;
248  std::cout << " num. Vertices = " << selectedVertices_.size() << std::endl;
249  std::cout << " size(jetToVertexAssociation) = " << jetToVertexAssociation_->size() << std::endl;
250  std::cout << " vertexTag = " << vertexTag_ << std::endl;
251  std::cout << " algorithm = " << algorithm_ << std::endl;
252  std::cout << " recoverLeadingTrk = " << recoverLeadingTrk_ << std::endl;
253  }
254 
255  reco::VertexRef jetVertex = ( selectedVertices_.size() > 0 ) ? selectedVertices_[0] : reco::VertexRef();
256  const PFJet* jetPtr = &jet;
257 
258  // check if jet-vertex association has been determined for this jet before
259  std::map<const reco::PFJet*, reco::VertexRef>::iterator vertexPtr = jetToVertexAssociation_->find(jetPtr);
260  if ( vertexPtr != jetToVertexAssociation_->end() ) {
261  jetVertex = vertexPtr->second;
262  } else {
263  // no jet-vertex association exists for this jet yet, compute it!
264  if ( algo_ == kHighestPtInEvent ) {
265  if ( selectedVertices_.size() > 0 ) jetVertex = selectedVertices_[0];
266  } else if ( algo_ == kClosestDeltaZ ) {
267  // find "leading" (highest Pt) track in jet
269  if ( verbosity_ ) {
270  if ( leadTrack.isNonnull() ) std::cout << "leadTrack: Pt = " << leadTrack->pt() << ", eta = " << leadTrack->eta() << ", phi = " << leadTrack->phi() << std::endl;
271  else std::cout << "leadTrack: N/A" << std::endl;
272  }
273  if ( leadTrack.isNonnull() ) {
274  double closestDistance = 1.e+6;
275  DZtoTrack dzComputer(leadTrack);
276  // Find the vertex that has the lowest dZ to the leading track
277  int idxVertex = 0;
278  for ( std::vector<reco::VertexRef>::const_iterator selectedVertex = selectedVertices_.begin();
279  selectedVertex != selectedVertices_.end(); ++selectedVertex ) {
280  double dZ = dzComputer(*selectedVertex);
281  if ( verbosity_ ) {
282  std::cout << "vertex #" << idxVertex << ": x = " << (*selectedVertex)->position().x() << ", y = " << (*selectedVertex)->position().y() << ", z = " << (*selectedVertex)->position().z()
283  << " --> dZ = " << dZ << std::endl;
284  }
285  if ( dZ < closestDistance ) {
286  jetVertex = (*selectedVertex);
287  closestDistance = dZ;
288  }
289  ++idxVertex;
290  }
291  }
292  } else if ( algo_ == kHighestWeigtForLeadTrack || algo_ == kCombined ) {
294  if ( verbosity_ ) {
295  if ( leadTrack.isNonnull() ) std::cout << "leadTrack: Pt = " << leadTrack->pt() << ", eta = " << leadTrack->eta() << ", phi = " << leadTrack->phi() << std::endl;
296  else std::cout << "leadTrack: N/A" << std::endl;
297  }
298  if ( leadTrack.isNonnull() ) {
299  double largestWeight = -1.;
300  // Find the vertex that has the highest association probability to the leading track
301  TrackWeightInVertex weightComputer(leadTrack);
302  int idxVertex = 0;
303  for ( std::vector<reco::VertexRef>::const_iterator selectedVertex = selectedVertices_.begin();
304  selectedVertex != selectedVertices_.end(); ++selectedVertex ) {
305  double weight = weightComputer(*selectedVertex);
306  if ( verbosity_ ) {
307  std::cout << "vertex #" << idxVertex << ": x = " << (*selectedVertex)->position().x() << ", y = " << (*selectedVertex)->position().y() << ", z = " << (*selectedVertex)->position().z()
308  << " --> weight = " << weight << std::endl;
309  }
310  if ( weight > largestWeight ) {
311  jetVertex = (*selectedVertex);
312  largestWeight = weight;
313  }
314  ++idxVertex;
315  }
316  // the weight was never larger than zero
317  if ( algo_ == kCombined && largestWeight < 1.e-7 ) {
318  if ( verbosity_ ) {
319  std::cout << "No vertex had positive weight! Trying dZ instead... " << std::endl;
320  }
321  double closestDistance = 1.e+6;
322  DZtoTrack dzComputer(leadTrack);
323  // Find the vertex that has the lowest dZ to the leading track
324  int idxVertex = 0;
325  for ( std::vector<reco::VertexRef>::const_iterator selectedVertex = selectedVertices_.begin();
326  selectedVertex != selectedVertices_.end(); ++selectedVertex ) {
327  double dZ = dzComputer(*selectedVertex);
328  if ( verbosity_ ) {
329  std::cout << "vertex #" << idxVertex << ": x = " << (*selectedVertex)->position().x() << ", y = " << (*selectedVertex)->position().y() << ", z = " << (*selectedVertex)->position().z()
330  << " --> dZ = " << dZ << std::endl;
331  }
332  if ( dZ < closestDistance ) {
333  jetVertex = (*selectedVertex);
334  closestDistance = dZ;
335  }
336  ++idxVertex;
337  }
338  }
339  }
340  }
341 
342  jetToVertexAssociation_->insert(std::pair<const PFJet*, reco::VertexRef>(jetPtr, jetVertex));
343  }
344 
345  if ( verbosity_ >= 1 ) {
346  std::cout << "--> returning vertex: x = " << jetVertex->position().x() << ", y = " << jetVertex->position().y() << ", z = " << jetVertex->position().z() << std::endl;
347  }
348 
349  return jetVertex;
350 }
351 
352 }}
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:44
const PFJetRef & jetRef() const
Definition: PFTau.cc:52
Coll filterCandRefs(const Coll &refcoll, bool invert=false) const
Filter a ref vector of PFCandidates.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
tuple trackPt
Definition: listHistos.py:120
reco::VertexRef associatedVertex(const PFJet &jet) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:137
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
void setEvent(const edm::Event &evt)
Load the vertices from the event.
reco::TrackBaseRef getLeadTrack(const PFJet &jet) const
Jets made from PFObjects.
Definition: PFJet.h:21
std::vector< reco::VertexRef > selectedVertices_
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:152
bool isNull() const
Checks for null.
Definition: Ref.h:247
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:139
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:22
void setPV(const reco::VertexRef &vtx) const
Update the primary vertex.
double pt() const
track transverse momentum
Definition: TrackBase.h:129
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:192
const double infinity
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
InputIterator leadPFCand(InputIterator begin, InputIterator end)
StringCutObjectSelector< reco::Vertex > * vertexSelector_
RecoTauVertexAssociator(const edm::ParameterSet &pset, edm::ConsumesCollector &&iC)
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:125
const PFTauTagInfoRef & pfTauTagInfoRef() const
Definition: PFTau.cc:55
ParameterSet const & getParameterSet(std::string const &) const
edm::EDGetTokenT< reco::VertexCollection > vxToken_
edm::EventID id() const
Definition: EventBase.h:56
bool isNull() const
Checks for null.
Definition: Ptr.h:148
std::vector< PFCandidatePtr > pfChargedCands(const PFJet &jet, bool sort=true)
Extract all non-neutral candidates from a PFJet.
tuple cout
Definition: gather_cfg.py:121
int weight
Definition: histoStyle.py:50
const reco::TrackBaseRef trk_
virtual float pt() const GCC11_FINAL
transverse momentum
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:279
std::map< const reco::PFJet *, reco::VertexRef > * jetToVertexAssociation_