CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RecoTauQualityCuts.cc
Go to the documentation of this file.
6 
7 #include <boost/bind.hpp>
8 
9 namespace reco { namespace tau {
10 
11 namespace {
12  // Get the KF track if it exists. Otherwise, see if PFCandidate has a GSF track.
13  const reco::TrackBaseRef getTrackRef(const PFCandidate& cand)
14  {
15  if ( cand.trackRef().isNonnull() ) return reco::TrackBaseRef(cand.trackRef());
16  else if ( cand.gsfTrackRef().isNonnull() ) return reco::TrackBaseRef(cand.gsfTrackRef());
17  else return reco::TrackBaseRef();
18  }
19 }
20 
21 // Quality cut implementations
22 namespace qcuts {
23 
24 bool ptMin(const TrackBaseRef& track, double cut)
25 {
26  //std::cout << "<ptMin>: Pt = " << track->pt() << ", cut = " << cut << std::endl;
27  return (track->pt() > cut);
28 }
29 
30 bool ptMin_cand(const PFCandidate& cand, double cut)
31 {
32  //std::cout << "<ptMin_cand>: Pt = " << cand.pt() << ", cut = " << cut << std::endl;
33  return (cand.pt() > cut);
34 }
35 
36 bool etMin_cand(const PFCandidate& cand, double cut)
37 {
38  //std::cout << "<etMin_cand>: Et = " << cand.et() << ", cut = " << cut << std::endl;
39  return (cand.et() > cut);
40 }
41 
42 bool trkPixelHits(const TrackBaseRef& track, int cut)
43 {
44  // For some reason, the number of hits is signed
45  //std::cout << "<trkPixelHits>: #Pxl hits = " << track->hitPattern().numberOfValidPixelHits() << ", cut = " << cut << std::endl;
46  return (track->hitPattern().numberOfValidPixelHits() >= cut);
47 }
48 
49 bool trkPixelHits_cand(const PFCandidate& cand, int cut)
50 {
51  // For some reason, the number of hits is signed
52  auto track = getTrackRef(cand);
53  if ( track.isNonnull() ) {
54  //std::cout << "<trkPixelHits_cand>: #Pxl hits = " << trkPixelHits(track, cut) << ", cut = " << cut << std::endl;
55  return trkPixelHits(track, cut);
56  } else {
57  //std::cout << "<trkPixelHits_cand>: #Pxl hits = N/A, cut = " << cut << std::endl;
58  return false;
59  }
60 }
61 
62 bool trkTrackerHits(const TrackBaseRef& track, int cut)
63 {
64  //std::cout << "<trkTrackerHits>: #Trk hits = " << track->hitPattern().numberOfValidHits() << ", cut = " << cut << std::endl;
65  return (track->hitPattern().numberOfValidHits() >= cut);
66 }
67 
68 bool trkTrackerHits_cand(const PFCandidate& cand, int cut)
69 {
70  auto track = getTrackRef(cand);
71  if ( track.isNonnull() ) {
72  //std::cout << "<trkTrackerHits>: #Trk hits = " << track->hitPattern().numberOfValidHits() << ", cut = " << cut << std::endl;
73  return trkTrackerHits(track, cut);
74  } else {
75  //std::cout << "<trkTrackerHits>: #Trk hits = N/A, cut = " << cut << std::endl;
76  return false;
77  }
78 }
79 
80 bool trkTransverseImpactParameter(const TrackBaseRef& track, const reco::VertexRef* pv, double cut)
81 {
82  if ( pv->isNull() ) {
83  edm::LogError("QCutsNoPrimaryVertex") << "Primary vertex Ref in " <<
84  "RecoTauQualityCuts is invalid. - trkTransverseImpactParameter";
85  return false;
86  }
87  //std::cout << "<trkTransverseImpactParameter>:" << std::endl;
88  //std::cout << " track: Pt = " << track->pt() << ", eta = " << track->eta() << ", phi = " << track->phi() << std::endl;
89  //std::cout << " vertex: x = " << (*pv)->position().x() << ", y = " << (*pv)->position().y() << ", z = " << (*pv)->position().z() << std::endl;
90  //std::cout << "--> dxy = " << std::fabs(track->dxy((*pv)->position())) << " (cut = " << cut << ")" << std::endl;
91  return (std::fabs(track->dxy((*pv)->position())) <= cut);
92 }
93 
95 {
96  auto track = getTrackRef(cand);
97  if ( track.isNonnull() ) {
98  return trkTransverseImpactParameter(track, pv, cut);
99  } else {
100  //std::cout << "<trkTransverseImpactParameter_cand>: dXY = N/A, cut = " << cut << std::endl;
101  return false;
102  }
103 }
104 
105 bool trkLongitudinalImpactParameter(const TrackBaseRef& track, const reco::VertexRef* pv, double cut)
106 {
107  if ( pv->isNull() ) {
108  edm::LogError("QCutsNoPrimaryVertex") << "Primary vertex Ref in " <<
109  "RecoTauQualityCuts is invalid. - trkLongitudinalImpactParameter";
110  return false;
111  }
112  //std::cout << "<trkLongitudinalImpactParameter>:" << std::endl;
113  //std::cout << " track: Pt = " << track->pt() << ", eta = " << track->eta() << ", phi = " << track->phi() << std::endl;
114  //std::cout << " vertex: x = " << (*pv)->position().x() << ", y = " << (*pv)->position().y() << ", z = " << (*pv)->position().z() << std::endl;
115  //std::cout << "--> dz = " << std::fabs(track->dz((*pv)->position())) << " (cut = " << cut << ")" << std::endl;
116  return (std::fabs(track->dz((*pv)->position())) <= cut);
117 }
118 
120 {
121  auto track = getTrackRef(cand);
122  if ( track.isNonnull() ) {
123  return trkLongitudinalImpactParameter(track, pv, cut);
124  } else {
125  //std::cout << "<trkLongitudinalImpactParameter_cand>: dZ = N/A, cut = " << cut << std::endl;
126  return false;
127  }
128 }
129 
132 {
133  if ( leadTrack->isNull()) {
134  edm::LogError("QCutsNoValidLeadTrack") << "Lead track Ref in " <<
135  "RecoTauQualityCuts is invalid. - trkLongitudinalImpactParameterWrtTrack";
136  return false;
137  }
138  return (std::fabs(track->dz((*pv)->position()) - (*leadTrack)->dz((*pv)->position())) <= cut);
139 }
140 
142 {
143  auto track = getTrackRef(cand);
144  if ( track.isNonnull() ) return trkLongitudinalImpactParameterWrtTrack(track, leadTrack, pv, cut);
145  else return false;
146 }
147 
148 bool minTrackVertexWeight(const TrackBaseRef& track, const reco::VertexRef* pv, double cut)
149 {
150  if ( pv->isNull() ) {
151  edm::LogError("QCutsNoPrimaryVertex") << "Primary vertex Ref in " <<
152  "RecoTauQualityCuts is invalid. - minTrackVertexWeight";
153  return false;
154  }
155  //std::cout << "<minTrackVertexWeight>:" << std::endl;
156  //std::cout << " track: Pt = " << track->pt() << ", eta = " << track->eta() << ", phi = " << track->phi() << std::endl;
157  //std::cout << " vertex: x = " << (*pv)->position().x() << ", y = " << (*pv)->position().y() << ", z = " << (*pv)->position().z() << std::endl;
158  //std::cout << "--> trackWeight = " << (*pv)->trackWeight(track) << " (cut = " << cut << ")" << std::endl;
159  return ((*pv)->trackWeight(track) >= cut);
160 }
161 
162 bool minTrackVertexWeight_cand(const PFCandidate& cand, const reco::VertexRef* pv, double cut)
163 {
164  auto track = getTrackRef(cand);
165  if ( track.isNonnull() ) {
166  return minTrackVertexWeight(track, pv, cut);
167  } else {
168  //std::cout << "<minTrackVertexWeight_cand>: weight = N/A, cut = " << cut << std::endl;
169  return false;
170  }
171 }
172 
173 bool trkChi2(const TrackBaseRef& track, double cut)
174 {
175  //std::cout << "<trkChi2>: chi^2 = " << track->normalizedChi2() << ", cut = " << cut << std::endl;
176  return (track->normalizedChi2() <= cut);
177 }
178 
179 bool trkChi2_cand(const PFCandidate& cand, double cut)
180 {
181  auto track = getTrackRef(cand);
182  if ( track.isNonnull() ) {
183  //std::cout << "<trkChi2_cand>: chi^2 = " << track->normalizedChi2() << ", cut = " << cut << std::endl;
184  return trkChi2(track, cut);
185  } else {
186  //std::cout << "<trkChi2_cand>: chi^2 = N/A, cut = " << cut << std::endl;
187  return false;
188  }
189 }
190 
191 // And a set of qcuts
193 {
194  BOOST_FOREACH( const RecoTauQualityCuts::TrackQCutFunc& func, cuts ) {
195  if ( !func(track) ) return false;
196  }
197  return true;
198 }
199 
201 {
202  BOOST_FOREACH( const RecoTauQualityCuts::CandQCutFunc& func, cuts ) {
203  if ( !func(cand) ) return false;
204  }
205  return true;
206 }
207 
208 // Get the set of Q cuts for a given type (i.e. gamma)
210 {
211  // Find the cuts that for this particle type
212  RecoTauQualityCuts::CandQCutFuncMap::const_iterator cuts = funcMap.find(cand.particleId());
213  // Return false if we dont' know how to deal with this particle type
214  if ( cuts == funcMap.end() ) return false;
215  return AND_cand(cand, cuts->second); // Otherwise AND all the cuts
216 }
217 
218 } // end qcuts implementation namespace
219 
221 {
222  // Setup all of our predicates
223  CandQCutFuncCollection chargedHadronCuts;
224  CandQCutFuncCollection gammaCuts;
225  CandQCutFuncCollection neutralHadronCuts;
226 
227  // Make sure there are no extra passed options
228  std::set<std::string> passedOptionSet;
229  std::vector<std::string> passedOptions = qcuts.getParameterNames();
230 
231  BOOST_FOREACH(const std::string& option, passedOptions) {
232  passedOptionSet.insert(option);
233  }
234 
235  // Build all the QCuts for tracks
236  if ( qcuts.exists("minTrackPt") ) {
237  trackQCuts_.push_back(boost::bind(qcuts::ptMin, _1, qcuts.getParameter<double>("minTrackPt")));
238  passedOptionSet.erase("minTrackPt");
239  }
240 
241  if ( qcuts.exists("maxTrackChi2") ) {
242  trackQCuts_.push_back(boost::bind(qcuts::trkChi2, _1, qcuts.getParameter<double>("maxTrackChi2")));
243  passedOptionSet.erase("maxTrackChi2");
244  }
245 
246  if ( qcuts.exists("minTrackPixelHits") ) {
247  uint32_t minTrackPixelHits = qcuts.getParameter<uint32_t>("minTrackPixelHits");
248  if ( minTrackPixelHits >= 1 ) {
249  trackQCuts_.push_back(boost::bind(qcuts::trkPixelHits, _1, minTrackPixelHits));
250  }
251  passedOptionSet.erase("minTrackPixelHits");
252  }
253 
254  if ( qcuts.exists("minTrackHits") ) {
255  uint32_t minTrackHits = qcuts.getParameter<uint32_t>("minTrackHits");
256  if ( minTrackHits >= 1 ) {
257  trackQCuts_.push_back(boost::bind(qcuts::trkTrackerHits, _1, minTrackHits));
258  }
259  passedOptionSet.erase("minTrackHits");
260  }
261 
262  // The impact parameter functions are bound to our member PV, since they
263  // need it to compute the discriminant value.
264  if ( qcuts.exists("maxTransverseImpactParameter") ) {
265  trackQCuts_.push_back(boost::bind(qcuts::trkTransverseImpactParameter, _1, &pv_, qcuts.getParameter<double>("maxTransverseImpactParameter")));
266  passedOptionSet.erase("maxTransverseImpactParameter");
267  }
268 
269  if ( qcuts.exists("maxDeltaZ") ) {
270  trackQCuts_.push_back(boost::bind(qcuts::trkLongitudinalImpactParameter, _1, &pv_, qcuts.getParameter<double>("maxDeltaZ")));
271  passedOptionSet.erase("maxDeltaZ");
272  }
273 
274  if ( qcuts.exists("maxDeltaZToLeadTrack") ) {
275  trackQCuts_.push_back(boost::bind(qcuts::trkLongitudinalImpactParameterWrtTrack, _1, &leadTrack_, &pv_, qcuts.getParameter<double>("maxDeltaZToLeadTrack")));
276  passedOptionSet.erase("maxDeltaZToLeadTrack");
277  }
278 
279  // Require tracks to contribute a minimum weight to the associated vertex.
280  if ( qcuts.exists("minTrackVertexWeight") ) {
281  double minTrackVertexWeight = qcuts.getParameter<double>("minTrackVertexWeight");
282  if ( minTrackVertexWeight > -1. ) {
283  trackQCuts_.push_back(boost::bind(qcuts::minTrackVertexWeight, _1, &pv_, minTrackVertexWeight));
284  }
285  passedOptionSet.erase("minTrackVertexWeight");
286  }
287 
288  // Build the QCuts for gammas
289  if ( qcuts.exists("minGammaEt") ) {
290  gammaCuts.push_back(boost::bind(qcuts::etMin_cand, _1, qcuts.getParameter<double>("minGammaEt")));
291  passedOptionSet.erase("minGammaEt");
292  }
293 
294  // Build QCuts for netural hadrons
295  if ( qcuts.exists("minNeutralHadronEt") ) {
296  neutralHadronCuts.push_back(boost::bind(qcuts::etMin_cand, _1, qcuts.getParameter<double>("minNeutralHadronEt")));
297  passedOptionSet.erase("minNeutralHadronEt");
298  }
299 
300  // Check if there are any remaining unparsed QCuts
301  if ( passedOptionSet.size() ) {
302  std::string unParsedOptions;
303  bool thereIsABadParameter = false;
304  BOOST_FOREACH( const std::string& option, passedOptionSet ) {
305  // Workaround for HLT - TODO FIXME
306  if ( option == "useTracksInsteadOfPFHadrons" ) {
307  // Crash if true - no one should have this option enabled.
308  if ( qcuts.getParameter<bool>("useTracksInsteadOfPFHadrons") ) {
309  throw cms::Exception("DontUseTracksInQcuts")
310  << "The obsolete exception useTracksInsteadOfPFHadrons "
311  << "is set to true in the quality cut config." << std::endl;
312  }
313  continue;
314  }
315 
316  // If we get to this point, there is a real unknown parameter
317  thereIsABadParameter = true;
318 
319  unParsedOptions += option;
320  unParsedOptions += "\n";
321  }
322  if ( thereIsABadParameter ) {
323  throw cms::Exception("BadQualityCutConfig")
324  << " The PSet passed to the RecoTauQualityCuts class had"
325  << " the following unrecognized options: " << std::endl
326  << unParsedOptions;
327  }
328  }
329 
330  // Make sure there are at least some quality cuts
331  size_t nCuts = chargedHadronCuts.size() + gammaCuts.size() + neutralHadronCuts.size() + trackQCuts_.size();
332  if ( !nCuts ) {
333  throw cms::Exception("BadQualityCutConfig")
334  << " No options were passed to the quality cut class!" << std::endl;
335  }
336 
337  // Build final level predicate that works on Tracks
338  trackPredicate_ = boost::bind(qcuts::AND, _1, boost::cref(trackQCuts_));
339 
340  // Map our QCut collections to the particle Ids they are associated to.
341  candQCuts_[PFCandidate::h] = chargedHadronCuts;
342  candQCuts_[PFCandidate::gamma] = gammaCuts;
343  candQCuts_[PFCandidate::h0] = neutralHadronCuts;
344  // We use the same qcuts for muons/electrons and charged hadrons.
345  candQCuts_[PFCandidate::e] = chargedHadronCuts;
346  candQCuts_[PFCandidate::mu] = chargedHadronCuts;
347 
348  // Build a final level predicate that works on any PFCand
349  candPredicate_ = boost::bind(qcuts::mapAndCutByType, _1, boost::cref(candQCuts_));
350 }
351 
352 std::pair<edm::ParameterSet, edm::ParameterSet> factorizePUQCuts(const edm::ParameterSet& input)
353 {
354  edm::ParameterSet puCuts;
355  edm::ParameterSet nonPUCuts;
356 
357  std::vector<std::string> inputNames = input.getParameterNames();
358  BOOST_FOREACH( const std::string& cut, inputNames ) {
359  if ( cut == "minTrackVertexWeight" ||
360  cut == "maxDeltaZ" ||
361  cut == "maxDeltaZToLeadTrack" ) {
362  puCuts.copyFrom(input, cut);
363  } else {
364  nonPUCuts.copyFrom(input, cut);
365  }
366  }
367  return std::make_pair(puCuts, nonPUCuts);
368 }
369 
371 {
372  return trackPredicate_(track);
373 }
374 
376 {
377  auto track = getTrackRef(cand);
378  if ( track.isNonnull() ) return (trackPredicate_(track) & candPredicate_(cand));
379  return candPredicate_(cand);
380 }
381 
383 {
384  leadTrack_ = reco::TrackBaseRef(leadTrack);
385 }
386 
388 {
389  leadTrack_ = getTrackRef(leadCand);
390 }
391 
393 {
394  if ( leadCand.isNonnull() ) {
395  leadTrack_ = getTrackRef(*leadCand);
396  } else {
397  // Set null
399  }
400 }
401 
402 }} // end namespace reco::tau
T getParameter(std::string const &) const
TrackQCutFuncCollection trackQCuts_
virtual double et() const GCC11_FINAL
transverse energy
bool trkLongitudinalImpactParameter_cand(const PFCandidate &cand, const reco::VertexRef *pv, double cut)
bool minTrackVertexWeight(const TrackBaseRef &track, const reco::VertexRef *pv, double cut)
bool trkTransverseImpactParameter_cand(const PFCandidate &cand, const reco::VertexRef *pv, double cut)
RecoTauQualityCuts(const edm::ParameterSet &qcuts)
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:109
bool minTrackVertexWeight_cand(const PFCandidate &cand, const reco::VertexRef *pv, double cut)
int numberOfValidHits() const
Definition: HitPattern.h:582
bool exists(std::string const &parameterName) const
checks if a parameter exists
bool etMin_cand(const PFCandidate &cand, double cut)
bool trkPixelHits(const TrackBaseRef &track, int cut)
bool trkTransverseImpactParameter(const TrackBaseRef &track, const reco::VertexRef *pv, double cut)
static std::string const input
Definition: EdmProvDump.cc:44
std::vector< CandQCutFunc > CandQCutFuncCollection
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
void copyFrom(ParameterSet const &from, std::string const &name)
bool isNull() const
Checks for null.
Definition: Ref.h:247
bool trkLongitudinalImpactParameterWrtTrack_cand(const PFCandidate &cand, const reco::TrackBaseRef *leadTrack, const reco::VertexRef *pv, double cut)
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:22
std::map< PFCandidate::ParticleType, CandQCutFuncCollection > CandQCutFuncMap
double pt() const
track transverse momentum
Definition: TrackBase.h:129
std::pair< edm::ParameterSet, edm::ParameterSet > factorizePUQCuts(const edm::ParameterSet &inputSet)
std::vector< TrackQCutFunc > TrackQCutFuncCollection
std::vector< std::string > getParameterNames() const
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:221
bool ptMin(const TrackBaseRef &track, double cut)
bool trkTrackerHits(const TrackBaseRef &track, int cut)
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
bool trkTrackerHits_cand(const PFCandidate &cand, int cut)
bool mapAndCutByType(const PFCandidate &cand, const RecoTauQualityCuts::CandQCutFuncMap &funcMap)
boost::function< bool(const TrackBaseRef &)> TrackQCutFunc
bool ptMin_cand(const PFCandidate &cand, double cut)
bool trkChi2_cand(const PFCandidate &cand, double cut)
boost::function< bool(const PFCandidate &)> CandQCutFunc
bool trkChi2(const TrackBaseRef &track, double cut)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
bool AND(const TrackBaseRef &track, const RecoTauQualityCuts::TrackQCutFuncCollection &cuts)
bool trkLongitudinalImpactParameter(const TrackBaseRef &track, const reco::VertexRef *pv, double cut)
bool trkPixelHits_cand(const PFCandidate &cand, int cut)
string func
Definition: statics.py:48
int numberOfValidPixelHits() const
Definition: HitPattern.h:594
void setLeadTrack(const reco::TrackRef &leadTrack) const
Update the leading track.
bool trkLongitudinalImpactParameterWrtTrack(const TrackBaseRef &track, const reco::TrackBaseRef *leadTrack, const reco::VertexRef *pv, double cut)
DZ cut, with respect to the current lead rack.
bool filterCand(const reco::PFCandidate &cand) const
Filter a single PFCandidate.
virtual ParticleType particleId() const
Definition: PFCandidate.h:355
virtual float pt() const GCC11_FINAL
transverse momentum
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:119
bool AND_cand(const PFCandidate &cand, const RecoTauQualityCuts::CandQCutFuncCollection &cuts)
bool filterTrack(const reco::TrackBaseRef &track) const
Filter a single Track.