CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauDiscriminationByIsolation.cc
Go to the documentation of this file.
1 #include <functional>
2 #include <boost/foreach.hpp>
9 
10 #include "TMath.h"
11 #include "TFormula.h"
12 
13 /* class PFRecoTauDiscriminationByIsolation
14  * created : Jul 23 2007,
15  * revised : Thu Aug 13 14:44:40 PDT 2009
16  * contributors : Ludovic Houchu (IPHC, Strasbourg),
17  * Christian Veelken (UC Davis),
18 * Evan K. Friis (UC Davis)
19  * Michalis Bachtis (UW Madison)
20  */
21 
22 using namespace reco;
23 using namespace std;
24 
27  public:
30  qualityCutsPSet_(pset.getParameter<edm::ParameterSet>("qualityCuts")) {
31 
32  includeTracks_ = pset.getParameter<bool>(
33  "ApplyDiscriminationByTrackerIsolation");
34  includeGammas_ = pset.getParameter<bool>(
35  "ApplyDiscriminationByECALIsolation");
36 
37  applyOccupancyCut_ = pset.getParameter<bool>("applyOccupancyCut");
38  maximumOccupancy_ = pset.getParameter<uint32_t>("maximumOccupancy");
39 
40  applySumPtCut_ = pset.getParameter<bool>("applySumPtCut");
41  maximumSumPt_ = pset.getParameter<double>("maximumSumPtCut");
42 
43  applyRelativeSumPtCut_ = pset.getParameter<bool>(
44  "applyRelativeSumPtCut");
45  maximumRelativeSumPt_ = pset.getParameter<double>(
46  "relativeSumPtCut");
47 
48  storeRawOccupancy_ = pset.exists("storeRawOccupancy") ?
49  pset.getParameter<bool>("storeRawOccupancy") : false;
50  storeRawSumPt_ = pset.exists("storeRawSumPt") ?
51  pset.getParameter<bool>("storeRawSumPt") : false;
52 
53  // Sanity check on requested options. We can't apply cuts and store the
54  // raw output at the same time
55  if (applySumPtCut_ || applyOccupancyCut_ || applyRelativeSumPtCut_) {
56  if (storeRawSumPt_ || storeRawOccupancy_) {
57  throw cms::Exception("BadIsoConfig") <<
58  "A 'store raw' and a 'apply cut' option have been set to true "
59  << "simultaneously. These options are mutually exclusive.";
60  }
61  }
62 
63  // Can only store one type
64  if (storeRawSumPt_ && storeRawOccupancy_) {
65  throw cms::Exception("BadIsoConfig") <<
66  "Both 'store sum pt' and 'store occupancy' options are set."
67  << " These options are mutually exclusive.";
68  }
69 
70  if (pset.exists("customOuterCone")) {
71  customIsoCone_ = pset.getParameter<double>("customOuterCone");
72  } else {
73  customIsoCone_ = -1;
74  }
75 
76  // Get the quality cuts specific to the isolation region
77  edm::ParameterSet isolationQCuts = qualityCutsPSet_.getParameterSet(
78  "isolationQualityCuts");
79 
80  qcuts_.reset(new tau::RecoTauQualityCuts(isolationQCuts));
81 
82  vertexAssociator_.reset(
83  new tau::RecoTauVertexAssociator(qualityCutsPSet_));
84 
85  applyDeltaBeta_ = pset.exists("applyDeltaBetaCorrection") ?
86  pset.getParameter<bool>("applyDeltaBetaCorrection") : false;
87 
88  if (applyDeltaBeta_) {
89  // Factorize the isolation QCuts into those that are used to
90  // select PU and those that are not.
91  std::pair<edm::ParameterSet, edm::ParameterSet> puFactorizedIsoQCuts =
92  reco::tau::factorizePUQCuts(isolationQCuts);
93 
94  // Determine the pt threshold for the PU tracks
95  // First check if the user specifies explicitly the cut.
96  if (pset.exists("deltaBetaPUTrackPtCutOverride")) {
97  puFactorizedIsoQCuts.second.addParameter<double>(
98  "minTrackPt",
99  pset.getParameter<double>("deltaBetaPUTrackPtCutOverride"));
100  } else {
101  // Secondly take it from the minGammaEt
102  puFactorizedIsoQCuts.second.addParameter<double>(
103  "minTrackPt",
104  isolationQCuts.getParameter<double>("minGammaEt"));
105  }
106 
107  pileupQcutsPUTrackSelection_.reset(new tau::RecoTauQualityCuts(
108  puFactorizedIsoQCuts.first));
109 
110  pileupQcutsGeneralQCuts_.reset(new tau::RecoTauQualityCuts(
111  puFactorizedIsoQCuts.second));
112 
113  pfCandSrc_ = pset.getParameter<edm::InputTag>("particleFlowSrc");
114  vertexSrc_ = pset.getParameter<edm::InputTag>("vertexSrc");
115  deltaBetaCollectionCone_ = pset.getParameter<double>(
116  "isoConeSizeForDeltaBeta");
117  std::string deltaBetaFactorFormula =
118  pset.getParameter<string>("deltaBetaFactor");
119  deltaBetaFormula_.reset(
120  new TFormula("DB_corr", deltaBetaFactorFormula.c_str()));
121  }
122 
123  applyRhoCorrection_ = pset.exists("applyRhoCorrection") ?
124  pset.getParameter<bool>("applyRhoCorrection") : false;
125  if (applyRhoCorrection_) {
126  rhoProducer_ = pset.getParameter<edm::InputTag>("rhoProducer");
127  rhoConeSize_ = pset.getParameter<double>("rhoConeSize");
128  rhoUEOffsetCorrection_ =
129  pset.getParameter<double>("rhoUEOffsetCorrection");
130  }
131  }
132 
134 
135  void beginEvent(const edm::Event& evt, const edm::EventSetup& evtSetup);
136  double discriminate(const PFTauRef& pfTau);
137 
138  private:
140  std::auto_ptr<tau::RecoTauQualityCuts> qcuts_;
141 
142  // Inverted QCut which selects tracks with bad DZ/trackWeight
143  std::auto_ptr<tau::RecoTauQualityCuts> pileupQcutsPUTrackSelection_;
144  std::auto_ptr<tau::RecoTauQualityCuts> pileupQcutsGeneralQCuts_;
145 
146  std::auto_ptr<tau::RecoTauVertexAssociator> vertexAssociator_;
147 
157 
158  // Options to store the raw value in the discriminator instead of
159  // boolean float
162 
163  /* **********************************************************************
164  **** Pileup Subtraction Parameters ***********************************
165  **********************************************************************/
166 
167  // Delta Beta correction
170  // Keep track of how many vertices are in the event
172  std::vector<reco::PFCandidateRef> chargedPFCandidatesInEvent_;
173  // Size of cone used to collect PU tracks
175  std::auto_ptr<TFormula> deltaBetaFormula_;
177 
178  // Rho correction
181  double rhoConeSize_;
185  };
186 
188  const edm::EventSetup& eventSetup) {
189 
190  // NB: The use of the PV in this context is necessitated by its use in
191  // applying quality cuts to the different objects in the isolation cone
192  // The vertex associator contains the logic to select the appropriate vertex
193  // We need to pass it the event so it can load the vertices.
194  vertexAssociator_->setEvent(event);
195 
196  // If we are applying the delta beta correction, we need to get the PF
197  // candidates from the event so we can find the PU tracks.
198  chargedPFCandidatesInEvent_.clear();
199  if (applyDeltaBeta_) {
200  // Collect all the PF pile up tracks
202  event.getByLabel(pfCandSrc_, pfCandHandle_);
203  chargedPFCandidatesInEvent_.reserve(pfCandHandle_->size());
204  for (size_t i = 0; i < pfCandHandle_->size(); ++i) {
205  reco::PFCandidateRef pfCand(pfCandHandle_, i);
206  if (pfCand->charge() != 0)
207  chargedPFCandidatesInEvent_.push_back(pfCand);
208  }
209  // Count all the vertices in the event, to parameterize the DB
210  // correction factor
212  event.getByLabel(vertexSrc_, vertices);
213  size_t nVtxThisEvent = vertices->size();
214  deltaBetaFactorThisEvent_ = deltaBetaFormula_->Eval(nVtxThisEvent);
215  }
216 
217  if (applyRhoCorrection_) {
218  edm::Handle<double> rhoHandle_;
219  event.getByLabel(rhoProducer_, rhoHandle_);
220  rhoThisEvent_ = (*rhoHandle_ - rhoUEOffsetCorrection_)*
221  (3.14159)*rhoConeSize_*rhoConeSize_;
222  }
223 }
224 
225 double
227  // collect the objects we are working with (ie tracks, tracks+gammas, etc)
228  std::vector<PFCandidateRef> isoCharged;
229  std::vector<PFCandidateRef> isoNeutral;
230  std::vector<PFCandidateRef> isoPU;
231 
232  // Get the primary vertex associated to this tau
233  reco::VertexRef pv = vertexAssociator_->associatedVertex(*pfTau);
234  // Let the quality cuts know which the vertex to use when applying selections
235  // on dz, etc.
236  qcuts_->setPV(pv);
237  qcuts_->setLeadTrack(pfTau->leadPFChargedHadrCand());
238  if (applyDeltaBeta_) {
239  pileupQcutsGeneralQCuts_->setPV(pv);
240  pileupQcutsGeneralQCuts_->setLeadTrack(pfTau->leadPFChargedHadrCand());
241  pileupQcutsPUTrackSelection_->setPV(pv);
242  pileupQcutsPUTrackSelection_->setLeadTrack(pfTau->leadPFChargedHadrCand());
243  }
244  // Load the tracks if they are being used.
245  if (includeTracks_) {
246  BOOST_FOREACH(const reco::PFCandidateRef& cand,
247  pfTau->isolationPFChargedHadrCands()) {
248  if (qcuts_->filterRef(cand))
249  isoCharged.push_back(cand);
250  }
251  }
252 
253  if (includeGammas_) {
254  BOOST_FOREACH(const reco::PFCandidateRef& cand,
255  pfTau->isolationPFGammaCands()) {
256  if (qcuts_->filterRef(cand))
257  isoNeutral.push_back(cand);
258  }
259  }
261 
262  // If desired, get PU tracks.
263  if (applyDeltaBeta_) {
264  // First select by inverted the DZ/track weight cuts. True = invert
265  //std::cout << "Initial PFCands: " << chargedPFCandidatesInEvent_.size()
266  // << std::endl;
267 
268  std::vector<PFCandidateRef> allPU =
269  pileupQcutsPUTrackSelection_->filterRefs(
270  chargedPFCandidatesInEvent_, true);
271 
272  //std::cout << "After track cuts: " << allPU.size() << std::endl;
273 
274  // Now apply the rest of the cuts, like pt, and TIP, tracker hits, etc
275  std::vector<PFCandidateRef> cleanPU =
276  pileupQcutsGeneralQCuts_->filterRefs(allPU);
277 
278  //std::cout << "After cleaning cuts: " << cleanPU.size() << std::endl;
279 
280  // Only select PU tracks inside the isolation cone.
281  DRFilter deltaBetaFilter(pfTau->p4(), 0, deltaBetaCollectionCone_);
282  BOOST_FOREACH(const reco::PFCandidateRef& cand, cleanPU) {
283  if (deltaBetaFilter(cand)) {
284  isoPU.push_back(cand);
285  }
286  }
287  //std::cout << "After cone cuts: " << isoPU.size() << std::endl;
288  }
289 
290  // Check if we want a custom iso cone
291  if (customIsoCone_ >= 0.) {
292  DRFilter filter(pfTau->p4(), 0, customIsoCone_);
293  std::vector<PFCandidateRef> isoCharged_filter;
294  std::vector<PFCandidateRef> isoNeutral_filter;
295  // Remove all the objects not in our iso cone
296  BOOST_FOREACH(const PFCandidateRef& isoObject, isoCharged) {
297  if(filter(isoObject)) isoCharged_filter.push_back(isoObject);
298  }
299  BOOST_FOREACH(const PFCandidateRef& isoObject, isoNeutral) {
300  if(filter(isoObject)) isoNeutral_filter.push_back(isoObject);
301  }
302  isoCharged.clear();
303  isoCharged=isoCharged_filter;
304  isoNeutral.clear();
305  isoNeutral=isoNeutral_filter;
306 
307  }
308 
309  bool failsOccupancyCut = false;
310  bool failsSumPtCut = false;
311  bool failsRelativeSumPtCut = false;
312 
313  //--- nObjects requirement
314  int neutrals = isoNeutral.size();
315 
316  if (applyDeltaBeta_) {
317  neutrals -= TMath::Nint(deltaBetaFactorThisEvent_*isoPU.size());
318  }
319  if(neutrals < 0) {
320  neutrals=0;
321  }
322 
323  size_t nOccupants = isoCharged.size() + neutrals;
324 
325  failsOccupancyCut = ( nOccupants > maximumOccupancy_ );
326 
327  double totalPt=0.0;
328  //--- Sum PT requirement
329  if( applySumPtCut_ || applyRelativeSumPtCut_ || storeRawSumPt_) {
330  double chargedPt=0.0;
331  double puPt=0.0;
332  double neutralPt=0.0;
333  BOOST_FOREACH(const PFCandidateRef& isoObject, isoCharged) {
334  chargedPt += isoObject->pt();
335  }
336  BOOST_FOREACH(const PFCandidateRef& isoObject, isoNeutral) {
337  neutralPt += isoObject->pt();
338  }
339  BOOST_FOREACH(const PFCandidateRef& isoObject, isoPU) {
340  puPt += isoObject->pt();
341  }
342 
343  if (applyDeltaBeta_) {
344  neutralPt -= deltaBetaFactorThisEvent_*puPt;
345  }
346 
347  if (applyRhoCorrection_) {
348  neutralPt -= rhoThisEvent_;
349  }
350 
351  if (neutralPt < 0.0) {
352  neutralPt = 0.0;
353  }
354 
355  totalPt = chargedPt+neutralPt;
356 
357  failsSumPtCut = (totalPt > maximumSumPt_);
358 
359  //--- Relative Sum PT requirement
360  failsRelativeSumPtCut = (
361  (pfTau->pt() > 0 ? totalPt/pfTau->pt() : 0 ) > maximumRelativeSumPt_ );
362  }
363 
364  bool fails = (applyOccupancyCut_ && failsOccupancyCut) ||
365  (applySumPtCut_ && failsSumPtCut) ||
366  (applyRelativeSumPtCut_ && failsRelativeSumPtCut);
367 
368  // We did error checking in the constructor, so this is safe.
369  if (storeRawSumPt_)
370  return totalPt;
371  else if (storeRawOccupancy_)
372  return nOccupants;
373  else
374  return (fails ? 0. : 1.);
375 }
376 
PFRecoTauDiscriminationByIsolation(const edm::ParameterSet &pset)
std::vector< reco::PFCandidateRef > chargedPFCandidatesInEvent_
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
std::auto_ptr< tau::RecoTauQualityCuts > pileupQcutsGeneralQCuts_
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::pair< edm::ParameterSet, edm::ParameterSet > factorizePUQCuts(const edm::ParameterSet &inputSet)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
void beginEvent(const edm::Event &evt, const edm::EventSetup &evtSetup)
std::auto_ptr< tau::RecoTauQualityCuts > qcuts_
std::auto_ptr< tau::RecoTauQualityCuts > pileupQcutsPUTrackSelection_
DEFINE_FWK_MODULE(CosmicTrackingParticleSelector)
ParameterSet const & getParameterSet(std::string const &) const
std::auto_ptr< tau::RecoTauVertexAssociator > vertexAssociator_