CMS 3D CMS Logo

PFRecoTauDiscriminationAgainstMuonMVA.cc
Go to the documentation of this file.
1 
11 
17 
19 
22 
29 
32 
33 #include <TMath.h>
34 #include <TFile.h>
35 
36 #include <iostream>
37 
38 using namespace reco;
39 
40 namespace {
41  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName,
42  const std::string& mvaName,
43  std::vector<TFile*>& inputFilesToDelete) {
44  if (inputFileName.location() == edm::FileInPath::Unknown)
45  throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
46  << " Failed to find File = " << inputFileName << " !!\n";
47  TFile* inputFile = new TFile(inputFileName.fullPath().data());
48 
49  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
50  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
51  if (!mva)
52  throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
53  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data()
54  << " !!\n";
55 
56  inputFilesToDelete.push_back(inputFile);
57 
58  return mva;
59  }
60 
62  public:
65  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
66  mvaReader_(nullptr),
67  mvaInput_(nullptr) {
68  mvaName_ = cfg.getParameter<std::string>("mvaName");
69  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
70  if (!loadMVAfromDB_) {
71  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
72  } else {
73  mvaToken_ = esConsumes(edm::ESInputTag{"", mvaName_});
74  }
75  mvaInput_ = new float[11];
76 
77  srcMuons_ = cfg.getParameter<edm::InputTag>("srcMuons");
78  Muons_token = consumes<reco::MuonCollection>(srcMuons_);
79  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
80 
81  verbosity_ = cfg.getParameter<int>("verbosity");
82  }
83 
84  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
85 
86  reco::SingleTauDiscriminatorContainer discriminate(const PFTauRef&) const override;
87 
89  if (!loadMVAfromDB_)
90  delete mvaReader_;
91  delete[] mvaInput_;
92  for (std::vector<TFile*>::iterator it = inputFilesToDelete_.begin(); it != inputFilesToDelete_.end(); ++it) {
93  delete (*it);
94  }
95  }
96 
97  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
98 
99  private:
100  std::string moduleLabel_;
101 
102  std::string mvaName_;
104  bool loadMVAfromDB_;
105  edm::FileInPath inputFileName_;
106  const GBRForest* mvaReader_;
107  float* mvaInput_;
108 
109  edm::InputTag srcMuons_;
112  double dRmuonMatch_;
113 
115 
116  std::vector<TFile*> inputFilesToDelete_;
117 
118  int verbosity_;
119  };
120 
122  if (!mvaReader_) {
123  if (loadMVAfromDB_) {
124  mvaReader_ = &es.getData(mvaToken_);
125  } else {
126  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
127  }
128  }
129 
130  evt.getByToken(Muons_token, muons_);
131 
132  evt.getByToken(Tau_token, taus_);
133  }
134 
135  namespace {
136  void countHits(const reco::Muon& muon,
137  std::vector<int>& numHitsDT,
138  std::vector<int>& numHitsCSC,
139  std::vector<int>& numHitsRPC) {
140  if (muon.outerTrack().isNonnull()) {
141  const reco::HitPattern& muonHitPattern = muon.outerTrack()->hitPattern();
142  for (int iHit = 0; iHit < muonHitPattern.numberOfAllHits(HitPattern::TRACK_HITS); ++iHit) {
143  uint32_t hit = muonHitPattern.getHitPattern(HitPattern::TRACK_HITS, iHit);
144  if (hit == 0)
145  break;
146  if (muonHitPattern.muonHitFilter(hit) && (muonHitPattern.getHitType(hit) == TrackingRecHit::valid ||
147  muonHitPattern.getHitType(hit) == TrackingRecHit::bad)) {
148  int muonStation = muonHitPattern.getMuonStation(hit) - 1; // CV: map into range 0..3
149  if (muonStation >= 0 && muonStation < 4) {
150  if (muonHitPattern.muonDTHitFilter(hit))
151  ++numHitsDT[muonStation];
152  else if (muonHitPattern.muonCSCHitFilter(hit))
153  ++numHitsCSC[muonStation];
154  else if (muonHitPattern.muonRPCHitFilter(hit))
155  ++numHitsRPC[muonStation];
156  }
157  }
158  }
159  }
160  }
161  } // namespace
162 
164  if (verbosity_) {
165  edm::LogPrint("PFTauAgainstMuonMVA") << "<PFRecoTauDiscriminationAgainstMuonMVA::discriminate>:";
166  edm::LogPrint("PFTauAgainstMuonMVA") << " moduleLabel = " << moduleLabel_;
167  }
168 
170  // CV: define dummy category index in order to use RecoTauDiscriminantCutMultiplexer module to apply WP cuts
171  result.rawValues = {-1., 0.};
172 
173  // CV: computation of anti-muon MVA value requires presence of leading charged hadron
174  if (tau->leadPFChargedHadrCand().isNull())
175  return 0.;
176 
177  mvaInput_[0] = TMath::Abs(tau->eta());
178  double tauCaloEnECAL = 0.;
179  double tauCaloEnHCAL = 0.;
180  const std::vector<reco::PFCandidatePtr>& tauSignalPFCands = tau->signalPFCands();
181  for (std::vector<reco::PFCandidatePtr>::const_iterator tauSignalPFCand = tauSignalPFCands.begin();
182  tauSignalPFCand != tauSignalPFCands.end();
183  ++tauSignalPFCand) {
184  tauCaloEnECAL += (*tauSignalPFCand)->ecalEnergy();
185  tauCaloEnHCAL += (*tauSignalPFCand)->hcalEnergy();
186  }
187  mvaInput_[1] = TMath::Sqrt(TMath::Max(0., tauCaloEnECAL));
188  mvaInput_[2] = TMath::Sqrt(TMath::Max(0., tauCaloEnHCAL));
189  mvaInput_[3] = tau->leadPFChargedHadrCand()->pt() / TMath::Max(1., Double_t(tau->pt()));
190  mvaInput_[4] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->ecalEnergy()));
191  mvaInput_[5] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->hcalEnergy()));
192  int numMatches = 0;
193  std::vector<int> numHitsDT(4);
194  std::vector<int> numHitsCSC(4);
195  std::vector<int> numHitsRPC(4);
196  for (int iStation = 0; iStation < 4; ++iStation) {
197  numHitsDT[iStation] = 0;
198  numHitsCSC[iStation] = 0;
199  numHitsRPC[iStation] = 0;
200  }
201  if (tau->leadPFChargedHadrCand().isNonnull()) {
202  reco::MuonRef muonRef = tau->leadPFChargedHadrCand()->muonRef();
203  if (muonRef.isNonnull()) {
204  numMatches = muonRef->numberOfMatches(reco::Muon::NoArbitration);
205  countHits(*muonRef, numHitsDT, numHitsCSC, numHitsRPC);
206  }
207  }
208  size_t numMuons = muons_->size();
209  for (size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon) {
210  reco::MuonRef muon(muons_, idxMuon);
211  if (tau->leadPFChargedHadrCand().isNonnull() && tau->leadPFChargedHadrCand()->muonRef().isNonnull() &&
212  muon == tau->leadPFChargedHadrCand()->muonRef()) {
213  continue;
214  }
215  double dR = deltaR(muon->p4(), tau->p4());
216  if (dR < dRmuonMatch_) {
217  numMatches += muon->numberOfMatches(reco::Muon::NoArbitration);
218  countHits(*muon, numHitsDT, numHitsCSC, numHitsRPC);
219  }
220  }
221  mvaInput_[6] = numMatches;
222  mvaInput_[7] = numHitsDT[0] + numHitsCSC[0] + numHitsRPC[0];
223  mvaInput_[8] = numHitsDT[1] + numHitsCSC[1] + numHitsRPC[1];
224  mvaInput_[9] = numHitsDT[2] + numHitsCSC[2] + numHitsRPC[2];
225  mvaInput_[10] = numHitsDT[3] + numHitsCSC[3] + numHitsRPC[3];
226 
227  result.rawValues.at(0) = mvaReader_->GetClassifier(mvaInput_);
228  if (verbosity_) {
229  edm::LogPrint("PFTauAgainstMuonMVA") << "mvaValue = " << result.rawValues.at(0);
230  }
231  return result.rawValues.at(0);
232  }
233 } // namespace
234 
236  // pfRecoTauDiscriminationAgainstMuonMVA
238  desc.add<double>("mvaMin", 0.0);
239  desc.add<std::string>("mvaName", "againstMuonMVA");
240  desc.add<edm::InputTag>("PFTauProducer", edm::InputTag("pfTauProducer"));
241  desc.add<int>("verbosity", 0);
242  desc.add<bool>("returnMVA", true);
243  desc.add<edm::FileInPath>("inputFileName", edm::FileInPath("RecoTauTag/RecoTau/data/emptyMVAinputFile"));
244  desc.add<bool>("loadMVAfromDB", true);
245  {
247  psd0.add<std::string>("BooleanOperator", "and");
248  {
250  psd1.add<double>("cut");
251  psd1.add<edm::InputTag>("Producer");
252  psd0.addOptional<edm::ParameterSetDescription>("leadTrack", psd1);
253  }
254  desc.add<edm::ParameterSetDescription>("Prediscriminants", psd0);
255  }
256  desc.add<double>("dRmuonMatch", 0.3);
257  desc.add<edm::InputTag>("srcMuons", edm::InputTag("muons"));
258  descriptions.add("pfRecoTauDiscriminationAgainstMuonMVA", desc);
259 }
260 
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
int numberOfAllHits(HitCategory category) const
Definition: HitPattern.h:804
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:528
virtual TauDiscriminatorDataType discriminate(const TauRef &tau) const =0
static bool muonCSCHitFilter(uint16_t pattern)
Definition: HitPattern.h:645
static uint32_t getHitType(uint16_t pattern)
Definition: HitPattern.h:747
virtual void beginEvent(const edm::Event &, const edm::EventSetup &)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Log< level::Warning, true > LogPrint
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:537
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
static bool muonHitFilter(uint16_t pattern)
Definition: HitPattern.h:683
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static bool muonDTHitFilter(uint16_t pattern)
Definition: HitPattern.h:636
fixed size matrix
static uint16_t getMuonStation(uint16_t pattern)
Muon station (1-4). Only valid for muon patterns, of course. only for patterns from muon...
Definition: HitPattern.h:755
static bool muonRPCHitFilter(uint16_t pattern)
Definition: HitPattern.h:654
void countHits(const reco::Muon &muon, std::vector< int > &numHitsDT, std::vector< int > &numHitsCSC, std::vector< int > &numHitsRPC)