CMS 3D CMS Logo

PFRecoTauDiscriminationAgainstMuonSimple.cc
Go to the documentation of this file.
1 
14 
16 
24 
26 
27 #include <vector>
28 #include <string>
29 #include <iostream>
30 
32 
33 namespace {
34 
35 class PFRecoTauDiscriminationAgainstMuonSimple final : public PFTauDiscriminationProducerBase
36 {
37  public:
38  explicit PFRecoTauDiscriminationAgainstMuonSimple(const edm::ParameterSet& cfg)
40  moduleLabel_(cfg.getParameter<std::string>("@module_label"))
41  {
42  hop_ = cfg.getParameter<double>("HoPMin");
43  doCaloMuonVeto_ = cfg.getParameter<bool>("doCaloMuonVeto");
44  srcPatMuons_ = cfg.getParameter<edm::InputTag>("srcPatMuons");
45  Muons_token = consumes<pat::MuonCollection>(srcPatMuons_);
46  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
47  dRmuonMatchLimitedToJetArea_ = cfg.getParameter<bool>("dRmuonMatchLimitedToJetArea");
48  minPtMatchedMuon_ = cfg.getParameter<double>("minPtMatchedMuon");
49  maxNumberOfMatches_ = cfg.getParameter<int>("maxNumberOfMatches");
50  maxNumberOfHitsLast2Stations_ = cfg.getParameter<int>("maxNumberOfHitsLast2Stations");
51  typedef std::vector<int> vint;
52  maskMatchesDT_ = cfg.getParameter<vint>("maskMatchesDT");
53  maskMatchesCSC_ = cfg.getParameter<vint>("maskMatchesCSC");
54  maskMatchesRPC_ = cfg.getParameter<vint>("maskMatchesRPC");
55  maskHitsDT_ = cfg.getParameter<vint>("maskHitsDT");
56  maskHitsCSC_ = cfg.getParameter<vint>("maskHitsCSC");
57  maskHitsRPC_ = cfg.getParameter<vint>("maskHitsRPC");
58  maxNumberOfSTAMuons_ = cfg.getParameter<int>("maxNumberOfSTAMuons");
59  maxNumberOfRPCMuons_ = cfg.getParameter<int>("maxNumberOfRPCMuons");
60 
61  numWarnings_ = 0;
62  maxWarnings_ = 3;
63  verbosity_ = cfg.exists("verbosity") ? cfg.getParameter<int>("verbosity") : 0;
64  }
65  ~PFRecoTauDiscriminationAgainstMuonSimple() override {}
66 
67  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
68 
69  double discriminate(const reco::PFTauRef&) const override;
70 
71  private:
73  int discriminatorOption_;
74  double hop_;
75  bool doCaloMuonVeto_;
76  edm::InputTag srcPatMuons_;
79  double dRmuonMatch_;
80  bool dRmuonMatchLimitedToJetArea_;
81  double minPtMatchedMuon_;
82  int maxNumberOfMatches_;
83  std::vector<int> maskMatchesDT_;
84  std::vector<int> maskMatchesCSC_;
85  std::vector<int> maskMatchesRPC_;
86  int maxNumberOfHitsLast2Stations_;
87  std::vector<int> maskHitsDT_;
88  std::vector<int> maskHitsCSC_;
89  std::vector<int> maskHitsRPC_;
90  int maxNumberOfSTAMuons_, maxNumberOfRPCMuons_;
91 
92  mutable int numWarnings_;
93  int maxWarnings_;
94  int verbosity_;
95 };
96 
98 {
99  evt.getByToken(Muons_token, muons_);
100 }
101 
103 {
104  if ( verbosity_ ) {
105  edm::LogPrint("PFTauAgainstMuonSimple") << "<PFRecoTauDiscriminationAgainstMuonSimple::discriminate>:" ;
106  edm::LogPrint("PFTauAgainstMuonSimple") << " moduleLabel = " << moduleLabel_ ;
107  edm::LogPrint("PFTauAgainstMuonSimple") << "tau #" << pfTau.key() << ": Pt = " << pfTau->pt() << ", eta = " << pfTau->eta() << ", phi = " << pfTau->phi() << ", decay mode = " << pfTau->decayMode() ;
108  }
109 
110  //if (pfTau->decayMode() >= 5) return true; //MB: accept all multi-prongs??
111 
112  const reco::CandidatePtr& pfLeadChargedHadron = pfTau->leadChargedHadrCand();
113  bool passesCaloMuonVeto = true;
114  if ( pfLeadChargedHadron.isNonnull() ) {
115  const pat::PackedCandidate* pCand = dynamic_cast<const pat::PackedCandidate*>(pfLeadChargedHadron.get());
116  if ( pCand != nullptr ) {
117  double rawCaloEnergyFraction = pCand->rawCaloFraction();
118  //if ( !(rawCaloEnergyFraction > 0.) ) rawCaloEnergyFraction = 99; //MB: hack against cases when rawCaloEnergyFraction is not stored; it makes performance of the H/P cut rather poor
119  if ( verbosity_ ) {
120  edm::LogPrint("PFTauAgainstMuonSimple") << "decayMode = " << pfTau->decayMode() << ", rawCaloEnergy(ECAL+HCAL)Fraction = " << rawCaloEnergyFraction << ", leadPFChargedHadronP = " << pCand->p() << ", leadPFChargedHadron pdgId = " << pCand->pdgId();
121  }
122  if ( pfTau->decayMode() == 0 && rawCaloEnergyFraction < hop_ ) passesCaloMuonVeto = false;
123  }
124  }
125  if ( doCaloMuonVeto_ && !passesCaloMuonVeto ) {
126  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuonSimple") << "--> CaloMuonVeto failed, returning 0";
127  return 0.;
128  }
129 
130  //iterate over muons to find ones to use for discrimination
131  std::vector<const pat::Muon*> muonsToCheck;
132  size_t numMuons = muons_->size();
133  for ( size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon ) {
134  bool matched = false;
135  const pat::MuonRef muon(muons_, idxMuon);
136  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuonSimple") << "muon #" << muon.key() << ": Pt = " << muon->pt() << ", eta = " << muon->eta() << ", phi = " << muon->phi() ;
137  //firsty check if the muon corrsponds with the leading tau particle
138  for ( size_t iCand = 0; iCand < muon->numberOfSourceCandidatePtrs(); ++iCand) {
139  const reco::CandidatePtr& srcCand = muon->sourceCandidatePtr(iCand);
140  if (srcCand.isNonnull() && pfLeadChargedHadron.isNonnull() &&
141  srcCand.id()==pfLeadChargedHadron.id() &&
142  srcCand.key()==pfLeadChargedHadron.key() ) {
143  muonsToCheck.push_back(muon.get());
144  matched = true;
145  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuonSimple") << " tau has muonRef." ;
146  break;
147  }
148  }
149  if (matched) continue;
150  //check dR matching
151  if ( !(muon->pt() > minPtMatchedMuon_) ) {
152  if ( verbosity_ ){ edm::LogPrint("PFTauAgainstMuonSimple") << " fails Pt cut --> skipping it." ;}
153  continue;
154  }
155  double dR = deltaR(muon->p4(), pfTau->p4());
156  double dRmatch = dRmuonMatch_;
157  if ( dRmuonMatchLimitedToJetArea_ ) {
158  double jetArea = 0.;
159  if ( pfTau->jetRef().isNonnull() ) jetArea = pfTau->jetRef()->jetArea();
160  if ( jetArea > 0. ) {
161  dRmatch = TMath::Min(dRmatch, TMath::Sqrt(jetArea/TMath::Pi()));
162  } else {
163  if ( numWarnings_ < maxWarnings_ ) {
164  edm::LogInfo("PFRecoTauDiscriminationAgainstMuonSimple::discriminate")
165  << "Jet associated to Tau: Pt = " << pfTau->pt() << ", eta = " << pfTau->eta() << ", phi = " << pfTau->phi() << " has area = " << jetArea << " !!" ;
166  ++numWarnings_;
167  }
168  dRmatch = pfTau->signalConeSize();
169  }
170  dRmatch = TMath::Max(dRmatch,pfTau->signalConeSize());
171  if ( dR < dRmatch ) {
172  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuonSimple") << " overlaps with tau, dR = " << dR ;
173  muonsToCheck.push_back(muon.get());
174  }
175  }
176  }
177  //now examine selected muons
178  bool pass = true;
179  std::vector<int> numMatchesDT(4);
180  std::vector<int> numMatchesCSC(4);
181  std::vector<int> numMatchesRPC(4);
182  std::vector<int> numHitsDT(4);
183  std::vector<int> numHitsCSC(4);
184  std::vector<int> numHitsRPC(4);
185  //MB: clear counters of matched segments and hits globally as in the AgainstMuon2 discriminant, but note that they will sum for all matched muons. However it is not likely that there is more than one matched muon.
186  for ( int iStation = 0; iStation < 4; ++iStation ) {
187  numMatchesDT[iStation] = 0;
188  numMatchesCSC[iStation] = 0;
189  numMatchesRPC[iStation] = 0;
190  numHitsDT[iStation] = 0;
191  numHitsCSC[iStation] = 0;
192  numHitsRPC[iStation] = 0;
193  }
194  int numSTAMuons=0, numRPCMuons=0;
195  if ( verbosity_ && !muonsToCheck.empty() ) edm::LogPrint("PFTauAgainstMuonSimple") << "Muons to check (" << muonsToCheck.size() << "):";
196  size_t iMu = 0;
197  for (const auto &mu: muonsToCheck) {
198  if ( mu->isStandAloneMuon() ) numSTAMuons++;
199  if ( mu->muonID("RPCMuLoose") ) numRPCMuons++;
200  reco::tau::countMatches(*mu, numMatchesDT, numMatchesCSC, numMatchesRPC);
201  int numStationsWithMatches = 0;
202  for ( int iStation = 0; iStation < 4; ++iStation ) {
203  if ( numMatchesDT[iStation] > 0 && !maskMatchesDT_[iStation] ) ++numStationsWithMatches;
204  if ( numMatchesCSC[iStation] > 0 && !maskMatchesCSC_[iStation] ) ++numStationsWithMatches;
205  if ( numMatchesRPC[iStation] > 0 && !maskMatchesRPC_[iStation] ) ++numStationsWithMatches;
206  }
207  reco::tau::countHits(*mu, numHitsDT, numHitsCSC, numHitsRPC);
208  int numLast2StationsWithHits = 0;
209  for ( int iStation = 2; iStation < 4; ++iStation ) {
210  if ( numHitsDT[iStation] > 0 && !maskHitsDT_[iStation] ) ++numLast2StationsWithHits;
211  if ( numHitsCSC[iStation] > 0 && !maskHitsCSC_[iStation] ) ++numLast2StationsWithHits;
212  if ( numHitsRPC[iStation] > 0 && !maskHitsRPC_[iStation] ) ++numLast2StationsWithHits;
213  }
214  if ( verbosity_ )
215  edm::LogPrint("PFTauAgainstMuonSimple")
216  << "\t" << iMu << ": Pt = " << mu->pt() << ", eta = " << mu->eta() << ", phi = " << mu->phi()
217  << "\n\t"
218  << " isSTA: "<<mu->isStandAloneMuon()
219  << ", isRPCLoose: "<<mu->muonID("RPCMuLoose")
220  << "\n\t numMatchesDT = " << format_vint(numMatchesDT)
221  << "\n\t numMatchesCSC = " << format_vint(numMatchesCSC)
222  << "\n\t numMatchesRPC = " << format_vint(numMatchesRPC)
223  << "\n\t --> numStationsWithMatches = " << numStationsWithMatches
224  << "\n\t numHitsDT = " << format_vint(numHitsDT)
225  << "\n\t numHitsCSC = " << format_vint(numHitsCSC)
226  << "\n\t numHitsRPC = " << format_vint(numHitsRPC)
227  << "\n\t --> numLast2StationsWithHits = " << numLast2StationsWithHits ;
228  if ( maxNumberOfMatches_ >= 0 && numStationsWithMatches > maxNumberOfMatches_ ) {
229  pass = false;
230  break;
231  }
232  if ( maxNumberOfHitsLast2Stations_ >= 0 && numLast2StationsWithHits > maxNumberOfHitsLast2Stations_ ) {
233  pass = false;
234  break;
235  }
236  if ( maxNumberOfSTAMuons_ >= 0 && numSTAMuons > maxNumberOfSTAMuons_ ) {
237  pass = false;
238  break;
239  }
240  if ( maxNumberOfRPCMuons_ >= 0 && numRPCMuons > maxNumberOfRPCMuons_ ) {
241  pass = false;
242  break;
243  }
244  iMu++;
245  }
246 
247  double discriminatorValue = pass ? 1.: 0.;
248  if ( verbosity_ ) edm::LogPrint("PFTauAgainstMuonSimple") << "--> returning discriminatorValue = " << discriminatorValue ;
249 
250  return discriminatorValue;
251 }
252 
253 }
254 
255 DEFINE_FWK_MODULE(PFRecoTauDiscriminationAgainstMuonSimple);
256 
const double Pi
T getParameter(std::string const &) const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
key_type key() const
Definition: Ptr.h:185
int pdgId() const override
PDG identifier.
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
bool exists(std::string const &parameterName) const
checks if a parameter exists
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 &)
const int mu
Definition: Constants.h:22
double p() const override
magnitude of momentum vector
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
T Max(T a, T b)
Definition: MathUtil.h:44
virtual double discriminate(const TauRef &tau) const =0
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:180
float rawCaloFraction() const
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)