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 {
43  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName, const std::string& mvaName, std::vector<TFile*>& inputFilesToDelete)
44  {
45  if ( inputFileName.location() == edm::FileInPath::Unknown ) 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() << " !!\n";
54 
55  inputFilesToDelete.push_back(inputFile);
56 
57  return mva;
58  }
59 
60  const GBRForest* loadMVAfromDB(const edm::EventSetup& es, const std::string& mvaName)
61  {
63  es.get<GBRWrapperRcd>().get(mvaName, mva);
64  return mva.product();
65  }
66 
67 
69 {
70  public:
73  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
74  mvaReader_(nullptr),
75  mvaInput_(nullptr)
76  {
77  mvaName_ = cfg.getParameter<std::string>("mvaName");
78  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
79  if ( !loadMVAfromDB_ ) {
80  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
81  }
82  mvaInput_ = new float[11];
83 
84  srcMuons_ = cfg.getParameter<edm::InputTag>("srcMuons");
85  Muons_token=consumes<reco::MuonCollection>(srcMuons_);
86  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
87 
88  verbosity_ = cfg.getParameter<int>("verbosity");
89 
90  produces<PFTauDiscriminator>("category");
91  }
92 
93  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
94 
95  double discriminate(const PFTauRef&) const override;
96 
97  void endEvent(edm::Event&) override;
98 
100  {
101  if ( !loadMVAfromDB_ ) delete mvaReader_;
102  delete[] mvaInput_;
103  for ( std::vector<TFile*>::iterator it = inputFilesToDelete_.begin();
104  it != inputFilesToDelete_.end(); ++it ) {
105  delete (*it);
106  }
107  }
108 
109  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
110 
111  private:
112 
113  std::string moduleLabel_;
114 
115  std::string mvaName_;
116  bool loadMVAfromDB_;
117  edm::FileInPath inputFileName_;
118  const GBRForest* mvaReader_;
119  float* mvaInput_;
120 
121  edm::InputTag srcMuons_;
124  double dRmuonMatch_;
125 
127  std::unique_ptr<PFTauDiscriminator> category_output_;
128 
129  std::vector<TFile*> inputFilesToDelete_;
130 
131  int verbosity_;
132 };
133 
135 {
136  if ( !mvaReader_ ) {
137  if ( loadMVAfromDB_ ) {
138  mvaReader_ = loadMVAfromDB(es, mvaName_);
139  } else {
140  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
141  }
142  }
143 
144  evt.getByToken(Muons_token, muons_);
145 
146  evt.getByToken(Tau_token, taus_);
147  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
148 }
149 
150 namespace
151 {
152  void countHits(const reco::Muon& muon, std::vector<int>& numHitsDT, std::vector<int>& numHitsCSC, std::vector<int>& numHitsRPC)
153  {
154  if ( muon.outerTrack().isNonnull() ) {
155  const reco::HitPattern &muonHitPattern = muon.outerTrack()->hitPattern();
156  for (int iHit = 0; iHit < muonHitPattern.numberOfAllHits(HitPattern::TRACK_HITS); ++iHit) {
157  uint32_t hit = muonHitPattern.getHitPattern(HitPattern::TRACK_HITS, iHit);
158  if ( hit == 0 ) break;
159  if ( muonHitPattern.muonHitFilter(hit) && (muonHitPattern.getHitType(hit) == TrackingRecHit::valid || muonHitPattern.getHitType(hit) == TrackingRecHit::bad) ) {
160  int muonStation = muonHitPattern.getMuonStation(hit) - 1; // CV: map into range 0..3
161  if ( muonStation >= 0 && muonStation < 4 ) {
162  if ( muonHitPattern.muonDTHitFilter(hit) ) ++numHitsDT[muonStation];
163  else if ( muonHitPattern.muonCSCHitFilter(hit) ) ++numHitsCSC[muonStation];
164  else if ( muonHitPattern.muonRPCHitFilter(hit) ) ++numHitsRPC[muonStation];
165  }
166  }
167  }
168  }
169  }
170 }
171 
173 {
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() ) return 0.;
185 
186  mvaInput_[0] = TMath::Abs(tau->eta());
187  double tauCaloEnECAL = 0.;
188  double tauCaloEnHCAL = 0.;
189  const std::vector<reco::PFCandidatePtr>& tauSignalPFCands = tau->signalPFCands();
190  for ( std::vector<reco::PFCandidatePtr>::const_iterator tauSignalPFCand = tauSignalPFCands.begin();
191  tauSignalPFCand != tauSignalPFCands.end(); ++tauSignalPFCand ) {
192  tauCaloEnECAL += (*tauSignalPFCand)->ecalEnergy();
193  tauCaloEnHCAL += (*tauSignalPFCand)->hcalEnergy();
194  }
195  mvaInput_[1] = TMath::Sqrt(TMath::Max(0., tauCaloEnECAL));
196  mvaInput_[2] = TMath::Sqrt(TMath::Max(0., tauCaloEnHCAL));
197  mvaInput_[3] = tau->leadPFChargedHadrCand()->pt()/TMath::Max(1.,Double_t(tau->pt()));
198  mvaInput_[4] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->ecalEnergy()));
199  mvaInput_[5] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->hcalEnergy()));
200  int numMatches = 0;
201  std::vector<int> numHitsDT(4);
202  std::vector<int> numHitsCSC(4);
203  std::vector<int> numHitsRPC(4);
204  for ( int iStation = 0; iStation < 4; ++iStation ) {
205  numHitsDT[iStation] = 0;
206  numHitsCSC[iStation] = 0;
207  numHitsRPC[iStation] = 0;
208  }
209  if ( tau->leadPFChargedHadrCand().isNonnull() ) {
210  reco::MuonRef muonRef = tau->leadPFChargedHadrCand()->muonRef();
211  if ( muonRef.isNonnull() ) {
212  numMatches = muonRef->numberOfMatches(reco::Muon::NoArbitration);
213  countHits(*muonRef, numHitsDT, numHitsCSC, numHitsRPC);
214  }
215  }
216  size_t numMuons = muons_->size();
217  for ( size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon ) {
218  reco::MuonRef muon(muons_, idxMuon);
219  if ( tau->leadPFChargedHadrCand().isNonnull() && tau->leadPFChargedHadrCand()->muonRef().isNonnull() && muon == tau->leadPFChargedHadrCand()->muonRef() ) {
220  continue;
221  }
222  double dR = deltaR(muon->p4(), tau->p4());
223  if ( dR < dRmuonMatch_ ) {
224  numMatches += muon->numberOfMatches(reco::Muon::NoArbitration);
225  countHits(*muon, numHitsDT, numHitsCSC, numHitsRPC);
226  }
227  }
228  mvaInput_[6] = numMatches;
229  mvaInput_[7] = numHitsDT[0] + numHitsCSC[0] + numHitsRPC[0];
230  mvaInput_[8] = numHitsDT[1] + numHitsCSC[1] + numHitsRPC[1];
231  mvaInput_[9] = numHitsDT[2] + numHitsCSC[2] + numHitsRPC[2];
232  mvaInput_[10] = numHitsDT[3] + numHitsCSC[3] + numHitsRPC[3];
233 
234  double mvaValue = mvaReader_->GetClassifier(mvaInput_);
235  if ( verbosity_ ) {
236  edm::LogPrint("PFTauAgainstMuonMVA") << "mvaValue = " << mvaValue;
237  }
238  return mvaValue;
239 }
240 
242 {
243  // add all category indices to event
244  evt.put(std::move(category_output_), "category");
245 }
246 
247 }
248 
249 void
251  // pfRecoTauDiscriminationAgainstMuonMVA
253  desc.add<double>("mvaMin", 0.0);
254  desc.add<std::string>("mvaName", "againstMuonMVA");
255  desc.add<edm::InputTag>("PFTauProducer", edm::InputTag("pfTauProducer"));
256  desc.add<int>("verbosity", 0);
257  desc.add<bool>("returnMVA", true);
258  desc.add<edm::FileInPath>("inputFileName", edm::FileInPath("RecoTauTag/RecoTau/data/emptyMVAinputFile"));
259  desc.add<bool>("loadMVAfromDB", true);
260  {
262  psd0.add<std::string>("BooleanOperator", "and");
263  {
265  psd1.add<double>("cut");
266  psd1.add<edm::InputTag>("Producer");
267  psd0.addOptional<edm::ParameterSetDescription>("leadTrack", psd1);
268  }
269  desc.add<edm::ParameterSetDescription>("Prediscriminants", psd0);
270  }
271  desc.add<double>("dRmuonMatch", 0.3);
272  desc.add<edm::InputTag>("srcMuons", edm::InputTag("muons"));
273  descriptions.add("pfRecoTauDiscriminationAgainstMuonMVA", desc);
274 }
275 
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
edm::RefProd< TauCollection > TauRefProd
Definition: Tau.h:40
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
#define nullptr
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static bool muonCSCHitFilter(uint16_t pattern)
Definition: HitPattern.h:678
virtual void beginEvent(const edm::Event &, const edm::EventSetup &)
static uint32_t getHitType(uint16_t pattern)
Definition: HitPattern.h:792
T Abs(T a)
Definition: MathUtil.h:49
int numberOfAllHits(HitCategory category) const
Definition: HitPattern.h:875
const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
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:248
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
T Max(T a, T b)
Definition: MathUtil.h:44
static bool muonHitFilter(uint16_t pattern)
Definition: HitPattern.h:720
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:668
fixed size matrix
T get() const
Definition: EventSetup.h:71
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:801
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:553
static bool muonRPCHitFilter(uint16_t pattern)
Definition: HitPattern.h:688
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