babymaker  e95a6a9342d4604277fe7cc6149b6b5b24447d89
jet_met_tools.cc
Go to the documentation of this file.
1 // jet_met_tools: Functions related to jets, MET, and JECs
2 
3 // System include files
4 #include <cmath>
5 #include <cstdlib>
6 #include <iostream>
7 #include <string>
8 
9 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
10 #include <DataFormats/Math/interface/deltaR.h>
11 #include <DataFormats/Math/interface/deltaPhi.h>
12 #include <fastjet/JetDefinition.hh>
13 #include <fastjet/PseudoJet.hh>
14 #include <fastjet/ClusterSequence.hh>
15 #include <fastjet/GhostedAreaSpec.hh>
16 
17 // User include files
20 
21 // ROOT include files
22 #include "TFile.h"
23 
24 using namespace std;
25 using namespace utilities;
26 
27 const vector<BTagEntry::OperatingPoint> jet_met_tools::op_pts_{BTagEntry::OP_LOOSE, BTagEntry::OP_MEDIUM, BTagEntry::OP_TIGHT};
28 const vector<BTagEntry::JetFlavor> jet_met_tools::flavors_{BTagEntry::FLAV_B, BTagEntry::FLAV_C, BTagEntry::FLAV_UDSG};
29 
30 namespace{
31  template<typename T, typename... Args>
32  std::unique_ptr<T> MakeUnique(Args&&... args){
33  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
34  }
35 }
36 
37 bool jet_met_tools::leptonInJet(const pat::Jet &jet, vCands leptons){
38  for(unsigned ilep(0); ilep < leptons.size(); ilep++){
39  int indpf(-1);
40  unsigned npflep(leptons[ilep]->numberOfSourceCandidatePtrs());
41  if(leptons[ilep]->isMuon() && npflep==1) indpf = 0;
42  if(leptons[ilep]->isElectron() && npflep==2) indpf = 1; // Electrons have a missing reference at 0
43  if(indpf>=0){ // The lepton is PF -> looping over PF cands in jet
44  for (unsigned ijet(0); ijet < jet.numberOfSourceCandidatePtrs(); ijet++)
45  if(jet.sourceCandidatePtr(ijet) == leptons[ilep]->sourceCandidatePtr(indpf))
46  return true;
47  } else { // The lepton is not PF, matching with deltaR
48  if(deltaR(jet, *leptons[ilep]) < sizeJet) return true;
49  }
50  } // Loop over leptons
51 
52  return false;
53 }
54 
55 // Loose jet matching from RA2/b just for cleaning
56 bool jet_met_tools::jetMatched(const pat::Jet &jet, vCands objects){
57  int nph(0); // Just cleaning the first photon with 100 GeV
58  for(unsigned ind(0); ind < objects.size(); ind++){
59  double dr(deltaR(jet, *(objects[ind])));
60  double drelpt(fabs((objects[ind]->pt() - jet.pt())/objects[ind]->pt()));
61  if(objects[ind]->pdgId()==22) {
62  if(objects[ind]->pt()>100){
63  nph++;
64  if(nph>1) continue;
65  } else continue;
66  } // If it is a photon
67  if(drelpt < 1. && dr < sizeJet) return true;
68  } // Loop over objects
69  return false;
70 }
71 
72 float jet_met_tools::getGenPt(const pat::Jet &jet, edm::Handle<edm::View <reco::GenJet> > genjets){
73  if(!genjets.isValid()) return -99999.;
74 
75  float genjetpt = -99999.;
76  float mindr = 999;
77  for (size_t ijet(0); ijet < genjets->size(); ijet++) {
78  const reco::GenJet &genjet = (*genjets)[ijet];
79  double dr(deltaR(jet, genjet));
80  if(dr < mindr) {
81  mindr = dr;
82  genjetpt = genjet.pt();
83  }
84  }
85  if (mindr<0.3) return genjetpt;
86  else return -99999.;
87 }
88 
89 bool jet_met_tools::matchesGenJet(const pat::Jet &jet, edm::Handle<edm::View <reco::GenJet> > genjets){
90  if(!genjets.isValid()) return false;
91  for (size_t ijet(0); ijet < genjets->size(); ijet++) {
92  const reco::GenJet &genjet = (*genjets)[ijet];
93  double dr(deltaR(jet, genjet));
94  if(dr < 0.3) return true;
95  }
96  return false;
97 }
98 
99 
100 
101 bool jet_met_tools::isLowDphi(vCands jets, float mht_phi, float &dphi1, float &dphi2, float &dphi3, float &dphi4){
102  dphi1 = 10.; dphi2 = 10.; dphi3 = 10.; dphi4 = 10.;
103  float *dphi[] = {&dphi1, &dphi2, &dphi3, &dphi4};
104  for(unsigned ind(0); ind < jets.size() && ind < 4; ind++)
105  *(dphi[ind]) = abs(reco::deltaPhi(jets[ind]->phi(), mht_phi));
106  return (dphi1<0.5 || dphi2<0.5 || dphi3<0.3 || dphi4<0.3);
107 }
108 
109 float jet_met_tools::trueHT(edm::Handle<edm::View <reco::GenJet> > genjets){
110  float ht(0.);
111  for (size_t ijet(0); ijet < genjets->size(); ijet++) {
112  const reco::GenJet &jet = (*genjets)[ijet];
113  if(jet.pt() > JetHLTPtCut && fabs(jet.eta()) <= JetHLTEtaCut) ht += jet.pt();
114  }
115  return ht;
116 }
117 
118 bool jet_met_tools::idJet(const pat::Jet &jet, CutLevel cut){
119  // From https://twiki.cern.ch/twiki/bin/view/CMS/JetID
120  double eta = fabs(jet.eta());
121  double NHF = jet.neutralHadronEnergyFraction();
122  double NEMF = jet.neutralEmEnergyFraction();
123  double NumConst = jet.chargedMultiplicity()+jet.neutralMultiplicity();
124  double NumNeutralParticles =jet.neutralMultiplicity();
125 
126  double CHF = jet.chargedHadronEnergyFraction();
127  double CHM = jet.chargedMultiplicity();
128  double CEMF = jet.chargedEmEnergyFraction();
129 
130  if(cut == kPBNR){ // RA2/b's PBNR and old Jet ID
131  bool eta_l_2p4 = NumConst>=2 && NHF<0.9 && NEMF<0.95 && CHM>0 && CHF>0 && CEMF<0.99;
132  bool eta_geq_2p4 = NHF<0.9 && NEMF<0.95 && NumConst>=2;
133  return (eta_l_2p4 && eta<2.4) || (eta>=2.4 && eta_geq_2p4);
134  }
135 
136  bool passJetID = true;
137  if (eta<=2.7) {
138  if (cut==kLoose) passJetID = NHF<0.99 && NEMF<0.99 && NumConst>1;
139  if (cut==kTight) passJetID = NHF<0.90 && NEMF<0.90 && NumConst>1;
140  if (eta<=2.4){
141  passJetID = passJetID && CHF>0 && CHM>0 && CEMF<0.99;
142  }
143  } else if (eta<=3.0) {
144  passJetID = NHF<0.98 && NEMF>0.01 && NumNeutralParticles>2;
145  } else {
146  passJetID = NEMF<0.90 && NumNeutralParticles>10;
147  }
148  return passJetID;
149 }
150 
151 
152 void jet_met_tools::getJetCorrections(edm::Handle<edm::View <reco::GenJet> > genjets, edm::Handle<pat::JetCollection> alljets, double rhoEvent){
153  rhoEvent_ = rhoEvent;
154  alljets_ = alljets;
155  jetTotCorrections.resize(alljets->size(), 1.);
156  jetL1Corrections.resize(alljets->size(), 1.);
157  jecUnc.resize(alljets->size(), 0.);
158  jerUnc.resize(alljets->size(), 0.);
159  corrJet.clear();
160  genJetPt.clear();
161  if(!doJEC) {
162  for (size_t ijet(0); ijet < alljets->size(); ijet++) {
163  const pat::Jet &jet = (*alljets)[ijet];
164  corrJet.push_back(jet.p4());
165  genJetPt.push_back(getGenPt(jet, genjets));
166  }
167  if (doSystematics) setJetUncertainties(genjets);
168  return;
169  }
170 
171  for (size_t ijet(0); ijet < alljets->size(); ijet++) {
172  const pat::Jet &jet = (*alljets)[ijet];
173  float rawFactor(jet.jecFactor("Uncorrected"));
174  jetValues.setJetPt(jet.pt()*rawFactor);
175  jetValues.setJetEta(jet.eta());
176  jetValues.setJetA(jet.jetArea());
177  jetValues.setRho(rhoEvent);
178  vector<float> corr_vals = jetCorrector->getSubCorrections(jetValues);
179  jetTotCorrections[ijet] = corr_vals.at(corr_vals.size()-1); // All corrections
180  jetL1Corrections[ijet] = corr_vals.at(0); // L1 PU correction (offset)
181  corrJet.push_back(jet.p4()*rawFactor*jetTotCorrections[ijet]); // LorentzVecor with all corrections * raw factor
182 
183  //the genJets should be obtained even if we are not running systematics, since we save the pT resolution in the babies
184  genJetPt.push_back(getGenPt(jet, genjets));
185  if (doSystematics){
186  //set JECs uncertainty values
187  jecUncProvider->setJetEta(jet.eta());
188  jecUncProvider->setJetPt(corrJet[ijet].pt());
189  jecUnc[ijet] = jecUncProvider->getUncertainty(true);
190  if (isData) jecUnc[ijet] = sqrt(pow(jecUnc[ijet],2) + pow((corr_vals.at(corr_vals.size()-1)/corr_vals.at(corr_vals.size()-2)-1.),2));
191  //set JER uncertainty values
192 
193  float smearedJetPt(0.);
194  if (genJetPt[ijet]>0) smearedJetPt = genJetPt[ijet] + getJetResolutionSF(jet.eta())*(corrJet[ijet].pt() - genJetPt[ijet]);
195  jerUnc[ijet] = smearedJetPt/corrJet[ijet].pt() - 1.;
196  if (smearedJetPt < 0.01) jerUnc[ijet] = 0.; // so data will not have resolution unc.
197  }
198  } // Loop over alljets
199 
200 }
201 
202 void jet_met_tools::setJetUncertainties(edm::Handle<edm::View <reco::GenJet> > genjets){
203  // if we are doing systematics but not applying JECs, call this function to load uncertainties independently of JECs
204  for (size_t ijet(0); ijet < alljets_->size(); ijet++) {
205  const pat::Jet &jet = (*alljets_)[ijet];
206  //set JECs uncertainty values
207  jecUncProvider->setJetEta(jet.eta());
208  jecUncProvider->setJetPt(corrJet[ijet].pt());
209  jecUnc[ijet] = jecUncProvider->getUncertainty(true);
210  if (isData) {
211  float rawFactor(jet.jecFactor("Uncorrected"));
212  jetValues.setJetPt(jet.pt()*rawFactor);
213  jetValues.setJetEta(jet.eta());
214  jetValues.setJetA(jet.jetArea());
215  jetValues.setRho(rhoEvent_);
216  vector<float> corr_vals = jetCorrector->getSubCorrections(jetValues);
217  jecUnc[ijet] = sqrt(pow(jecUnc[ijet],2) + pow((corr_vals.at(corr_vals.size()-1)/corr_vals.at(corr_vals.size()-2)-1.),2));
218  }
219  //set JER uncertainty values
220  float smearedJetPt(0.);
221  if (genJetPt[ijet]>0) smearedJetPt = genJetPt[ijet] + getJetResolutionSF(jet.eta())*(corrJet[ijet].pt() - genJetPt[ijet]);
222  jerUnc[ijet] = smearedJetPt/corrJet[ijet].pt() - 1.;
223  if (smearedJetPt < 0.01) jerUnc[ijet] = 0.; // so data will not have resolution unc.
224  } // Loop over alljets
225 }
226 
227 void jet_met_tools::getMETRaw(edm::Handle<pat::METCollection> mets, float &metRaw, float &metRawPhi){
228  metRaw = mets->at(0).uncorPt();
229  metRawPhi = mets->at(0).uncorPhi();
230 }
231 
232 void jet_met_tools::getMETWithJEC(edm::Handle<pat::METCollection> mets, float &met, float &metPhi, unsigned isys){
233  if(!doJEC && (!doSystematics || isys==kSysLast)) {
234  met = mets->at(0).pt();
235  metPhi = mets->at(0).phi();
236  return;
237  }
238 
239  float metRaw, metRawPhi;
240  getMETRaw(mets, metRaw, metRawPhi);
241  float metx(metRaw*cos(metRawPhi)), mety(metRaw*sin(metRawPhi));
242 
243  // Code to skip muons and EM from
244  // https://github.com/cms-sw/cmssw/blob/8d582ad580a446865fc58675d16f6cdf2dae3605/JetMETCorrections/Type1MET/interface/PFJetMETcorrInputProducerT.h#L173-L184
245  StringCutObjectSelector<reco::Candidate> skipMuonSelection("isGlobalMuon | isStandAloneMuon",true);
246  for (size_t ijet(0); ijet < alljets_->size(); ijet++) {
247  const pat::Jet &jet = (*alljets_)[ijet];
248 
249  double emEnergyFraction = jet.chargedEmEnergyFraction() + jet.neutralEmEnergyFraction();
250  if(emEnergyFraction > 0.90 || fabs(jet.eta()) > 9.9) continue;
251 
252  reco::Candidate::LorentzVector rawJetP4 = jet.p4()*jet.jecFactor("Uncorrected");
253  float totCorr(jetTotCorrections[ijet]), l1Corr(jetL1Corrections[ijet]);
254  const std::vector<reco::CandidatePtr> & cands = jet.daughterPtrVector();
255  for ( std::vector<reco::CandidatePtr>::const_iterator cand = cands.begin();
256  cand != cands.end(); ++cand ) {
257  const reco::PFCandidate *pfcand = dynamic_cast<const reco::PFCandidate *>(cand->get());
258  const reco::Candidate *mu = (pfcand != 0 ? ( pfcand->muonRef().isNonnull() ? pfcand->muonRef().get() : 0) : cand->get());
259  if ( mu != 0 && skipMuonSelection(*mu) ) {
260  reco::Candidate::LorentzVector muonP4 = (*cand)->p4();
261  rawJetP4 -= muonP4;
262  jetValues.setJetPt(rawJetP4.pt());
263  jetValues.setJetEta(rawJetP4.eta());
264  jetValues.setJetA(jet.jetArea());
265  jetValues.setRho(rhoEvent_);
266  vector<float> corr_vals = jetCorrector->getSubCorrections(jetValues);
267  totCorr = corr_vals.at(corr_vals.size()-1); // All corrections
268  l1Corr = corr_vals.at(0); // L1 PU correction (offset)
269  }
270  }
271 
272  if (isys == kSysJER) totCorr *= 1+jerUnc[ijet];
273  else if (isys == kSysJECUp) totCorr *= 1+jecUnc[ijet];
274  else if (isys == kSysJECDn) totCorr *= 1-jecUnc[ijet];
275 
276  if((rawJetP4.pt()*totCorr) <= 15.) continue;
277  metx -= rawJetP4.px()*(totCorr - l1Corr);
278  mety -= rawJetP4.py()*(totCorr - l1Corr);
279  } // Loop over alljets_
280 
281  met = hypot(metx,mety);
282  metPhi = atan2(mety,metx);
283 
284 }
285 
286 float jet_met_tools::jetBTagWeight(const pat::Jet &jet, const LVector &jetp4,
287  BTagEntry::OperatingPoint op,
288  const string &bc_full_syst, const string &udsg_full_syst,
289  const string &bc_fast_syst, const string &udsg_fast_syst, bool doDeepCSV, bool doByProc) const{
290  return jetBTagWeight(jet, jetp4, vector<BTagEntry::OperatingPoint>{op},
291  bc_full_syst, udsg_full_syst, bc_fast_syst, udsg_fast_syst, doDeepCSV, doByProc);
292 }
293 
294 float jet_met_tools::jetBTagWeight(const pat::Jet &jet, const LVector &jetp4,
295  BTagEntry::OperatingPoint op,
296  const string &bc_full_syst, const string &udsg_full_syst, bool doDeepCSV, bool doByProc) const{
297  return jetBTagWeight(jet, jetp4, vector<BTagEntry::OperatingPoint>{op},
298  bc_full_syst, udsg_full_syst, "central", "central", doDeepCSV, doByProc);
299 }
300 
301 float jet_met_tools::jetBTagWeight(const pat::Jet &jet, const LVector &jetp4,
302  const vector<BTagEntry::OperatingPoint> &ops,
303  const string &bc_full_syst, const string &udsg_full_syst, bool doDeepCSV, bool doByProc) const{
304  return jetBTagWeight(jet, jetp4, ops,
305  bc_full_syst, udsg_full_syst, "central", "central", doDeepCSV, doByProc);
306 }
307 
308 float jet_met_tools::jetBTagWeight(const pat::Jet &jet, const LVector &jetp4,
309  const vector<BTagEntry::OperatingPoint> &ops,
310  const string &bc_full_syst, const string &udsg_full_syst,
311  const string &bc_fast_syst, const string &udsg_fast_syst, bool doDeepCSV, bool doByProc) const{
312  // procedure from https://twiki.cern.ch/twiki/bin/view/CMS/BTagSFMethods#1a_Event_reweighting_using_scale
313  int hadronFlavour = abs(jet.hadronFlavour());
314  BTagEntry::JetFlavor flav;
315  string full_syst, fast_syst;
316  switch(hadronFlavour){
317  case 5: flav = BTagEntry::FLAV_B; break;
318  case 4: flav = BTagEntry::FLAV_C; break;
319  default: flav = BTagEntry::FLAV_UDSG; break;
320  }
321  switch(flav){
322  case BTagEntry::FLAV_B:
323  case BTagEntry::FLAV_C:
324  full_syst = bc_full_syst;
325  fast_syst = bc_fast_syst;
326  break;
327  case BTagEntry::FLAV_UDSG:
328  full_syst = udsg_full_syst;
329  fast_syst = udsg_fast_syst;
330  break;
331  default:
332  ERROR("Did not recognize BTagEntry::JetFlavor " << static_cast<int>(flav));
333  }
334 
335  vector<float> opcuts;
336  for (auto &iop: ops) {
337  if (iop==BTagEntry::OP_LOOSE) opcuts.push_back(doDeepCSV ? DeepCSVLoose: CSVLoose);
338  else if (iop==BTagEntry::OP_MEDIUM) opcuts.push_back(doDeepCSV ? DeepCSVMedium: CSVMedium);
339  else if (iop==BTagEntry::OP_TIGHT) opcuts.push_back(doDeepCSV ? DeepCSVTight: CSVTight);
340  }
341 
342  float csv = jet.bDiscriminator("pfCombinedInclusiveSecondaryVertexV2BJetTags");
343  if (doDeepCSV)
344  csv = jet.bDiscriminator("deepFlavourJetTags:probb")+jet.bDiscriminator("deepFlavourJetTags:probbb");
345 
346  int tag = -1;
347  for (unsigned iop(0); iop<opcuts.size(); iop++)
348  if (csv>opcuts[iop]) tag = iop;
349 
350  const map<BTagEntry::OperatingPoint, unique_ptr<BTagCalibrationReader> > *ireaders_full = &readers_full_;
351  if (doDeepCSV) ireaders_full = &readers_deep_full_;
352  const map<BTagEntry::OperatingPoint, unique_ptr<BTagCalibrationReader> > *ireaders_fast = &readers_fast_;
353  if (doDeepCSV) ireaders_fast = &readers_deep_fast_;
354 
355  double eff1(1), eff2(0), sf1(1), sf2(1), sf1_fs(1), sf2_fs(1);
356  if (tag >= 0){
357  BTagEntry::OperatingPoint iop = ops[tag];
358  eff1 = getMCTagEfficiency(hadronFlavour, jetp4.pt(), jetp4.eta(), iop, doDeepCSV, doByProc);
359  sf1 = ireaders_full->at(iop)->eval_auto_bounds(full_syst, flav, jetp4.eta(), jetp4.pt());
360  if (isFastSim) sf1_fs = ireaders_fast->at(iop)->eval_auto_bounds(fast_syst, flav, jetp4.eta(), jetp4.pt());
361  }
362  if (tag < int(ops.size())-1) {
363  BTagEntry::OperatingPoint iop = ops[tag+1];
364  eff2 = getMCTagEfficiency(hadronFlavour, jetp4.pt(), jetp4.eta(), iop, doDeepCSV, doByProc);
365  sf2 = ireaders_full->at(iop)->eval_auto_bounds(full_syst, flav, jetp4.eta(), jetp4.pt());
366  if (isFastSim) sf2_fs = ireaders_fast->at(iop)->eval_auto_bounds(fast_syst, flav, jetp4.eta(), jetp4.pt());
367  }
368 
369  double eff1_fs(eff1/sf1_fs), eff2_fs(eff2/sf2_fs);
370  return (sf1*sf1_fs*eff1_fs-sf2*sf2_fs*eff2_fs)/(eff1_fs-eff2_fs);
371 }
372 
373 float jet_met_tools::getMCTagEfficiency(int pdgId, float pT, float eta, BTagEntry::OperatingPoint op, bool doDeepCSV, bool doByProc) const{
374  size_t rdr_idx = distance(op_pts_.cbegin(), find(op_pts_.cbegin(), op_pts_.cend(), op));
375  pdgId = abs(pdgId);
376  if(pdgId != 4 && pdgId != 5){
377  // in the ghost clustering scheme to determine flavor, there are only b, c and other (id=0) flavors
378  pdgId = 0;
379  }
380 
381  int bin;
382  float eff;
383  if(!doDeepCSV){
384  if(!doByProc){
385  bin = btag_efficiencies_.at(rdr_idx)->FindFixBin(fabs(eta), pT, pdgId);
386  eff = btag_efficiencies_.at(rdr_idx)->GetBinContent(bin);
387  }
388  else{
389  bin = btag_efficiencies_proc_.at(rdr_idx)->FindFixBin(fabs(eta), pT, pdgId);
390  eff = btag_efficiencies_proc_.at(rdr_idx)->GetBinContent(bin);
391  }
392  }
393  else{
394  if(!doByProc){
395  bin = btag_efficiencies_deep_.at(rdr_idx)->FindFixBin(fabs(eta), pT, pdgId);
396  eff = btag_efficiencies_deep_.at(rdr_idx)->GetBinContent(bin);
397  }
398  else{
399  bin = btag_efficiencies_deep_proc_.at(rdr_idx)->FindFixBin(fabs(eta), pT, pdgId);
400  eff = btag_efficiencies_deep_proc_.at(rdr_idx)->GetBinContent(bin);
401  }
402  }
403 
404  return eff;
405 }
406 
407 // get deltaR between two b-tagged CSVM jets
408 void jet_met_tools::fillDeltaRbb(vector<float> & deltaRbb, vector<float> & bb_pt,vector<float> & bb_m,vector<int> & bb_jet_idx1, vector<int> & bb_jet_idx2,vector<int> & bb_gs_idx,vector<int> & bb_gs_flavor, const vector<LVector> &jets, const vector<float> &jets_csv, const vector<bool> &jets_islep, const vector<float> &jets_pt, const vector<size_t> &branks, int & highcsv_index, bool deep)
409 {
410  for(size_t ijet(0); ijet<jets.size(); ijet++) {
411  for(size_t jjet=ijet+1; jjet<jets.size(); jjet++) {
412  if(jets_pt[ijet]<JetPtCut || jets_pt[jjet]<JetPtCut) continue;
413  if(!deep) {if(jets_csv[ijet]<CSVMedium || jets_csv[jjet]<CSVMedium) continue;}
414  else {if(jets_csv[ijet]<DeepCSVMedium || jets_csv[jjet]<DeepCSVMedium) continue;} //Note here that jets_csv is not baby.jets_csv(), but is whatever is fed when function is called (csv or csvd)
415  if(jets_islep[ijet] || jets_islep[jjet]) continue;
416  deltaRbb.push_back(deltaR(jets.at(ijet), jets.at(jjet)));
417  bb_pt.push_back(sumPt(jets.at(ijet), jets.at(jjet)));
418  bb_m.push_back(sumMass(jets.at(ijet), jets.at(jjet)));
419  bb_jet_idx1.push_back(ijet);
420  bb_jet_idx2.push_back(jjet);
421 
422  //Save index of pair with highest CSV
423  if((ijet==branks.at(0) && jjet==branks.at(1)) || (ijet==branks.at(1) && jjet==branks.at(0))) highcsv_index = deltaRbb.size()-1;
424 
425  bb_gs_idx.push_back(-1); //Filled in writeMC
426  bb_gs_flavor.push_back(0); //Filled in writeMC
427  }
428  }
429 
430 }
431 
432 // ranks jets by CSV, breaking ties by pt and mass, with jets less than 30 GeV or matched to leptons last
433 vector<size_t> jet_met_tools::getBRanking(const vector<LVector> &momentum, const vector<float> &csv,
434  const vector<bool> &is_lep){
435  typedef tuple<bool, float, float, float> Bness;
436  vector<pair<Bness, long> > jets;
437  for(size_t i = 0; i < momentum.size(); ++i){
438  jets.push_back(pair<Bness, size_t>(Bness(!(is_lep.at(i)||momentum.at(i).pt()<30.0), csv.at(i), momentum.at(i).pt(), momentum.at(i).M()), -i));
439  }
440  sort(jets.rbegin(), jets.rend());
441  vector<size_t> indices(jets.size());
442  for(size_t i = 0; i < jets.size(); ++i){
443  indices.at(i) = -jets.at(i).second;
444  }
445  return indices;
446 }
447 
448 float jet_met_tools::getDeltaRbbHighCSV(const vector<LVector> &momentum, const vector<size_t> &brank, size_t nb){
449  return (brank.size() > 1 && nb > 1) ? deltaR(momentum.at(brank.at(0)), momentum.at(brank.at(1))) : -1.;
450 }
451 
452 float jet_met_tools::getDeltaRbbMax(const vector<LVector> &momentum, const vector<size_t> &brank,
453  size_t nb){
454  float max = -1.;
455  for(size_t i = 0; i < nb && i < brank.size(); ++i){
456  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
457  float x = deltaR(momentum.at(brank.at(i)), momentum.at(brank.at(j)));
458  if(x > max) max = x;
459  }
460  }
461  return max;
462 }
463 
464 float jet_met_tools::getDeltaRbbMin(const vector<LVector> &momentum, const vector<size_t> &brank,
465  size_t nb){
466  float min = -1.;
467  for(size_t i = 0; i < nb && i < brank.size(); ++i){
468  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
469  float x = deltaR(momentum.at(brank.at(i)), momentum.at(brank.at(j)));
470  if(x < min || min < 0.) min = x;
471  }
472  }
473  return min;
474 }
475 
476 float jet_met_tools::getDeltaPhibb(const vector<LVector> &momentum, const vector<size_t> &brank, size_t nb){
477  return (brank.size() > 1 && nb > 1) ? fabs(reco::deltaPhi(momentum.at(brank.at(0)).phi(), momentum.at(brank.at(1)).phi())) : -1.;
478 }
479 
480 float jet_met_tools::getDeltaPhibbMax(const vector<LVector> &momentum, const vector<size_t> &brank,
481  size_t nb){
482  float max = -1.;
483  for(size_t i = 0; i < nb && i < brank.size(); ++i){
484  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
485  float x = fabs(reco::deltaPhi(momentum.at(brank.at(i)).phi(), momentum.at(brank.at(j)).phi()));
486  if(x > max) max = x;
487  }
488  }
489  return max;
490 }
491 
492 float jet_met_tools::getDeltaPhibbMin(const vector<LVector> &momentum, const vector<size_t> &brank,
493  size_t nb){
494  float min = -1.;
495  for(size_t i = 0; i < nb && i < brank.size(); ++i){
496  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
497  float x = fabs(reco::deltaPhi(momentum.at(brank.at(i)).phi(), momentum.at(brank.at(j)).phi()));
498  if(x < min || min < 0.) min = x;
499  }
500  }
501  return min;
502 }
503 
504 float jet_met_tools::getMbb(const vector<LVector> &momentum, const vector<size_t> &brank, size_t nb){
505  return (brank.size() > 1 && nb > 1) ? sumMass(momentum.at(brank.at(0)), momentum.at(brank.at(1))) : -1.;
506 }
507 
508 float jet_met_tools::getMbbMax(const vector<LVector> &momentum, const vector<size_t> &brank,
509  size_t nb){
510  float max = -1.;
511  for(size_t i = 0; i < nb && i < brank.size(); ++i){
512  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
513  float x = sumMass(momentum.at(brank.at(i)), momentum.at(brank.at(j)));
514  if(x > max) max = x;
515  }
516  }
517  return max;
518 }
519 
520 float jet_met_tools::getMbbMin(const vector<LVector> &momentum, const vector<size_t> &brank,
521  size_t nb){
522  float min = -1.;
523  for(size_t i = 0; i < nb && i < brank.size(); ++i){
524  for(size_t j = i + 1; j < nb && j < brank.size(); ++j){
525  float x = sumMass(momentum.at(brank.at(i)), momentum.at(brank.at(j)));
526  if(x < min || min < 0.) min = x;
527  }
528  }
529  return min;
530 }
531 
532 float jet_met_tools::getMblepMax2(const vector<LVector> &jets, const vector<size_t> &brank,
533  size_t nb, const LVector &lep){
534  switch(nb){
535  case 0: return -1.;
536  case 1: return sumMass(jets.at(brank.at(0)), lep);
537  default:
538  float a = sumMass(jets.at(brank.at(0)), lep);
539  float b = sumMass(jets.at(brank.at(1)), lep);
540  return max(a,b);
541  }
542 }
543 
544 float jet_met_tools::getMblepMin2(const vector<LVector> &jets, const vector<size_t> &brank,
545  size_t nb, const LVector &lep){
546  switch(nb){
547  case 0: return -1.;
548  case 1: return sumMass(jets.at(brank.at(0)), lep);
549  default:
550  float a = sumMass(jets.at(brank.at(0)), lep);
551  float b = sumMass(jets.at(brank.at(1)), lep);
552  return min(a,b);
553  }
554 }
555 
556 float jet_met_tools::getMblepMax(const vector<LVector> &jets, const vector<size_t> &brank,
557  size_t nb, const LVector &lep){
558  float max = -1.;
559  for(size_t i = 0; i < nb && i < brank.size(); ++i){
560  float m = sumMass(jets.at(brank.at(i)), lep);
561  if(m>max) max = m;
562  }
563  return max;
564 }
565 
566 float jet_met_tools::getMblepMin(const vector<LVector> &jets, const vector<size_t> &brank,
567  size_t nb, const LVector &lep){
568  float min = -1.;
569  for(size_t i = 0; i < nb && i < brank.size(); ++i){
570  float m = sumMass(jets.at(brank.at(i)), lep);
571  if(m<min || min<0.) min = m;
572  }
573  return min;
574 }
575 
576 float jet_met_tools::getDeltaRblepMax2(const vector<LVector> &jets, const vector<size_t> &brank,
577  size_t nb, const LVector &lep){
578  switch(nb){
579  case 0: return -1.;
580  case 1: return deltaR(jets.at(brank.at(0)), lep);
581  default:
582  float a = deltaR(jets.at(brank.at(0)), lep);
583  float b = deltaR(jets.at(brank.at(1)), lep);
584  return max(a,b);
585  }
586 }
587 
588 float jet_met_tools::getDeltaRblepMin2(const vector<LVector> &jets, const vector<size_t> &brank,
589  size_t nb, const LVector &lep){
590  switch(nb){
591  case 0: return -1.;
592  case 1: return deltaR(jets.at(brank.at(0)), lep);
593  default:
594  float a = deltaR(jets.at(brank.at(0)), lep);
595  float b = deltaR(jets.at(brank.at(1)), lep);
596  return min(a,b);
597  }
598 }
599 
600 float jet_met_tools::getDeltaRblepMax(const vector<LVector> &jets, const vector<size_t> &brank,
601  size_t nb, const LVector &lep){
602  float max = -1.;
603  for(size_t i = 0; i < nb && i < brank.size(); ++i){
604  float m = deltaR(jets.at(brank.at(i)), lep);
605  if(m>max) max = m;
606  }
607  return max;
608 }
609 
610 float jet_met_tools::getDeltaRblepMin(const vector<LVector> &jets, const vector<size_t> &brank,
611  size_t nb, const LVector &lep){
612  float min = -1.;
613  for(size_t i = 0; i < nb && i < brank.size(); ++i){
614  float m = deltaR(jets.at(brank.at(i)), lep);
615  if(m<min || min < 0.) min = m;
616  }
617  return min;
618 }
619 
620 float jet_met_tools::getDeltaPhiblepMax2(const vector<LVector> &jets, const vector<size_t> &brank,
621  size_t nb, const LVector &lep){
622  switch(nb){
623  case 0: return -1.;
624  case 1: return fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), lep.phi()));
625  default:
626  float a = fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), lep.phi()));
627  float b = fabs(reco::deltaPhi(jets.at(brank.at(1)).phi(), lep.phi()));
628  return max(a,b);
629  }
630 }
631 
632 float jet_met_tools::getDeltaPhiblepMin2(const vector<LVector> &jets, const vector<size_t> &brank,
633  size_t nb, const LVector &lep){
634  switch(nb){
635  case 0: return -1.;
636  case 1: return fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), lep.phi()));
637  default:
638  float a = fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), lep.phi()));
639  float b = fabs(reco::deltaPhi(jets.at(brank.at(1)).phi(), lep.phi()));
640  return min(a,b);
641  }
642 }
643 
644 float jet_met_tools::getDeltaPhiblepMax(const vector<LVector> &jets, const vector<size_t> &brank,
645  size_t nb, const LVector &lep){
646  float max = -1.;
647  for(size_t i = 0; i < nb && i < brank.size(); ++i){
648  float m = fabs(reco::deltaPhi(jets.at(brank.at(i)).phi(), lep.phi()));
649  if(m>max) max = m;
650  }
651  return max;
652 }
653 
654 float jet_met_tools::getDeltaPhiblepMin(const vector<LVector> &jets, const vector<size_t> &brank,
655  size_t nb, const LVector &lep){
656  float min = -1.;
657  for(size_t i = 0; i < nb && i < brank.size(); ++i){
658  float m = fabs(reco::deltaPhi(jets.at(brank.at(i)).phi(), lep.phi()));
659  if(m<min || min < 0.) min = m;
660  }
661  return min;
662 }
663 
664 float jet_met_tools::getMTbmetMax2(const vector<LVector> &jets, const vector<size_t> &brank,
665  size_t nb, float met, float met_phi){
666  if(nb == 0){
667  return -1.;
668  }else if(nb == 1){
669  const auto &j = jets.at(brank.at(0));
670  return getMT(j.M(), j.pt(), j.phi(), 0., met, met_phi);
671  }else{
672  const auto &ja = jets.at(brank.at(0));
673  const auto &jb = jets.at(brank.at(1));
674  float a = getMT(ja.M(), ja.pt(), ja.phi(), 0., met, met_phi);
675  float b = getMT(jb.M(), jb.pt(), jb.phi(), 0., met, met_phi);
676  return max(a,b);
677  }
678 }
679 
680 float jet_met_tools::getMTbmetMin2(const vector<LVector> &jets, const vector<size_t> &brank,
681  size_t nb, float met, float met_phi){
682  if(nb == 0){
683  return -1.;
684  }else if(nb == 1){
685  const auto &j = jets.at(brank.at(0));
686  return getMT(j.M(), j.pt(), j.phi(), 0., met, met_phi);
687  }else{
688  const auto &ja = jets.at(brank.at(0));
689  const auto &jb = jets.at(brank.at(1));
690  float a = getMT(ja.M(), ja.pt(), ja.phi(), 0., met, met_phi);
691  float b = getMT(jb.M(), jb.pt(), jb.phi(), 0., met, met_phi);
692  return min(a,b);
693  }
694 }
695 
696 float jet_met_tools::getMTbmetMax(const vector<LVector> &jets, const vector<size_t> &brank,
697  size_t nb, float met, float met_phi){
698  float max = -1.;
699  for(size_t i = 0; i < nb && i < brank.size(); ++i){
700  const auto &jet = jets.at(brank.at(i));
701  float m = getMT(jet.M(), jet.pt(), jet.phi(), 0., met, met_phi);
702  if(m>max) m = max;
703  }
704  return max;
705 }
706 
707 float jet_met_tools::getMTbmetMin(const vector<LVector> &jets, const vector<size_t> &brank,
708  size_t nb, float met, float met_phi){
709  float min = -1.;
710  for(size_t i = 0; i < nb && i < brank.size(); ++i){
711  const auto &jet = jets.at(brank.at(i));
712  float m = getMT(jet.M(), jet.pt(), jet.phi(), 0., met, met_phi);
713  if(m<min || min<0.) m = min;
714  }
715  return min;
716 }
717 
718 float jet_met_tools::getDeltaPhibmetMax2(const vector<LVector> &jets, const vector<size_t> &brank,
719  size_t nb, float met_phi){
720  switch(nb){
721  case 0: return -1.;
722  case 1: return fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), met_phi));
723  default:
724  float a = fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), met_phi));
725  float b = fabs(reco::deltaPhi(jets.at(brank.at(1)).phi(), met_phi));
726  return max(a,b);
727  }
728 }
729 
730 float jet_met_tools::getDeltaPhibmetMin2(const vector<LVector> &jets, const vector<size_t> &brank,
731  size_t nb, float met_phi){
732  switch(nb){
733  case 0: return -1.;
734  case 1: return fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), met_phi));
735  default:
736  float a = fabs(reco::deltaPhi(jets.at(brank.at(0)).phi(), met_phi));
737  float b = fabs(reco::deltaPhi(jets.at(brank.at(1)).phi(), met_phi));
738  return min(a,b);
739  }
740 }
741 
742 float jet_met_tools::getDeltaPhibmetMax(const vector<LVector> &jets, const vector<size_t> &brank,
743  size_t nb, float met_phi){
744  float max = -1.;
745  for(size_t i = 0; i < nb && i < brank.size(); ++i){
746  float m = fabs(reco::deltaPhi(jets.at(brank.at(i)).phi(), met_phi));
747  if(m>max) max = m;
748  }
749  return max;
750 }
751 
752 float jet_met_tools::getDeltaPhibmetMin(const vector<LVector> &jets, const vector<size_t> &brank,
753  size_t nb, float met_phi){
754  float min = -1;
755  for(size_t i = 0; i < nb && i < brank.size(); ++i){
756  float m = fabs(reco::deltaPhi(jets.at(brank.at(i)).phi(), met_phi));
757  if(m<min || min < 0.) min = m;
758  }
759  return min;
760 }
761 
762 void jet_met_tools::clusterFatJets(int &nfjets, float &mj,
763  std::vector<float> &fjets_pt,
764  std::vector<float> &fjets_eta,
765  std::vector<float> &fjets_phi,
766  std::vector<float> &fjets_m,
767  std::vector<int> &fjets_nconst,
768  std::vector<int> &jets_fjet_index,
769  baby_full &baby,
770  double radius,
771  double min_jets_pt,
772  bool cluster_leps){
773 
774  vector<fastjet::PseudoJet> sjets(0);
775  for(size_t ijet(0); ijet < baby.jets_pt().size(); ijet++){
776  if (!cluster_leps && baby.jets_islep()[ijet]) continue;
777  if (baby.jets_pt()[ijet]>min_jets_pt || (cluster_leps && baby.jets_islep()[ijet])) {
778  TLorentzVector vjet; vjet.SetPtEtaPhiM(baby.jets_pt()[ijet], baby.jets_eta()[ijet], baby.jets_phi()[ijet], baby.jets_m()[ijet]);
779  const fastjet::PseudoJet this_pj(vjet.Px(), vjet.Py(), vjet.Pz(), vjet.E());
780  sjets.push_back(this_pj);
781  }
782  } // Loop over skinny jets
783  fastjet::JetDefinition jet_def(fastjet::antikt_algorithm, radius);
784  fastjet::ClusterSequence cs(sjets, jet_def);
785  vector<fastjet::PseudoJet> fjets = cs.inclusive_jets();
786  sort(fjets.begin(), fjets.end(), greaterM);
787  nfjets = 0;
788  mj = 0.;
789  fjets_pt.resize(fjets.size());
790  fjets_eta.resize(fjets.size());
791  fjets_phi.resize(fjets.size());
792  fjets_m.resize(fjets.size());
793  fjets_nconst.resize(fjets.size());
794  jets_fjet_index.resize(baby.jets_csv().size(), -1);
795 
796  for(size_t ipj = 0; ipj < fjets.size(); ++ipj){
797  const fastjet::PseudoJet &pj = fjets.at(ipj);
798  fjets_pt.at(ipj) = pj.pt();
799  fjets_eta.at(ipj) = pj.eta();
800  fjets_phi.at(ipj) = pj.phi_std();
801  fjets_m.at(ipj) = pj.m();
802  const vector<fastjet::PseudoJet> &cjets = pj.constituents();
803  fjets_nconst.at(ipj) = cjets.size();
804  mj += pj.m();
805  ++nfjets;
806  for(size_t ijet = 0; ijet < baby.jets_pt().size(); ++ijet){
807  for(size_t cjet = 0; cjet < cjets.size(); ++ cjet){
808  if(fabs(cjets.at(cjet).pt() - baby.jets_pt()[ijet]) < 0.0001){
809  jets_fjet_index.at(ijet) = ipj;
810  }
811  } // Loop over fat jet constituents
812  } // Loop over skinny jets
813  } // Loop over fat jets
814 
815 }
816 
817 double jet_met_tools::getSysMJ(double radius, vector<LVector> &jets, vector<bool> &jets_islep, double min_jets_pt, bool cluster_leps){
818 
819  double mj(0.);
820  vector<fastjet::PseudoJet> sjets(0);
821  for(size_t ijet(0); ijet < jets.size(); ijet++){
822  if (!cluster_leps && jets_islep[ijet]) continue;
823  if (jets[ijet].pt()>min_jets_pt || (cluster_leps && jets_islep[ijet])) {
824  const fastjet::PseudoJet this_pj(jets[ijet].px(), jets[ijet].py(), jets[ijet].pz(), jets[ijet].energy());
825  sjets.push_back(this_pj);
826  }
827  } // Loop over skinny jets
828  fastjet::JetDefinition jet_def(fastjet::antikt_algorithm, radius);
829  fastjet::ClusterSequence cs(sjets, jet_def);
830  vector<fastjet::PseudoJet> fjets = cs.inclusive_jets();
831  sort(fjets.begin(), fjets.end(), greaterM);
832  for(size_t ipj = 0; ipj < fjets.size(); ++ipj) mj += fjets.at(ipj).m();
833 
834  return mj;
835 }
836 jet_met_tools::jet_met_tools(TString ijecName, bool doSys, bool fastSim, TString outname):
837  jecName(ijecName),
838  doSystematics(doSys),
839  isFastSim(fastSim),
840  calib_full_(),
841  calib_fast_(),
842  readers_full_(),
843  readers_fast_(),
844  btag_efficiencies_(op_pts_.size()),
845  btag_efficiencies_proc_(op_pts_.size()),
846  calib_deep_full_(),
847  calib_deep_fast_(),
848  readers_deep_full_(),
849  readers_deep_fast_(),
850  btag_efficiencies_deep_(op_pts_.size()),
851  btag_efficiencies_deep_proc_(op_pts_.size()){
852  if (jecName.Contains("DATA")) isData = true;
853  else if (jecName.Contains("MC")) isData = false;
854  else cout<<endl<<"BABYMAKER: jet_met_tools: The jecLabel string must contain either 'DATA' or 'MC'. "
855  <<"Currently running with "<<jecName<<endl<<endl;
856 
857  doJEC = jecName.Contains("onthefly");
858  jecName.ReplaceAll("onthefly_","");
859  string basename(getenv("CMSSW_BASE"));
860  basename += "/src/babymaker/data/jec/";
861  basename += jecName.Data();
862 
863  if(doJEC || doSystematics) {
864  vector<JetCorrectorParameters> jecFiles;
865  if (doJEC) cout<<endl<<"BABYMAKER: jet_met_tools: Applying JECs on-the-fly with files "
866  <<basename.c_str()<<"*.txt"<<endl<<endl;
867  //these files need to be loaded even if doing only systematics
868  jecFiles.push_back(JetCorrectorParameters(basename+"_L1FastJet_AK4PFchs.txt"));
869  jecFiles.push_back(JetCorrectorParameters(basename+"_L2Relative_AK4PFchs.txt"));
870  jecFiles.push_back(JetCorrectorParameters(basename+"_L3Absolute_AK4PFchs.txt"));
871  if(jecName.Contains("DATA"))
872  jecFiles.push_back(JetCorrectorParameters(basename+"_L2L3Residual_AK4PFchs.txt"));
873  jetCorrector.reset(new FactorizedJetCorrectorCalculator(jecFiles));
874  }
875  if (doSystematics){
876  cout<<endl<<"BABYMAKER: jet_met_tools: Using JEC uncertainties from file "
877  <<basename.c_str()<<"_Uncertainty_AK4PFchs.txt"<<endl<<endl;
878  jecUncProvider.reset(new JetCorrectionUncertainty(basename+"_Uncertainty_AK4PFchs.txt"));
879  }
880 
881  // set btag working points
882  TString cmssw(getenv("CMSSW_VERSION"));
883  if(cmssw.Contains("CMSSW_7_4")){
884  CSVLoose = 0.605;
885  CSVMedium = 0.890;
886  CSVTight = 0.970;
887  }
888  else if (cmssw.Contains("CMSSW_8")){
889  CSVLoose = 0.5426;
890  CSVMedium = 0.8484;
891  CSVTight = 0.9535;
892  DeepCSVLoose = 0.2219;
893  DeepCSVMedium = 0.6324;
894  DeepCSVTight = 0.8958;
895  }
896  else if (cmssw.Contains("CMSSW_9") || cmssw.Contains("CMSSW_10")){
897  CSVLoose = 0.5803;
898  CSVMedium = 0.8838;
899  CSVTight = 0.9693;
900  DeepCSVLoose = 0.1522;
901  DeepCSVMedium = 0.4941;
902  DeepCSVTight = 0.8001;
903  DeepFlavourLoose = 0.0574;
904  DeepFlavourMedium = 0.4318;
905  DeepFlavourTight = 0.9068;
906  }
907 
908  // only add b-tagging weights if requested
909  string scaleFactorFile(getenv("CMSSW_BASE"));
910  scaleFactorFile+="/src/babymaker/bmaker/data/CSVv2_Moriond17_B_H.csv";//CSVv2Moriond17_2017_1_26_BtoH.csv";//CSVv2Moriond17_comb.csv";
911  calib_full_.reset(new BTagCalibration("csvv2", scaleFactorFile));
912  for(const auto &op: op_pts_){
913  readers_full_[op] = MakeUnique<BTagCalibrationReader>(op, "central", vector<string>{"up", "down"});
914  readers_full_.at(op)->load(*calib_full_, BTagEntry::FLAV_UDSG, "incl");
915  readers_full_.at(op)->load(*calib_full_, BTagEntry::FLAV_C, "comb");
916  readers_full_.at(op)->load(*calib_full_, BTagEntry::FLAV_B, "comb");
917  }
918  string scaleFactorFile_deep(getenv("CMSSW_BASE"));
919  scaleFactorFile_deep+="/src/babymaker/bmaker/data/DeepCSV_Moriond17_B_H.csv";//CSVv2Moriond17_2017_1_26_BtoH.csv";//DeepCSVMoriond17_comb.csv";
920  calib_deep_full_.reset(new BTagCalibration("csvv2_deep", scaleFactorFile_deep));
921  for(const auto &op: op_pts_){
922  readers_deep_full_[op] = MakeUnique<BTagCalibrationReader>(op, "central", vector<string>{"up", "down"});
923  readers_deep_full_.at(op)->load(*calib_deep_full_, BTagEntry::FLAV_UDSG, "incl");
924  readers_deep_full_.at(op)->load(*calib_deep_full_, BTagEntry::FLAV_C, "comb");
925  readers_deep_full_.at(op)->load(*calib_deep_full_, BTagEntry::FLAV_B, "comb");
926  }
927 
928  if (isFastSim){
929  string scaleFactorFileFastSim(getenv("CMSSW_BASE"));
930  scaleFactorFileFastSim+="/src/babymaker/bmaker/data/fastsim_csvv2_ttbar_26_1_2017.csv";//CSV_13TEV_Combined_14_7_2016.csv";
931  calib_fast_.reset(new BTagCalibration("csvv2", scaleFactorFileFastSim));
932  for(const auto &op: op_pts_){
933  readers_fast_[op] = MakeUnique<BTagCalibrationReader>(op, "central", vector<string>{"up", "down"});
934  readers_fast_.at(op)->load(*calib_fast_, BTagEntry::FLAV_UDSG, "fastsim");
935  readers_fast_.at(op)->load(*calib_fast_, BTagEntry::FLAV_C, "fastsim");
936  readers_fast_.at(op)->load(*calib_fast_, BTagEntry::FLAV_B, "fastsim");
937  }
938  string scaleFactorFileFastSim_deep(getenv("CMSSW_BASE"));
939  scaleFactorFileFastSim_deep+="/src/babymaker/bmaker/data/fastsim_deepcsv_ttbar_26_1_2017.csv";//CSV_13TEV_Combined_14_7_2016.csv";
940  calib_deep_fast_.reset(new BTagCalibration("csvv2", scaleFactorFileFastSim_deep));
941  for(const auto &op: op_pts_){
942  readers_deep_fast_[op] = MakeUnique<BTagCalibrationReader>(op, "central", vector<string>{"up", "down"});
943  readers_deep_fast_.at(op)->load(*calib_deep_fast_, BTagEntry::FLAV_UDSG, "fastsim");
944  readers_deep_fast_.at(op)->load(*calib_deep_fast_, BTagEntry::FLAV_C, "fastsim");
945  readers_deep_fast_.at(op)->load(*calib_deep_fast_, BTagEntry::FLAV_B, "fastsim");
946  }
947  }
948 
949  string filename(getenv("CMSSW_BASE"));
950  filename+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency.root";
951  TFile *efficiencyFile = TFile::Open(filename.c_str());
952  if(efficiencyFile->IsOpen()) {
953  for(size_t i = 0; i < op_pts_.size(); ++i){
954  string hist_name;
955  switch(op_pts_.at(i)){
956  case BTagEntry::OP_LOOSE: hist_name = "btagEfficiency_loose"; break;
957  case BTagEntry::OP_MEDIUM: hist_name = "btagEfficiency_medium"; break;
958  case BTagEntry::OP_TIGHT: hist_name = "btagEfficiency_tight"; break;
959  case BTagEntry::OP_RESHAPING: hist_name = "btagEfficiency_reshaping"; break;
960  default: hist_name = "btagEfficiency"; break;
961  }
962  btag_efficiencies_.at(i) = static_cast<const TH3D*>(efficiencyFile->Get(hist_name.c_str()));
963  if(!btag_efficiencies_.at(i)){
964  ERROR("Could not find efficiency parametrization " << hist_name);
965  }
966  }
967  }else{
968  ERROR("Could not find efficiency file " << filename);
969  }
970 
971  string filename_deep(getenv("CMSSW_BASE"));
972  filename_deep+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_deep.root";
973  TFile *efficiencyFile_deep = TFile::Open(filename_deep.c_str());
974  if(efficiencyFile_deep->IsOpen()) {
975  for(size_t i = 0; i < op_pts_.size(); ++i){
976  string hist_name;
977  switch(op_pts_.at(i)){
978  case BTagEntry::OP_LOOSE: hist_name = "btagEfficiency_deep_loose"; break;
979  case BTagEntry::OP_MEDIUM: hist_name = "btagEfficiency_deep_medium"; break;
980  case BTagEntry::OP_TIGHT: hist_name = "btagEfficiency_deep_tight"; break;
981  case BTagEntry::OP_RESHAPING: hist_name = "btagEfficiency_deep_reshaping"; break;
982  default: hist_name = "btagEfficiency"; break;
983  }
984  btag_efficiencies_deep_.at(i) = static_cast<const TH3D*>(efficiencyFile_deep->Get(hist_name.c_str()));
985  if(!btag_efficiencies_deep_.at(i)){
986  ERROR("Could not find efficiency parametrization " << hist_name);
987  }
988  }
989  }else{
990  ERROR("Could not find efficiency file " << filename_deep);
991  }
992 
993  string filename_proc(getenv("CMSSW_BASE"));
994  if(outname.Contains("QCD")) filename_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_qcd.root";
995  else if(outname.Contains("WJets") && !outname.Contains("TTWJets")) filename_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_wjets.root";
996  else filename_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_tt.root";
997  TFile *efficiencyFile_proc = TFile::Open(filename_proc.c_str());
998  if(efficiencyFile_proc->IsOpen()) {
999  for(size_t i = 0; i < op_pts_.size(); ++i){
1000  string hist_name;
1001  switch(op_pts_.at(i)){
1002  case BTagEntry::OP_LOOSE: hist_name = "btagEfficiency_loose"; break;
1003  case BTagEntry::OP_MEDIUM: hist_name = "btagEfficiency_medium"; break;
1004  case BTagEntry::OP_TIGHT: hist_name = "btagEfficiency_tight"; break;
1005  case BTagEntry::OP_RESHAPING: hist_name = "btagEfficiency_reshaping"; break;
1006  default: hist_name = "btagEfficiency"; break;
1007  }
1008  btag_efficiencies_proc_.at(i) = static_cast<const TH3D*>(efficiencyFile_proc->Get(hist_name.c_str()));
1009  if(!btag_efficiencies_proc_.at(i)){
1010  ERROR("Could not find efficiency parametrization " << hist_name);
1011  }
1012  }
1013  }else{
1014  ERROR("Could not find efficiency file " << filename_proc);
1015  }
1016 
1017  string filename_deep_proc(getenv("CMSSW_BASE"));
1018  if(outname.Contains("QCD")) filename_deep_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_deep_qcd.root";
1019  else if(outname.Contains("WJets") && !outname.Contains("TTWJets")) filename_deep_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_deep_wjets.root";
1020  else filename_deep_proc+="/src/babymaker/bmaker/data/btagEfficiencies/btagEfficiency_deep_tt.root";
1021  TFile *efficiencyFile_deep_proc = TFile::Open(filename_deep_proc.c_str());
1022  if(efficiencyFile_deep_proc->IsOpen()) {
1023  for(size_t i = 0; i < op_pts_.size(); ++i){
1024  string hist_name;
1025  switch(op_pts_.at(i)){
1026  case BTagEntry::OP_LOOSE: hist_name = "btagEfficiency_deep_loose"; break;
1027  case BTagEntry::OP_MEDIUM: hist_name = "btagEfficiency_deep_medium"; break;
1028  case BTagEntry::OP_TIGHT: hist_name = "btagEfficiency_deep_tight"; break;
1029  case BTagEntry::OP_RESHAPING: hist_name = "btagEfficiency_deep_reshaping"; break;
1030  default: hist_name = "btagEfficiency"; break;
1031  }
1032  btag_efficiencies_deep_proc_.at(i) = static_cast<const TH3D*>(efficiencyFile_deep_proc->Get(hist_name.c_str()));
1033  if(!btag_efficiencies_deep_proc_.at(i)){
1034  ERROR("Could not find efficiency parametrization " << hist_name);
1035  }
1036  }
1037  }else{
1038  ERROR("Could not find efficiency file " << filename_deep_proc);
1039  }
1040 }
1041 
1042 // 2016 PromptReco Data/MC SFs
1043 // https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetResolution#JER_Scaling_factors_and_Uncertai
1045  double abseta = fabs(jet_eta);
1046  if (abseta < 0.5) return 1.109;
1047  else if (abseta < 0.8) return 1.138;
1048  else if (abseta < 1.1) return 1.114;
1049  else if (abseta < 1.3) return 1.123;
1050  else if (abseta < 1.7) return 1.084;
1051  else if (abseta < 1.9) return 1.082;
1052  else if (abseta < 2.1) return 1.140;
1053  else if (abseta < 2.3) return 1.067;
1054  else if (abseta < 2.5) return 1.177;
1055  else if (abseta < 2.8) return 1.364;
1056  else if (abseta < 3.0) return 1.857;
1057  else if (abseta < 3.2) return 1.328;
1058  else if (abseta < 5.0) return 1.160;
1059  else return 1.;
1060 }
std::unique_ptr< JetCorrectionUncertainty > jecUncProvider
bool greaterM(const fastjet::PseudoJet &a, const fastjet::PseudoJet &b)
Definition: utilities.cc:40
float DeepFlavourTight
bool leptonInJet(const pat::Jet &jet, vCands leptons)
std::vector< float > const & jets_csv() const
Definition: baby_base.cc:6705
static float getMbbMax(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
tuple args
Definition: cache.py:302
void fillDeltaRbb(std::vector< float > &deltaRbb, std::vector< float > &bb_pt, std::vector< float > &bb_m, std::vector< int > &bb_jet_idx1, std::vector< int > &bb_jet_idx2, std::vector< int > &bb_gs_idx, std::vector< int > &bb_gs_flavor, const std::vector< LVector > &jets, const std::vector< float > &jets_csv, const std::vector< bool > &jets_islep, const std::vector< float > &jets_pt, const std::vector< size_t > &brank, int &highcsv_index, bool deep=false)
double getSysMJ(double radius, std::vector< LVector > &jets, std::vector< bool > &jets_islep, double min_jets_pt, bool cluster_leps)
bool jetMatched(const pat::Jet &jet, vCands objects)
void setJetUncertainties(edm::Handle< edm::View< reco::GenJet > > genjets)
static float getMTbmetMin(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met, float met_phi)
void clusterFatJets(int &nfjets, float &mj, std::vector< float > &fjets_pt, std::vector< float > &fjets_eta, std::vector< float > &fjets_phi, std::vector< float > &fjets_m, std::vector< int > &fjets_nconst, std::vector< int > &jets_fjet_index, baby_full &baby, double radius, double min_jets_pt, bool cluster_leps)
float DeepFlavourLoose
static std::vector< size_t > getBRanking(const std::vector< LVector > &momentum, const std::vector< float > &csv, const std::vector< bool > &is_lep)
bool isLowDphi(vCands jets, float mht_phi, float &dphi1, float &dphi2, float &dphi3, float &dphi4)
std::vector< const TH3D * > btag_efficiencies_deep_
float getJetResolutionSF(float jet_eta)
static float getDeltaPhiblepMin(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getDeltaPhibmetMin(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met_phi)
static float getDeltaPhibb(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
jet_met_tools(TString ijecName, bool doSys, bool isFastSim, TString outname)
static float getDeltaPhiblepMin2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getDeltaRblepMin(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
std::vector< const reco::Candidate * > vCands
Definition: utilities.hh:15
STL namespace.
std::vector< bool > const & jets_islep() const
Definition: baby_base.cc:6210
void getMETRaw(edm::Handle< pat::METCollection > mets, float &metRaw, float &metRawPhi)
static float getDeltaPhibmetMax(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met_phi)
float trueHT(edm::Handle< edm::View< reco::GenJet > > genjets)
float getGenPt(const pat::Jet &jet, edm::Handle< edm::View< reco::GenJet > > genjets)
std::vector< const TH3D * > btag_efficiencies_proc_
static float getDeltaRblepMin2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
std::vector< float > const & jets_phi() const
Definition: baby_base.cc:6738
isData
If you only want to re-correct and get the proper uncertainties, no reclustering. ...
float DeepFlavourMedium
float getMT(float pt1, float phi1, float pt2, float phi2)
Definition: utilities.cc:44
std::unique_ptr< BTagCalibration > calib_deep_full_
std::unique_ptr< BTagCalibration > calib_full_
#define ERROR(x)
Definition: utilities.hh:18
std::map< BTagEntry::OperatingPoint, std::unique_ptr< BTagCalibrationReader > > readers_deep_full_
std::vector< float > const & jets_pt() const
Definition: baby_base.cc:6749
void getMETWithJEC(edm::Handle< pat::METCollection > mets, float &met, float &metPhi, unsigned isys)
static float getDeltaPhiblepMax2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
std::vector< const TH3D * > btag_efficiencies_deep_proc_
doJEC
JECs must be undone and reapplied when rerunning b-tagging => if doJEC = False, DeepCSV discriminator...
std::vector< float > const & jets_eta() const
Definition: baby_base.cc:6716
std::map< BTagEntry::OperatingPoint, std::unique_ptr< BTagCalibrationReader > > readers_deep_fast_
float jetBTagWeight(const pat::Jet &jet, const LVector &jetp4, BTagEntry::OperatingPoint op, const std::string &bc_full_syst, const std::string &udsg_full_syst, const std::string &bc_fast_syst, const std::string &udsg_fast_syst, bool doDeepCSV, bool doByProc=false) const
static float getDeltaPhibmetMax2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met_phi)
static float getDeltaRblepMax2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
float getMCTagEfficiency(int pdgId, float pT, float eta, BTagEntry::OperatingPoint op, bool doDeepCSV, bool doByProc) const
std::map< BTagEntry::OperatingPoint, std::unique_ptr< BTagCalibrationReader > > readers_full_
static float getDeltaRbbMin(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
static float getMbb(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
static float getMTbmetMin2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met, float met_phi)
static const std::vector< BTagEntry::OperatingPoint > op_pts_
float sumMass(const LVector &a, const LVector &b)
Definition: utilities.cc:16
static float getDeltaPhibmetMin2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met_phi)
static float getMblepMax(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
std::vector< float > const & jets_m() const
Definition: baby_base.cc:6727
tuple ind
Definition: resubmit.py:140
reco::Candidate::LorentzVector LVector
Definition: utilities.hh:16
static float getMTbmetMax(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met, float met_phi)
static float getDeltaPhiblepMax(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getDeltaRbbMax(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
static float getMblepMin2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getMblepMin(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getDeltaRbbHighCSV(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
std::unique_ptr< FactorizedJetCorrectorCalculator > jetCorrector
std::unique_ptr< BTagCalibration > calib_fast_
void getJetCorrections(edm::Handle< edm::View< reco::GenJet > > genjets, edm::Handle< pat::JetCollection > alljets, double rhoEvent)
std::unique_ptr< BTagCalibration > calib_deep_fast_
std::vector< const TH3D * > btag_efficiencies_
std::unique_ptr< T > MakeUnique(Args &&...args)
static const std::vector< BTagEntry::JetFlavor > flavors_
static float getDeltaPhibbMax(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
bool idJet(const pat::Jet &jet, CutLevel cut)
static float getMTbmetMax2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, float met, float met_phi)
bool matchesGenJet(const pat::Jet &jet, edm::Handle< edm::View< reco::GenJet > > genjets)
static float getDeltaRblepMax(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
static float getMblepMax2(const std::vector< LVector > &jets, const std::vector< size_t > &brank, size_t nb, const LVector &lep)
float sumPt(const LVector &a, const LVector &b)
Definition: utilities.cc:20
std::map< BTagEntry::OperatingPoint, std::unique_ptr< BTagCalibrationReader > > readers_fast_
static float getDeltaPhibbMin(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)
static float getMbbMin(const std::vector< LVector > &momentum, const std::vector< size_t > &brank, size_t nb)