15 #include "TGraphAsymmErrors.h" 18 #include "FWCore/Framework/interface/ESHandle.h" 19 #include "DataFormats/Math/interface/deltaR.h" 24 #include "DataFormats/PatCandidates/interface/PFIsolation.h" 31 T
GetSF(
const string &file_name,
const string &item_name){
32 string path = string(getenv(
"CMSSW_BASE"))+
"/src/babymaker/bmaker/data/lepton_sf/"+file_name;
33 TFile
f(path.c_str(),
"read");
34 if(!
f.IsOpen())
ERROR(
"Could not open " << file_name);
35 T* item =
static_cast<T*
>(
f.Get(item_name.c_str()));
36 if(!item)
ERROR(
"Could not find " << item_name <<
" in " << file_name);
41 pair<double, double>
GetSF(
const T &h,
double x,
double y,
bool ignore_error =
false){
42 pair<double, double> sf;
43 auto bin = h.FindFixBin(x, y);
44 if((h.IsBinOverflow(bin) || h.IsBinUnderflow(bin))
45 && h.GetBinContent(bin) == 0. && h.GetBinError(bin) == 0.){
46 auto bin_x = h.GetXaxis()->FindFixBin(x);
47 auto bin_y = h.GetYaxis()->FindFixBin(y);
48 if(bin_x <= 0) bin_x = 1;
49 if(bin_x > h.GetNbinsX()) bin_x = h.GetNbinsX();
50 if(bin_y <= 0) bin_y = 1;
51 if(bin_y > h.GetNbinsY()) bin_y = h.GetNbinsY();
52 sf = {h.GetBinContent(bin_x, bin_y), h.GetBinError(bin_x, bin_y)};
54 sf = {h.GetBinContent(bin), h.GetBinError(bin)};
56 if(ignore_error) sf.second = 0.;
60 pair<double, double>
MergeSF(pair<double, double> a,
61 pair<double, double> b){
62 double sf = a.first * b.first;
63 double err = hypot(a.first*b.second, b.first*a.second);
70 Point(
double xl_in,
double xh_in,
double y_in,
double e_in):
76 bool operator<(
const Point &p)
const{
77 return make_tuple(xl, xh, fabs(log(fabs(y))), fabs(e))
78 <make_tuple(p.xl, p.xh, fabs(log(fabs(p.y))), fabs(p.e));
82 Double_t *x = g.GetX();
83 Double_t *xl = g.GetEXlow();
84 Double_t *xh = g.GetEXhigh();
85 Double_t *y = g.GetY();
86 Double_t *yl = g.GetEYlow();
87 Double_t *yh = g.GetEYhigh();
88 for(
int i = 0; i < g.GetN(); ++i){
89 bins.emplace_back(x[i]-fabs(xl[i]), x[i]+fabs(xh[i]),
90 y[i], max(fabs(yl[i]), fabs(yh[i])));
94 stable_sort(bins.begin(), bins.end());
96 for(
auto low = bins.begin(); !problems && low != bins.end(); ++low){
99 if(high == bins.end())
break;
100 double new_y = sqrt(low->y * high->y);
101 double top = max(low->y+low->e, high->y+high->e);
102 double bot = min(low->y-low->e, high->y-high->e);
103 double new_e = max(top-new_y, new_y-bot);
104 if(low->xh < high->xl){
106 bins.insert(high, Point(low->xh, high->xl, new_y, new_e));
107 }
else if(low->xh > high->xl){
110 if(low->xh < high->xh){
112 Point new_low(low->xl, high->xl, low->y, low->e);
113 Point new_mid(high->xl, low->xh, new_y, new_e);
114 Point new_high(low->xh, high->xh, high->y, high->e);
117 bins.insert(high, new_mid);
118 }
else if(low->xh == high->xh){
120 Point new_low(low->xl, high->xl, low->y, low->e);
121 Point new_high(high->xl, high->xh, new_y, new_e);
126 Point new_low(low->xl, high->xl, low->y, low->e);
127 Point new_mid(high->xl, high->xh, new_y, new_e);
128 Point new_high(high->xh, low->xh, low->y, low->e);
131 bins.insert(high, new_mid);
136 vector<double> bin_edges(bins.size()+1);
137 for(
size_t i = 0; i < bins.size(); ++i){
138 bin_edges.at(i) = bins.at(i).xl;
140 bin_edges.back() = bins.back().xh;
141 TH2D h(g.GetName(), (string(g.GetTitle())+
";"+g.GetXaxis()->GetTitle()+
";"+g.GetYaxis()->GetTitle()).c_str(),
142 1, 0., 1.e4, bin_edges.size()-1, &bin_edges.at(0));
143 for(
int ix = 0; ix <= 2; ++ix){
144 h.SetBinContent(ix, 0, 1.);
145 h.SetBinError(ix, 0, 1.);
146 h.SetBinContent(ix, h.GetNbinsY()+1, 1.);
147 h.SetBinError(ix, h.GetNbinsY()+1, 1.);
148 for(
int iy = 1; iy <= h.GetNbinsY(); ++iy){
149 h.SetBinContent(ix, iy, bins.at(iy-1).y);
150 h.SetBinError(ix ,iy, bins.at(iy-1).e);
175 "GsfElectronToCutBasedSpring15M");
177 "MVAVLooseElectronToMini");
192 if(lep.pt() <= SignalLeptonPtCut)
return false;
193 if(fabs(lep.eta()) > MuonEtaCut)
return false;
195 if(!idMuon(lep, vtx, kMedium))
return false;
197 if(lepIso >= 0 && lepIso > MuonMiniIsoCut)
return false;
204 if(lep.pt() <= VetoLeptonPtCut)
return false;
205 if(fabs(lep.eta()) > MuonEtaCut)
return false;
207 if(!idMuon(lep, vtx, kMedium))
return false;
209 if(lepIso >= 0 && lepIso > MuonMiniIsoCut)
return false;
215 double dz(0.), d0(0.);
216 if(!vertexMuon(lep, vtx, dz, d0))
return false;
223 return lep.isLooseMuon();
225 return lep.isMediumMuon();
228 good_global = lep.isGlobalMuon()
229 && lep.globalTrack()->normalizedChi2() < 3.
230 && lep.combinedQuality().chi2LocalPosition < 12.
231 && lep.combinedQuality().trkKink < 20.;
232 return muon::isLooseMuon(lep)
233 && lep.innerTrack()->validFraction() > 0.49
234 && muon::segmentCompatibility(lep) > (good_global ? 0.303 : 0.451);
236 return lep.isTightMuon(vtx->at(0));
242 if(lep.track().isAvailable()){
243 dz = lep.track()->vz()-vtx->at(0).z();
244 d0 = lep.track()->d0()-vtx->at(0).x()*sin(lep.track()->phi())+vtx->at(0).y()*cos(lep.track()->phi());
246 if(fabs(dz) > 0.5 || fabs(d0) > 0.2)
return false;
252 double abseta = fabs(eta);
253 if (abseta < 0.8)
return 0.0735;
254 else if (abseta < 1.3)
return 0.0619;
255 else if (abseta < 2.0)
return 0.0465;
256 else if (abseta < 2.2)
return 0.0433;
257 else if (abseta < 2.5)
return 0.0577;
262 double ch_iso(lep.pfIsolationR04().sumChargedHadronPt);
263 double neu_iso(max(0., lep.pfIsolationR04().sumNeutralHadronEt + lep.pfIsolationR04().sumPhotonEt
264 -rho*getEffAreaMuon(lep.eta())));
266 return (ch_iso + neu_iso) / lep.pt();
280 if(lep.pt() <= SignalLeptonPtCut)
return false;
281 if(fabs(lep.superCluster()->position().eta()) > ElectronEtaCut)
return false;
283 if(!idElectron(lep, vtx, kMedium))
return false;
285 if(lepIso >= 0 && lepIso > ElectronMiniIsoCut)
return false;
292 if(lep.pt() <= VetoLeptonPtCut)
return false;
293 if(fabs(lep.superCluster()->position().eta()) > ElectronEtaCut)
return false;
295 if(!idElectron(lep, vtx, kVeto))
return false;
297 if(lepIso >= 0 && lepIso > ElectronMiniIsoCut)
return false;
304 bool barrel(lep.isEB());
305 double deta_cut, dphi_cut, ieta_cut, hovere_cut, d0_cut, dz_cut,
306 ooeminusoop_cut, reliso_cut, misshits_cut;
336 ieta_cut = chooseVal(threshold ,0.0114, 0.0103, 0.0101, 0.0101);
337 deta_cut = chooseVal(threshold ,0.0152, 0.0105, 0.0103, 0.00926);
338 dphi_cut = chooseVal(threshold ,0.216, 0.115, 0.0336, 0.0336);
339 hovere_cut = chooseVal(threshold ,0.181, 0.104, 0.0876, 0.0597);
340 reliso_cut = chooseVal(threshold ,0.126, 0.0893, 0.0766, 0.0354);
341 ooeminusoop_cut = chooseVal(threshold ,0.207, 0.102, 0.0174, 0.012);
342 d0_cut = chooseVal(threshold ,0.0564, 0.0261, 0.0118, 0.0111);
343 dz_cut = chooseVal(threshold ,0.472, 0.41, 0.373, 0.0466);
344 misshits_cut = chooseVal(threshold ,2, 2, 2, 2);
345 req_conv_veto = chooseVal(threshold ,
true ,
true ,
true ,
true );
347 ieta_cut = chooseVal(threshold ,0.0352 , 0.0301 , 0.0283 , 0.0279);
348 deta_cut = chooseVal(threshold ,0.0113 , 0.00814 , 0.00733 , 0.00724);
349 dphi_cut = chooseVal(threshold ,0.237 , 0.182 , 0.114 , 0.0918);
350 hovere_cut = chooseVal(threshold ,0.116 , 0.0897 , 0.0678 , 0.0615);
351 reliso_cut = chooseVal(threshold ,0.144 , 0.121 , 0.0678 , 0.0646);
352 ooeminusoop_cut = chooseVal(threshold ,0.174 , 0.126 , 0.0898 , 0.00999);
353 d0_cut = chooseVal(threshold ,0.222 , 0.118 , 0.0739 , 0.0351);
354 dz_cut = chooseVal(threshold ,0.921 , 0.822 , 0.602 , 0.417);
355 misshits_cut = chooseVal(threshold ,3, 1, 1, 1);
356 req_conv_veto = chooseVal(threshold ,
true ,
true ,
true ,
true );
359 double dz(0.), d0(0.);
360 vertexElectron(lep, vtx, dz, d0);
363 if(lep.gsfTrack().isAvailable()){
364 mhits = lep.gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS);;
366 const double sigietaieta(lep.full5x5_sigmaIetaIeta());
368 return deta_cut > fabs(lep.deltaEtaSuperClusterTrackAtVtx())
369 && dphi_cut > fabs(lep.deltaPhiSuperClusterTrackAtVtx())
370 && ieta_cut > sigietaieta
371 && hovere_cut > lep.hadronicOverEm()
374 && ooeminusoop_cut > fabs((1.0-lep.eSuperClusterOverP())/lep.ecalEnergy())
375 && (!doIso || reliso_cut > 0)
376 && (!req_conv_veto || lep.passConversionVeto())
377 && (misshits_cut >= mhits);
382 if(lep.gsfTrack().isAvailable()){
383 dz = lep.gsfTrack()->vz()-vtx->at(0).z();
384 d0 = lep.gsfTrack()->d0()-vtx->at(0).x()*sin(lep.gsfTrack()->phi())+vtx->at(0).y()*cos(lep.gsfTrack()->phi());
386 if(fabs(dz) > 0.5 || fabs(d0) > 0.2)
return false;
392 double abseta = fabs(eta);
393 if (abseta < 1)
return 0.1752;
394 else if (abseta < 1.479)
return 0.1862;
395 else if (abseta < 2.0)
return 0.1411;
396 else if (abseta < 2.2)
return 0.1534;
397 else if (abseta < 2.3)
return 0.1903;
398 else if (abseta < 2.4)
return 0.2243;
399 else if (abseta < 2.5)
return 0.2687;
404 double ch_iso(lep.pfIsolationVariables().sumChargedHadronPt);
405 double neu_iso(max(0., lep.pfIsolationVariables().sumNeutralHadronEt + lep.pfIsolationVariables().sumPhotonEt
406 -rho*getEffAreaElectron(lep.eta())));
408 return (ch_iso + neu_iso) / lep.pt();
418 if(
const pat::Electron * ele_ptr = dynamic_cast<const pat::Electron*>(&cand)){
419 return getScaleFactor(*ele_ptr);
420 }
else if(
const reco::Muon * mu_ptr = dynamic_cast<const reco::Muon*>(&cand)){
421 return getScaleFactor(*mu_ptr);
423 ERROR(
"Cannot get scale factor for type " <<
typeid(cand).name());
429 return accumulate(sig_leps.cbegin(), sig_leps.cend(), make_pair(1., 0.),
430 [](pair<double, double> sf,
const reco::Candidate* cand){
431 if(cand ==
nullptr)
ERROR(
"Dereferencing nullptr");
432 return MergeSF(sf, getScaleFactor(*cand));
437 if(
const pat::Electron * ele_ptr = dynamic_cast<const pat::Electron*>(&cand)){
438 return getScaleFactorFs(*ele_ptr);
439 }
else if(
const reco::Muon * mu_ptr = dynamic_cast<const reco::Muon*>(&cand)){
440 return getScaleFactorFs(*mu_ptr);
442 ERROR(
"Cannot get scale factor for type " <<
typeid(cand).name());
448 return accumulate(sig_leps.cbegin(), sig_leps.cend(), make_pair(1., 0.),
449 [](pair<double, double> sf,
const reco::Candidate* cand){
450 if(cand ==
nullptr)
ERROR(
"Dereferencing nullptr");
451 return MergeSF(sf, getScaleFactorFs(*cand));
459 double pt = lep.pt();
460 double eta = lep.eta();
461 double abseta = fabs(eta);
462 vector<pair<double, double> > sfs{
463 GetSF(sf_full_muon_medium, pt, abseta,
false),
465 GetSF(sf_full_muon_iso, pt, abseta,
false),
467 GetSF(sf_full_muon_vtx, pt, abseta,
false),
471 return accumulate(sfs.cbegin(), sfs.cend(), make_pair(1., 0.),
MergeSF);
480 double pt = lep.superCluster()->energy()*sin(lep.superClusterPosition().theta());
481 double eta = lep.superCluster()->eta();
482 double abseta = fabs(eta);
483 vector<pair<double, double> > sfs{
484 GetSF(sf_full_electron_medium, pt, abseta),
485 GetSF(sf_full_electron_iso, pt, abseta),
486 GetSF(sf_full_electron_tracking, eta, pt),
488 make_pair(1., pt<20. || pt >80. ? 0.01 : 0.)
490 return accumulate(sfs.cbegin(), sfs.cend(), make_pair(1., 0.),
MergeSF);
497 double pt = lep.pt();
498 double abseta = fabs(lep.eta());
499 vector<pair<double, double> > sfs{
500 GetSF(sf_fast_muon_medium, pt, abseta,
false),
502 GetSF(sf_fast_muon_iso, pt, abseta,
false),
505 return accumulate(sfs.cbegin(), sfs.cend(), make_pair(1., 0.),
MergeSF);
512 double pt = lep.superCluster()->energy()*sin(lep.superClusterPosition().theta());
513 double abseta = fabs(lep.superCluster()->eta());
514 vector<pair<double, double> > sfs{
515 GetSF(sf_fast_electron_mediumiso, pt, abseta,
false),
519 return accumulate(sfs.cbegin(), sfs.cend(), make_pair(1., 0.),
MergeSF);
523 const reco::Candidate* ptcl,
524 double r_iso_min,
double r_iso_max,
double kt_scale,
525 double rho,
bool charged_only) {
526 if (ptcl->pt()<1.)
return 99999.;
528 double deadcone_nh(0.), deadcone_ch(0.), deadcone_ph(0.), deadcone_pu(0.);
529 if(ptcl->isElectron()) {
530 if (fabs(ptcl->eta())>1.479) {deadcone_ch = 0.015; deadcone_pu = 0.015; deadcone_ph = 0.08;}
531 }
else if(ptcl->isMuon()) {
532 deadcone_ch = 0.0001; deadcone_pu = 0.01; deadcone_ph = 0.01;deadcone_nh = 0.01;
536 double iso_nh(0.), iso_ch(0.), iso_ph(0.), iso_pu(0.);
537 double ptThresh(0.5), r_mini(kt_scale/ptcl->pt());
538 if(ptcl->isElectron()) ptThresh = 0;
539 double r_iso(max(r_iso_min, min(r_iso_max, r_mini)));
541 for (
const pat::PackedCandidate &pfc : *pfcands) {
542 if (abs(pfc.pdgId())<7)
continue;
543 double dr = deltaR(pfc, *ptcl);
544 if (dr > r_iso)
continue;
545 if (&pfc == ptcl)
continue;
546 if (pfc.charge()==0){
547 if (pfc.pt()>ptThresh) {
548 if (abs(pfc.pdgId())==22) {
549 if(dr < deadcone_ph)
continue;
551 }
else if (abs(pfc.pdgId())==130) {
552 if(dr < deadcone_nh)
continue;
556 }
else if (pfc.fromPV()>1){
557 if (abs(pfc.pdgId())==211) {
558 if(dr < deadcone_ch)
continue;
562 if (pfc.pt()>ptThresh){
563 if(dr < deadcone_pu)
continue;
569 double effarea = ptcl->isElectron() ? getEffAreaElectron(ptcl->eta()) : getEffAreaMuon(ptcl->eta());
570 double pu_corr = rho*effarea*pow(r_iso/0.3, 2);
572 if (charged_only) iso = iso_ch;
573 else iso = iso_ch + max(0.,iso_ph + iso_nh - pu_corr);
575 return iso/ptcl->pt();
585 float cone_size = 0.3;
587 for (
size_t i(0); i < pfcands->size(); i++) {
588 const pat::PackedCandidate &tk = (*pfcands)[i];
589 unsigned int id = abs(tk.pdgId());
592 float pt_min =
id==211 ? 10. : 5.;
593 float iso_max =
id==211 ? 0.1 : 0.2;
596 if (tk.charge()==0)
continue;
597 if (
id!=11 &&
id!=13 &&
id!=211)
continue;
598 if (tk.pt() < pt_min)
continue;
599 if (fabs(tk.eta()) > eta_max)
continue;
600 if (fabs(tk.dz()) > dz_max)
continue;
601 if (mt_max>0.01 &&
getMT(met, met_phi, tk.pt(), tk.phi())>mt_max)
continue;
605 for (
size_t j(0); j < pfcands->size(); j++) {
607 const pat::PackedCandidate &pfc = (*pfcands)[j];
609 if (pfc.charge()==0)
continue;
610 if (deltaR(tk,pfc) > cone_size)
continue;
611 if (fabs(pfc.dz()) > dz_max)
continue;
614 if (iso/tk.pt()>iso_max)
continue;
616 tks.push_back(dynamic_cast<const reco::Candidate *>(&tk));
622 vCands lepton_tools::getRA4IsoTracks(edm::Handle<pat::PackedCandidateCollection> pfcands,
double met,
double met_phi,
double rhoEventCentral, vector<float> &isos, vector<float> &relisos,
int primary_pdg){
630 for (
size_t i(0); i < pfcands->size(); i++) {
631 const pat::PackedCandidate &tk = (*pfcands)[i];
632 unsigned int id = abs(tk.pdgId());
635 if (tk.charge()==0)
continue;
636 if (
id!=11 &&
id!=13 &&
id!=211)
continue;
637 if (tk.pt() < pt_min)
continue;
638 if (fabs(tk.dz()) > dz_max)
continue;
642 if(tk.pdgId() * primary_pdg < 0 )
continue;
645 if(tk.pdgId() * primary_pdg > 0 )
continue;
653 iso = getPFIsolation(pfcands, dynamic_cast<const reco::Candidate *>(&tk), 0.05, 0.2, 10., rhoEventCentral,
false);
654 reliso = getPFIsolation(pfcands, dynamic_cast<const reco::Candidate *>(&tk), 0.3, 0.3, 10., rhoEventCentral,
false);
657 iso = getPFIsolation(pfcands, dynamic_cast<const reco::Candidate *>(&tk), 0.05, 0.2, 10., rhoEventCentral,
true);
658 reliso = getPFIsolation(pfcands, dynamic_cast<const reco::Candidate *>(&tk), 0.3, 0.3, 10., rhoEventCentral,
true);
661 if(iso>iso_max && reliso>iso_max)
continue;
663 relisos.push_back(reliso);
664 tks.push_back(dynamic_cast<const reco::Candidate *>(&tk));
672 const reco::Track &tk = *mu.innerTrack();
673 return tk.algoMask().count() == 1 && tk.isAlgoInMask(reco::Track::muonSeededStepOutIn);
676 return (!selectClones || outInOnly(mu));
679 return muon::isMediumMuon(mu) && mu.numberOfMatchedStations() >= 2;
682 return mu.isGlobalMuon() && (mu.globalTrack()->hitPattern().muonStationsWithValidHits() >= 3 && mu.globalTrack()->normalizedChi2() <= 20);
685 if (mu.muonBestTrack()->ptError() > 0.2 * mu.muonBestTrack()->pt()) {
return false; }
686 return mu.numberOfMatchedStations() >= 1 || tightGlobal(mu);
689 return mu.pt() >= 10 && mu.numberOfMatchedStations() >= 1;
693 edm::Handle<pat::MuonCollection> muptr,
bool selectClones) {
696 bool verbose_ =
false;
697 assert(vtx->size() >= 1);
698 const auto &PV = vtx->front().position();
700 set<unsigned> badmus;
701 std::vector<int> goodMuon;
702 const pat::MuonCollection &muons = *muptr;
703 for (
auto & mu : muons) {
704 if (!mu.userInt(
"muonsCleaned:oldPF") || mu.innerTrack().isNull()) {
705 goodMuon.push_back(-1);
708 if (preselection(mu, selectClones)) {
709 float dxypv = std::abs(mu.innerTrack()->dxy(PV));
710 float dzpv = std::abs(mu.innerTrack()->dz(PV));
712 bool ipLoose = ((dxypv < 0.5 && dzpv < 2.0) || mu.innerTrack()->hitPattern().pixelLayersWithMeasurement() >= 2);
713 goodMuon.push_back(ipLoose || (!selectClones && tightGlobal(mu)));
714 }
else if (safeId(mu)) {
715 bool ipTight = (dxypv < 0.2 && dzpv < 0.5);
716 goodMuon.push_back(ipTight);
718 goodMuon.push_back(0);
721 goodMuon.push_back(3);
725 for (
unsigned int i = 0, n = muons.size(); i < n; ++i) {
726 if (muons[i].pt() < ptCut_ || goodMuon[i] != 0)
continue;
727 if (verbose_) printf(
"potentially bad muon %d of pt %.1f eta %+.3f phi %+.3f\n",
int(i+1), muons[i].pt(), muons[i].eta(), muons[i].phi());
731 unsigned int n1 = muons[i].numberOfMatches(reco::Muon::SegmentArbitration);
732 for (
unsigned int j = 0; j < n; ++j) {
733 if (j == i || goodMuon[j] <= 0 || !partnerId(muons[j]))
continue;
734 unsigned int n2 = muons[j].numberOfMatches(reco::Muon::SegmentArbitration);
735 if (deltaR2(muons[i],muons[j]) < 0.16 || (n1 > 0 && n2 > 0 && muon::sharedSegments(muons[i],muons[j]) >= 0.5*std::min(n1,n2))) {
736 if (verbose_) printf(
" tagged as clone of muon %d of pt %.1f eta %+.3f phi %+.3f\n",
int(j+1), muons[j].pt(), muons[j].eta(), muons[j].phi());
742 if (bad) badmus.insert(i);
std::vector< const reco::Candidate * > vCands
float getMT(float pt1, float phi1, float pt2, float phi2)