CMS 3D CMS Logo

PFRecoTauDiscriminationAgainstMuon2.cc
Go to the documentation of this file.
1 
11 
13 
16 
26 
28 
29 #include <vector>
30 #include <string>
31 #include <iostream>
32 
34 
35 namespace {
36 
37 class PFRecoTauDiscriminationAgainstMuon2 final : public PFTauDiscriminationProducerBase
38 {
39  enum { kLoose, kMedium, kTight, kCustom };
40  public:
41  explicit PFRecoTauDiscriminationAgainstMuon2(const edm::ParameterSet& cfg)
43  moduleLabel_(cfg.getParameter<std::string>("@module_label"))
44  {
45  std::string discriminatorOption_string = cfg.getParameter<std::string>("discriminatorOption");
46  if ( discriminatorOption_string == "loose" ) discriminatorOption_ = kLoose;
47  else if ( discriminatorOption_string == "medium" ) discriminatorOption_ = kMedium;
48  else if ( discriminatorOption_string == "tight" ) discriminatorOption_ = kTight;
49  else if ( discriminatorOption_string == "custom" ) discriminatorOption_ = kCustom;
51  << " Invalid Configuration parameter 'discriminatorOption' = " << discriminatorOption_string << " !!\n";
52  hop_ = cfg.getParameter<double>("HoPMin");
53  maxNumberOfMatches_ = cfg.getParameter<int>("maxNumberOfMatches");
54  doCaloMuonVeto_ = cfg.getParameter<bool>("doCaloMuonVeto");
55  maxNumberOfHitsLast2Stations_ = cfg.getParameter<int>("maxNumberOfHitsLast2Stations");
56  srcMuons_ = cfg.getParameter<edm::InputTag>("srcMuons");
57  Muons_token = consumes<reco::MuonCollection>(srcMuons_);
58  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
59  dRmuonMatchLimitedToJetArea_ = cfg.getParameter<bool>("dRmuonMatchLimitedToJetArea");
60  minPtMatchedMuon_ = cfg.getParameter<double>("minPtMatchedMuon");
61  typedef std::vector<int> vint;
62  maskMatchesDT_ = cfg.getParameter<vint>("maskMatchesDT");
63  maskMatchesCSC_ = cfg.getParameter<vint>("maskMatchesCSC");
64  maskMatchesRPC_ = cfg.getParameter<vint>("maskMatchesRPC");
65  maskHitsDT_ = cfg.getParameter<vint>("maskHitsDT");
66  maskHitsCSC_ = cfg.getParameter<vint>("maskHitsCSC");
67  maskHitsRPC_ = cfg.getParameter<vint>("maskHitsRPC");
68  numWarnings_ = 0;
69  maxWarnings_ = 3;
70  verbosity_ = cfg.getParameter<int>("verbosity");
71  }
72  ~PFRecoTauDiscriminationAgainstMuon2() override {}
73 
74  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
75 
76  double discriminate(const reco::PFTauRef&) const override;
77 
78  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
79 
80  private:
82  int discriminatorOption_;
83  double hop_;
84  int maxNumberOfMatches_;
85  bool doCaloMuonVeto_;
86  int maxNumberOfHitsLast2Stations_;
87  edm::InputTag srcMuons_;
90  double dRmuonMatch_;
91  bool dRmuonMatchLimitedToJetArea_;
92  double minPtMatchedMuon_;
93  std::vector<int> maskMatchesDT_;
94  std::vector<int> maskMatchesCSC_;
95  std::vector<int> maskMatchesRPC_;
96  std::vector<int> maskHitsDT_;
97  std::vector<int> maskHitsCSC_;
98  std::vector<int> maskHitsRPC_;
99  mutable int numWarnings_;
100  int maxWarnings_;
101  int verbosity_;
102 };
103 
105 {
106  if ( !srcMuons_.label().empty() ) {
107  evt.getByToken(Muons_token, muons_);
108  }
109 }
110 
112 {
113  if ( verbosity_ ) {
114  edm::LogPrint("PFTauAgainstMuon2") << "<PFRecoTauDiscriminationAgainstMuon2::discriminate>:" ;
115  edm::LogPrint("PFTauAgainstMuon2") << " moduleLabel = " << moduleLabel_ ;
116  edm::LogPrint("PFTauAgainstMuon2") << "tau #" << pfTau.key() << ": Pt = " << pfTau->pt() << ", eta = " << pfTau->eta() << ", phi = " << pfTau->phi() ;
117  }
118 
119  std::vector<int> numMatchesDT(4);
120  std::vector<int> numMatchesCSC(4);
121  std::vector<int> numMatchesRPC(4);
122  std::vector<int> numHitsDT(4);
123  std::vector<int> numHitsCSC(4);
124  std::vector<int> numHitsRPC(4);
125  for ( int iStation = 0; iStation < 4; ++iStation ) {
126  numMatchesDT[iStation] = 0;
127  numMatchesCSC[iStation] = 0;
128  numMatchesRPC[iStation] = 0;
129  numHitsDT[iStation] = 0;
130  numHitsCSC[iStation] = 0;
131  numHitsRPC[iStation] = 0;
132  }
133 
134  const reco::PFCandidatePtr& pfLeadChargedHadron = pfTau->leadPFChargedHadrCand();
135  if ( pfLeadChargedHadron.isNonnull() ) {
136  reco::MuonRef muonRef = pfLeadChargedHadron->muonRef();
137  if ( muonRef.isNonnull() ) {
138  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuon2") << " has muonRef." ;
139  reco::tau::countMatches(*muonRef, numMatchesDT, numMatchesCSC, numMatchesRPC);
140  reco::tau::countHits(*muonRef, numHitsDT, numHitsCSC, numHitsRPC);
141  }
142  }
143 
144  if ( !srcMuons_.label().empty() ) {
145  size_t numMuons = muons_->size();
146  for ( size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon ) {
147  reco::MuonRef muon(muons_, idxMuon);
148  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuon2") << "muon #" << muon.key() << ": Pt = " << muon->pt() << ", eta = " << muon->eta() << ", phi = " << muon->phi() ;
149  if ( !(muon->pt() > minPtMatchedMuon_) ) {
150  if ( verbosity_ ){ edm::LogPrint("PFTauAgainstMuon2") << " fails Pt cut --> skipping it." ;}
151  continue;
152  }
153  if ( pfLeadChargedHadron.isNonnull()) {
154  reco::MuonRef muonRef = pfLeadChargedHadron->muonRef();
155  if (muonRef.isNonnull() && muon == pfLeadChargedHadron->muonRef() ) {
156  if ( verbosity_ ) { edm::LogPrint("PFTauAgainstMuon2") << " matches muonRef of tau --> skipping it."; }
157  continue;
158  }
159  }
160  double dR = deltaR(muon->p4(), pfTau->p4());
161  double dRmatch = dRmuonMatch_;
162  if ( dRmuonMatchLimitedToJetArea_ ) {
163  double jetArea = 0.;
164  if ( pfTau->jetRef().isNonnull() ) jetArea = pfTau->jetRef()->jetArea();
165  if ( jetArea > 0. ) {
166  dRmatch = TMath::Min(dRmatch, TMath::Sqrt(jetArea/TMath::Pi()));
167  } else {
168  if ( numWarnings_ < maxWarnings_ ) {
169  edm::LogInfo("PFRecoTauDiscriminationAgainstMuon2::discriminate")
170  << "Jet associated to Tau: Pt = " << pfTau->pt() << ", eta = " << pfTau->eta() << ", phi = " << pfTau->phi() << " has area = " << jetArea << " !!" ;
171  ++numWarnings_;
172  }
173  dRmatch = 0.1;
174  }
175  }
176  if ( dR < dRmatch ) {
177  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuon2") << " overlaps with tau, dR = " << dR ;
178  reco::tau::countMatches(*muon, numMatchesDT, numMatchesCSC, numMatchesRPC);
179  reco::tau::countHits(*muon, numHitsDT, numHitsCSC, numHitsRPC);
180  }
181  }
182  }
183 
184  int numStationsWithMatches = 0;
185  for ( int iStation = 0; iStation < 4; ++iStation ) {
186  if ( numMatchesDT[iStation] > 0 && !maskMatchesDT_[iStation] ) ++numStationsWithMatches;
187  if ( numMatchesCSC[iStation] > 0 && !maskMatchesCSC_[iStation] ) ++numStationsWithMatches;
188  if ( numMatchesRPC[iStation] > 0 && !maskMatchesRPC_[iStation] ) ++numStationsWithMatches;
189  }
190 
191  int numLast2StationsWithHits = 0;
192  for ( int iStation = 2; iStation < 4; ++iStation ) {
193  if ( numHitsDT[iStation] > 0 && !maskHitsDT_[iStation] ) ++numLast2StationsWithHits;
194  if ( numHitsCSC[iStation] > 0 && !maskHitsCSC_[iStation] ) ++numLast2StationsWithHits;
195  if ( numHitsRPC[iStation] > 0 && !maskHitsRPC_[iStation] ) ++numLast2StationsWithHits;
196  }
197 
198  if ( verbosity_ ) {
199  edm::LogPrint("PFTauAgainstMuon2") << "numMatchesDT = " << format_vint(numMatchesDT) ;
200  edm::LogPrint("PFTauAgainstMuon2") << "numMatchesCSC = " << format_vint(numMatchesCSC) ;
201  edm::LogPrint("PFTauAgainstMuon2") << "numMatchesRPC = " << format_vint(numMatchesRPC) ;
202  edm::LogPrint("PFTauAgainstMuon2") << " --> numStationsWithMatches = " << numStationsWithMatches ;
203  edm::LogPrint("PFTauAgainstMuon2") << "numHitsDT = " << format_vint(numHitsDT) ;
204  edm::LogPrint("PFTauAgainstMuon2") << "numHitsCSC = " << format_vint(numHitsCSC) ;
205  edm::LogPrint("PFTauAgainstMuon2") << "numHitsRPC = " << format_vint(numHitsRPC) ;
206  edm::LogPrint("PFTauAgainstMuon2") << " --> numLast2StationsWithHits = " << numLast2StationsWithHits ;
207  }
208 
209  bool passesCaloMuonVeto = true;
210  if ( pfLeadChargedHadron.isNonnull() ) {
211  double energyECALplusHCAL = pfLeadChargedHadron->ecalEnergy() + pfLeadChargedHadron->hcalEnergy();
212  if ( verbosity_ ) {
213  if ( pfLeadChargedHadron->trackRef().isNonnull() ) {
214  edm::LogPrint("PFTauAgainstMuon2") << "decayMode = " << pfTau->decayMode() << ", energy(ECAL+HCAL) = " << energyECALplusHCAL << ", leadPFChargedHadronP = " << pfLeadChargedHadron->trackRef()->p() ;
215  } else if ( pfLeadChargedHadron->gsfTrackRef().isNonnull() ) {
216  edm::LogPrint("PFTauAgainstMuon2") << "decayMode = " << pfTau->decayMode() << ", energy(ECAL+HCAL) = " << energyECALplusHCAL << ", leadPFChargedHadronP = " << pfLeadChargedHadron->gsfTrackRef()->p() ;
217  }
218  }
219  const reco::Track* leadTrack = nullptr;
220  if ( pfLeadChargedHadron->trackRef().isNonnull() )
221  leadTrack = pfLeadChargedHadron->trackRef().get();
222  else if ( pfLeadChargedHadron->gsfTrackRef().isNonnull() )
223  leadTrack = pfLeadChargedHadron->gsfTrackRef().get();
224  if ( pfTau->decayMode() == 0 && leadTrack && energyECALplusHCAL < (hop_*leadTrack->p()) )
225  passesCaloMuonVeto = false;
226  }
227 
228  double discriminatorValue = 0.;
229  if ( discriminatorOption_ == kLoose && numStationsWithMatches <= maxNumberOfMatches_ ) discriminatorValue = 1.;
230  else if ( discriminatorOption_ == kMedium && numStationsWithMatches <= maxNumberOfMatches_ && numLast2StationsWithHits <= maxNumberOfHitsLast2Stations_ ) discriminatorValue = 1.;
231  else if ( discriminatorOption_ == kTight && numStationsWithMatches <= maxNumberOfMatches_ && numLast2StationsWithHits <= maxNumberOfHitsLast2Stations_ && passesCaloMuonVeto ) discriminatorValue = 1.;
232  else if ( discriminatorOption_ == kCustom ) {
233  bool pass = true;
234  if ( maxNumberOfMatches_ >= 0 && numStationsWithMatches > maxNumberOfMatches_ ) pass = false;
235  if ( maxNumberOfHitsLast2Stations_ >= 0 && numLast2StationsWithHits > maxNumberOfHitsLast2Stations_ ) pass = false;
236  if ( doCaloMuonVeto_ && !passesCaloMuonVeto ) pass = false;
237  discriminatorValue = pass ? 1.: 0.;
238  }
239  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuon2") << "--> returning discriminatorValue = " << discriminatorValue ;
240 
241  return discriminatorValue;
242 }
243 
244 }
245 
246 void
248  // pfRecoTauDiscriminationAgainstMuon2
250  desc.add<std::vector<int>>("maskHitsRPC", {
251  0,
252  0,
253  0,
254  0,
255  });
256  desc.add<int>("maxNumberOfHitsLast2Stations", 0);
257  desc.add<std::vector<int>>("maskMatchesRPC", {
258  0,
259  0,
260  0,
261  0,
262  });
263  desc.add<std::vector<int>>("maskMatchesCSC", {
264  1,
265  0,
266  0,
267  0,
268  });
269  desc.add<std::vector<int>>("maskHitsCSC", {
270  0,
271  0,
272  0,
273  0,
274  });
275  desc.add<edm::InputTag>("PFTauProducer", edm::InputTag("pfRecoTauProducer"));
276  desc.add<int>("verbosity", 0);
277  desc.add<std::vector<int>>("maskMatchesDT", {
278  0,
279  0,
280  0,
281  0,
282  });
283  desc.add<double>("minPtMatchedMuon", 5.0);
284  desc.add<bool>("dRmuonMatchLimitedToJetArea", false);
285  {
287  psd0.add<std::string>("BooleanOperator", "and");
288  {
290  psd1.add<double>("cut"); //, 0.5);
291  psd1.add<edm::InputTag>("Producer"); //, edm::InputTag("pfRecoTauDiscriminationByLeadingTrackFinding"));
292  psd0.addOptional<edm::ParameterSetDescription>("leadTrack", psd1); // optional with default?
293  }
294  // Prediscriminants can be
295  // Prediscriminants = noPrediscriminants,
296  // as in RecoTauTag/Configuration/python/HPSPFTaus_cff.py
297  //
298  // and the definition is:
299  // RecoTauTag/RecoTau/python/TauDiscriminatorTools.py
300  // # Require no prediscriminants
301  // noPrediscriminants = cms.PSet(
302  // BooleanOperator = cms.string("and"),
303  // )
304  // -- so this is the minimum required definition
305  // otherwise it inserts the leadTrack with Producer = InpuTag(...) and does not find the corresponding output during the run
306  desc.add<edm::ParameterSetDescription>("Prediscriminants", psd0);
307  }
308  desc.add<std::vector<int>>("maskHitsDT", {
309  0,
310  0,
311  0,
312  0,
313  });
314  desc.add<double>("HoPMin", 0.2);
315  desc.add<int>("maxNumberOfMatches", 0);
316  desc.add<std::string>("discriminatorOption", "loose");
317  desc.add<double>("dRmuonMatch", 0.3);
318  desc.add<edm::InputTag>("srcMuons", edm::InputTag("muons"));
319  desc.add<bool>("doCaloMuonVeto", false);
320  descriptions.add("pfRecoTauDiscriminationAgainstMuon2", desc);
321 }
322 
323 DEFINE_FWK_MODULE(PFRecoTauDiscriminationAgainstMuon2);
double p() const
momentum vector magnitude
Definition: TrackBase.h:648
const double Pi
T getParameter(std::string const &) const
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:159
void countMatches(const reco::Muon &muon, std::vector< int > &numMatchesDT, std::vector< int > &numMatchesCSC, std::vector< int > &numMatchesRPC)
key_type key() const
Accessor for product key.
Definition: Ref.h:263
T Min(T a, T b)
Definition: MathUtil.h:39
double vint[400]
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual void beginEvent(const edm::Event &, const edm::EventSetup &)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
virtual double discriminate(const TauRef &tau) const =0
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::string format_vint(const std::vector< int > &vi)
void countHits(const reco::Muon &muon, std::vector< int > &numHitsDT, std::vector< int > &numHitsCSC, std::vector< int > &numHitsRPC)