CMS 3D CMS Logo

PFRecoTauDiscriminationAgainstMuonMVA.cc
Go to the documentation of this file.
1 
11 
17 
19 
22 
29 
33 
34 #include <TMath.h>
35 #include <TFile.h>
36 
37 #include <iostream>
38 
39 using namespace reco;
40 
41 namespace {
42  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName,
43  const std::string& mvaName,
44  std::vector<TFile*>& inputFilesToDelete) {
45  if (inputFileName.location() == edm::FileInPath::Unknown)
46  throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
47  << " Failed to find File = " << inputFileName << " !!\n";
48  TFile* inputFile = new TFile(inputFileName.fullPath().data());
49 
50  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
51  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
52  if (!mva)
53  throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
54  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data()
55  << " !!\n";
56 
57  inputFilesToDelete.push_back(inputFile);
58 
59  return mva;
60  }
61 
62  const GBRForest* loadMVAfromDB(const edm::EventSetup& es, const std::string& mvaName) {
64  es.get<GBRWrapperRcd>().get(mvaName, mva);
65  return mva.product();
66  }
67 
69  public:
72  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
73  mvaReader_(nullptr),
74  mvaInput_(nullptr) {
75  mvaName_ = cfg.getParameter<std::string>("mvaName");
76  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
77  if (!loadMVAfromDB_) {
78  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
79  }
80  mvaInput_ = new float[11];
81 
82  srcMuons_ = cfg.getParameter<edm::InputTag>("srcMuons");
83  Muons_token = consumes<reco::MuonCollection>(srcMuons_);
84  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
85 
86  verbosity_ = cfg.getParameter<int>("verbosity");
87 
88  produces<PFTauDiscriminator>("category");
89  }
90 
91  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
92 
93  double discriminate(const PFTauRef&) const override;
94 
95  void endEvent(edm::Event&) override;
96 
98  if (!loadMVAfromDB_)
99  delete mvaReader_;
100  delete[] mvaInput_;
101  for (std::vector<TFile*>::iterator it = inputFilesToDelete_.begin(); it != inputFilesToDelete_.end(); ++it) {
102  delete (*it);
103  }
104  }
105 
106  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
107 
108  private:
109  std::string moduleLabel_;
110 
111  std::string mvaName_;
112  bool loadMVAfromDB_;
113  edm::FileInPath inputFileName_;
114  const GBRForest* mvaReader_;
115  float* mvaInput_;
116 
117  edm::InputTag srcMuons_;
120  double dRmuonMatch_;
121 
123  std::unique_ptr<PFTauDiscriminator> category_output_;
124 
125  std::vector<TFile*> inputFilesToDelete_;
126 
127  int verbosity_;
128  };
129 
131  if (!mvaReader_) {
132  if (loadMVAfromDB_) {
133  mvaReader_ = loadMVAfromDB(es, mvaName_);
134  } else {
135  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
136  }
137  }
138 
139  evt.getByToken(Muons_token, muons_);
140 
141  evt.getByToken(Tau_token, taus_);
142  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
143  }
144 
145  namespace {
146  void countHits(const reco::Muon& muon,
147  std::vector<int>& numHitsDT,
148  std::vector<int>& numHitsCSC,
149  std::vector<int>& numHitsRPC) {
150  if (muon.outerTrack().isNonnull()) {
151  const reco::HitPattern& muonHitPattern = muon.outerTrack()->hitPattern();
152  for (int iHit = 0; iHit < muonHitPattern.numberOfAllHits(HitPattern::TRACK_HITS); ++iHit) {
153  uint32_t hit = muonHitPattern.getHitPattern(HitPattern::TRACK_HITS, iHit);
154  if (hit == 0)
155  break;
156  if (muonHitPattern.muonHitFilter(hit) && (muonHitPattern.getHitType(hit) == TrackingRecHit::valid ||
157  muonHitPattern.getHitType(hit) == TrackingRecHit::bad)) {
158  int muonStation = muonHitPattern.getMuonStation(hit) - 1; // CV: map into range 0..3
159  if (muonStation >= 0 && muonStation < 4) {
160  if (muonHitPattern.muonDTHitFilter(hit))
161  ++numHitsDT[muonStation];
162  else if (muonHitPattern.muonCSCHitFilter(hit))
163  ++numHitsCSC[muonStation];
164  else if (muonHitPattern.muonRPCHitFilter(hit))
165  ++numHitsRPC[muonStation];
166  }
167  }
168  }
169  }
170  }
171  } // namespace
172 
174  if (verbosity_) {
175  edm::LogPrint("PFTauAgainstMuonMVA") << "<PFRecoTauDiscriminationAgainstMuonMVA::discriminate>:";
176  edm::LogPrint("PFTauAgainstMuonMVA") << " moduleLabel = " << moduleLabel_;
177  }
178 
179  // CV: define dummy category index in order to use RecoTauDiscriminantCutMultiplexer module to appy WP cuts
180  double category = 0.;
181  category_output_->setValue(tauIndex_, category);
182 
183  // CV: computation of anti-muon MVA value requires presence of leading charged hadron
184  if (tau->leadPFChargedHadrCand().isNull())
185  return 0.;
186 
187  mvaInput_[0] = TMath::Abs(tau->eta());
188  double tauCaloEnECAL = 0.;
189  double tauCaloEnHCAL = 0.;
190  const std::vector<reco::PFCandidatePtr>& tauSignalPFCands = tau->signalPFCands();
191  for (std::vector<reco::PFCandidatePtr>::const_iterator tauSignalPFCand = tauSignalPFCands.begin();
192  tauSignalPFCand != tauSignalPFCands.end();
193  ++tauSignalPFCand) {
194  tauCaloEnECAL += (*tauSignalPFCand)->ecalEnergy();
195  tauCaloEnHCAL += (*tauSignalPFCand)->hcalEnergy();
196  }
197  mvaInput_[1] = TMath::Sqrt(TMath::Max(0., tauCaloEnECAL));
198  mvaInput_[2] = TMath::Sqrt(TMath::Max(0., tauCaloEnHCAL));
199  mvaInput_[3] = tau->leadPFChargedHadrCand()->pt() / TMath::Max(1., Double_t(tau->pt()));
200  mvaInput_[4] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->ecalEnergy()));
201  mvaInput_[5] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->hcalEnergy()));
202  int numMatches = 0;
203  std::vector<int> numHitsDT(4);
204  std::vector<int> numHitsCSC(4);
205  std::vector<int> numHitsRPC(4);
206  for (int iStation = 0; iStation < 4; ++iStation) {
207  numHitsDT[iStation] = 0;
208  numHitsCSC[iStation] = 0;
209  numHitsRPC[iStation] = 0;
210  }
211  if (tau->leadPFChargedHadrCand().isNonnull()) {
212  reco::MuonRef muonRef = tau->leadPFChargedHadrCand()->muonRef();
213  if (muonRef.isNonnull()) {
214  numMatches = muonRef->numberOfMatches(reco::Muon::NoArbitration);
215  countHits(*muonRef, numHitsDT, numHitsCSC, numHitsRPC);
216  }
217  }
218  size_t numMuons = muons_->size();
219  for (size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon) {
220  reco::MuonRef muon(muons_, idxMuon);
221  if (tau->leadPFChargedHadrCand().isNonnull() && tau->leadPFChargedHadrCand()->muonRef().isNonnull() &&
222  muon == tau->leadPFChargedHadrCand()->muonRef()) {
223  continue;
224  }
225  double dR = deltaR(muon->p4(), tau->p4());
226  if (dR < dRmuonMatch_) {
227  numMatches += muon->numberOfMatches(reco::Muon::NoArbitration);
228  countHits(*muon, numHitsDT, numHitsCSC, numHitsRPC);
229  }
230  }
231  mvaInput_[6] = numMatches;
232  mvaInput_[7] = numHitsDT[0] + numHitsCSC[0] + numHitsRPC[0];
233  mvaInput_[8] = numHitsDT[1] + numHitsCSC[1] + numHitsRPC[1];
234  mvaInput_[9] = numHitsDT[2] + numHitsCSC[2] + numHitsRPC[2];
235  mvaInput_[10] = numHitsDT[3] + numHitsCSC[3] + numHitsRPC[3];
236 
237  double mvaValue = mvaReader_->GetClassifier(mvaInput_);
238  if (verbosity_) {
239  edm::LogPrint("PFTauAgainstMuonMVA") << "mvaValue = " << mvaValue;
240  }
241  return mvaValue;
242  }
243 
245  // add all category indices to event
246  evt.put(std::move(category_output_), "category");
247  }
248 
249 } // namespace
250 
252  // pfRecoTauDiscriminationAgainstMuonMVA
254  desc.add<double>("mvaMin", 0.0);
255  desc.add<std::string>("mvaName", "againstMuonMVA");
256  desc.add<edm::InputTag>("PFTauProducer", edm::InputTag("pfTauProducer"));
257  desc.add<int>("verbosity", 0);
258  desc.add<bool>("returnMVA", true);
259  desc.add<edm::FileInPath>("inputFileName", edm::FileInPath("RecoTauTag/RecoTau/data/emptyMVAinputFile"));
260  desc.add<bool>("loadMVAfromDB", true);
261  {
263  psd0.add<std::string>("BooleanOperator", "and");
264  {
266  psd1.add<double>("cut");
267  psd1.add<edm::InputTag>("Producer");
268  psd0.addOptional<edm::ParameterSetDescription>("leadTrack", psd1);
269  }
270  desc.add<edm::ParameterSetDescription>("Prediscriminants", psd0);
271  }
272  desc.add<double>("dRmuonMatch", 0.3);
273  desc.add<edm::InputTag>("srcMuons", edm::InputTag("muons"));
274  descriptions.add("pfRecoTauDiscriminationAgainstMuonMVA", desc);
275 }
276 
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
edm::RefProd< TauCollection > TauRefProd
Definition: Tau.h:38
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
#define nullptr
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static bool muonCSCHitFilter(uint16_t pattern)
Definition: HitPattern.h:633
virtual void beginEvent(const edm::Event &, const edm::EventSetup &)
static uint32_t getHitType(uint16_t pattern)
Definition: HitPattern.h:726
T Abs(T a)
Definition: MathUtil.h:49
int numberOfAllHits(HitCategory category) const
Definition: HitPattern.h:774
const LorentzVector & p4() const final
four-momentum Lorentz vector
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:161
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isNull() const
Checks for null.
Definition: Ref.h:235
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:48
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
T Max(T a, T b)
Definition: MathUtil.h:44
static bool muonHitFilter(uint16_t pattern)
Definition: HitPattern.h:668
virtual double discriminate(const TauRef &tau) const =0
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
static bool muonDTHitFilter(uint16_t pattern)
Definition: HitPattern.h:625
fixed size matrix
T get() const
Definition: EventSetup.h:73
std::string fullPath() const
Definition: FileInPath.cc:163
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:733
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:531
static bool muonRPCHitFilter(uint16_t pattern)
Definition: HitPattern.h:641
T const * product() const
Definition: ESHandle.h:86
void countHits(const reco::Muon &muon, std::vector< int > &numHitsDT, std::vector< int > &numHitsCSC, std::vector< int > &numHitsRPC)
def move(src, dest)
Definition: eostools.py:511