CMS 3D CMS Logo

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 = std::cos(-1);
19 
21  if (input == "sumet")
22  return "particleFlow_SumET";
23  if (input == "npv")
24  return "nPV";
25  if (input == "pfu")
26  return "particleFlow_U";
27  if (input == "pfuphi")
28  return "particleFlow_UPhi";
29  if (input == "tksumet")
30  return "track_SumET";
31  if (input == "tku")
32  return "track_U";
33  if (input == "tkuphi")
34  return "track_UPhi";
35  if (input == "nopusumet")
36  return "noPileUp_SumET";
37  if (input == "nopuu")
38  return "noPileUp_U";
39  if (input == "nopuuphi")
40  return "noPileUp_UPhi";
41  if (input == "pusumet")
42  return "pileUp_SumET";
43  if (input == "pumet")
44  return "pileUp_MET";
45  if (input == "pumetphi")
46  return "pileUp_METPhi";
47  if (input == "pucsumet")
48  return "pileUpCorrected_SumET";
49  if (input == "pucu")
50  return "pileUpCorrected_U";
51  if (input == "pucuphi")
52  return "pileUpCorrected_UPhi";
53  if (input == "jetpt1")
54  return "jet1_pT";
55  if (input == "jeteta1")
56  return "jet1_eta";
57  if (input == "jetphi1")
58  return "jet1_Phi";
59  if (input == "jetpt2")
60  return "jet2_pT";
61  if (input == "jeteta2")
62  return "jet2_eta";
63  if (input == "jetphi2")
64  return "jet2_Phi";
65  if (input == "nalljet")
66  return "nJets";
67  if (input == "njet")
68  return "numJetsPtGt30";
69  if (input == "uphi_mva")
70  return "PhiCor_UPhi";
71  if (input == "uphix_mva")
72  return "PhiCor_UPhi";
73  if (input == "ux_mva")
74  return "RecoilCor_U";
75  return input;
76 }
77 
79  if (inputFileName.location() == edm::FileInPath::Unknown)
80  throw cms::Exception("PFMETAlgorithmMVA::loadMVA") << " Failed to find File = " << inputFileName << " !!\n";
81  std::unique_ptr<TFile> inputFile(new TFile(inputFileName.fullPath().data()));
82 
83  std::vector<std::string>* lVec = (std::vector<std::string>*)inputFile->Get("varlist");
84 
85  if (lVec == nullptr) {
86  throw cms::Exception("PFMETAlgorithmMVA::loadMVA")
87  << " Failed to load mva file : " << inputFileName.fullPath().data() << " is not a proper file !!\n";
88  }
89 
90  std::vector<std::string> variableNames;
91  for (unsigned int i = 0; i < lVec->size(); ++i) {
92  variableNames.push_back(updateVariableNames(lVec->at(i)));
93  }
94 
95  if (mvaName.find(mvaNameU_) != std::string::npos)
96  varForU_ = variableNames;
97  else if (mvaName.find(mvaNameDPhi_) != std::string::npos)
98  varForDPhi_ = variableNames;
99  else if (mvaName.find(mvaNameCovU1_) != std::string::npos)
100  varForCovU1_ = variableNames;
101  else if (mvaName.find(mvaNameCovU2_) != std::string::npos)
102  varForCovU2_ = variableNames;
103  else
104  throw cms::Exception("PFMETAlgorithmMVA::loadMVA")
105  << "MVA MET weight file tree names do not match specified inputs" << std::endl;
106 
107  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
108  if (!mva)
109  throw cms::Exception("PFMETAlgorithmMVA::loadMVA")
110  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
111 
112  return mva;
113 }
114 
117  es.get<GBRWrapperRcd>().get(mvaName, mva);
118  return mva.product();
119 }
120 
122  : utils_(cfg),
127  cfg_(cfg) {
129 
130  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
131 }
132 
134  if (!loadMVAfromDB_) {
135  delete mvaReaderU_;
136  delete mvaReaderDPhi_;
137  delete mvaReaderCovU1_;
138  delete mvaReaderCovU2_;
139  }
140 }
141 
142 //-------------------------------------------------------------------------------
144  edm::ParameterSet cfgInputRecords = cfg_.getParameter<edm::ParameterSet>("inputRecords");
145  mvaNameU_ = cfgInputRecords.getParameter<std::string>("U");
146  mvaNameDPhi_ = cfgInputRecords.getParameter<std::string>("DPhi");
147  mvaNameCovU1_ = cfgInputRecords.getParameter<std::string>("CovU1");
148  mvaNameCovU2_ = cfgInputRecords.getParameter<std::string>("CovU2");
149 
150  if (loadMVAfromDB_) {
151  mvaReaderU_ = loadMVAfromDB(es, mvaNameU_);
152  mvaReaderDPhi_ = loadMVAfromDB(es, mvaNameDPhi_);
153  mvaReaderCovU1_ = loadMVAfromDB(es, mvaNameCovU1_);
154  mvaReaderCovU2_ = loadMVAfromDB(es, mvaNameCovU2_);
155  } else {
156  edm::ParameterSet cfgInputFileNames = cfg_.getParameter<edm::ParameterSet>("inputFileNames");
157 
158  edm::FileInPath inputFileNameU = cfgInputFileNames.getParameter<edm::FileInPath>("U");
159  mvaReaderU_ = loadMVAfromFile(inputFileNameU, mvaNameU_);
160  edm::FileInPath inputFileNameDPhi = cfgInputFileNames.getParameter<edm::FileInPath>("DPhi");
161  mvaReaderDPhi_ = loadMVAfromFile(inputFileNameDPhi, mvaNameDPhi_);
162  edm::FileInPath inputFileNameCovU1 = cfgInputFileNames.getParameter<edm::FileInPath>("CovU1");
163  mvaReaderCovU1_ = loadMVAfromFile(inputFileNameCovU1, mvaNameCovU1_);
164  edm::FileInPath inputFileNameCovU2 = cfgInputFileNames.getParameter<edm::FileInPath>("CovU2");
165  mvaReaderCovU2_ = loadMVAfromFile(inputFileNameCovU2, mvaNameCovU2_);
166  }
167 }
168 
169 //-------------------------------------------------------------------------------
170 void PFMETAlgorithmMVA::setInput(const std::vector<reco::PUSubMETCandInfo>& leptons,
171  const std::vector<reco::PUSubMETCandInfo>& jets,
172  const std::vector<reco::PUSubMETCandInfo>& pfCandidates,
173  const std::vector<reco::Vertex::Point>& vertices) {
174  utils_.computeAllSums(jets, leptons, pfCandidates);
175 
178 
181 
182  const std::vector<reco::PUSubMETCandInfo> jets_cleaned = utils_.getCleanedJets();
183 
189 
190  reco::Candidate::LorentzVector jet1P4 = utils_.leadJetP4(jets_cleaned);
191  reco::Candidate::LorentzVector jet2P4 = utils_.subleadJetP4(jets_cleaned);
192 
193  var_["particleFlow_U"] = pfRecoil_data.met;
194  var_["particleFlow_SumET"] = pfRecoil_data.sumet;
195  var_["particleFlow_UPhi"] = pfRecoil_data.phi;
196 
197  var_["track_SumET"] = chHSRecoil_data.sumet / var_["particleFlow_SumET"];
198  var_["track_U"] = chHSRecoil_data.met;
199  var_["track_UPhi"] = chHSRecoil_data.phi;
200 
201  var_["noPileUp_SumET"] = hsRecoil_data.sumet / var_["particleFlow_SumET"];
202  var_["noPileUp_U"] = hsRecoil_data.met;
203  var_["noPileUp_UPhi"] = hsRecoil_data.phi;
204 
205  var_["pileUp_SumET"] = puRecoil_data.sumet / var_["particleFlow_SumET"];
206  var_["pileUp_MET"] = puRecoil_data.met;
207  var_["pileUp_METPhi"] = puRecoil_data.phi;
208 
209  var_["pileUpCorrected_SumET"] = hsMinusNeutralPUMEt_data.sumet / var_["particleFlow_SumET"];
210  var_["pileUpCorrected_U"] = hsMinusNeutralPUMEt_data.met;
211  var_["pileUpCorrected_UPhi"] = hsMinusNeutralPUMEt_data.phi;
212 
213  var_["jet1_pT"] = jet1P4.pt();
214  var_["jet1_eta"] = jet1P4.eta();
215  var_["jet1_Phi"] = jet1P4.phi();
216  var_["jet2_pT"] = jet2P4.pt();
217  var_["jet2_eta"] = jet2P4.eta();
218  var_["jet2_Phi"] = jet2P4.phi();
219 
220  var_["numJetsPtGt30"] = utils_.numJetsAboveThreshold(jets_cleaned, 30.);
221  var_["nJets"] = jets_cleaned.size();
222  var_["nPV"] = vertices.size();
223 }
224 
225 //-------------------------------------------------------------------------------
226 std::unique_ptr<float[]> PFMETAlgorithmMVA::createFloatVector(std::vector<std::string> variableNames) {
227  std::unique_ptr<float[]> floatVector(new float[variableNames.size()]);
228  int i = 0;
229  for (auto variableName : variableNames) {
230  floatVector[i++] = var_[variableName];
231  }
232  return floatVector;
233 }
234 
235 //-------------------------------------------------------------------------------
237  // CV: MVAs needs to be evaluated in order { DPhi, U1, CovU1, CovU2 }
238  // as MVA for U1 (CovU1, CovU2) uses output of DPhi (DPhi and U1) MVA
240  var_["PhiCor_UPhi"] = var_["particleFlow_UPhi"] + mvaOutputDPhi_;
242  var_["RecoilCor_U"] = var_["particleFlow_U"] * mvaOutputU_;
243  var_["RecoilCor_UPhi"] = var_["PhiCor_UPhi"];
244  mvaOutputCovU1_ = std::pow(GetResponse(mvaReaderCovU1_, varForCovU1_) * mvaOutputU_ * var_["particleFlow_U"], 2);
245  mvaOutputCovU2_ = std::pow(GetResponse(mvaReaderCovU2_, varForCovU2_) * mvaOutputU_ * var_["particleFlow_U"], 2);
246 
247  // compute MET(Photon check)
248  if (hasPhotons_) {
249  //Fix events with unphysical properties
250  double sumLeptonPt = std::max(sqrt(sumLeptonPx_ * sumLeptonPx_ + sumLeptonPy_ * sumLeptonPy_), 1.);
251  if (var_["track_U"] / sumLeptonPt < 0.1 || var_["noPileUp_U"] / sumLeptonPt < 0.1) {
252  mvaOutputU_ = 1.;
253  mvaOutputDPhi_ = 0.;
254  }
255  }
256  computeMET();
257 }
258 //-------------------------------------------------------------------------------
259 
261  double U = var_["RecoilCor_U"];
262  double Phi = var_["PhiCor_UPhi"];
263  if (U < 0.)
264  Phi += Pi; //RF: No sign flip for U necessary in that case?
265  double cosPhi = std::cos(Phi);
266  double sinPhi = std::sin(Phi);
267  double metPx = U * cosPhi - sumLeptonPx_;
268  double metPy = U * sinPhi - sumLeptonPy_;
269  double metPt = sqrt(metPx * metPx + metPy * metPy);
270  mvaMEt_.SetCoordinates(metPx, metPy, 0., metPt);
271  // compute MET uncertainties in dirrections parallel and perpendicular to hadronic recoil
272  // (neglecting uncertainties on lepton momenta)
273  mvaMEtCov_(0, 0) = mvaOutputCovU1_ * cosPhi * cosPhi + mvaOutputCovU2_ * sinPhi * sinPhi;
274  mvaMEtCov_(0, 1) = -mvaOutputCovU1_ * sinPhi * cosPhi + mvaOutputCovU2_ * sinPhi * cosPhi;
275  mvaMEtCov_(1, 0) = mvaMEtCov_(0, 1);
276  mvaMEtCov_(1, 1) = mvaOutputCovU1_ * sinPhi * sinPhi + mvaOutputCovU2_ * cosPhi * cosPhi;
277 }
278 
279 //-------------------------------------------------------------------------------
280 const float PFMETAlgorithmMVA::GetResponse(const GBRForest* Reader, std::vector<std::string>& variableNames) {
281  std::unique_ptr<float[]> mvaInputVector = createFloatVector(variableNames);
282  double result = Reader->GetResponse(mvaInputVector.get());
283  return result;
284 }
285 
286 //-------------------------------------------------------------------------------
287 void PFMETAlgorithmMVA::print(std::ostream& stream) const {
288  stream << "<PFMETAlgorithmMVA::print>:" << std::endl;
289  for (auto entry : var_)
290  stream << entry.first << " = " << entry.second << std::endl;
291  stream << " covU1 = " << mvaOutputCovU1_ << ", covU2 = " << mvaOutputCovU2_ << std::endl;
292  stream << " sum(leptons): Pt = " << sqrt(sumLeptonPx_ * sumLeptonPx_ + sumLeptonPy_ * sumLeptonPy_) << ","
293  << " phi = " << atan2(sumLeptonPy_, sumLeptonPx_) << " "
294  << "(Px = " << sumLeptonPx_ << ", Py = " << sumLeptonPy_ << ")";
295  stream << " MVA output: U = " << mvaOutputU_ << ", dPhi = " << mvaOutputDPhi_ << ","
296  << " covU1 = " << mvaOutputCovU1_ << ", covU2 = " << mvaOutputCovU2_ << std::endl;
297  stream << std::endl;
298 }
double GetResponse(const float *vector) const
Definition: GBRForest.h:49
T getParameter(std::string const &) const
std::vector< std::string > varForCovU2_
const std::vector< reco::PUSubMETCandInfo > & getCleanedJets() const
double getLeptonsChSumMEX() const
double getLeptonsChSumMEY() const
unsigned numJetsAboveThreshold(const std::vector< reco::PUSubMETCandInfo > &, double)
MvaMEtUtilities utils_
void print(std::ostream &) const
const GBRForest * loadMVAfromFile(const edm::FileInPath &inputFileName, const std::string &mvaName)
std::vector< std::string > varForU_
const GBRForest * mvaReaderCovU1_
const float GetResponse(const GBRForest *Reader, std::vector< std::string > &variableNames)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
#define nullptr
const GBRForest * mvaReaderCovU2_
const std::string updateVariableNames(std::string input)
edm::ParameterSet cfg_
reco::Candidate::LorentzVector subleadJetP4(const std::vector< reco::PUSubMETCandInfo > &)
std::string mvaNameCovU1_
void setInput(const std::vector< reco::PUSubMETCandInfo > &, const std::vector< reco::PUSubMETCandInfo > &, const std::vector< reco::PUSubMETCandInfo > &, const std::vector< reco::Vertex::Point > &)
static std::string const input
Definition: EdmProvDump.cc:48
const GBRForest * mvaReaderDPhi_
const GBRForest * mvaReaderU_
PFMETAlgorithmMVA(const edm::ParameterSet &cfg)
double getLeptonsSumMEX() const
T sqrt(T t)
Definition: SSEVec.h:19
std::unique_ptr< float[]> createFloatVector(std::vector< std::string > variableNames)
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 computeAllSums(const std::vector< reco::PUSubMETCandInfo > &jets, const std::vector< reco::PUSubMETCandInfo > &leptons, const std::vector< reco::PUSubMETCandInfo > &pfCandidates)
const GBRForest * loadMVAfromDB(const edm::EventSetup &es, const std::string &mvaName)
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:161
void initialize(const edm::EventSetup &)
reco::METCovMatrix mvaMEtCov_
std::vector< std::string > varForCovU1_
reco::Candidate::LorentzVector leadJetP4(const std::vector< reco::PUSubMETCandInfo > &)
const double Pi
double getLeptonsSumMEY() const
CommonMETData computeRecoil(int metType)
std::vector< std::string > varForDPhi_
std::map< std::string, float > var_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
std::string mvaNameDPhi_
reco::Candidate::LorentzVector mvaMEt_
T get() const
Definition: EventSetup.h:73
std::string fullPath() const
Definition: FileInPath.cc:163
std::string mvaNameCovU2_
T const * product() const
Definition: ESHandle.h:86
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30