CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFMETAlgorithmMVA.cc
Go to the documentation of this file.
2 
5 
9 
11 
12 #include <TFile.h>
13 
14 #include <iomanip>
15 
16 enum MVAType { kBaseline = 0 };
17 
18 const double Pi=cos(-1);
19 
20 namespace
21 {
22  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName, const std::string& mvaName)
23  {
24  if ( inputFileName.location()==edm::FileInPath::Unknown ) throw cms::Exception("PFMETAlgorithmMVA::loadMVA")
25  << " Failed to find File = " << inputFileName << " !!\n";
26  TFile* inputFile = new TFile(inputFileName.fullPath().data());
27 
28  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
29  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
30  if ( !mva )
31  throw cms::Exception("PFMETAlgorithmMVA::loadMVA")
32  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
33 
34  delete inputFile;
35 
36  return mva;
37  }
38 
39  const GBRForest* loadMVAfromDB(const edm::EventSetup& es, const std::string& mvaName)
40  {
42  es.get<GBRWrapperRcd>().get(mvaName, mva);
43  return mva.product();
44  }
45 }
46 
48  : utils_(cfg),
49  mvaInputU_(nullptr),
50  mvaInputDPhi_(nullptr),
51  mvaInputCovU1_(nullptr),
52  mvaInputCovU2_(nullptr),
53  mvaReaderU_(nullptr),
54  mvaReaderDPhi_(nullptr),
55  mvaReaderCovU1_(nullptr),
56  mvaReaderCovU2_(nullptr),
57  cfg_(cfg)
58 {
60 
61  dZcut_ = cfg.getParameter<double>("dZcut");
62  isOld42_ = cfg.getParameter<bool>("useOld42");
63 
64  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
65 
66  is42_ = cfg.getParameter<bool>("is42");
67 
68  mvaInputU_ = new Float_t[25];
69  mvaInputDPhi_ = new Float_t[23];
70  mvaInputCovU1_ = new Float_t[26];
71  mvaInputCovU2_ = new Float_t[26];
72 }
73 
75 {
76  delete mvaInputU_;
77  delete mvaInputDPhi_;
78  delete mvaInputCovU1_;
79  delete mvaInputCovU2_;
80 
81  if ( !loadMVAfromDB_ ) {
82  delete mvaReaderU_;
83  delete mvaReaderDPhi_;
84  delete mvaReaderCovU1_;
85  delete mvaReaderCovU2_;
86  }
87 }
88 
90 {
91  if ( loadMVAfromDB_ ) {
92  //std::cout << "<PFMETAlgorithmMVA::initialize>: loading BDTs from Database." << std::endl;
93  edm::ParameterSet cfgInputRecords = cfg_.getParameter<edm::ParameterSet>("inputRecords");
94  mvaNameU_ = cfgInputRecords.getParameter<std::string>("U");
95  mvaReaderU_ = loadMVAfromDB(es, mvaNameU_);
96  mvaNameDPhi_ = cfgInputRecords.getParameter<std::string>("DPhi");
98  mvaNameCovU1_ = cfgInputRecords.getParameter<std::string>("CovU1");
100  mvaNameCovU2_ = cfgInputRecords.getParameter<std::string>("CovU2");
102  } else {
103  //std::cout << "<PFMETAlgorithmMVA::initialize>: loading BDTs from ROOT files." << std::endl;
104  edm::ParameterSet cfgInputFileNames = cfg_.getParameter<edm::ParameterSet>("inputFileNames");
105 
106  mvaNameU_ = "U1Correction";
107  mvaNameDPhi_ = "PhiCorrection";
108  mvaNameCovU1_ = "CovU1";
109  mvaNameCovU2_ = "CovU2";
110 
111  edm::FileInPath inputFileNameU = cfgInputFileNames.getParameter<edm::FileInPath>("U");
112  mvaReaderU_ = loadMVAfromFile(inputFileNameU, mvaNameU_);
113  edm::FileInPath inputFileNameDPhi = cfgInputFileNames.getParameter<edm::FileInPath>("DPhi");
114  mvaReaderDPhi_ = loadMVAfromFile(inputFileNameDPhi, mvaNameDPhi_);
115  edm::FileInPath inputFileNameCovU1 = cfgInputFileNames.getParameter<edm::FileInPath>("CovU1");
116  mvaReaderCovU1_ = loadMVAfromFile(inputFileNameCovU1, mvaNameCovU1_);
117  edm::FileInPath inputFileNameCovU2 = cfgInputFileNames.getParameter<edm::FileInPath>("CovU2");
118  mvaReaderCovU2_ = loadMVAfromFile(inputFileNameCovU2, mvaNameCovU2_);
119  }
120 }
121 
122 //-------------------------------------------------------------------------------
123 void PFMETAlgorithmMVA::setInput(const std::vector<mvaMEtUtilities::leptonInfo>& leptons,
124  const std::vector<mvaMEtUtilities::JetInfo>& jets,
125  const std::vector<mvaMEtUtilities::pfCandInfo>& pfCandidates,
126  const std::vector<reco::Vertex::Point>& vertices)
127 {
128  //std::vector<mvaMEtUtilities::pfCandInfo> pfCandidates_leptons = utils_.cleanPFCands(pfCandidates, leptons, 0.3, true);
130  //const std::vector<mvaMEtUtilities::pfCandInfo> pfCandidates_cleaned = utils_.cleanPFCands(pfCandidates, leptons, 0.3, false);
131 
132  CommonMETData sumLeptons = utils_.computeSumLeptons(leptons, false);
133  CommonMETData chargedSumLeptons = utils_.computeSumLeptons(leptons, true);
134 
135  sumLeptonPx_ = sumLeptons.mex;
136  sumLeptonPy_ = sumLeptons.mey;
137 
138  chargedSumLeptonPx_ = chargedSumLeptons.mex;
139  chargedSumLeptonPy_ = chargedSumLeptons.mey;
140 
141  double ptThreshold = -1000.;
142  if ( is42_ ) ptThreshold = 1.; //PH: For 42 training added a pT cut of 1 GeV on corrected Jets
143  std::vector<mvaMEtUtilities::JetInfo> jets_cleaned = utils_.cleanJets(jets, leptons, ptThreshold, 0.5);
144 
145  CommonMETData pfRecoil_data = utils_.computeNegPFRecoil (sumLeptons , pfCandidates, dZcut_);
146  CommonMETData tkRecoil_data = utils_.computeNegTrackRecoil(chargedSumLeptons, pfCandidates, dZcut_);
147  CommonMETData npuRecoil_data = utils_.computeNegNoPURecoil (chargedSumLeptons, pfCandidates, jets_cleaned, dZcut_);
148  CommonMETData pucRecoil_data = utils_.computeNegPUCRecoil (sumLeptons , pfCandidates, jets_cleaned, dZcut_);
149  CommonMETData puMEt_data = utils_.computePUMEt ( pfCandidates, jets_cleaned, 0.2); //dZCut bug
150 
151  reco::Candidate::LorentzVector jet1P4 = utils_.leadJetP4(jets_cleaned);
152  reco::Candidate::LorentzVector jet2P4 = utils_.subleadJetP4(jets_cleaned);
153 
154  double pfSumEt = pfRecoil_data.sumet;
155  double pfU = pfRecoil_data.met;
156  double pfPhi = pfRecoil_data.phi;
157  double tkSumEt = tkRecoil_data.sumet;
158  double tkU = tkRecoil_data.met;
159  double tkPhi = tkRecoil_data.phi;
160  double npuSumEt = npuRecoil_data.sumet;
161  double npuU = npuRecoil_data.met;
162  double npuPhi = npuRecoil_data.phi;
163  double puSumEt = puMEt_data.sumet;
164  double puMEt = puMEt_data.met;
165  double puPhi = puMEt_data.phi;
166  double pucSumEt = pucRecoil_data.sumet;
167  double pucU = pucRecoil_data.met;
168  double pucPhi = pucRecoil_data.phi;
169  double jet1Pt = jet1P4.pt();
170  double jet1Eta = jet1P4.eta();
171  double jet1Phi = jet1P4.phi();
172  double jet2Pt = jet2P4.pt();
173  double jet2Eta = jet2P4.eta();
174  double jet2Phi = jet2P4.phi();
175  double numJetsPtGt30 = utils_.numJetsAboveThreshold(jets_cleaned, 30.);
176  double numJets = jets_cleaned.size();
177  double numVertices = vertices.size();
178 
179  setInput(pfSumEt, pfU, pfPhi,
180  tkSumEt, tkU, tkPhi,
181  npuSumEt, npuU, npuPhi,
182  puSumEt, puMEt, puPhi,
183  pucSumEt, pucU, pucPhi,
184  jet1Pt, jet1Eta, jet1Phi,
185  jet2Pt, jet2Eta, jet2Phi,
186  numJetsPtGt30, numJets,
187  numVertices);
188 
189 }
190 
191 void PFMETAlgorithmMVA::setInput(double pfSumEt, double pfU, double pfPhi,
192  double tkSumEt, double tkU, double tkPhi,
193  double npuSumEt, double npuU, double npuPhi,
194  double puSumEt, double puMEt, double puPhi,
195  double pucSumEt, double pucU, double pucPhi,
196  double jet1Pt, double jet1Eta, double jet1Phi,
197  double jet2Pt, double jet2Eta, double jet2Phi,
198  double numJetsPtGt30, double numJets,
199  double numVertices)
200 {
201  // CV: add protection against "empty events"
202  if ( pfSumEt < 1. ) pfSumEt = 1.;
203 
204  pfSumEt_ = pfSumEt;
205  pfU_ = pfU;
206  pfPhi_ = pfPhi;
207  tkSumEt_ = tkSumEt/pfSumEt_;
208  tkU_ = tkU;
209  tkPhi_ = tkPhi;
210  npuSumEt_ = npuSumEt/pfSumEt_;
211  npuU_ = npuU;
212  npuPhi_ = npuPhi;
213  puSumEt_ = puSumEt/pfSumEt_;
214  puMEt_ = puMEt;
215  puPhi_ = puPhi;
216  pucSumEt_ = pucSumEt/pfSumEt_;
217  pucU_ = pucU;
218  pucPhi_ = pucPhi;
219  jet1Pt_ = jet1Pt;
220  jet1Eta_ = jet1Eta;
221  jet1Phi_ = jet1Phi;
222  jet2Pt_ = jet2Pt;
223  jet2Eta_ = jet2Eta;
224  jet2Phi_ = jet2Phi;
225  numJetsPtGt30_ = numJetsPtGt30;
226  numJets_ = numJets;
227  numVertices_ = numVertices;
228 }
229 //-------------------------------------------------------------------------------
230 
231 //-------------------------------------------------------------------------------
233 {
234  // CV: MVAs needs to be evaluated in order { DPhi, U1, CovU1, CovU2 }
235  // as MVA for U1 (CovU1, CovU2) uses output of DPhi (DPhi and U1) MVA
236  evaluateDPhi();
237  evaluateU();
238  evaluateCovU1();
239  evaluateCovU2();
240 
241  // compute MET(Photon check)
242  if(hasPhotons_) {
243  //Fix events with unphysical properties
245  if(tkU_/sumLeptonPt < 0.1 || npuU_/sumLeptonPt < 0.1 ) mvaOutputU_ = 1.;
246  if(tkU_/sumLeptonPt < 0.1 || npuU_/sumLeptonPt < 0.1 ) mvaOutputDPhi_ = 0.;
247  }
248  double U = pfU_*mvaOutputU_;
249  double Phi = pfPhi_ + mvaOutputDPhi_;
250  if ( U < 0. ) Phi += Pi;
251  double cosPhi = cos(Phi);
252  double sinPhi = sin(Phi);
253  double metPx = U*cosPhi - sumLeptonPx_; // CV: U is actually minus the hadronic recoil in the event
254  double metPy = U*sinPhi - sumLeptonPy_;
255  double metPt = sqrt(metPx*metPx + metPy*metPy);
256  mvaMEt_.SetCoordinates(metPx, metPy, 0., metPt);
257 
258  // compute MET uncertainties in dirrections parallel and perpendicular to hadronic recoil
259  // (neglecting uncertainties on lepton momenta)
260  mvaMEtCov_(0, 0) = mvaOutputCovU1_*cosPhi*cosPhi + mvaOutputCovU2_*sinPhi*sinPhi;
261  mvaMEtCov_(0, 1) = -mvaOutputCovU1_*sinPhi*cosPhi + mvaOutputCovU2_*sinPhi*cosPhi;
262  mvaMEtCov_(1, 0) = mvaMEtCov_(0, 1);
263  mvaMEtCov_(1, 1) = mvaOutputCovU1_*sinPhi*sinPhi + mvaOutputCovU2_*cosPhi*cosPhi;
264 }
265 //-------------------------------------------------------------------------------
266 
267 //-------------------------------------------------------------------------------
269 {
270  mvaInputU_[0] = pfSumEt_; // PH: helps flattens response vs. Nvtx
272  mvaInputU_[2] = pfU_;
273  mvaInputU_[3] = pfPhi_;
274  mvaInputU_[4] = tkSumEt_;
275  mvaInputU_[5] = tkU_;
276  mvaInputU_[6] = tkPhi_;
277  mvaInputU_[7] = npuSumEt_;
278  mvaInputU_[8] = npuU_;
279  mvaInputU_[9] = npuPhi_;
280  mvaInputU_[10] = puSumEt_;
281  mvaInputU_[11] = puMEt_;
282  mvaInputU_[12] = puPhi_;
283  mvaInputU_[13] = pucSumEt_;
284  mvaInputU_[14] = pucU_;
285  mvaInputU_[15] = pucPhi_;
286  mvaInputU_[16] = jet1Pt_;
287  mvaInputU_[17] = jet1Eta_;
288  mvaInputU_[18] = jet1Phi_;
289  mvaInputU_[19] = jet2Pt_;
290  mvaInputU_[20] = jet2Eta_;
291  mvaInputU_[21] = jet2Phi_;
292  mvaInputU_[22] = numJets_;
296 }
297 
299 {
301  mvaInputDPhi_[1] = pfU_;
302  mvaInputDPhi_[2] = pfPhi_;
303  mvaInputDPhi_[3] = tkSumEt_;
304  mvaInputDPhi_[4] = tkU_;
305  mvaInputDPhi_[5] = tkPhi_;
307  mvaInputDPhi_[7] = npuU_;
308  mvaInputDPhi_[8] = npuPhi_;
309  mvaInputDPhi_[9] = puSumEt_;
310  mvaInputDPhi_[10] = puMEt_;
311  mvaInputDPhi_[11] = puPhi_;
312  mvaInputDPhi_[12] = pucSumEt_;
313  mvaInputDPhi_[13] = pucU_;
314  mvaInputDPhi_[14] = pucPhi_;
315  mvaInputDPhi_[15] = jet1Pt_;
316  mvaInputDPhi_[16] = jet1Eta_;
317  mvaInputDPhi_[17] = jet1Phi_;
318  mvaInputDPhi_[18] = jet2Pt_;
319  mvaInputDPhi_[19] = jet2Eta_;
320  mvaInputDPhi_[20] = jet2Phi_;
321  mvaInputDPhi_[21] = numJets_;
324 }
325 
327 {
328  mvaInputCovU1_[0] = pfSumEt_; // PH: helps flattens response vs. Nvtx
330  mvaInputCovU1_[2] = pfU_;
331  mvaInputCovU1_[3] = pfPhi_;
333  mvaInputCovU1_[5] = tkU_;
334  mvaInputCovU1_[6] = tkPhi_;
336  mvaInputCovU1_[8] = npuU_;
337  mvaInputCovU1_[9] = npuPhi_;
338  mvaInputCovU1_[10] = puSumEt_;
339  mvaInputCovU1_[11] = puMEt_;
340  mvaInputCovU1_[12] = puPhi_;
342  mvaInputCovU1_[14] = pucU_;
343  mvaInputCovU1_[15] = pucPhi_;
344  mvaInputCovU1_[16] = jet1Pt_;
345  mvaInputCovU1_[17] = jet1Eta_;
346  mvaInputCovU1_[18] = jet1Phi_;
347  mvaInputCovU1_[19] = jet2Pt_;
348  mvaInputCovU1_[20] = jet2Eta_;
349  mvaInputCovU1_[21] = jet2Phi_;
350  mvaInputCovU1_[22] = numJets_;
355  if ( !isOld42_ ) mvaOutputCovU1_ *= mvaOutputCovU1_; // PH: Training is not on the square anymore
356 }
357 
359 {
360  mvaInputCovU2_[0] = pfSumEt_; // PH: helps flattens response vs. Nvtx
362  mvaInputCovU2_[2] = pfU_;
363  mvaInputCovU2_[3] = pfPhi_;
365  mvaInputCovU2_[5] = tkU_;
366  mvaInputCovU2_[6] = tkPhi_;
368  mvaInputCovU2_[8] = npuU_;
369  mvaInputCovU2_[9] = npuPhi_;
370  mvaInputCovU2_[10] = puSumEt_;
371  mvaInputCovU2_[11] = puMEt_;
372  mvaInputCovU2_[12] = puPhi_;
374  mvaInputCovU2_[14] = pucU_;
375  mvaInputCovU2_[15] = pucPhi_;
376  mvaInputCovU2_[16] = jet1Pt_;
377  mvaInputCovU2_[17] = jet1Eta_;
378  mvaInputCovU2_[18] = jet1Phi_;
379  mvaInputCovU2_[19] = jet2Pt_;
380  mvaInputCovU2_[20] = jet2Eta_;
381  mvaInputCovU2_[21] = jet2Phi_;
382  mvaInputCovU2_[22] = numJets_;
387  if ( !isOld42_ ) mvaOutputCovU2_ *= mvaOutputCovU2_; // PH: Training is not on the square anymore
388 }
389 void PFMETAlgorithmMVA::print(std::ostream& stream) const
390 {
391  stream << "<PFMETAlgorithmMVA::print>:" << std::endl;
392  stream << " PF: sumEt = " << pfSumEt_ << ", U = " << pfU_ << ", phi = " << pfPhi_ << std::endl;
393  stream << " TK: sumEt = " << tkSumEt_ << ", U = " << tkU_ << ", phi = " << tkPhi_ << std::endl;
394  stream << " NPU: sumEt = " << npuSumEt_ << ", U = " << npuU_ << ", phi = " << npuPhi_ << std::endl;
395  stream << " PU: sumEt = " << puSumEt_ << ", MEt = " << puMEt_ << ", phi = " << puPhi_ << std::endl;
396  stream << " PUC: sumEt = " << pucSumEt_ << ", U = " << pucU_ << ", phi = " << pucPhi_ << std::endl;
397  stream << " jet1: Pt = " << jet1Pt_ << ", eta = " << jet1Eta_ << ", phi = " << jet1Phi_ << std::endl;
398  stream << " jet2: Pt = " << jet2Pt_ << ", eta = " << jet2Eta_ << ", phi = " << jet2Phi_ << std::endl;
399  stream << " num. jets = " << numJets_ << " (" << numJetsPtGt30_ << " with Pt > 30 GeV)" << std::endl;
400  stream << " num. vertices = " << numVertices_ << std::endl;
401  stream << " MVA output: U = " << mvaOutputU_ << ", dPhi = " << mvaOutputDPhi_ << ","
402  << " covU1 = " << mvaOutputCovU1_ << ", covU2 = " << mvaOutputCovU2_ << std::endl;
403  stream << " sum(leptons): Pt = " << sqrt(sumLeptonPx_*sumLeptonPx_ + sumLeptonPy_*sumLeptonPy_) << ","
404  << " phi = " << atan2(sumLeptonPy_, sumLeptonPx_) << " "
405  << "(Px = " << sumLeptonPx_ << ", Py = " << sumLeptonPy_ << ")" << std::endl;
406 }
407 
double GetResponse(const float *vector) const
Definition: GBRForest.h:55
const double Pi
T getParameter(std::string const &) const
reco::Candidate::LorentzVector leadJetP4(const std::vector< JetInfo > &)
tuple cfg
Definition: looper.py:237
void print(std::ostream &) const
unsigned numJetsAboveThreshold(const std::vector< JetInfo > &, double)
mvaMEtUtilities utils_
const GBRForest * mvaReaderCovU1_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const GBRForest * mvaReaderCovU2_
edm::ParameterSet cfg_
#define nullptr
std::string mvaNameCovU1_
CommonMETData computeNegPFRecoil(const CommonMETData &, const std::vector< pfCandInfo > &, double)
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
const GBRForest * mvaReaderDPhi_
const GBRForest * mvaReaderU_
PFMETAlgorithmMVA(const edm::ParameterSet &cfg)
T sqrt(T t)
Definition: SSEVec.h:48
vector< PseudoJet > jets
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Structure containing data common to all types of MET.
Definition: CommonMETData.h:12
void initialize(const edm::EventSetup &)
reco::Candidate::LorentzVector subleadJetP4(const std::vector< JetInfo > &)
reco::METCovMatrix mvaMEtCov_
CommonMETData computeNegNoPURecoil(const CommonMETData &, const std::vector< pfCandInfo > &, const std::vector< JetInfo > &, double)
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:159
const T & get() const
Definition: EventSetup.h:55
CommonMETData computeSumLeptons(const std::vector< leptonInfo > &leptons, bool iCharged)
T const * product() const
Definition: ESHandle.h:86
CommonMETData computeNegPUCRecoil(const CommonMETData &, const std::vector< pfCandInfo > &, const std::vector< JetInfo > &, double)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:41
CommonMETData computePUMEt(const std::vector< pfCandInfo > &, const std::vector< JetInfo > &, double)
std::string mvaNameDPhi_
reco::Candidate::LorentzVector mvaMEt_
void setInput(const std::vector< mvaMEtUtilities::leptonInfo > &, const std::vector< mvaMEtUtilities::JetInfo > &, const std::vector< mvaMEtUtilities::pfCandInfo > &, const std::vector< reco::Vertex::Point > &)
std::string mvaNameCovU2_
std::string fullPath() const
Definition: FileInPath.cc:165
CommonMETData computeNegTrackRecoil(const CommonMETData &, const std::vector< pfCandInfo > &, double)
std::vector< JetInfo > cleanJets(const std::vector< JetInfo > &, const std::vector< leptonInfo > &, double, double)
tuple loadMVAfromDB
Definition: mvaPFMET_cff.py:41