CMS 3D CMS Logo

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