CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauDiscriminationAgainstMuonMVA.cc
Go to the documentation of this file.
1 
11 
17 
19 
26 
28 
29 #include <TMath.h>
30 #include <TFile.h>
31 
32 #include <iostream>
33 
34 using namespace reco;
35 
36 namespace
37 {
38  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName, const std::string& mvaName, std::vector<TFile*>& inputFilesToDelete)
39  {
40  if ( inputFileName.location() == edm::FileInPath::Unknown ) throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
41  << " Failed to find File = " << inputFileName << " !!\n";
42  TFile* inputFile = new TFile(inputFileName.fullPath().data());
43 
44  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
45  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
46  if ( !mva )
47  throw cms::Exception("PFRecoTauDiscriminationAgainstMuonMVA::loadMVA")
48  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
49 
50  inputFilesToDelete.push_back(inputFile);
51 
52  return mva;
53  }
54 }
55 
57 {
58  public:
61  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
62  mvaReader_(0),
63  mvaInput_(0)
64  {
65  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
66  mvaName_ = cfg.getParameter<std::string>("mvaName");
67  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
68  returnMVA_ = cfg.getParameter<bool>("returnMVA");
69  mvaMin_ = cfg.getParameter<double>("mvaMin");
70  mvaInput_ = new float[11];
71 
72  srcMuons_ = cfg.getParameter<edm::InputTag>("srcMuons");
73  Muons_token=consumes<reco::MuonCollection>(srcMuons_);
74  dRmuonMatch_ = cfg.getParameter<double>("dRmuonMatch");
75 
76  verbosity_ = ( cfg.exists("verbosity") ) ?
77  cfg.getParameter<int>("verbosity") : 0;
78 
79  produces<PFTauDiscriminator>("category");
80  }
81 
82  void beginEvent(const edm::Event&, const edm::EventSetup&);
83 
84  double discriminate(const PFTauRef&);
85 
86  void endEvent(edm::Event&);
87 
89  {
90  delete mvaReader_;
91  delete[] mvaInput_;
92  for ( std::vector<TFile*>::iterator it = inputFilesToDelete_.begin();
93  it != inputFilesToDelete_.end(); ++it ) {
94  delete (*it);
95  }
96  }
97 
98  private:
99 
101 
106  double mvaMin_;
107  float* mvaInput_;
108 
112  double dRmuonMatch_;
113 
115  std::auto_ptr<PFTauDiscriminator> category_output_;
116  size_t tauIndex_;
117 
118  std::vector<TFile*> inputFilesToDelete_;
119 
121 };
122 
124 {
125  evt.getByToken(Muons_token, muons_);
126 
127  evt.getByToken(Tau_token, taus_);
128  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
129  tauIndex_ = 0;
130 }
131 
132 namespace
133 {
134  void countHits(const reco::Muon& muon, std::vector<int>& numHitsDT, std::vector<int>& numHitsCSC, std::vector<int>& numHitsRPC)
135  {
136  if ( muon.outerTrack().isNonnull() ) {
137  const reco::HitPattern& muonHitPattern = muon.outerTrack()->hitPattern();
138  for ( int iHit = 0; iHit < muonHitPattern.numberOfHits(); ++iHit ) {
139  uint32_t hit = muonHitPattern.getHitPattern(iHit);
140  if ( hit == 0 ) break;
141  if ( muonHitPattern.muonHitFilter(hit) && (muonHitPattern.getHitType(hit) == TrackingRecHit::valid || muonHitPattern.getHitType(hit) == TrackingRecHit::bad) ) {
142  int muonStation = muonHitPattern.getMuonStation(hit) - 1; // CV: map into range 0..3
143  if ( muonStation >= 0 && muonStation < 4 ) {
144  if ( muonHitPattern.muonDTHitFilter(hit) ) ++numHitsDT[muonStation];
145  else if ( muonHitPattern.muonCSCHitFilter(hit) ) ++numHitsCSC[muonStation];
146  else if ( muonHitPattern.muonRPCHitFilter(hit) ) ++numHitsRPC[muonStation];
147  }
148  }
149  }
150  }
151  }
152 }
153 
155 {
156  if ( verbosity_ ) {
157  edm::LogPrint("PFTauAgainstMuonMVA") << "<PFRecoTauDiscriminationAgainstMuonMVA::discriminate>:" ;
158  edm::LogPrint("PFTauAgainstMuonMVA") << " moduleLabel = " << moduleLabel_ ;
159  edm::LogPrint("PFTauAgainstMuonMVA") << " mvaMin = " << mvaMin_ ;
160  }
161 
162  // CV: define dummy category index in order to use RecoTauDiscriminantCutMultiplexer module to appy WP cuts
163  double category = 0.;
164  category_output_->setValue(tauIndex_, category);
165  ++tauIndex_;
166 
167  // CV: computation of anti-muon MVA value requires presence of leading charged hadron
168  if ( tau->leadPFChargedHadrCand().isNull() ) return 0.;
169 
170  mvaInput_[0] = TMath::Abs(tau->eta());
171  double tauCaloEnECAL = 0.;
172  double tauCaloEnHCAL = 0.;
173  const std::vector<reco::PFCandidatePtr>& tauSignalPFCands = tau->signalPFCands();
174  for ( std::vector<reco::PFCandidatePtr>::const_iterator tauSignalPFCand = tauSignalPFCands.begin();
175  tauSignalPFCand != tauSignalPFCands.end(); ++tauSignalPFCand ) {
176  tauCaloEnECAL += (*tauSignalPFCand)->ecalEnergy();
177  tauCaloEnHCAL += (*tauSignalPFCand)->hcalEnergy();
178  }
179  mvaInput_[1] = TMath::Sqrt(TMath::Max(0., tauCaloEnECAL));
180  mvaInput_[2] = TMath::Sqrt(TMath::Max(0., tauCaloEnHCAL));
181  mvaInput_[3] = tau->leadPFChargedHadrCand()->pt()/TMath::Max(1.,Double_t(tau->pt()));
182  mvaInput_[4] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->ecalEnergy()));
183  mvaInput_[5] = TMath::Sqrt(TMath::Max(0., tau->leadPFChargedHadrCand()->hcalEnergy()));
184  int numMatches = 0;
185  std::vector<int> numHitsDT(4);
186  std::vector<int> numHitsCSC(4);
187  std::vector<int> numHitsRPC(4);
188  for ( int iStation = 0; iStation < 4; ++iStation ) {
189  numHitsDT[iStation] = 0;
190  numHitsCSC[iStation] = 0;
191  numHitsRPC[iStation] = 0;
192  }
193  if ( tau->leadPFChargedHadrCand().isNonnull() ) {
194  reco::MuonRef muonRef = tau->leadPFChargedHadrCand()->muonRef();
195  if ( muonRef.isNonnull() ) {
196  numMatches = muonRef->numberOfMatches(reco::Muon::NoArbitration);
197  countHits(*muonRef, numHitsDT, numHitsCSC, numHitsRPC);
198  }
199  }
200  size_t numMuons = muons_->size();
201  for ( size_t idxMuon = 0; idxMuon < numMuons; ++idxMuon ) {
202  reco::MuonRef muon(muons_, idxMuon);
203  if ( tau->leadPFChargedHadrCand().isNonnull() && tau->leadPFChargedHadrCand()->muonRef().isNonnull() && muon == tau->leadPFChargedHadrCand()->muonRef() ) {
204  continue;
205  }
206  double dR = deltaR(muon->p4(), tau->p4());
207  if ( dR < dRmuonMatch_ ) {
208  numMatches += muon->numberOfMatches(reco::Muon::NoArbitration);
209  countHits(*muon, numHitsDT, numHitsCSC, numHitsRPC);
210  }
211  }
212  mvaInput_[6] = numMatches;
213  mvaInput_[7] = numHitsDT[0] + numHitsCSC[0] + numHitsRPC[0];
214  mvaInput_[8] = numHitsDT[1] + numHitsCSC[1] + numHitsRPC[1];
215  mvaInput_[9] = numHitsDT[2] + numHitsCSC[2] + numHitsRPC[2];
216  mvaInput_[10] = numHitsDT[3] + numHitsCSC[3] + numHitsRPC[3];
217 
218  double mvaValue = mvaReader_->GetClassifier(mvaInput_);
219  if ( verbosity_ ) {
220  edm::LogPrint("PFTauAgainstMuonMVA") << "mvaValue = " << mvaValue ;
221  }
222 
223  double retVal = -1.;
224  if ( returnMVA_ ) {
225  retVal = mvaValue;
226  if ( verbosity_ ) {
227  edm::LogPrint("PFTauAgainstMuonMVA") << "--> retVal = " << retVal ;
228  }
229  } else {
230  retVal = ( mvaValue > mvaMin_ ) ? 1. : 0.;
231  if ( verbosity_ ) {
232  edm::LogPrint("PFTauAgainstMuonMVA") << "--> retVal = " << retVal << ": discriminator = ";
233  if ( retVal > 0.5 ) edm::LogPrint("PFTauAgainstMuonMVA") << "PASSED." ;
234  else edm::LogPrint("PFTauAgainstMuonMVA") << "FAILED." ;
235  }
236  }
237  return retVal;
238 }
239 
241 {
242  // add all category indices to event
243  evt.put(category_output_, "category");
244 }
245 
T getParameter(std::string const &) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
static bool muonDTHitFilter(uint32_t pattern)
Definition: HitPattern.h:479
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
edm::EDGetTokenT< reco::MuonCollection > Muons_token
bool exists(std::string const &parameterName) const
checks if a parameter exists
static uint32_t getHitType(uint32_t pattern)
Definition: HitPattern.h:536
static uint32_t getMuonStation(uint32_t pattern)
Muon station (1-4). Only valid for muon patterns, of course.
Definition: HitPattern.h:541
double deltaR(const T1 &t1, const T2 &t2)
Definition: deltaR.h:48
void beginEvent(const edm::Event &, const edm::EventSetup &)
static bool muonHitFilter(uint32_t pattern)
Definition: HitPattern.h:507
tuple numMuons
Definition: patZpeak.py:40
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
bool isNull() const
Checks for null.
Definition: Ref.h:247
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
T Abs(T a)
Definition: MathUtil.h:49
int numberOfHits() const
Definition: HitPattern.cc:211
static bool muonRPCHitFilter(uint32_t pattern)
Definition: HitPattern.h:493
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
T Max(T a, T b)
Definition: MathUtil.h:44
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:159
static bool muonCSCHitFilter(uint32_t pattern)
Definition: HitPattern.h:486
std::string fullPath() const
Definition: FileInPath.cc:165
uint32_t getHitPattern(int position) const
Definition: HitPattern.cc:142
moduleLabel_(iConfig.getParameter< string >("@module_label"))