void selectWe(const TString conf, // input file const TString outputDir, // output directory const Bool_t doScaleCorr // apply energy scale corrections? ) { gBenchmark->Start("selectWe"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t PT_CUT = 20; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Double_t escaleNbins = 6; const Double_t escaleEta[] = { 0.4, 0.8, 1.2, 1.4442, 2, 2.5 }; const Double_t escaleCorr[] = { 1.00284, 1.00479, 1.00734, 1.00851, 1.00001, 0.982898 }; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== vector<TString> snamev; // sample name (for output files) vector<CSample*> samplev; // data/MC samples // // parse .conf file // confParse(conf, snamev, samplev); const Bool_t hasData = (samplev[0]->fnamev.size()>0); // Create output directory gSystem->mkdir(outputDir,kTRUE); const TString ntupDir = outputDir + TString("/ntuples"); gSystem->mkdir(ntupDir,kTRUE); // // Declare output ntuple variables // UInt_t runNum, lumiSec, evtNum; UInt_t npv, npu; Float_t genVPt, genVPhi, genVy, genVMass; Float_t genLepPt, genLepPhi; Float_t scale1fb; Float_t met, metPhi, sumEt, mt, u1, u2; Int_t q; LorentzVector *lep=0; ///// electron specific ///// Float_t trkIso, emIso, hadIso; Float_t pfChIso, pfGamIso, pfNeuIso, pfCombIso; Float_t sigieie, hovere, eoverp, fbrem, ecalE; Float_t dphi, deta; Float_t d0, dz; UInt_t isConv, nexphits, typeBits; LorentzVector *sc=0; // Data structures to store info from TTrees mithep::TEventInfo *info = new mithep::TEventInfo(); mithep::TGenInfo *gen = new mithep::TGenInfo(); TClonesArray *electronArr = new TClonesArray("mithep::TElectron"); TClonesArray *pvArr = new TClonesArray("mithep::TVertex"); TFile *infile=0; TTree *eventTree=0; // // loop over samples // for(UInt_t isam=0; isam<samplev.size(); isam++) { // Assume data sample is first sample in .conf file // If sample is empty (i.e. contains no ntuple files), skip to next sample if(isam==0 && !hasData) continue; CSample* samp = samplev[isam]; // // Set up output ntuple // TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root"); if(isam==0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root"); TFile *outFile = new TFile(outfilename,"RECREATE"); TTree *outTree = new TTree("Events","Events"); outTree->Branch("runNum", &runNum, "runNum/i"); // event run number outTree->Branch("lumiSec", &lumiSec, "lumiSec/i"); // event lumi section outTree->Branch("evtNum", &evtNum, "evtNum/i"); // event number outTree->Branch("npv", &npv, "npv/i"); // number of primary vertices outTree->Branch("npu", &npu, "npu/i"); // number of in-time PU events (MC) outTree->Branch("genVPt", &genVPt, "genVPt/F"); // GEN boson pT (signal MC) outTree->Branch("genVPhi", &genVPhi, "genVPhi/F"); // GEN boson phi (signal MC) outTree->Branch("genVy", &genVy, "genVy/F"); // GEN boson rapidity (signal MC) outTree->Branch("genVMass", &genVMass, "genVMass/F"); // GEN boson mass (signal MC) outTree->Branch("genLepPt", &genLepPt, "genLepPt/F"); // GEN lepton pT (signal MC) outTree->Branch("genLepPhi",&genLepPhi,"genLepPhi/F"); // GEN lepton phi (signal MC) outTree->Branch("scale1fb", &scale1fb, "scale1fb/F"); // event weight per 1/fb (MC) outTree->Branch("met", &met, "met/F"); // MET outTree->Branch("metPhi", &metPhi, "metPhi/F"); // phi(MET) outTree->Branch("sumEt", &sumEt, "sumEt/F"); // Sum ET outTree->Branch("mt", &mt, "mt/F"); // transverse mass outTree->Branch("u1", &u1, "u1/F"); // parallel component of recoil outTree->Branch("u2", &u2, "u2/F"); // perpendicular component of recoil outTree->Branch("q", &q, "q/I"); // lepton charge outTree->Branch("lep", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep); // lepton 4-vector ///// electron specific ///// outTree->Branch("trkIso", &trkIso, "trkIso/F"); // track isolation of tag lepton outTree->Branch("emIso", &emIso, "emIso/F"); // ECAL isolation of tag lepton outTree->Branch("hadIso", &hadIso, "hadIso/F"); // HCAL isolation of tag lepton outTree->Branch("pfChIso", &pfChIso, "pfChIso/F"); // PF charged hadron isolation of lepton outTree->Branch("pfGamIso", &pfGamIso, "pfGamIso/F"); // PF photon isolation of lepton outTree->Branch("pfNeuIso", &pfNeuIso, "pfNeuIso/F"); // PF neutral hadron isolation of lepton outTree->Branch("pfCombIso", &pfCombIso, "pfCombIso/F"); // PF combined isolation of electron outTree->Branch("sigieie", &sigieie, "sigieie/F"); // sigma-ieta-ieta of electron outTree->Branch("hovere", &hovere, "hovere/F"); // H/E of electron outTree->Branch("eoverp", &eoverp, "eoverp/F"); // E/p of electron outTree->Branch("fbrem", &fbrem, "fbrem/F"); // brem fraction of electron outTree->Branch("dphi", &dphi, "dphi/F"); // GSF track - ECAL dphi of electron outTree->Branch("deta", &deta, "deta/F"); // GSF track - ECAL deta of electron outTree->Branch("ecalE", &ecalE, "ecalE/F"); // ECAL energy of electron outTree->Branch("d0", &d0, "d0/F"); // transverse impact parameter of electron outTree->Branch("dz", &dz, "dz/F"); // longitudinal impact parameter of electron outTree->Branch("isConv", &isConv, "isConv/i"); // conversion filter flag of electron outTree->Branch("nexphits", &nexphits, "nexphits/i"); // number of missing expected inner hits of electron outTree->Branch("typeBits", &typeBits, "typeBits/i"); // electron type of electron outTree->Branch("sc", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc); // electron Supercluster 4-vector // // loop through files // const UInt_t nfiles = samp->fnamev.size(); for(UInt_t ifile=0; ifile<nfiles; ifile++) { // Read input file and get the TTrees cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush(); infile = new TFile(samp->fnamev[ifile]); assert(infile); Bool_t hasJSON = kFALSE; mithep::RunLumiRangeMap rlrm; if(samp->jsonv[ifile].CompareTo("NONE")!=0) { hasJSON = kTRUE; rlrm.AddJSONFile(samp->jsonv[ifile].Data()); } eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("PV", &pvArr); TBranch *pvBr = eventTree->GetBranch("PV"); Bool_t hasGen = eventTree->GetBranchStatus("Gen"); TBranch *genBr=0; if(hasGen) { eventTree->SetBranchAddress("Gen", &gen); genBr = eventTree->GetBranch("Gen"); } // Compute MC event weight per 1/fb Double_t weight = 1; const Double_t xsec = samp->xsecv[ifile]; if(xsec>0) weight = 1000.*xsec/(Double_t)eventTree->GetEntries(); // // loop over events // Double_t nsel=0, nselvar=0; for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { infoBr->GetEntry(ientry); if(genBr) genBr->GetEntry(ientry); // check for certified lumi (if applicable) mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec); if(hasJSON && !rlrm.HasRunLumi(rl)) continue; // trigger requirement ULong64_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL; ULong64_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj; if(!(info->triggerBits & trigger)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; pvArr->Clear(); pvBr->GetEntry(ientry); // // SELECTION PROCEDURE: // (1) Look for 1 good electron matched to trigger // (2) Reject event if another electron is present passing looser cuts // electronArr->Clear(); electronBr->GetEntry(ientry); Int_t nLooseLep=0; const mithep::TElectron *goodEle=0; Bool_t passSel=kFALSE; for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) { const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i]); // check ECAL gap if(fabs(ele->scEta)>=ECAL_GAP_LOW && fabs(ele->scEta)<=ECAL_GAP_HIGH) continue; Double_t escale=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(ele->scEta)<escaleEta[ieta]) { escale = escaleCorr[ieta]; break; } } } if(fabs(ele->scEta) > 2.5) continue; // loose lepton |eta| cut if(escale*(ele->scEt) < 20) continue; // loose lepton pT cut if(passEleLooseID(ele,info->rhoLowEta)) nLooseLep++; // loose lepton selection if(nLooseLep>1) { // extra lepton veto passSel=kFALSE; break; } if(fabs(ele->scEta) > ETA_CUT) continue; // lepton |eta| cut if(escale*(ele->scEt) < PT_CUT) continue; // lepton pT cut if(!passEleID(ele,info->rhoLowEta)) continue; // lepton selection if(!(ele->hltMatchBits & trigObj)) continue; // check trigger matching passSel=kTRUE; goodEle = ele; } if(passSel) { /******** We have a W candidate! HURRAY! ********/ nsel+=weight; nselvar+=weight*weight; Double_t escale=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(goodEle->scEta)<escaleEta[ieta]) { escale = escaleCorr[ieta]; break; } } } LorentzVector vLep(escale*(goodEle->pt), goodEle->eta, goodEle->phi, ELE_MASS); LorentzVector vSC(escale*(goodEle->scEt), goodEle->scEta, goodEle->scPhi, ELE_MASS); // // Fill tree // runNum = info->runNum; lumiSec = info->lumiSec; evtNum = info->evtNum; npv = pvArr->GetEntriesFast(); npu = info->nPU; genVPt = 0; genVPhi = 0; genVy = 0; genVMass = 0; genLepPt = 0; genLepPhi= 0; u1 = 0; u2 = 0; if(hasGen) { genVPt = gen->vpt; genVPhi = gen->vphi; genVy = gen->vy; genVMass = gen->vmass; TVector2 vWPt((gen->vpt)*cos(gen->vphi),(gen->vpt)*sin(gen->vphi)); TVector2 vLepPt(vLep.Px(),vLep.Py()); TVector2 vMet((info->pfMET)*cos(info->pfMETphi), (info->pfMET)*sin(info->pfMETphi)); TVector2 vU = -1.0*(vMet+vLepPt); u1 = ((vWPt.Px())*(vU.Px()) + (vWPt.Py())*(vU.Py()))/(gen->vpt); // u1 = (pT . u)/|pT| u2 = ((vWPt.Px())*(vU.Py()) - (vWPt.Py())*(vU.Px()))/(gen->vpt); // u2 = (pT x u)/|pT| if(abs(gen->id_1)==EGenType::kElectron) { genLepPt = gen->vpt_1; genLepPhi = gen->vphi_1; } if(abs(gen->id_2)==EGenType::kElectron) { genLepPt = gen->vpt_2; genLepPhi = gen->vphi_2; } } scale1fb = weight; met = info->pfMET; metPhi = info->pfMETphi; sumEt = info->pfSumET; mt = sqrt( 2.0 * (vLep.Pt()) * (info->pfMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->pfMETphi))) ); q = goodEle->q; lep = &vLep; ///// electron specific ///// sc = &vSC; trkIso = goodEle->trkIso03; emIso = goodEle->emIso03; hadIso = goodEle->hadIso03; pfChIso = goodEle->pfChIso03; pfGamIso = goodEle->pfGamIso03; pfNeuIso = goodEle->pfNeuIso03; pfCombIso = goodEle->pfChIso03 + TMath::Max(goodEle->pfNeuIso03 + goodEle->pfGamIso03 - (info->rhoLowEta)*getEffArea(goodEle->scEta), 0.); sigieie = goodEle->sigiEtaiEta; hovere = goodEle->HoverE; eoverp = goodEle->EoverP; fbrem = goodEle->fBrem; dphi = goodEle->deltaPhiIn; deta = goodEle->deltaEtaIn; d0 = goodEle->d0; dz = goodEle->dz; isConv = goodEle->isConv; nexphits = goodEle->nExpHitsInner; typeBits = goodEle->typeBits; outTree->Fill(); } } delete infile; infile=0, eventTree=0; cout << nsel << " +/- " << sqrt(nselvar); if(isam!=0) cout << " per 1/fb"; cout << endl; } outFile->Write(); outFile->Close(); } delete info; delete gen; delete electronArr; delete pvArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " W -> e nu" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; if(doScaleCorr) cout << " *** Scale corrections applied ***" << endl; cout << endl; cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("selectWe"); }
void selectWe(const TString conf="we.conf", // input file const TString outputDir=".", // output directory const Bool_t doScaleCorr=0 // apply energy scale corrections? ) { gBenchmark->Start("selectWe"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t PT_CUT = 25; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t VETO_PT = 10; const Double_t VETO_ETA = 2.5; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Double_t escaleNbins = 2; const Double_t escaleEta[] = { 1.4442, 2.5 }; const Double_t escaleCorr[] = { 0.992, 1.009 }; const Int_t BOSON_ID = 24; const Int_t LEPTON_ID = 11; // load trigger menu const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun"); // load pileup reweighting file TFile *f_rw = TFile::Open("../Tools/pileup_rw_Golden.root", "read"); TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden"); TH1D *h_rw_up = (TH1D*) f_rw->Get("h_rw_up_golden"); TH1D *h_rw_down = (TH1D*) f_rw->Get("h_rw_down_golden"); //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== vector<TString> snamev; // sample name (for output files) vector<CSample*> samplev; // data/MC samples // // parse .conf file // confParse(conf, snamev, samplev); const Bool_t hasData = (samplev[0]->fnamev.size()>0); // Create output directory gSystem->mkdir(outputDir,kTRUE); const TString ntupDir = outputDir + TString("/ntuples"); gSystem->mkdir(ntupDir,kTRUE); // // Declare output ntuple variables // UInt_t runNum, lumiSec, evtNum; UInt_t npv, npu; UInt_t id_1, id_2; Double_t x_1, x_2, xPDF_1, xPDF_2; Double_t scalePDF, weightPDF; TLorentzVector *genV=0, *genLep=0; Float_t genVPt, genVPhi, genVy, genVMass; Float_t genLepPt, genLepPhi; Float_t scale1fb, puWeight, puWeightUp, puWeightDown; Float_t met, metPhi, sumEt, mt, u1, u2; Float_t tkMet, tkMetPhi, tkSumEt, tkMt, tkU1, tkU2; Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaMt, mvaU1, mvaU2; Float_t puppiMet, puppiMetPhi, puppiSumEt, puppiMt, puppiU1, puppiU2; Int_t q; TLorentzVector *lep=0; Int_t lepID; ///// electron specific ///// Float_t trkIso, emIso, hadIso; Float_t pfChIso, pfGamIso, pfNeuIso, pfCombIso; Float_t sigieie, hovere, eoverp, fbrem, ecalE; Float_t dphi, deta; Float_t d0, dz; UInt_t isConv, nexphits, typeBits; TLorentzVector *sc=0; // Data structures to store info from TTrees baconhep::TEventInfo *info = new baconhep::TEventInfo(); baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo(); TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle"); TClonesArray *electronArr = new TClonesArray("baconhep::TElectron"); TClonesArray *scArr = new TClonesArray("baconhep::TPhoton"); TClonesArray *vertexArr = new TClonesArray("baconhep::TVertex"); TFile *infile=0; TTree *eventTree=0; // // loop over samples // for(UInt_t isam=0; isam<samplev.size(); isam++) { // Assume data sample is first sample in .conf file // If sample is empty (i.e. contains no ntuple files), skip to next sample Bool_t isData=kFALSE; if(isam==0 && !hasData) continue; else if (isam==0) isData=kTRUE; // Assume signal sample is given name "we" -- flag to store GEN W kinematics Bool_t isSignal = (snamev[isam].CompareTo("we",TString::kIgnoreCase)==0); // flag to reject W->enu events when selecting at wrong-flavor background events Bool_t isWrongFlavor = (snamev[isam].CompareTo("wx",TString::kIgnoreCase)==0); CSample* samp = samplev[isam]; // // Set up output ntuple // TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root"); if(isam!=0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root"); TFile *outFile = new TFile(outfilename,"RECREATE"); TTree *outTree = new TTree("Events","Events"); outTree->Branch("runNum", &runNum, "runNum/i"); // event run number outTree->Branch("lumiSec", &lumiSec, "lumiSec/i"); // event lumi section outTree->Branch("evtNum", &evtNum, "evtNum/i"); // event number outTree->Branch("npv", &npv, "npv/i"); // number of primary vertices outTree->Branch("npu", &npu, "npu/i"); // number of in-time PU events (MC) outTree->Branch("id_1", &id_1, "id_1/i"); // PDF info -- parton ID for parton 1 outTree->Branch("id_2", &id_2, "id_2/i"); // PDF info -- parton ID for parton 2 outTree->Branch("x_1", &x_1, "x_1/d"); // PDF info -- x for parton 1 outTree->Branch("x_2", &x_2, "x_2/d"); // PDF info -- x for parton 2 outTree->Branch("xPDF_1", &xPDF_1, "xPDF_1/d"); // PDF info -- x*F for parton 1 outTree->Branch("xPDF_2", &xPDF_2, "xPDF_2/d"); // PDF info -- x*F for parton 2 outTree->Branch("scalePDF", &scalePDF, "scalePDF/d"); // PDF info -- energy scale of parton interaction outTree->Branch("weightPDF", &weightPDF, "weightPDF/d"); // PDF info -- PDF weight outTree->Branch("genV", "TLorentzVector", &genV); // GEN boson 4-vector (signal MC) outTree->Branch("genLep", "TLorentzVector", &genLep); // GEN lepton 4-vector (signal MC) outTree->Branch("genVPt", &genVPt, "genVPt/F"); // GEN boson pT (signal MC) outTree->Branch("genVPhi", &genVPhi, "genVPhi/F"); // GEN boson phi (signal MC) outTree->Branch("genVy", &genVy, "genVy/F"); // GEN boson rapidity (signal MC) outTree->Branch("genVMass", &genVMass, "genVMass/F"); // GEN boson mass (signal MC) outTree->Branch("genLepPt", &genLepPt, "genLepPt/F"); // GEN lepton pT (signal MC) outTree->Branch("genLepPhi", &genLepPhi, "genLepPhi/F"); // GEN lepton phi (signal MC) outTree->Branch("scale1fb", &scale1fb, "scale1fb/F"); // event weight per 1/fb (MC) outTree->Branch("puWeight", &puWeight, "puWeight/F"); // scale factor for pileup reweighting (MC) outTree->Branch("puWeightUp", &puWeightUp, "puWeightUp/F"); // scale factor for pileup reweighting (MC) outTree->Branch("puWeightDown", &puWeightDown, "puWeightDown/F"); // scale factor for pileup reweighting (MC) outTree->Branch("met", &met, "met/F"); // MET outTree->Branch("metPhi", &metPhi, "metPhi/F"); // phi(MET) outTree->Branch("sumEt", &sumEt, "sumEt/F"); // Sum ET outTree->Branch("mt", &mt, "mt/F"); // transverse mass outTree->Branch("u1", &u1, "u1/F"); // parallel component of recoil outTree->Branch("u2", &u2, "u2/F"); // perpendicular component of recoil outTree->Branch("tkMet", &tkMet, "tkMet/F"); // MET (track MET) outTree->Branch("tkMetPhi", &tkMetPhi, "tkMetPhi/F"); // phi(MET) (track MET) outTree->Branch("tkSumEt", &tkSumEt, "tkSumEt/F"); // Sum ET (track MET) outTree->Branch("tkMt", &tkMt, "tkMt/F"); // transverse mass (track MET) outTree->Branch("tkU1", &tkU1, "tkU1/F"); // parallel component of recoil (track MET) outTree->Branch("tkU2", &tkU2, "tkU2/F"); // perpendicular component of recoil (track MET) outTree->Branch("mvaMet", &mvaMet, "mvaMet/F"); // MVA MET outTree->Branch("mvaMetPhi", &mvaMetPhi, "mvaMetPhi/F"); // phi(MVA MET) outTree->Branch("mvaSumEt", &mvaSumEt, "mvaSumEt/F"); // Sum ET (mva MET) outTree->Branch("mvaMt", &mvaMt, "mvaMt/F"); // transverse mass (mva MET) outTree->Branch("mvaU1", &mvaU1, "mvaU1/F"); // parallel component of recoil (mva MET) outTree->Branch("mvaU2", &mvaU2, "mvaU2/F"); // perpendicular component of recoil (mva MET) outTree->Branch("puppiMet", &puppiMet, "puppiMet/F"); // Puppi MET outTree->Branch("puppiMetPhi", &puppiMetPhi,"puppiMetPhi/F"); // phi(Puppi MET) outTree->Branch("puppiSumEt", &puppiSumEt, "puppiSumEt/F"); // Sum ET (Puppi MET) outTree->Branch("puppiU1", &puppiU1, "puppiU1/F"); // parallel component of recoil (Puppi MET) outTree->Branch("puppiU2", &puppiU2, "puppiU2/F"); // perpendicular component of recoil (Puppi MET) outTree->Branch("q", &q, "q/I"); // lepton charge outTree->Branch("lep", "TLorentzVector", &lep); // lepton 4-vector outTree->Branch("lepID", &lepID, "lepID/I"); // lepton PDG ID ///// electron specific ///// outTree->Branch("trkIso", &trkIso, "trkIso/F"); // track isolation of tag lepton outTree->Branch("emIso", &emIso, "emIso/F"); // ECAL isolation of tag lepton outTree->Branch("hadIso", &hadIso, "hadIso/F"); // HCAL isolation of tag lepton outTree->Branch("pfChIso", &pfChIso, "pfChIso/F"); // PF charged hadron isolation of lepton outTree->Branch("pfGamIso", &pfGamIso, "pfGamIso/F"); // PF photon isolation of lepton outTree->Branch("pfNeuIso", &pfNeuIso, "pfNeuIso/F"); // PF neutral hadron isolation of lepton outTree->Branch("pfCombIso", &pfCombIso, "pfCombIso/F"); // PF combined isolation of electron outTree->Branch("sigieie", &sigieie, "sigieie/F"); // sigma-ieta-ieta of electron outTree->Branch("hovere", &hovere, "hovere/F"); // H/E of electron outTree->Branch("eoverp", &eoverp, "eoverp/F"); // E/p of electron outTree->Branch("fbrem", &fbrem, "fbrem/F"); // brem fraction of electron outTree->Branch("dphi", &dphi, "dphi/F"); // GSF track - ECAL dphi of electron outTree->Branch("deta", &deta, "deta/F"); // GSF track - ECAL deta of electron outTree->Branch("ecalE", &ecalE, "ecalE/F"); // ECAL energy of electron outTree->Branch("d0", &d0, "d0/F"); // transverse impact parameter of electron outTree->Branch("dz", &dz, "dz/F"); // longitudinal impact parameter of electron outTree->Branch("isConv", &isConv, "isConv/i"); // conversion filter flag of electron outTree->Branch("nexphits", &nexphits, "nexphits/i"); // number of missing expected inner hits of electron outTree->Branch("typeBits", &typeBits, "typeBits/i"); // electron type of electron outTree->Branch("sc", "TLorentzVector", &sc); // supercluster 4-vector // // loop through files // const UInt_t nfiles = samp->fnamev.size(); for(UInt_t ifile=0; ifile<nfiles; ifile++) { // Read input file and get the TTrees cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush(); infile = TFile::Open(samp->fnamev[ifile]); assert(infile); Bool_t hasJSON = kFALSE; baconhep::RunLumiRangeMap rlrm; if(samp->jsonv[ifile].CompareTo("NONE")!=0) { hasJSON = kTRUE; rlrm.addJSONFile(samp->jsonv[ifile].Data()); } eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("PV", &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV"); Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo"); TBranch *genBr=0, *genPartBr=0; if(hasGen) { eventTree->SetBranchAddress("GenEvtInfo", &gen); genBr = eventTree->GetBranch("GenEvtInfo"); eventTree->SetBranchAddress("GenParticle",&genPartArr); genPartBr = eventTree->GetBranch("GenParticle"); } // Compute MC event weight per 1/fb const Double_t xsec = samp->xsecv[ifile]; Double_t totalWeight=0; if (hasGen) { TH1D *hall = new TH1D("hall", "", 1,0,1); eventTree->Draw("0.5>>hall", "GenEvtInfo->weight"); totalWeight=hall->Integral(); delete hall; hall=0; } // // loop over events // Double_t nsel=0, nselvar=0; for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { infoBr->GetEntry(ientry); if(ientry%1000000==0) cout << "Processing event " << ientry << ". " << (double)ientry/(double)eventTree->GetEntries()*100 << " percent done with this file." << endl; Double_t weight=1; if(xsec>0 && totalWeight>0) weight = xsec/totalWeight; if(hasGen) { genPartArr->Clear(); genBr->GetEntry(ientry); genPartBr->GetEntry(ientry); weight*=gen->weight; } // veto w -> xv decays for signal and w -> ev for bacground samples (needed for inclusive WToLNu sample) if (isWrongFlavor && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))==LEPTON_ID) continue; else if (isSignal && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue; // check for certified lumi (if applicable) baconhep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec); if(hasJSON && !rlrm.hasRunLumi(rl)) continue; // trigger requirement if (!isEleTrigger(triggerMenu, info->triggerBits, isData)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; // // SELECTION PROCEDURE: // (1) Look for 1 good electron matched to trigger // (2) Reject event if another electron is present passing looser cuts // electronArr->Clear(); electronBr->GetEntry(ientry); Int_t nLooseLep=0; const baconhep::TElectron *goodEle=0; Bool_t passSel=kFALSE; for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) { const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i]); // check ECAL gap if(fabs(ele->scEta)>=ECAL_GAP_LOW && fabs(ele->scEta)<=ECAL_GAP_HIGH) continue; // apply scale and resolution corrections to MC Double_t elescEt_corr = ele->scEt; if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) elescEt_corr = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0),getEleResCorr(ele->scEta,0)); if(fabs(ele->scEta) > VETO_ETA) continue; // loose lepton |eta| cut if(elescEt_corr < VETO_PT) continue; // loose lepton pT cut if(passEleLooseID(ele,info->rhoIso)) nLooseLep++; // loose lepton selection if(nLooseLep>1) { // extra lepton veto passSel=kFALSE; break; } if(fabs(ele->scEta) > ETA_CUT) continue; // lepton |eta| cut if(elescEt_corr < PT_CUT) continue; // lepton pT cut if(!passEleID(ele,info->rhoIso)) continue; // lepton selection if(!isEleTriggerObj(triggerMenu, ele->hltMatchBits, kFALSE, isData)) continue; passSel=kTRUE; goodEle = ele; } if(passSel) { //******* We have a W candidate! HURRAY! ******** nsel+=weight; nselvar+=weight*weight; // apply scale and resolution corrections to MC Double_t goodElept_corr = goodEle->pt; if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) goodElept_corr = gRandom->Gaus(goodEle->pt*getEleScaleCorr(goodEle->scEta,0),getEleResCorr(goodEle->scEta,0)); TLorentzVector vLep(0,0,0,0); TLorentzVector vSC(0,0,0,0); // apply scale and resolution corrections to MC if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) { vLep.SetPtEtaPhiM(goodElept_corr, goodEle->eta, goodEle->phi, ELE_MASS); vSC.SetPtEtaPhiM(gRandom->Gaus(goodEle->scEt*getEleScaleCorr(goodEle->scEta,0),getEleResCorr(goodEle->scEta,0)), goodEle->scEta, goodEle->scPhi, ELE_MASS); } else { vLep.SetPtEtaPhiM(goodEle->pt,goodEle->eta,goodEle->phi,ELE_MASS); vSC.SetPtEtaPhiM(goodEle->scEt,goodEle->scEta,goodEle->scPhi,ELE_MASS); } // // Fill tree // runNum = info->runNum; lumiSec = info->lumiSec; evtNum = info->evtNum; vertexArr->Clear(); vertexBr->GetEntry(ientry); npv = vertexArr->GetEntries(); npu = info->nPUmean; genV = new TLorentzVector(0,0,0,0); genLep = new TLorentzVector(0,0,0,0); genVPt = -999; genVPhi = -999; genVy = -999; genVMass = -999; genLepPt = -999; genLepPhi = -999; u1 = -999; u2 = -999; tkU1 = -999; tkU2 = -999; mvaU1 = -999; mvaU2 = -999; puppiU1 = -999; puppiU2 = -999; id_1 = -999; id_2 = -999; x_1 = -999; x_2 = -999; xPDF_1 = -999; xPDF_2 = -999; scalePDF = -999; weightPDF = -999; if(isSignal && hasGen) { TLorentzVector *gvec=new TLorentzVector(0,0,0,0); TLorentzVector *glep1=new TLorentzVector(0,0,0,0); TLorentzVector *glep2=new TLorentzVector(0,0,0,0); toolbox::fillGen(genPartArr, BOSON_ID, gvec, glep1, glep2,1); if (gvec && glep1) { genV = new TLorentzVector(0,0,0,0); genV->SetPtEtaPhiM(gvec->Pt(),gvec->Eta(),gvec->Phi(),gvec->M()); genLep = new TLorentzVector(0,0,0,0); genLep->SetPtEtaPhiM(glep1->Pt(),glep1->Eta(),glep1->Phi(),glep1->M()); genVPt = gvec->Pt(); genVPhi = gvec->Phi(); genVy = gvec->Rapidity(); genVMass = gvec->M(); genLepPt = glep1->Pt(); genLepPhi = glep1->Phi(); TVector2 vWPt((genVPt)*cos(genVPhi),(genVPt)*sin(genVPhi)); TVector2 vLepPt(vLep.Px(),vLep.Py()); TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi)); TVector2 vU = -1.0*(vMet+vLepPt); u1 = ((vWPt.Px())*(vU.Px()) + (vWPt.Py())*(vU.Py()))/(genVPt); // u1 = (pT . u)/|pT| u2 = ((vWPt.Px())*(vU.Py()) - (vWPt.Py())*(vU.Px()))/(genVPt); // u2 = (pT x u)/|pT| TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi)); TVector2 vTkU = -1.0*(vTkMet+vLepPt); tkU1 = ((vWPt.Px())*(vTkU.Px()) + (vWPt.Py())*(vTkU.Py()))/(genVPt); // u1 = (pT . u)/|pT| tkU2 = ((vWPt.Px())*(vTkU.Py()) - (vWPt.Py())*(vTkU.Px()))/(genVPt); // u2 = (pT x u)/|pT| TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi)); TVector2 vMvaU = -1.0*(vMvaMet+vLepPt); mvaU1 = ((vWPt.Px())*(vMvaU.Px()) + (vWPt.Py())*(vMvaU.Py()))/(genVPt); // u1 = (pT . u)/|pT| mvaU2 = ((vWPt.Px())*(vMvaU.Py()) - (vWPt.Py())*(vMvaU.Px()))/(genVPt); // u2 = (pT x u)/|pT| TVector2 vPuppiMet((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi)); TVector2 vPuppiU = -1.0*(vPuppiMet+vLepPt); puppiU1 = ((vWPt.Px())*(vPuppiU.Px()) + (vWPt.Py())*(vPuppiU.Py()))/(genVPt); // u1 = (pT . u)/|pT| puppiU2 = ((vWPt.Px())*(vPuppiU.Py()) - (vWPt.Py())*(vPuppiU.Px()))/(genVPt); // u2 = (pT x u)/|pT| } id_1 = gen->id_1; id_2 = gen->id_2; x_1 = gen->x_1; x_2 = gen->x_2; xPDF_1 = gen->xPDF_1; xPDF_2 = gen->xPDF_2; scalePDF = gen->scalePDF; weightPDF = gen->weight; delete gvec; delete glep1; delete glep2; gvec=0; glep1=0; glep2=0; } scale1fb = weight; puWeight = h_rw->GetBinContent(h_rw->FindBin(npu)); puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(npu)); puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(npu)); met = info->pfMETC; metPhi = info->pfMETCphi; sumEt = 0; mt = sqrt( 2.0 * (vLep.Pt()) * (info->pfMETC) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->pfMETCphi))) ); tkMet = info->trkMET; tkMetPhi = info->trkMETphi; tkSumEt = 0; tkMt = sqrt( 2.0 * (vLep.Pt()) * (info->trkMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->trkMETphi))) ); mvaMet = info->mvaMET; mvaMetPhi = info->mvaMETphi; mvaSumEt = 0; mvaMt = sqrt( 2.0 * (vLep.Pt()) * (info->mvaMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->mvaMETphi))) ); // TVector2 vLepPt(vLep.Px(),vLep.Py()); // TVector2 vPuppi((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi)); // TVector2 vpp; vpp=vPuppi-vLepPt; puppiMet = info->puppET; puppiMetPhi = info->puppETphi; puppiSumEt = 0; puppiMt = sqrt( 2.0 * (vLep.Pt()) * (info->puppET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->puppETphi))) ); q = goodEle->q; lep = &vLep; ///// electron specific ///// sc = &vSC; trkIso = goodEle->trkIso; emIso = goodEle->ecalIso; hadIso = goodEle->hcalIso; pfChIso = goodEle->chHadIso; pfGamIso = goodEle->gammaIso; pfNeuIso = goodEle->neuHadIso; pfCombIso = goodEle->chHadIso + TMath::Max(goodEle->neuHadIso + goodEle->gammaIso - (info->rhoIso)*getEffAreaEl(goodEle->scEta), 0.); sigieie = goodEle->sieie; hovere = goodEle->hovere; eoverp = goodEle->eoverp; fbrem = goodEle->fbrem; dphi = goodEle->dPhiIn; deta = goodEle->dEtaIn; ecalE = goodEle->ecalEnergy; d0 = goodEle->d0; dz = goodEle->dz; isConv = goodEle->isConv; nexphits = goodEle->nMissingHits; typeBits = goodEle->typeBits; outTree->Fill(); delete genV; delete genLep; genV=0, genLep=0, lep=0, sc=0; } } delete infile; infile=0, eventTree=0; cout << nsel << " +/- " << sqrt(nselvar); if(isam!=0) cout << " per 1/pb"; cout << endl; } outFile->Write(); outFile->Close(); } delete h_rw; delete h_rw_up; delete h_rw_down; delete f_rw; delete info; delete gen; delete genPartArr; delete electronArr; delete vertexArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " W -> e nu" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; if(doScaleCorr) cout << " *** Scale corrections applied ***" << endl; cout << endl; cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("selectWe"); }
void computeAccSelZeeBinned(const TString conf, // input file const TString outputDir, // output directory const Int_t doPU ) { gBenchmark->Start("computeAccSelZeeBinned"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t MASS_LOW = 60; const Double_t MASS_HIGH = 120; const Double_t PT_CUT = 25; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ETA_BARREL = 1.4442; const Double_t ETA_ENDCAP = 1.566; const Int_t BOSON_ID = 23; const Int_t LEPTON_ID = 11; // efficiency files const TString dataHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root"; const TString dataHLTEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root"; const TString dataHLTEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root"; const TString zeeHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root"; const TString zeeHLTEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root"; const TString zeeHLTEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root"; const TString dataGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root"; const TString dataGsfSelEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root"; const TString dataGsfSelEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root"; const TString zeeGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root"; const TString zeeGsfSelEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root"; const TString zeeGsfSelEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root"; // load pileup reweighting file TFile *f_rw = TFile::Open("../Tools/pileup_rw_76X.root", "read"); TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden"); //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== vector<TString> fnamev; // file name per input file vector<TString> labelv; // TLegend label per input file vector<Int_t> colorv; // plot color per input file vector<Int_t> linev; // plot line style per input file // // parse .conf file // ifstream ifs; ifs.open(conf.Data()); assert(ifs.is_open()); string line; while(getline(ifs,line)) { if(line[0]=='#') continue; string fname; Int_t color, linesty; stringstream ss(line); ss >> fname >> color >> linesty; string label = line.substr(line.find('@')+1); fnamev.push_back(fname); labelv.push_back(label); colorv.push_back(color); linev.push_back(linesty); } ifs.close(); // Create output directory gSystem->mkdir(outputDir,kTRUE); TH2D *h=0; // // HLT efficiency // cout << "Loading trigger efficiencies..." << endl; TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos); CEffUser2D dataHLTEff_pos; dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt")); TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg); CEffUser2D dataHLTEff_neg; dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt")); TFile *zeeHLTEffFile_pos = new TFile(zeeHLTEffName_pos); CEffUser2D zeeHLTEff_pos; zeeHLTEff_pos.loadEff((TH2D*)zeeHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrhEtaPt")); TFile *zeeHLTEffFile_neg = new TFile(zeeHLTEffName_neg); CEffUser2D zeeHLTEff_neg; zeeHLTEff_neg.loadEff((TH2D*)zeeHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrhEtaPt")); h =(TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"); TH2D *hHLTErr_pos = new TH2D("hHLTErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); TH2D *hHLTErr_neg = new TH2D("hHLTErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); // // Selection efficiency // cout << "Loading GSF+selection efficiencies..." << endl; TFile *dataGsfSelEffFile_pos = new TFile(dataGsfSelEffName_pos); CEffUser2D dataGsfSelEff_pos; dataGsfSelEff_pos.loadEff((TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrhEtaPt")); TFile *dataGsfSelEffFile_neg = new TFile(dataGsfSelEffName_neg); CEffUser2D dataGsfSelEff_neg; dataGsfSelEff_neg.loadEff((TH2D*)dataGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrhEtaPt")); TFile *zeeGsfSelEffFile_pos = new TFile(zeeGsfSelEffName_pos); CEffUser2D zeeGsfSelEff_pos; zeeGsfSelEff_pos.loadEff((TH2D*)zeeGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrhEtaPt")); TFile *zeeGsfSelEffFile_neg = new TFile(zeeGsfSelEffName_neg); CEffUser2D zeeGsfSelEff_neg; zeeGsfSelEff_neg.loadEff((TH2D*)zeeGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrhEtaPt")); h =(TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"); TH2D *hGsfSelErr_pos = new TH2D("hGsfSelErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); TH2D *hGsfSelErr_neg = new TH2D("hGsfSelErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); // Data structures to store info from TTrees baconhep::TEventInfo *info = new baconhep::TEventInfo(); baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo(); TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle"); TClonesArray *electronArr = new TClonesArray("baconhep::TElectron"); TClonesArray *vertexArr = new TClonesArray("baconhep::TVertex"); TFile *infile=0; TTree *eventTree=0; // Variables to store acceptances and uncertainties (per input file) vector<Double_t> nEvtsv, nSelv; vector<Double_t> nSelCorrv, nSelCorrVarv; vector<Double_t> accv, accCorrv; vector<Double_t> accErrv, accErrCorrv; const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun"); // // loop through files // for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { // Read input file and get the TTrees cout << "Processing " << fnamev[ifile] << " ..." << endl; infile = TFile::Open(fnamev[ifile]); assert(infile); eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("GenEvtInfo", &gen); TBranch *genBr = eventTree->GetBranch("GenEvtInfo"); eventTree->SetBranchAddress("GenParticle", &genPartArr); TBranch *genPartBr = eventTree->GetBranch("GenParticle"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("PV", &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV"); nEvtsv.push_back(0); nSelv.push_back(0); nSelCorrv.push_back(0); nSelCorrVarv.push_back(0); // // loop over events // for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { genBr->GetEntry(ientry); genPartArr->Clear(); genPartBr->GetEntry(ientry); infoBr->GetEntry(ientry); Int_t glepq1=-99; Int_t glepq2=-99; if (fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue; TLorentzVector *vec=new TLorentzVector(0,0,0,0); TLorentzVector *lep1=new TLorentzVector(0,0,0,0); TLorentzVector *lep2=new TLorentzVector(0,0,0,0); toolbox::fillGen(genPartArr, BOSON_ID, vec, lep1, lep2,&glepq1,&glepq2,1); if(vec->M()<MASS_LOW || vec->M()>MASS_HIGH) continue; delete vec; delete lep1; delete lep2; vertexArr->Clear(); vertexBr->GetEntry(ientry); double npv = vertexArr->GetEntries(); Double_t weight=gen->weight; if(doPU>0) weight*=h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)); nEvtsv[ifile]+=weight; // trigger requirement if (!isEleTrigger(triggerMenu, info->triggerBits, kFALSE)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; electronArr->Clear(); electronBr->GetEntry(ientry); for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) { const baconhep::TElectron *ele1 = (baconhep::TElectron*)((*electronArr)[i1]); // check ECAL gap if(fabs(ele1->scEta)>=ETA_BARREL && fabs(ele1->scEta)<=ETA_ENDCAP) continue; //double ele1_pt = gRandom->Gaus(ele1->pt*getEleScaleCorr(ele1->scEta,0), getEleResCorr(ele1->scEta,0)); if(ele1->pt < PT_CUT && ele1->scEt < PT_CUT) continue; // lepton pT cut if(fabs(ele1->scEta) > ETA_CUT && fabs(ele1->eta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(ele1,info->rhoIso)) continue; // lepton selection //if(!isEleTriggerObj(triggerMenu, ele1->hltMatchBits, kFALSE, kFALSE)) continue; TLorentzVector vEle1(0,0,0,0); vEle1.SetPtEtaPhiM(ele1->pt, ele1->eta, ele1->phi, ELE_MASS); Bool_t isB1 = (fabs(ele1->scEta)<ETA_BARREL) ? kTRUE : kFALSE; for(Int_t i2=i1+1; i2<electronArr->GetEntriesFast(); i2++) { const baconhep::TElectron *ele2 = (baconhep::TElectron*)((*electronArr)[i2]); // check ECAL gap if(fabs(ele2->scEta)>=ETA_BARREL && fabs(ele2->scEta)<=ETA_ENDCAP) continue; //double ele2_pt = gRandom->Gaus(ele2->scEt*getEleScaleCorr(ele2->scEta,0), getEleResCorr(ele2->scEta,0)); if(ele1->q == ele2->q) continue; if(ele2->pt < PT_CUT && ele2->scEt < PT_CUT) continue; // lepton pT cut if(fabs(ele2->scEta) > ETA_CUT && fabs(ele2->eta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(ele2,info->rhoIso)) continue; // lepton selection TLorentzVector vEle2(0,0,0,0); vEle2.SetPtEtaPhiM(ele2->pt, ele2->eta, ele2->phi, ELE_MASS); Bool_t isB2 = (fabs(ele2->scEta)<ETA_BARREL) ? kTRUE : kFALSE; if(!isEleTriggerObj(triggerMenu, ele1->hltMatchBits, kFALSE, kFALSE) && !isEleTriggerObj(triggerMenu, ele2->hltMatchBits, kFALSE, kFALSE)) continue; // mass window TLorentzVector vDilep = vEle1 + vEle2; if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue; /******** We have a Z candidate! HURRAY! ********/ Double_t effdata, effmc; //Double_t sceta1 = (fabs(ele1->scEta)<2.5) ? ele1->scEta : 0.99*(ele1->scEta); Double_t sceta1 = ele1->scEta; //Double_t sceta2 = (fabs(ele2->scEta)<2.5) ? ele2->scEta : 0.99*(ele2->scEta); Double_t sceta2 = ele2->scEta; Double_t corr=1; effdata=1; effmc=1; if(ele1->q>0) { effdata *= (1.-dataHLTEff_pos.getEff(sceta1, ele1->scEt)); effmc *= (1.-zeeHLTEff_pos.getEff(sceta1, ele1->scEt)); } else { effdata *= (1.-dataHLTEff_neg.getEff(sceta1, ele1->scEt)); effmc *= (1.-zeeHLTEff_neg.getEff(sceta1, ele1->scEt)); } if(ele2->q>0) { effdata *= (1.-dataHLTEff_pos.getEff(sceta2, ele2->scEt)); effmc *= (1.-zeeHLTEff_pos.getEff(sceta2, ele2->scEt)); } else { effdata *= (1.-dataHLTEff_neg.getEff(sceta2, ele2->scEt)); effmc *= (1.-zeeHLTEff_neg.getEff(sceta2, ele2->scEt)); } effdata = 1.-effdata; effmc = 1.-effmc; corr *= effdata/effmc; effdata=1; effmc=1; if(ele1->q>0) { effdata *= dataGsfSelEff_pos.getEff(sceta1, ele1->scEt); effmc *= zeeGsfSelEff_pos.getEff(sceta1, ele1->scEt); } else { effdata *= dataGsfSelEff_neg.getEff(sceta1, ele1->scEt); effmc *= zeeGsfSelEff_neg.getEff(sceta1, ele1->scEt); } if(ele2->q>0) { effdata *= dataGsfSelEff_pos.getEff(sceta2, ele2->scEt); effmc *= zeeGsfSelEff_pos.getEff(sceta2, ele2->scEt); } else { effdata *= dataGsfSelEff_neg.getEff(sceta2, ele2->scEt); effmc *= zeeGsfSelEff_neg.getEff(sceta2, ele2->scEt); } corr *= effdata/effmc; // scale factor uncertainties if(ele1->q>0) { Double_t effdata = dataGsfSelEff_pos.getEff(sceta1, ele1->scEt); Double_t errdata = TMath::Max(dataGsfSelEff_pos.getErrLow(sceta1, ele1->scEt), dataGsfSelEff_pos.getErrHigh(sceta1, ele1->scEt)); Double_t effmc = zeeGsfSelEff_pos.getEff(sceta1, ele1->scEt); Double_t errmc = TMath::Max(zeeGsfSelEff_pos.getErrLow(sceta1, ele1->scEt), zeeGsfSelEff_pos.getErrHigh(sceta1, ele1->scEt)); Double_t errGsfSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); hGsfSelErr_pos->Fill(sceta1, ele1->scEt, errGsfSel); } else { Double_t effdata = dataGsfSelEff_neg.getEff(sceta1, ele1->scEt); Double_t errdata = TMath::Max(dataGsfSelEff_neg.getErrLow(sceta1, ele1->scEt), dataGsfSelEff_neg.getErrHigh(sceta1, ele1->scEt)); Double_t effmc = zeeGsfSelEff_neg.getEff(sceta1, ele1->scEt); Double_t errmc = TMath::Max(zeeGsfSelEff_neg.getErrLow(sceta1, ele1->scEt), zeeGsfSelEff_neg.getErrHigh(sceta1, ele1->scEt)); Double_t errGsfSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); hGsfSelErr_neg->Fill(sceta1, ele1->scEt, errGsfSel); } if(ele2->q>0) { Double_t effdata = dataHLTEff_pos.getEff(sceta2, ele2->scEt); Double_t errdata = TMath::Max(dataHLTEff_pos.getErrLow(sceta2, ele2->scEt), dataHLTEff_pos.getErrHigh(sceta2, ele2->scEt)); Double_t effmc = zeeHLTEff_pos.getEff(sceta2, ele2->scEt); Double_t errmc = TMath::Max(zeeHLTEff_pos.getErrLow(sceta2, ele2->scEt), zeeHLTEff_pos.getErrHigh(sceta2, ele2->scEt)); Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); hHLTErr_pos->Fill(sceta2, ele2->scEt, errHLT); } else { Double_t effdata = dataHLTEff_neg.getEff(sceta2, ele2->scEt); Double_t errdata = TMath::Max(dataHLTEff_neg.getErrLow(sceta2, ele2->scEt), dataHLTEff_neg.getErrHigh(sceta2, ele2->scEt)); Double_t effmc = zeeHLTEff_neg.getEff(sceta2, ele2->scEt); Double_t errmc = TMath::Max(zeeHLTEff_neg.getErrLow(sceta2, ele2->scEt), zeeHLTEff_neg.getErrHigh(sceta2, ele2->scEt)); Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); hHLTErr_neg->Fill(sceta2, ele2->scEt, errHLT); } nSelv[ifile]+=weight; nSelCorrv[ifile]+=weight*corr; nSelCorrVarv[ifile]+=weight*weight*corr*corr; } } } Double_t var=0; for(Int_t iy=0; iy<=hHLTErr_pos->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hHLTErr_pos->GetNbinsX(); ix++) { Double_t err=hHLTErr_pos->GetBinContent(ix,iy); var+=err*err; } } for(Int_t iy=0; iy<=hHLTErr_neg->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hHLTErr_neg->GetNbinsX(); ix++) { Double_t err=hHLTErr_neg->GetBinContent(ix,iy); var+=err*err; } } cout << "var1: " << var << endl; for(Int_t iy=0; iy<=hGsfSelErr_pos->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hGsfSelErr_pos->GetNbinsX(); ix++) { Double_t err=hGsfSelErr_pos->GetBinContent(ix,iy); var+=err*err; } } for(Int_t iy=0; iy<=hGsfSelErr_neg->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hGsfSelErr_neg->GetNbinsX(); ix++) { Double_t err=hGsfSelErr_neg->GetBinContent(ix,iy); var+=err*err; } } cout << "var2: " << var << endl; nSelCorrVarv[ifile]+=var; // compute acceptances std::cout << nEvtsv[ifile] << " " << nSelv[ifile] << std::endl; accv.push_back(nSelv[ifile]/nEvtsv[ifile]); accErrv.push_back(sqrt(accv[ifile]*(1. +accv[ifile])/nEvtsv[ifile])); accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accErrCorrv.push_back(accCorrv[ifile]*sqrt((nSelCorrVarv[ifile])/(nSelCorrv[ifile]*nSelCorrv[ifile]) + 1./nEvtsv[ifile])); delete infile; infile=0, eventTree=0; } delete info; delete gen; delete electronArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " Z -> e e" << endl; cout << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; cout << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { cout << " ================================================" << endl; cout << " Label: " << labelv[ifile] << endl; cout << " File: " << fnamev[ifile] << endl; cout << endl; cout << " *** Acceptance ***" << endl; cout << " nominal: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile] << endl; cout << " SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl; cout << endl; } char txtfname[100]; sprintf(txtfname,"%s/binned.txt",outputDir.Data()); ofstream txtfile; txtfile.open(txtfname); txtfile << "*" << endl; txtfile << "* SUMMARY" << endl; txtfile << "*--------------------------------------------------" << endl; txtfile << " Z -> e e" << endl; txtfile << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; txtfile << " pT > " << PT_CUT << endl; txtfile << " |eta| < " << ETA_CUT << endl; txtfile << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { txtfile << " ================================================" << endl; txtfile << " Label: " << labelv[ifile] << endl; txtfile << " File: " << fnamev[ifile] << endl; txtfile << endl; txtfile << " *** Acceptance ***" << endl; txtfile << " nominal: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile] << endl; txtfile << " SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl; txtfile << endl; } txtfile.close(); cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("computeAccSelZeeBinned"); }
void computeAccSelWe_Charge(const TString conf, // input file const TString outputDir, // output directory const Int_t charge, // 0 = inclusive, +1 = W+, -1 = W- const Int_t doPU, const Int_t doScaleCorr, const Int_t sigma ) { gBenchmark->Start("computeAccSelWe"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t PT_CUT = 25; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ETA_BARREL = 1.4442; const Double_t ETA_ENDCAP = 1.566; const Double_t VETO_PT = 10; const Double_t VETO_ETA = 2.5; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Int_t BOSON_ID = 24; const Int_t LEPTON_ID = 11; // efficiency files TString dataHLTEffName( "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root"); TString zeeHLTEffName( "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root"); TString dataGsfSelEffName("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root"); TString zeeGsfSelEffName( "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root"); if(charge==1) { dataHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MGpositive/eff.root"; zeeHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CTpositive/eff.root"; dataGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MGpositive_FineBin/eff.root"; zeeGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CTpositive/eff.root"; } if(charge==-1) { dataHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MGnegative/eff.root"; zeeHLTEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CTnegative/eff.root"; dataGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MGnegative_FineBin/eff.root"; zeeGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CTnegative/eff.root"; } const TString corrFiles = "../EleScale/76X_16DecRereco_2015_Etunc"; EnergyScaleCorrection_class eleCorr( corrFiles.Data()); eleCorr.doScale= true; eleCorr.doSmearings =true; // load pileup reweighting file TFile *f_rw = TFile::Open("../Tools/puWeights_76x.root", "read"); TH1D *h_rw = (TH1D*) f_rw->Get("puWeights"); TFile *f_r9 = TFile::Open("../EleScale/transformation.root","read"); TGraph* gR9EB = (TGraph*) f_r9->Get("transformR90"); TGraph* gR9EE = (TGraph*) f_r9->Get("transformR91"); TFile *f_hlt_data; TFile *f_hlt_mc; if(charge==1){ f_hlt_data = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_Data_Positive.root"); f_hlt_mc = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_MC_Positive.root"); } if(charge==-1){ f_hlt_data = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_Data_Negative.root"); f_hlt_mc = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_MC_Negative.root"); } //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== vector<TString> fnamev; // file name per input file vector<TString> labelv; // TLegend label per input file vector<Int_t> colorv; // plot color per input file vector<Int_t> linev; // plot line style per input file // // parse .conf file // ifstream ifs; ifs.open(conf.Data()); assert(ifs.is_open()); string line; while(getline(ifs,line)) { if(line[0]=='#') continue; string fname; Int_t color, linesty; stringstream ss(line); ss >> fname >> color >> linesty; string label = line.substr(line.find('@')+1); fnamev.push_back(fname); labelv.push_back(label); colorv.push_back(color); linev.push_back(linesty); } ifs.close(); // Create output directory gSystem->mkdir(outputDir,kTRUE); // // Get efficiency // TFile *dataHLTEffFile = new TFile(dataHLTEffName); CEffUser2D dataHLTEff; TH2D *hHLTErr=0, *hHLTErrB=0, *hHLTErrE=0; if(dataHLTEffName) { dataHLTEff.loadEff((TH2D*)dataHLTEffFile->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile->Get("hErrhEtaPt")); TH2D* h =(TH2D*)dataHLTEffFile->Get("hEffEtaPt"); hHLTErr = new TH2D("hHLTErr", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); hHLTErrB = new TH2D("hHLTErrB","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); hHLTErrE = new TH2D("hHLTErrE","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); } TFile *zeeHLTEffFile = new TFile(zeeHLTEffName); CEffUser2D zeeHLTEff; if(zeeHLTEffName) { zeeHLTEff.loadEff((TH2D*)zeeHLTEffFile->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile->Get("hErrhEtaPt")); } TFile *dataGsfSelEffFile = new TFile(dataGsfSelEffName); CEffUser2D dataGsfSelEff; TH2D *hGsfSelErr=0, *hGsfSelErrB=0, *hGsfSelErrE=0; if(dataGsfSelEffName) { dataGsfSelEff.loadEff((TH2D*)dataGsfSelEffFile->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile->Get("hErrhEtaPt")); TH2D* h =(TH2D*)dataGsfSelEffFile->Get("hEffEtaPt"); hGsfSelErr = new TH2D("hGsfSelErr", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); hGsfSelErrB = new TH2D("hGsfSelErrB","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); hGsfSelErrE = new TH2D("hGsfSelErrE","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); } TFile *zeeGsfSelEffFile = new TFile(zeeGsfSelEffName); CEffUser2D zeeGsfSelEff; if(zeeGsfSelEffName) { zeeGsfSelEff.loadEff((TH2D*)zeeGsfSelEffFile->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile->Get("hErrhEtaPt")); } // Data structures to store info from TTrees baconhep::TEventInfo *info = new baconhep::TEventInfo(); baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo(); TClonesArray *electronArr = new TClonesArray("baconhep::TElectron"); TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle"); TClonesArray *vertexArr = new TClonesArray("baconhep::TVertex"); TFile *infile=0; TTree *eventTree=0; // Variables to store acceptances and uncertainties (per input file) vector<Double_t> nEvtsv, nSelv, nSelBv, nSelEv; vector<Double_t> accv, accBv, accEv; vector<Double_t> accErrv, accErrBv, accErrEv; vector<Double_t> nSelCorrv, nSelBCorrv, nSelECorrv; vector<Double_t> nSelCorrVarv, nSelBCorrVarv, nSelECorrVarv; vector<Double_t> accCorrv, accBCorrv, accECorrv; vector<Double_t> accErrCorrv, accErrBCorrv, accErrECorrv; const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun"); // loop through files // for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { // Read input file and get the TTrees cout << "Processing " << fnamev[ifile] << " ..." << endl; infile = TFile::Open(fnamev[ifile]); assert(infile); eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("GenEvtInfo", &gen); TBranch *genBr = eventTree->GetBranch("GenEvtInfo"); eventTree->SetBranchAddress("GenParticle",&genPartArr); TBranch *genPartBr = eventTree->GetBranch("GenParticle"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("PV", &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV"); nEvtsv.push_back(0); nSelv.push_back(0); nSelBv.push_back(0); nSelEv.push_back(0); nSelCorrv.push_back(0); nSelBCorrv.push_back(0); nSelECorrv.push_back(0); nSelCorrVarv.push_back(0); nSelBCorrVarv.push_back(0); nSelECorrVarv.push_back(0); for(Int_t iy=0; iy<=hHLTErr->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hHLTErr->GetNbinsX(); ix++) { hHLTErr ->SetBinContent(ix,iy,0); hHLTErrB->SetBinContent(ix,iy,0); hHLTErrE->SetBinContent(ix,iy,0); } } for(Int_t iy=0; iy<=hGsfSelErr->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hGsfSelErr->GetNbinsX(); ix++) { hGsfSelErr ->SetBinContent(ix,iy,0); hGsfSelErrB->SetBinContent(ix,iy,0); hGsfSelErrE->SetBinContent(ix,iy,0); } } // // loop over events // for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { // if(ientry==10000) break; infoBr->GetEntry(ientry); genBr->GetEntry(ientry); genPartArr->Clear(); genPartBr->GetEntry(ientry); if (charge==-1 && toolbox::flavor(genPartArr, -BOSON_ID)!=LEPTON_ID) continue; if (charge==1 && toolbox::flavor(genPartArr, BOSON_ID)!=-LEPTON_ID) continue; if (charge==0 && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue; vertexArr->Clear(); vertexBr->GetEntry(ientry); double npv = vertexArr->GetEntries(); Double_t weight=gen->weight; if(doPU>0) weight*=h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)); nEvtsv[ifile]+=weight; // trigger requirement if (!isEleTrigger(triggerMenu, info->triggerBits, kFALSE)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; electronArr->Clear(); electronBr->GetEntry(ientry); Int_t nLooseLep=0; const baconhep::TElectron *goodEle=0; TLorentzVector vEle(0,0,0,0); TLorentzVector vElefinal(0,0,0,0); Bool_t passSel=kFALSE; for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) { const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i]); vEle.SetPtEtaPhiM(ele->pt, ele->eta, ele->phi, ELE_MASS); //double ele_pt = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0), getEleResCorr(ele->scEta,0)); //double ele_pt = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0), getEleResCorr(ele->scEta,0)); // check ECAL gap // if(fabs(ele->scEta)>=ETA_BARREL && fabs(ele->scEta)<=ETA_ENDCAP) continue; if(fabs(vEle.Eta())>=ECAL_GAP_LOW && fabs(vEle.Eta())<=ECAL_GAP_HIGH) continue; if(doScaleCorr && (ele->r9 < 1.)){ float eleSmear = 0.; float eleAbsEta = fabs(vEle.Eta()); float eleEt = vEle.E() / cosh(eleAbsEta); bool eleisBarrel = eleAbsEta < 1.4442; float eleR9Prime = ele->r9; // r9 corrections MC only if(eleisBarrel){ eleR9Prime = gR9EB->Eval(ele->r9);} else { eleR9Prime = gR9EE->Eval(ele->r9); } double eleRamdom = gRandom->Gaus(0,1); eleSmear = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, 0., 0.); float eleSmearEP = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, 1., 0.); float eleSmearEM = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, -1., 0.); if(sigma==0){ (vEle) *= 1. + eleSmear * eleRamdom; }else if(sigma==1){ (vEle) *= 1. + eleSmearEP * eleRamdom; }else if(sigma==-1){ (vEle) *= 1. + eleSmearEM * eleRamdom; } } // if(fabs(ele->scEta) > VETO_ETA) continue; // loose lepton |eta| cut // if(ele->scEt < VETO_PT) continue; // loose lepton pT cut // if(passEleLooseID(ele,info->rhoIso)) nLooseLep++; // loose lepton selection if(fabs(vEle.Eta()) > VETO_ETA) continue; if(vEle.Pt() < VETO_PT) continue; if(passEleLooseID(ele, vEle, info->rhoIso)) nLooseLep++; if(nLooseLep>1) { // extra lepton veto passSel=kFALSE; break; } // if(fabs(ele->scEta) > ETA_CUT && fabs(ele->eta) > ETA_CUT) continue; // lepton |eta| cut // if(ele->pt < PT_CUT && ele->scEt < PT_CUT) continue; // lepton pT cut // if(!passEleID(ele,info->rhoIso)) continue; // lepton selection if(vEle.Pt() < PT_CUT) continue; // lepton pT cut if(fabs(vEle.Eta()) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(ele, vEle, info->rhoIso)) continue; // lepton selection if(!isEleTriggerObj(triggerMenu, ele->hltMatchBits, kFALSE, kFALSE)) continue; //if(!(ele->hltMatchBits[trigObjHLT])) continue; // check trigger matching if(charge!=0 && ele->q!=charge) continue; // check charge (if necessary) passSel=kTRUE; goodEle = ele; vElefinal = vEle; } if(passSel) { /******** We have a W candidate! HURRAY! ********/ Bool_t isBarrel = (fabs(vElefinal.Eta())<ETA_BARREL) ? kTRUE : kFALSE; Double_t corr=1; if(dataHLTEffFile && zeeHLTEffFile) { // Double_t effdata = dataHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt()); // Double_t effmc = zeeHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt()); char funcname[20]; sprintf(funcname, "fitfcn_%d", getEtaBinLabel(vElefinal.Eta())); TF1 *fdt = (TF1*)f_hlt_data->Get(funcname); TF1 *fmc = (TF1*)f_hlt_mc ->Get(funcname); Double_t effdata = fdt->Eval(TMath::Min(vElefinal.Pt(),119.0)); Double_t effmc = fmc->Eval(TMath::Min(vElefinal.Pt(),119.0)); delete fdt; delete fmc; corr *= effdata/effmc; } if(dataGsfSelEffFile && zeeGsfSelEffFile) { Double_t effdata = dataGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt()); Double_t effmc = zeeGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt()); corr *= effdata/effmc; } if(dataHLTEffFile && zeeHLTEffFile) { Double_t effdata = dataHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt()); Double_t effmc = zeeHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt()); Double_t errdata = TMath::Max(dataHLTEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()),dataHLTEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt())); Double_t errmc = TMath::Max(zeeHLTEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()), zeeHLTEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt())); Double_t err = corr*sqrt(errdata*errdata/effdata/effdata+errmc*errmc/effmc/effmc); hHLTErr->Fill(vElefinal.Eta(),vElefinal.Pt(),err); if(isBarrel) hHLTErrB->Fill(vElefinal.Eta(),vElefinal.Pt(),err); else hHLTErrE->Fill(vElefinal.Eta(),vElefinal.Pt(),err); } if(dataGsfSelEffFile && zeeGsfSelEffFile) { Double_t effdata = dataGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt()); Double_t effmc = zeeGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt()); Double_t errdata = TMath::Max(dataGsfSelEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()),dataGsfSelEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt())); Double_t errmc = TMath::Max(zeeGsfSelEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()), zeeGsfSelEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt())); Double_t err = corr*sqrt(errdata*errdata/effdata/effdata+errmc*errmc/effmc/effmc); hGsfSelErr->Fill(vElefinal.Eta(),vElefinal.Pt(),err); if(isBarrel) hGsfSelErrB->Fill(vElefinal.Eta(),vElefinal.Pt(),err); else hGsfSelErrE->Fill(vElefinal.Eta(),vElefinal.Pt(),err); } nSelv[ifile]+=weight; nSelCorrv[ifile]+=weight*corr; nSelCorrVarv[ifile]+=weight*weight*corr*corr; if(isBarrel) { nSelBv[ifile]+=weight; nSelBCorrv[ifile]+=weight*corr; nSelBCorrVarv[ifile]+=weight*weight*corr*corr; } else { nSelEv[ifile]+=weight; nSelECorrv[ifile]+=weight*corr; nSelECorrVarv[ifile]+=weight*weight*corr*corr; } } } Double_t var=0, varB=0, varE=0; for(Int_t iy=0; iy<=hHLTErr->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hHLTErr->GetNbinsX(); ix++) { Double_t err; err=hHLTErr->GetBinContent(ix,iy); var+=err*err; err=hHLTErrB->GetBinContent(ix,iy); varB+=err*err; err=hHLTErrE->GetBinContent(ix,iy); varE+=err*err; } } for(Int_t iy=0; iy<=hGsfSelErr->GetNbinsY(); iy++) { for(Int_t ix=0; ix<=hGsfSelErr->GetNbinsX(); ix++) { Double_t err; err=hGsfSelErr->GetBinContent(ix,iy); var+=err*err; err=hGsfSelErrB->GetBinContent(ix,iy); varB+=err*err; err=hGsfSelErrE->GetBinContent(ix,iy); varE+=err*err; } } nSelCorrVarv[ifile]+=var; nSelBCorrVarv[ifile]+=varB; nSelECorrVarv[ifile]+=varE; // compute acceptances accv.push_back(nSelv[ifile]/nEvtsv[ifile]); accErrv.push_back(sqrt(accv[ifile]*(1.+accv[ifile])/nEvtsv[ifile])); accBv.push_back(nSelBv[ifile]/nEvtsv[ifile]); accErrBv.push_back(sqrt(accBv[ifile]*(1.+accBv[ifile])/nEvtsv[ifile])); accEv.push_back(nSelEv[ifile]/nEvtsv[ifile]); accErrEv.push_back(sqrt(accEv[ifile]*(1.+accEv[ifile])/nEvtsv[ifile])); accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accErrCorrv.push_back(accCorrv[ifile]*sqrt(nSelCorrVarv[ifile]/nSelCorrv[ifile]/nSelCorrv[ifile] + 1./nEvtsv[ifile])); accBCorrv.push_back(nSelBCorrv[ifile]/nEvtsv[ifile]); accErrBCorrv.push_back(accBCorrv[ifile]*sqrt(nSelBCorrVarv[ifile]/nSelBCorrv[ifile]/nSelBCorrv[ifile] + 1./nEvtsv[ifile])); accECorrv.push_back(nSelECorrv[ifile]/nEvtsv[ifile]); accErrECorrv.push_back(accECorrv[ifile]*sqrt(nSelECorrVarv[ifile]/nSelECorrv[ifile]/nSelECorrv[ifile] + 1./nEvtsv[ifile])); delete infile; infile=0, eventTree=0; } delete info; delete gen; delete electronArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; if(charge== 0) cout << " W -> e nu" << endl; if(charge==-1) cout << " W- -> e nu" << endl; if(charge== 1) cout << " W+ -> e nu" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; cout << " Barrel definition: |eta| < " << ETA_BARREL << endl; cout << " Endcap definition: |eta| > " << ETA_ENDCAP << endl; cout << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { cout << " ================================================" << endl; cout << " Label: " << labelv[ifile] << endl; cout << " File: " << fnamev[ifile] << endl; cout << endl; cout << " *** Acceptance ***" << endl; cout << " barrel: " << setw(12) << nSelBv[ifile] << " / " << nEvtsv[ifile] << " = " << accBv[ifile] << " +/- " << accErrBv[ifile]; cout << " ==eff corr==> " << accBCorrv[ifile] << " +/- " << accErrBCorrv[ifile] << endl; cout << " endcap: " << setw(12) << nSelEv[ifile] << " / " << nEvtsv[ifile] << " = " << accEv[ifile] << " +/- " << accErrEv[ifile]; cout << " ==eff corr==> " << accECorrv[ifile] << " +/- " << accErrECorrv[ifile] << endl; cout << " total: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile]; cout << " ==eff corr==> " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl; cout << endl; } char txtfname[100]; sprintf(txtfname,"%s/sel.txt",outputDir.Data()); ofstream txtfile; txtfile.open(txtfname); txtfile << "*" << endl; txtfile << "* SUMMARY" << endl; txtfile << "*--------------------------------------------------" << endl; if(charge== 0) txtfile << " W -> e nu" << endl; if(charge==-1) txtfile << " W- -> e nu" << endl; if(charge== 1) txtfile << " W+ -> e nu" << endl; txtfile << " pT > " << PT_CUT << endl; txtfile << " |eta| < " << ETA_CUT << endl; txtfile << " Barrel definition: |eta| < " << ETA_BARREL << endl; txtfile << " Endcap definition: |eta| > " << ETA_ENDCAP << endl; txtfile << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { txtfile << " ================================================" << endl; txtfile << " Label: " << labelv[ifile] << endl; txtfile << " File: " << fnamev[ifile] << endl; txtfile << endl; txtfile << " *** Acceptance ***" << endl; txtfile << " barrel: " << setw(12) << nSelBv[ifile] << " / " << nEvtsv[ifile] << " = " << accBv[ifile] << " +/- " << accErrBv[ifile]; txtfile << " ==eff corr==> " << accBCorrv[ifile] << " +/- " << accErrBCorrv[ifile] << endl; txtfile << " endcap: " << setw(12) << nSelEv[ifile] << " / " << nEvtsv[ifile] << " = " << accEv[ifile] << " +/- " << accErrEv[ifile]; txtfile << " ==eff corr==> " << accECorrv[ifile] << " +/- " << accErrECorrv[ifile] << endl; txtfile << " total: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile]; txtfile << " ==eff corr==> " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl; txtfile << endl; } txtfile.close(); cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("computeAccSelWe"); }
void selectZee(const TString conf="zee.conf", // input file const TString outputDir=".", // output directory const Bool_t doScaleCorr=0 // apply energy scale corrections? ) { gBenchmark->Start("selectZee"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t MASS_LOW = 40; const Double_t MASS_HIGH = 200; const Double_t PT_CUT = 10; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Double_t escaleNbins = 6; const Double_t escaleEta[] = { 0.4, 0.8, 1.2, 1.4442, 2, 2.5 }; const Double_t escaleCorr[] = { 1.00284, 1.00479, 1.00734, 1.00851, 1.00001, 0.982898 }; const Int_t BOSON_ID = 23; const Int_t LEPTON_ID = 11; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== enum { eEleEle2HLT=1, eEleEle1HLT1L1, eEleEle1HLT, eEleEleNoSel, eEleSC }; // event category enum vector<TString> snamev; // sample name (for output files) vector<CSample*> samplev; // data/MC samples // // parse .conf file // confParse(conf, snamev, samplev); const Bool_t hasData = (samplev[0]->fnamev.size()>0); // Create output directory gSystem->mkdir(outputDir,kTRUE); const TString ntupDir = outputDir + TString("/ntuples"); gSystem->mkdir(ntupDir,kTRUE); // // Declare output ntuple variables // UInt_t runNum, lumiSec, evtNum; UInt_t matchGen; UInt_t category; UInt_t npv, npu; UInt_t id_1, id_2; Double_t x_1, x_2, xPDF_1, xPDF_2; Double_t scalePDF, weightPDF; TLorentzVector *genV=0; Float_t genVPt, genVPhi, genVy, genVMass; Float_t scale1fb; Float_t met, metPhi, sumEt, u1, u2; Float_t tkMet, tkMetPhi, tkSumEt, tkU1, tkU2; Int_t q1, q2; TLorentzVector *dilep=0, *lep1=0, *lep2=0; ///// electron specific ///// Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2; Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2; Float_t sigieie1, hovere1, eoverp1, fbrem1, ecalE1, sigieie2, hovere2, eoverp2, fbrem2, ecalE2; Float_t dphi1, deta1, dphi2, deta2; Float_t d01, dz1, d02, dz2; UInt_t isConv1, nexphits1, typeBits1, isConv2, nexphits2, typeBits2; TLorentzVector *sc1=0, *sc2=0; // Data structures to store info from TTrees baconhep::TEventInfo *info = new baconhep::TEventInfo(); baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo(); TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle"); TClonesArray *electronArr = new TClonesArray("baconhep::TElectron"); TClonesArray *scArr = new TClonesArray("baconhep::TPhoton"); TClonesArray *pvArr = new TClonesArray("baconhep::TVertex"); TFile *infile=0; TTree *eventTree=0; // // loop over samples // for(UInt_t isam=0; isam<samplev.size(); isam++) { // Assume data sample is first sample in .conf file // If sample is empty (i.e. contains no ntuple files), skip to next sample if(isam==0 && !hasData) continue; // Assume signal sample is given name "zee" - flag to store GEN Z kinematics Bool_t isSignal = (snamev[isam].CompareTo("zee",TString::kIgnoreCase)==0); // flag to reject Z->ee events for wrong flavor backgrounds Bool_t isWrongFlavor = (snamev[isam].CompareTo("zxx",TString::kIgnoreCase)==0); CSample* samp = samplev[isam]; // // Set up output ntuple // TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root"); if(isam==0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root"); TFile *outFile = new TFile(outfilename,"RECREATE"); TTree *outTree = new TTree("Events","Events"); outTree->Branch("runNum", &runNum, "runNum/i"); // event run number outTree->Branch("lumiSec", &lumiSec, "lumiSec/i"); // event lumi section outTree->Branch("evtNum", &evtNum, "evtNum/i"); // event number outTree->Branch("matchGen", &matchGen, "matchGen/i"); // event has both leptons matched to MC Z->ll outTree->Branch("category", &category, "category/i"); // dilepton category outTree->Branch("id_1", &id_1, "id_1/i"); // PDF info -- parton ID for parton 1 outTree->Branch("id_2", &id_2, "id_2/i"); // PDF info -- parton ID for parton 2 outTree->Branch("x_1", &x_1, "x_1/d"); // PDF info -- x for parton 1 outTree->Branch("x_2", &x_2, "x_2/d"); // PDF info -- x for parton 2 outTree->Branch("xPDF_1", &xPDF_1, "xPDF_1/d"); // PDF info -- x*F for parton 1 outTree->Branch("xPDF_2", &xPDF_2, "xPDF_2/d"); // PDF info -- x*F for parton 2 outTree->Branch("scalePDF", &scalePDF, "scalePDF/d"); // PDF info -- energy scale of parton interaction outTree->Branch("weightPDF", &weightPDF, "weightPDF/d"); // PDF info -- PDF weight outTree->Branch("npv", &npv, "npv/i"); // number of primary vertices outTree->Branch("npu", &npu, "npu/i"); // number of in-time PU events (MC) outTree->Branch("genV", "TLorentzVector", &genV); // GEN boson 4-vector outTree->Branch("genVPt", &genVPt, "genVPt/F"); // GEN boson pT (signal MC) outTree->Branch("genVPhi", &genVPhi, "genVPhi/F"); // GEN boson phi (signal MC) outTree->Branch("genVy", &genVy, "genVy/F"); // GEN boson rapidity (signal MC) outTree->Branch("genVMass", &genVMass, "genVMass/F"); // GEN boson mass (signal MC) outTree->Branch("scale1fb", &scale1fb, "scale1fb/F"); // event weight per 1/fb (MC) outTree->Branch("met", &met, "met/F"); // MET outTree->Branch("metPhi", &metPhi, "metPhi/F"); // phi(MET) outTree->Branch("sumEt", &sumEt, "sumEt/F"); // Sum ET outTree->Branch("u1", &u1, "u1/F"); // parallel component of recoil outTree->Branch("u2", &u2, "u2/F"); // perpendicular component of recoil outTree->Branch("tkMet", &tkMet, "tkMet/F"); // MET (track MET) outTree->Branch("tkMetPhi", &tkMetPhi, "tkMetPhi/F"); // phi(MET) (track MET) outTree->Branch("tkSumEt", &tkSumEt, "tkSumEt/F"); // Sum ET (track MET) outTree->Branch("tkU1", &tkU1, "tkU1/F"); // parallel component of recoil (track MET) outTree->Branch("tkU2", &tkU2, "tkU2/F"); // perpendicular component of recoil (track MET) outTree->Branch("q1", &q1, "q1/I"); // charge of tag lepton outTree->Branch("q2", &q2, "q2/I"); // charge of probe lepton outTree->Branch("dilep", "TLorentzVector", &dilep); // di-lepton 4-vector outTree->Branch("lep1", "TLorentzVector", &lep1); // tag lepton 4-vector outTree->Branch("lep2", "TLorentzVector", &lep2); // probe lepton 4-vector ///// electron specific ///// outTree->Branch("trkIso1", &trkIso1, "trkIso1/F"); // track isolation of tag lepton outTree->Branch("trkIso2", &trkIso2, "trkIso2/F"); // track isolation of probe lepton outTree->Branch("emIso1", &emIso1, "emIso1/F"); // ECAL isolation of tag lepton outTree->Branch("emIso2", &emIso2, "emIso2/F"); // ECAL isolation of probe lepton outTree->Branch("hadIso1", &hadIso1, "hadIso1/F"); // HCAL isolation of tag lepton outTree->Branch("hadIso2", &hadIso2, "hadIso2/F"); // HCAL isolation of probe lepton outTree->Branch("pfChIso1", &pfChIso1, "pfChIso1/F"); // PF charged hadron isolation of tag lepton outTree->Branch("pfChIso2", &pfChIso2, "pfChIso2/F"); // PF charged hadron isolation of probe lepton outTree->Branch("pfGamIso1", &pfGamIso1, "pfGamIso1/F"); // PF photon isolation of tag lepton outTree->Branch("pfGamIso2", &pfGamIso2, "pfGamIso2/F"); // PF photon isolation of probe lepton outTree->Branch("pfNeuIso1", &pfNeuIso1, "pfNeuIso1/F"); // PF neutral hadron isolation of tag lepton outTree->Branch("pfNeuIso2", &pfNeuIso2, "pfNeuIso2/F"); // PF neutral hadron isolation of probe lepton outTree->Branch("pfCombIso1", &pfCombIso1, "pfCombIso1/F"); // PF combine isolation of tag lepton outTree->Branch("pfCombIso2", &pfCombIso2, "pfCombIso2/F"); // PF combined isolation of probe lepton outTree->Branch("sigieie1", &sigieie1, "sigieie1/F"); // sigma-ieta-ieta of tag outTree->Branch("sigieie2", &sigieie2, "sigieie2/F"); // sigma-ieta-ieta of probe outTree->Branch("hovere1", &hovere1, "hovere1/F"); // H/E of tag outTree->Branch("hovere2", &hovere2, "hovere2/F"); // H/E of probe outTree->Branch("eoverp1", &eoverp1, "eoverp1/F"); // E/p of tag outTree->Branch("eoverp2", &eoverp2, "eoverp2/F"); // E/p of probe outTree->Branch("fbrem1", &fbrem1, "fbrem1/F"); // brem fraction of tag outTree->Branch("fbrem2", &fbrem2, "fbrem2/F"); // brem fraction of probe outTree->Branch("dphi1", &dphi1, "dphi1/F"); // GSF track - ECAL dphi of tag outTree->Branch("dphi2", &dphi2, "dphi2/F"); // GSF track - ECAL dphi of probe outTree->Branch("deta1", &deta1, "deta1/F"); // GSF track - ECAL deta of tag outTree->Branch("deta2", &deta2, "deta2/F"); // GSF track - ECAL deta of probe outTree->Branch("ecalE1", &ecalE1, "ecalE1/F"); // ECAL energy of tag outTree->Branch("ecalE2", &ecalE2, "ecalE2/F"); // ECAL energy of probe outTree->Branch("d01", &d01, "d01/F"); // transverse impact parameter of tag outTree->Branch("d02", &d02, "d02/F"); // transverse impact parameter of probe outTree->Branch("dz1", &dz1, "dz1/F"); // longitudinal impact parameter of tag outTree->Branch("dz2", &dz2, "dz2/F"); // longitudinal impact parameter of probe outTree->Branch("isConv1", &isConv1, "isConv1/i"); // conversion filter flag of tag lepton outTree->Branch("isConv2", &isConv2, "isConv2/i"); // conversion filter flag of probe lepton outTree->Branch("nexphits1", &nexphits1, "nexphits1/i"); // number of missing expected inner hits of tag lepton outTree->Branch("nexphits2", &nexphits2, "nexphits2/i"); // number of missing expected inner hits of probe lepton outTree->Branch("typeBits1", &typeBits1, "typeBits1/i"); // electron type of tag lepton outTree->Branch("typeBits2", &typeBits2, "typeBits2/i"); // electron type of probe lepton outTree->Branch("sc1", "TLorentzVector", &sc1); // tag supercluster 4-vector outTree->Branch("sc2", "TLorentzVector", &sc2); // probe supercluster 4-vector // // loop through files // const UInt_t nfiles = samp->fnamev.size(); for(UInt_t ifile=0; ifile<nfiles; ifile++) { // Read input file and get the TTrees cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... " << endl; cout.flush(); infile = TFile::Open(samp->fnamev[ifile]); assert(infile); const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun"); UInt_t trigger = triggerMenu.getTriggerBit("HLT_Ele23_WP75_Gsf_v*"); //need to clean this up UInt_t trigObjL1 = 4;//triggerMenu.getTriggerObjectBit("HLT_Ele22_WP75_Gsf_v*", "hltL1sL1SingleEG20"); UInt_t trigObjHLT = 5;//triggerMenu.getTriggerObjectBit("HLT_Ele23_WP75_Gsf_v*", "hltEle23WP75GsfTrackIsoFilter"); /* cout << endl << "Checking trigger bits: " << endl; cout << "HLT_Ele22_WP75_Gsf_v* " << triggerMenu.getTriggerBit("HLT_Ele22_WP75_Gsf_v*") << endl; cout << "HLT_Ele23_WP75_Gsf_v* " << triggerMenu.getTriggerBit("HLT_Ele23_WP75_Gsf_v*") << endl; cout << "HLT_IsoMu20_v* " << triggerMenu.getTriggerBit("HLT_IsoMu20_v*") << endl; cout << "trigObjL1 " << trigObjL1 << endl; cout << "trigObjHLT " << trigObjHLT << endl;*/ //Bool_t hasJSON = kFALSE; //baconhep::RunLumiRangeMap rlrm; //if(samp->jsonv[ifile].CompareTo("NONE")!=0) { //hasJSON = kTRUE; //rlrm.AddJSONFile(samp->jsonv[ifile].Data()); //} eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("Photon", &scArr); TBranch *scBr = eventTree->GetBranch("Photon"); Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo"); TBranch *genBr=0, *genPartBr=0; if(hasGen) { eventTree->SetBranchAddress("GenEvtInfo", &gen); genBr = eventTree->GetBranch("GenEvtInfo"); eventTree->SetBranchAddress("GenParticle",&genPartArr); genPartBr = eventTree->GetBranch("GenParticle"); } Bool_t hasVer = eventTree->GetBranchStatus("Vertex"); TBranch *pvBr=0; if (hasVer) { eventTree->SetBranchAddress("Vertex", &pvArr); pvBr = eventTree->GetBranch("Vertex"); } // Compute MC event weight per 1/fb Double_t weight = 1; const Double_t xsec = samp->xsecv[ifile]; if(xsec>0) weight = 1000.*xsec/(Double_t)eventTree->GetEntries(); // // loop over events // Double_t nsel=0, nselvar=0; //for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { for(UInt_t ientry=0; ientry<1000; ientry++) { infoBr->GetEntry(ientry); if(hasGen) { genBr->GetEntry(ientry); genPartArr->Clear(); genPartBr->GetEntry(ientry); } // check for certified lumi (if applicable) //baconhep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec); //if(hasJSON && !rlrm.HasRunLumi(rl)) continue; // trigger requirement if(!(info->triggerBits[trigger])) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; if (hasVer) { pvArr->Clear(); pvBr->GetEntry(ientry); } // // SELECTION PROCEDURE: // (1) Find a good electron matched to trigger -> this will be the "tag" // (2) Pair the tag with Supercluster probes which form a tag+probe mass inside // the Z window and divide candidates into exclusive categories as follows: // (a) if probe SC is part of a good electron matched to trigger -> EleEle2HLT category // (b) if probe SC is part of a good electron not matched to trigger -> EleEle1HLT category // (c) if probe SC is part of an electron failing selection cuts -> EleEleNoSel category // (d) if probe SC is not part of an ECAL driven electron -> EleSC category // electronArr->Clear(); electronBr->GetEntry(ientry); scArr->Clear(); scBr->GetEntry(ientry); for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) { const baconhep::TElectron *tag = (baconhep::TElectron*)((*electronArr)[i1]); // check ECAL gap if(fabs(tag->scEta)>=ECAL_GAP_LOW && fabs(tag->scEta)<=ECAL_GAP_HIGH) continue; Double_t escale1=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(tag->scEta)<escaleEta[ieta]) { escale1 = escaleCorr[ieta]; break; } } } if(escale1*(tag->scEt) < PT_CUT) continue; // lepton pT cut if(fabs(tag->scEta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(tag,info->rhoIso)) continue; // lepton selection if(!(tag->hltMatchBits[trigObjHLT])) continue; // check trigger matching TLorentzVector vTag; vTag.SetPtEtaPhiM(escale1*(tag->pt), tag->eta, tag->phi, ELE_MASS); TLorentzVector vTagSC; vTagSC.SetPtEtaPhiM(escale1*(tag->scEt), tag->scEta, tag->scPhi, ELE_MASS); for(Int_t j=0; j<scArr->GetEntriesFast(); j++) { const baconhep::TPhoton *scProbe = (baconhep::TPhoton*)((*scArr)[j]); if(scProbe->scID == tag->scID) continue; // check ECAL gap if(fabs(scProbe->scEta)>=ECAL_GAP_LOW && fabs(scProbe->scEta)<=ECAL_GAP_HIGH) continue; Double_t escale2=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(scProbe->scEta)<escaleEta[ieta]) { escale2 = escaleCorr[ieta]; break; } } } if(escale2*(scProbe->pt) < PT_CUT) continue; // Supercluster ET cut ("pt" = corrected by PV position) if(fabs(scProbe->scEta) > ETA_CUT) continue; // Supercluster |eta| cuts const baconhep::TElectron *eleProbe=0; Int_t iprobe=-1; for(Int_t i2=0; i2<electronArr->GetEntriesFast(); i2++) { if(i1==i2) continue; const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i2]); if(!(ele->typeBits & baconhep::EEleType::kEcalDriven)) continue; if(scProbe->scID==ele->scID) { eleProbe = ele; iprobe = i2; break; } } TLorentzVector vProbe(0,0,0,0); vProbe.SetPtEtaPhiM((eleProbe) ? escale2*(eleProbe->pt) : escale2*(scProbe->pt), (eleProbe) ? eleProbe->eta : scProbe->eta, (eleProbe) ? eleProbe->phi : scProbe->phi, ELE_MASS); TLorentzVector vProbeSC(0,0,0,0); vProbeSC.SetPtEtaPhiM((eleProbe) ? escale2*(eleProbe->scEt) : escale2*(scProbe->scEt), scProbe->scEta, scProbe->scPhi, ELE_MASS); // mass window TLorentzVector vDilep = vTag + vProbe; if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue; //only for looking at low pT trigger efficiencies //if (toolbox::deltaR(vTag.Eta(), vProbe.Eta(), vTag.Phi(), vProbe.Phi())<0.3) continue; // determine event category UInt_t icat=0; if(eleProbe) { if(passEleID(eleProbe,info->rhoIso)) { if(eleProbe->hltMatchBits[trigObjHLT]) { if(i1>iprobe) continue; // make sure we don't double count EleEle2HLT category icat=eEleEle2HLT; } else if (eleProbe->hltMatchBits[trigObjL1]) { icat=eEleEle1HLT1L1; } else { icat=eEleEle1HLT; } } else { icat=eEleEleNoSel; } } else { icat=eEleSC; } if(icat==0) continue; // veto z -> ee decay for wrong flavor background samples (needed for inclusive DYToLL sample) if (isWrongFlavor) { TLorentzVector *vec=0, *lep1=0, *lep2=0; if (fabs(toolbox::flavor(genPartArr, BOSON_ID, vec, lep1, lep2))==LEPTON_ID) continue; } /******** We have a Z candidate! HURRAY! ********/ nsel+=weight; nselvar+=weight*weight; // Perform matching of dileptons to GEN leptons from Z decay Bool_t hasGenMatch = kFALSE; if(isSignal && hasGen) { TLorentzVector *vec=0, *lep1=0, *lep2=0; // veto wrong flavor events for signal sample if (fabs(toolbox::flavor(genPartArr, BOSON_ID, vec, lep1, lep2))!=LEPTON_ID) continue; Bool_t match1 = ( ((lep1) && toolbox::deltaR(tag->eta, tag->phi, lep1->Eta(), lep1->Phi())<0.3) || ((lep2) && toolbox::deltaR(tag->eta, tag->phi, lep2->Eta(), lep2->Phi())<0.3) ); Bool_t match2 = ( ((lep1) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), lep1->Eta(), lep1->Phi())<0.3) || ((lep2) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), lep2->Eta(), lep2->Phi())<0.3) ); if(match1 && match2) { hasGenMatch = kTRUE; if (vec!=0) { genV=new TLorentzVector(0,0,0,0); genV->SetPtEtaPhiM(vec->Pt(), vec->Eta(), vec->Phi(), vec->M()); genVPt = vec->Pt(); genVPhi = vec->Phi(); genVy = vec->Rapidity(); genVMass = vec->M(); } else { TLorentzVector tvec=*lep1+*lep2; genV=new TLorentzVector(0,0,0,0); genV->SetPtEtaPhiM(tvec.Pt(), tvec.Eta(), tvec.Phi(), tvec.M()); genVPt = tvec.Pt(); genVPhi = tvec.Phi(); genVy = tvec.Rapidity(); genVMass = tvec.M(); } } else { genV = new TLorentzVector(0,0,0,0); genVPt = -999; genVPhi = -999; genVy = -999; genVMass = -999; } } if (hasGen) { id_1 = gen->id_1; id_2 = gen->id_2; x_1 = gen->x_1; x_2 = gen->x_2; xPDF_1 = gen->xPDF_1; xPDF_2 = gen->xPDF_2; scalePDF = gen->scalePDF; weightPDF = gen->weight; } else { id_1 = -999; id_2 = -999; x_1 = -999; x_2 = -999; xPDF_1 = -999; xPDF_2 = -999; scalePDF = -999; weightPDF = -999; } // // Fill tree // runNum = info->runNum; lumiSec = info->lumiSec; evtNum = info->evtNum; if (hasGenMatch) matchGen=1; else matchGen=0; category = icat; npv = hasVer ? pvArr->GetEntriesFast() : 0; npu = info->nPU; scale1fb = weight; met = info->pfMET; metPhi = info->pfMETphi; sumEt = 0; tkMet = info->trkMET; tkMetPhi = info->trkMETphi; tkSumEt = 0; lep1 = &vTag; lep2 = &vProbe; dilep = &vDilep; q1 = tag->q; q2 = (eleProbe) ? eleProbe->q : -(tag->q); TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi())); TVector2 vMet((info->pfMET)*cos(info->pfMETphi), (info->pfMET)*sin(info->pfMETphi)); TVector2 vU = -1.0*(vMet+vZPt); u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi)); TVector2 vTkU = -1.0*(vTkMet+vZPt); tkU1 = ((vDilep.Px())*(vTkU.Px()) + (vDilep.Py())*(vTkU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| tkU2 = ((vDilep.Px())*(vTkU.Py()) - (vDilep.Py())*(vTkU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| ///// electron specific ///// sc1 = &vTagSC; trkIso1 = tag->trkIso; emIso1 = tag->ecalIso; hadIso1 = tag->hcalIso; pfChIso1 = tag->chHadIso; pfGamIso1 = tag->gammaIso; pfNeuIso1 = tag->neuHadIso; pfCombIso1 = tag->chHadIso + TMath::Max(tag->neuHadIso + tag->gammaIso - (info->rhoIso)*getEffArea(tag->scEta), 0.); sigieie1 = tag->sieie; hovere1 = tag->hovere; eoverp1 = tag->eoverp; fbrem1 = tag->fbrem; dphi1 = tag->dPhiIn; deta1 = tag->dEtaIn; ecalE1 = tag->ecalEnergy; d01 = tag->d0; dz1 = tag->dz; isConv1 = tag->isConv; nexphits1 = tag->nMissingHits; typeBits1 = tag->typeBits; sc2 = &vProbeSC; trkIso2 = (eleProbe) ? eleProbe->trkIso : -1; emIso2 = (eleProbe) ? eleProbe->ecalIso : -1; hadIso2 = (eleProbe) ? eleProbe->hcalIso : -1; pfChIso2 = (eleProbe) ? eleProbe->chHadIso : -1; pfGamIso2 = (eleProbe) ? eleProbe->gammaIso : -1; pfNeuIso2 = (eleProbe) ? eleProbe->neuHadIso : -1; pfCombIso2 = (eleProbe) ? eleProbe->chHadIso + TMath::Max(eleProbe->neuHadIso + eleProbe->gammaIso - (info->rhoIso)*getEffArea(eleProbe->scEta), 0.) : -1; sigieie2 = (eleProbe) ? eleProbe->sieie : scProbe->sieie; hovere2 = (eleProbe) ? eleProbe->hovere : scProbe->hovere; eoverp2 = (eleProbe) ? eleProbe->eoverp : -1; fbrem2 = (eleProbe) ? eleProbe->fbrem : -1; dphi2 = (eleProbe) ? eleProbe->dPhiIn : -999; deta2 = (eleProbe) ? eleProbe->dEtaIn : -999; ecalE2 = (eleProbe) ? eleProbe->ecalEnergy : -999; d02 = (eleProbe) ? eleProbe->d0 : -999; dz2 = (eleProbe) ? eleProbe->dz : -999; isConv2 = (eleProbe) ? eleProbe->isConv : 0; nexphits2 = (eleProbe) ? eleProbe->nMissingHits : 0; typeBits2 = (eleProbe) ? eleProbe->typeBits : 0; outTree->Fill(); genV=0, dilep=0, lep1=0, lep2=0, sc1=0, sc2=0; } } } delete infile; infile=0, eventTree=0; cout << nsel << " +/- " << sqrt(nselvar); if(isam!=0) cout << " per 1/fb"; cout << endl; } outFile->Write(); outFile->Close(); } delete info; delete gen; delete electronArr; delete scArr; delete pvArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " Z -> e e" << endl; cout << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; if(doScaleCorr) cout << " *** Scale corrections applied ***" << endl; cout << endl; cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("selectZee"); }
void selectZee(const TString conf="zee.conf", // input file const TString outputDir=".", // output directory const Bool_t doScaleCorr=0 // apply energy scale corrections? ) { gBenchmark->Start("selectZee"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t MASS_LOW = 40; const Double_t MASS_HIGH = 200; const Double_t PT_CUT = 22; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Double_t escaleNbins = 2; const Double_t escaleEta[] = { 1.4442, 2.5 }; const Double_t escaleCorr[] = { 0.992, 1.009 }; const Int_t BOSON_ID = 23; const Int_t LEPTON_ID = 11; // load trigger menu const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun"); // load pileup reweighting file TFile *f_rw = TFile::Open("../Tools/pileup_rw_76X.root", "read"); // for systematics we need 3 TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden"); TH1D *h_rw_up = (TH1D*) f_rw->Get("h_rw_up_golden"); TH1D *h_rw_down = (TH1D*) f_rw->Get("h_rw_down_golden"); if (h_rw==NULL) cout<<"WARNIG h_rw == NULL"<<endl; if (h_rw_up==NULL) cout<<"WARNIG h_rw == NULL"<<endl; if (h_rw_down==NULL) cout<<"WARNIG h_rw == NULL"<<endl; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== enum { eEleEle2HLT=1, eEleEle1HLT1L1, eEleEle1HLT, eEleEleNoSel, eEleSC }; // event category enum vector<TString> snamev; // sample name (for output files) vector<CSample*> samplev; // data/MC samples // // parse .conf file // confParse(conf, snamev, samplev); const Bool_t hasData = (samplev[0]->fnamev.size()>0); // Create output directory gSystem->mkdir(outputDir,kTRUE); const TString ntupDir = outputDir + TString("/ntuples"); gSystem->mkdir(ntupDir,kTRUE); // // Declare output ntuple variables // UInt_t runNum, lumiSec, evtNum; UInt_t matchGen; UInt_t category; UInt_t npv, npu; UInt_t id_1, id_2; Double_t x_1, x_2, xPDF_1, xPDF_2; Double_t scalePDF, weightPDF; TLorentzVector *genV=0; Float_t genVPt, genVPhi, genVy, genVMass; Float_t genWeight, PUWeight; Float_t scale1fb,scale1fbUp,scale1fbDown; Float_t met, metPhi, sumEt, u1, u2; Float_t tkMet, tkMetPhi, tkSumEt, tkU1, tkU2; Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaU1, mvaU2; Float_t puppiMet, puppiMetPhi, puppiSumEt, puppiU1, puppiU2; Int_t q1, q2; TLorentzVector *dilep=0, *lep1=0, *lep2=0; ///// electron specific ///// Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2; Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2; Float_t sigieie1, hovere1, eoverp1, fbrem1, ecalE1, sigieie2, hovere2, eoverp2, fbrem2, ecalE2; Float_t dphi1, deta1, dphi2, deta2; Float_t d01, dz1, d02, dz2; UInt_t isConv1, nexphits1, typeBits1, isConv2, nexphits2, typeBits2; TLorentzVector *sc1=0, *sc2=0; // Data structures to store info from TTrees baconhep::TEventInfo *info = new baconhep::TEventInfo(); baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo(); TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle"); TClonesArray *electronArr = new TClonesArray("baconhep::TElectron"); TClonesArray *scArr = new TClonesArray("baconhep::TPhoton"); TClonesArray *vertexArr = new TClonesArray("baconhep::TVertex"); TFile *infile=0; TTree *eventTree=0; // // loop over samples // for(UInt_t isam=0; isam<samplev.size(); isam++) { // Assume data sample is first sample in .conf file // If sample is empty (i.e. contains no ntuple files), skip to next sample Bool_t isData=kFALSE; if(isam==0 && !hasData) continue; else if (isam==0) isData=kTRUE; // Assume signal sample is given name "zee" - flag to store GEN Z kinematics Bool_t isSignal = (snamev[isam].CompareTo("zee",TString::kIgnoreCase)==0); // flag to reject Z->ee events when selecting at wrong-flavor background events Bool_t isWrongFlavor = (snamev[isam].CompareTo("zxx",TString::kIgnoreCase)==0); CSample* samp = samplev[isam]; // // Set up output ntuple // TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root"); if(isam!=0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root"); TFile *outFile = new TFile(outfilename,"RECREATE"); TTree *outTree = new TTree("Events","Events"); outTree->Branch("runNum", &runNum, "runNum/i"); // event run number outTree->Branch("lumiSec", &lumiSec, "lumiSec/i"); // event lumi section outTree->Branch("evtNum", &evtNum, "evtNum/i"); // event number outTree->Branch("matchGen", &matchGen, "matchGen/i"); // event has both leptons matched to MC Z->ll outTree->Branch("category", &category, "category/i"); // dilepton category outTree->Branch("id_1", &id_1, "id_1/i"); // PDF info -- parton ID for parton 1 outTree->Branch("id_2", &id_2, "id_2/i"); // PDF info -- parton ID for parton 2 outTree->Branch("x_1", &x_1, "x_1/d"); // PDF info -- x for parton 1 outTree->Branch("x_2", &x_2, "x_2/d"); // PDF info -- x for parton 2 outTree->Branch("xPDF_1", &xPDF_1, "xPDF_1/d"); // PDF info -- x*F for parton 1 outTree->Branch("xPDF_2", &xPDF_2, "xPDF_2/d"); // PDF info -- x*F for parton 2 outTree->Branch("scalePDF", &scalePDF, "scalePDF/d"); // PDF info -- energy scale of parton interaction outTree->Branch("weightPDF", &weightPDF, "weightPDF/d"); // PDF info -- PDF weight outTree->Branch("npv", &npv, "npv/i"); // number of primary vertices outTree->Branch("npu", &npu, "npu/i"); // number of in-time PU events (MC) outTree->Branch("genV", "TLorentzVector", &genV); // GEN boson 4-vector outTree->Branch("genVPt", &genVPt, "genVPt/F"); // GEN boson pT (signal MC) outTree->Branch("genVPhi", &genVPhi, "genVPhi/F"); // GEN boson phi (signal MC) outTree->Branch("genVy", &genVy, "genVy/F"); // GEN boson rapidity (signal MC) outTree->Branch("genVMass", &genVMass, "genVMass/F"); // GEN boson mass (signal MC) outTree->Branch("genWeight", &genWeight, "genWeight/F"); outTree->Branch("PUWeight", &PUWeight, "PUWeight/F"); outTree->Branch("scale1fb", &scale1fb, "scale1fb/F"); // event weight per 1/fb (MC) outTree->Branch("scale1fbUp", &scale1fbUp, "scale1fbUp/F"); // event weight per 1/fb (MC) outTree->Branch("scale1fbDown", &scale1fbDown, "scale1fbDown/F"); // event weight per 1/fb (MC) outTree->Branch("met", &met, "met/F"); // MET outTree->Branch("metPhi", &metPhi, "metPhi/F"); // phi(MET) outTree->Branch("sumEt", &sumEt, "sumEt/F"); // Sum ET outTree->Branch("u1", &u1, "u1/F"); // parallel component of recoil outTree->Branch("u2", &u2, "u2/F"); // perpendicular component of recoil outTree->Branch("tkMet", &tkMet, "tkMet/F"); // MET (track MET) outTree->Branch("tkMetPhi", &tkMetPhi, "tkMetPhi/F"); // phi(MET) (track MET) outTree->Branch("tkSumEt", &tkSumEt, "tkSumEt/F"); // Sum ET (track MET) outTree->Branch("tkU1", &tkU1, "tkU1/F"); // parallel component of recoil (track MET) outTree->Branch("tkU2", &tkU2, "tkU2/F"); // perpendicular component of recoil (track MET) outTree->Branch("mvaMet", &mvaMet, "mvaMet/F"); // MVA MET outTree->Branch("mvaMetPhi", &mvaMetPhi, "mvaMetPhi/F"); // phi(MVA MET) outTree->Branch("mvaSumEt", &mvaSumEt, "mvaSumEt/F"); // Sum ET (mva MET) outTree->Branch("mvaU1", &mvaU1, "mvaU1/F"); // parallel component of recoil (mva MET) outTree->Branch("mvaU2", &mvaU2, "mvaU2/F"); // perpendicular component of recoil (mva MET) outTree->Branch("puppiMet", &puppiMet, "puppiMet/F"); // Puppi MET outTree->Branch("puppiMetPhi", &puppiMetPhi,"puppiMetPhi/F"); // phi(Puppi MET) outTree->Branch("puppiSumEt", &puppiSumEt, "puppiSumEt/F"); // Sum ET (Puppi MET) outTree->Branch("puppiU1", &puppiU1, "puppiU1/F"); // parallel component of recoil (Puppi MET) outTree->Branch("puppiU2", &puppiU2, "puppiU2/F"); // perpendicular component of recoil (Puppi MET) outTree->Branch("q1", &q1, "q1/I"); // charge of tag lepton outTree->Branch("q2", &q2, "q2/I"); // charge of probe lepton outTree->Branch("dilep", "TLorentzVector", &dilep); // di-lepton 4-vector outTree->Branch("lep1", "TLorentzVector", &lep1); // tag lepton 4-vector outTree->Branch("lep2", "TLorentzVector", &lep2); // probe lepton 4-vector ///// electron specific ///// outTree->Branch("trkIso1", &trkIso1, "trkIso1/F"); // track isolation of tag lepton outTree->Branch("trkIso2", &trkIso2, "trkIso2/F"); // track isolation of probe lepton outTree->Branch("emIso1", &emIso1, "emIso1/F"); // ECAL isolation of tag lepton outTree->Branch("emIso2", &emIso2, "emIso2/F"); // ECAL isolation of probe lepton outTree->Branch("hadIso1", &hadIso1, "hadIso1/F"); // HCAL isolation of tag lepton outTree->Branch("hadIso2", &hadIso2, "hadIso2/F"); // HCAL isolation of probe lepton outTree->Branch("pfChIso1", &pfChIso1, "pfChIso1/F"); // PF charged hadron isolation of tag lepton outTree->Branch("pfChIso2", &pfChIso2, "pfChIso2/F"); // PF charged hadron isolation of probe lepton outTree->Branch("pfGamIso1", &pfGamIso1, "pfGamIso1/F"); // PF photon isolation of tag lepton outTree->Branch("pfGamIso2", &pfGamIso2, "pfGamIso2/F"); // PF photon isolation of probe lepton outTree->Branch("pfNeuIso1", &pfNeuIso1, "pfNeuIso1/F"); // PF neutral hadron isolation of tag lepton outTree->Branch("pfNeuIso2", &pfNeuIso2, "pfNeuIso2/F"); // PF neutral hadron isolation of probe lepton outTree->Branch("pfCombIso1", &pfCombIso1, "pfCombIso1/F"); // PF combine isolation of tag lepton outTree->Branch("pfCombIso2", &pfCombIso2, "pfCombIso2/F"); // PF combined isolation of probe lepton outTree->Branch("sigieie1", &sigieie1, "sigieie1/F"); // sigma-ieta-ieta of tag outTree->Branch("sigieie2", &sigieie2, "sigieie2/F"); // sigma-ieta-ieta of probe outTree->Branch("hovere1", &hovere1, "hovere1/F"); // H/E of tag outTree->Branch("hovere2", &hovere2, "hovere2/F"); // H/E of probe outTree->Branch("eoverp1", &eoverp1, "eoverp1/F"); // E/p of tag outTree->Branch("eoverp2", &eoverp2, "eoverp2/F"); // E/p of probe outTree->Branch("fbrem1", &fbrem1, "fbrem1/F"); // brem fraction of tag outTree->Branch("fbrem2", &fbrem2, "fbrem2/F"); // brem fraction of probe outTree->Branch("dphi1", &dphi1, "dphi1/F"); // GSF track - ECAL dphi of tag outTree->Branch("dphi2", &dphi2, "dphi2/F"); // GSF track - ECAL dphi of probe outTree->Branch("deta1", &deta1, "deta1/F"); // GSF track - ECAL deta of tag outTree->Branch("deta2", &deta2, "deta2/F"); // GSF track - ECAL deta of probe outTree->Branch("ecalE1", &ecalE1, "ecalE1/F"); // ECAL energy of tag outTree->Branch("ecalE2", &ecalE2, "ecalE2/F"); // ECAL energy of probe outTree->Branch("d01", &d01, "d01/F"); // transverse impact parameter of tag outTree->Branch("d02", &d02, "d02/F"); // transverse impact parameter of probe outTree->Branch("dz1", &dz1, "dz1/F"); // longitudinal impact parameter of tag outTree->Branch("dz2", &dz2, "dz2/F"); // longitudinal impact parameter of probe outTree->Branch("isConv1", &isConv1, "isConv1/i"); // conversion filter flag of tag lepton outTree->Branch("isConv2", &isConv2, "isConv2/i"); // conversion filter flag of probe lepton outTree->Branch("nexphits1", &nexphits1, "nexphits1/i"); // number of missing expected inner hits of tag lepton outTree->Branch("nexphits2", &nexphits2, "nexphits2/i"); // number of missing expected inner hits of probe lepton outTree->Branch("typeBits1", &typeBits1, "typeBits1/i"); // electron type of tag lepton outTree->Branch("typeBits2", &typeBits2, "typeBits2/i"); // electron type of probe lepton outTree->Branch("sc1", "TLorentzVector", &sc1); // tag supercluster 4-vector outTree->Branch("sc2", "TLorentzVector", &sc2); // probe supercluster 4-vector // // loop through files // const UInt_t nfiles = samp->fnamev.size(); for(UInt_t ifile=0; ifile<nfiles; ifile++) { // Read input file and get the TTrees cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... " << endl; cout.flush(); infile = TFile::Open(samp->fnamev[ifile]); assert(infile); Bool_t hasJSON = kFALSE; baconhep::RunLumiRangeMap rlrm; if(samp->jsonv[ifile].CompareTo("NONE")!=0) { hasJSON = kTRUE; rlrm.addJSONFile(samp->jsonv[ifile].Data()); } eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("Photon", &scArr); TBranch *scBr = eventTree->GetBranch("Photon"); eventTree->SetBranchAddress("PV", &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV"); Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo"); TBranch *genBr=0, *genPartBr=0; if(hasGen) { eventTree->SetBranchAddress("GenEvtInfo", &gen); genBr = eventTree->GetBranch("GenEvtInfo"); eventTree->SetBranchAddress("GenParticle",&genPartArr); genPartBr = eventTree->GetBranch("GenParticle"); } // Compute MC event weight per 1/fb const Double_t xsec = samp->xsecv[ifile]; Double_t totalWeight=0; Double_t totalWeightUp=0; Double_t totalWeightDown=0; Double_t puWeight=0; Double_t puWeightUp=0; Double_t puWeightDown=0; if (hasGen) { for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { infoBr->GetEntry(ientry); genBr->GetEntry(ientry); puWeight = h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)); puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)); puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)); totalWeight+=gen->weight*puWeight; totalWeightUp+=gen->weight*puWeightUp; totalWeightDown+=gen->weight*puWeightDown; } } else if (not isData){ for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { puWeight = h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)); puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)); puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)); totalWeight+= 1.0*puWeight; totalWeightUp+= 1.0*puWeightUp; totalWeightDown+= 1.0*puWeightDown; } } // // loop over events // Double_t nsel=0, nselvar=0; for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { infoBr->GetEntry(ientry); if(ientry%1000000==0) cout << "Processing event " << ientry << ". " << (double)ientry/(double)eventTree->GetEntries()*100 << " percent done with this file." << endl; Double_t weight=1; Double_t weightUp=1; Double_t weightDown=1; if(xsec>0 && totalWeight>0) weight = xsec/totalWeight; if(xsec>0 && totalWeightUp>0) weightUp = xsec/totalWeightUp; if(xsec>0 && totalWeightDown>0) weightDown = xsec/totalWeightDown; if(hasGen) { genPartArr->Clear(); genBr->GetEntry(ientry); genPartBr->GetEntry(ientry); puWeight = h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)); puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)); puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)); weight*=gen->weight*puWeight; weightUp*=gen->weight*puWeightUp; weightDown*=gen->weight*puWeightDown; } // veto z -> xx decays for signal and z -> ee for bacground samples (needed for inclusive DYToLL sample) if (isWrongFlavor && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))==LEPTON_ID) continue; else if (isSignal && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue; // check for certified lumi (if applicable) baconhep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec); if(hasJSON && !rlrm.hasRunLumi(rl)) continue; // trigger requirement if (!isEleTrigger(triggerMenu, info->triggerBits, isData)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; electronArr->Clear(); electronBr->GetEntry(ientry); scArr->Clear(); scBr->GetEntry(ientry); TLorentzVector vTag(0,0,0,0); TLorentzVector vTagSC(0,0,0,0); Double_t tagPt=0; Double_t Pt1=0; Double_t Pt2=0; Int_t itag=-1; Int_t tagscID=-1; for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) { const baconhep::TElectron *tag = (baconhep::TElectron*)((*electronArr)[i1]); // check ECAL gap if(fabs(tag->scEta)>=ECAL_GAP_LOW && fabs(tag->scEta)<=ECAL_GAP_HIGH) continue; // apply scale and resolution corrections to MC Double_t tagscEt_corr = tag->scEt; if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) tagscEt_corr = gRandom->Gaus(tag->scEt*getEleScaleCorr(tag->scEta,0),getEleResCorr(tag->scEta,0)); if(tagscEt_corr < PT_CUT) continue; // lepton pT cut if(fabs(tag->scEta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(tag,info->rhoIso)) continue; // lepton selection double El_Pt=0; if(doScaleCorr) { El_Pt=gRandom->Gaus(tag->pt*getEleScaleCorr(tag->scEta,0),getEleResCorr(tag->scEta,0)); } else { El_Pt=tag->pt; } if(El_Pt>Pt1) { Pt2=Pt1; Pt1=El_Pt; } else if(El_Pt>Pt2&&El_Pt<Pt1) { Pt2=El_Pt; } if(!isEleTriggerObj(triggerMenu, tag->hltMatchBits, kFALSE, isData)) continue; if(El_Pt<tagPt) continue; tagPt=El_Pt; itag=i1; tagscID=tag->scID; // apply scale and resolution corrections to MC if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) { vTag.SetPtEtaPhiM(El_Pt, tag->eta, tag->phi, ELE_MASS); vTagSC.SetPtEtaPhiM(tagscEt_corr, tag->scEta, tag->scPhi, ELE_MASS); } else { vTag.SetPtEtaPhiM(tag->pt, tag->eta, tag->phi, ELE_MASS); vTagSC.SetPtEtaPhiM(tag->scEt, tag->scEta, tag->scPhi, ELE_MASS); } trkIso1 = tag->trkIso; emIso1 = tag->ecalIso; hadIso1 = tag->hcalIso; pfChIso1 = tag->chHadIso; pfGamIso1 = tag->gammaIso; pfNeuIso1 = tag->neuHadIso; pfCombIso1 = tag->chHadIso + TMath::Max(tag->neuHadIso + tag->gammaIso - (info->rhoIso)*getEffAreaEl(tag->scEta), 0.); sigieie1 = tag->sieie; hovere1 = tag->hovere; eoverp1 = tag->eoverp; fbrem1 = tag->fbrem; dphi1 = tag->dPhiIn; deta1 = tag->dEtaIn; ecalE1 = tag->ecalEnergy; d01 = tag->d0; dz1 = tag->dz; isConv1 = tag->isConv; nexphits1 = tag->nMissingHits; typeBits1 = tag->typeBits; q1 = tag->q; } if(tagPt<Pt2) continue; TLorentzVector vProbe(0,0,0,0); TLorentzVector vProbeSC(0,0,0,0); Double_t probePt=0; Int_t iprobe=-1; Int_t passID=false; UInt_t icat=0; const baconhep::TElectron *eleProbe=0; for(Int_t j=0; j<scArr->GetEntriesFast(); j++) { const baconhep::TPhoton *scProbe = (baconhep::TPhoton*)((*scArr)[j]); if(scProbe->scID == tagscID) continue; // check ECAL gap if(fabs(scProbe->eta)>=ECAL_GAP_LOW && fabs(scProbe->eta)<=ECAL_GAP_HIGH) continue; // apply scale and resolution corrections to MC Double_t scProbept_corr = scProbe->pt; if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) scProbept_corr = gRandom->Gaus(scProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)); if(scProbept_corr < PT_CUT) continue; // Supercluster ET cut ("pt" = corrected by PV position) if(fabs(scProbe->eta) > ETA_CUT) continue; // Supercluster |eta| cuts for(Int_t i2=0; i2<electronArr->GetEntriesFast(); i2++) { if(itag==i2) continue; const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i2]); if(!(ele->typeBits & baconhep::EEleType::kEcalDriven)) continue; if(scProbe->scID==ele->scID) { eleProbe = ele; iprobe = i2; break; } } double El_Pt=0; if(doScaleCorr&&eleProbe) { El_Pt=gRandom->Gaus(eleProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)); } else if(!doScaleCorr&&eleProbe) { El_Pt=eleProbe->pt; } else { El_Pt=scProbept_corr; } if(passID&&eleProbe&&passEleID(eleProbe,info->rhoIso)&&El_Pt<probePt) continue; if(passID&&eleProbe&&!passEleID(eleProbe,info->rhoIso)) continue; if(passID&&!eleProbe) continue; if(!passID&&eleProbe&&!passEleID(eleProbe,info->rhoIso)&&El_Pt<probePt) continue; if(!passID&&!eleProbe&&El_Pt<probePt) continue; if(!passID&&eleProbe&&passEleID(eleProbe,info->rhoIso)) passID=true; probePt=El_Pt; // apply scale and resolution corrections to MC if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) { vProbe.SetPtEtaPhiM((eleProbe) ? gRandom->Gaus(eleProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)) : scProbept_corr, (eleProbe) ? eleProbe->eta : scProbe->eta, (eleProbe) ? eleProbe->phi : scProbe->phi, ELE_MASS); vProbeSC.SetPtEtaPhiM((eleProbe) ? gRandom->Gaus(eleProbe->scEt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)) : gRandom->Gaus(scProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)), scProbe->eta, scProbe->phi, ELE_MASS); } else { vProbe.SetPtEtaPhiM((eleProbe) ? eleProbe->pt : scProbe->pt, (eleProbe) ? eleProbe->eta : scProbe->eta, (eleProbe) ? eleProbe->phi : scProbe->phi, ELE_MASS); vProbeSC.SetPtEtaPhiM((eleProbe) ? eleProbe->scEt : scProbe->pt, scProbe->eta, scProbe->phi, ELE_MASS); } trkIso2 = (eleProbe) ? eleProbe->trkIso : -1; emIso2 = (eleProbe) ? eleProbe->ecalIso : -1; hadIso2 = (eleProbe) ? eleProbe->hcalIso : -1; pfChIso2 = (eleProbe) ? eleProbe->chHadIso : -1; pfGamIso2 = (eleProbe) ? eleProbe->gammaIso : -1; pfNeuIso2 = (eleProbe) ? eleProbe->neuHadIso : -1; pfCombIso2 = (eleProbe) ? eleProbe->chHadIso + TMath::Max(eleProbe->neuHadIso + eleProbe->gammaIso - (info->rhoIso)*getEffAreaEl(eleProbe->scEta), 0.) : -1; sigieie2 = (eleProbe) ? eleProbe->sieie : scProbe->sieie; hovere2 = (eleProbe) ? eleProbe->hovere : scProbe->hovere; eoverp2 = (eleProbe) ? eleProbe->eoverp : -1; fbrem2 = (eleProbe) ? eleProbe->fbrem : -1; dphi2 = (eleProbe) ? eleProbe->dPhiIn : -999; deta2 = (eleProbe) ? eleProbe->dEtaIn : -999; ecalE2 = (eleProbe) ? eleProbe->ecalEnergy : -999; d02 = (eleProbe) ? eleProbe->d0 : -999; dz2 = (eleProbe) ? eleProbe->dz : -999; isConv2 = (eleProbe) ? eleProbe->isConv : 0; nexphits2 = (eleProbe) ? eleProbe->nMissingHits : 0; typeBits2 = (eleProbe) ? eleProbe->typeBits : 0; q2 = (eleProbe) ? eleProbe->q : -q1; // determine event category if(eleProbe) { if(passEleID(eleProbe,info->rhoIso)) { if(isEleTriggerObj(triggerMenu, eleProbe->hltMatchBits, kFALSE, isData)) { icat=eEleEle2HLT; } else if(isEleTriggerObj(triggerMenu, eleProbe->hltMatchBits, kTRUE, isData)) { icat=eEleEle1HLT1L1; } else { icat=eEleEle1HLT; } } else { icat=eEleEleNoSel; } } else { icat=eEleSC; } } if(q1 == q2) continue; // opposite charge requirement // mass window TLorentzVector vDilep = vTag + vProbe; if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue; if(icat==0) continue; //******** We have a Z candidate! HURRAY! ******** nsel+=weight; nselvar+=weight*weight; // Perform matching of dileptons to GEN leptons from Z decay Int_t glepq1=-99; Int_t glepq2=-99; TLorentzVector *gvec=new TLorentzVector(0,0,0,0); TLorentzVector *glep1=new TLorentzVector(0,0,0,0); TLorentzVector *glep2=new TLorentzVector(0,0,0,0); TLorentzVector *gph=new TLorentzVector(0,0,0,0); Bool_t hasGenMatch = kFALSE; if(isSignal && hasGen) { toolbox::fillGen(genPartArr, BOSON_ID, gvec, glep1, glep2,&glepq1,&glepq2,1); Bool_t match1 = ( ((glep1) && toolbox::deltaR(vTag.Eta(), vTag.Phi(), glep1->Eta(), glep1->Phi())<0.3) || ((glep2) && toolbox::deltaR(vTag.Eta(), vTag.Phi(), glep2->Eta(), glep2->Phi())<0.3) ); Bool_t match2 = ( ((glep1) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep1->Eta(), glep1->Phi())<0.3) || ((glep2) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep2->Eta(), glep2->Phi())<0.3) ); if(match1 && match2) { hasGenMatch = kTRUE; if (gvec!=0) { genV=new TLorentzVector(0,0,0,0); genV->SetPtEtaPhiM(gvec->Pt(), gvec->Eta(), gvec->Phi(), gvec->M()); genVPt = gvec->Pt(); genVPhi = gvec->Phi(); genVy = gvec->Rapidity(); genVMass = gvec->M(); } else { TLorentzVector tvec=*glep1+*glep2; genV=new TLorentzVector(0,0,0,0); genV->SetPtEtaPhiM(tvec.Pt(), tvec.Eta(), tvec.Phi(), tvec.M()); genVPt = tvec.Pt(); genVPhi = tvec.Phi(); genVy = tvec.Rapidity(); genVMass = tvec.M(); } delete gvec; delete glep1; delete glep2; glep1=0; glep2=0; gvec=0; } else { genV = new TLorentzVector(0,0,0,0); genVPt = -999; genVPhi = -999; genVy = -999; genVMass = -999; } } if (hasGen) { id_1 = gen->id_1; id_2 = gen->id_2; x_1 = gen->x_1; x_2 = gen->x_2; xPDF_1 = gen->xPDF_1; xPDF_2 = gen->xPDF_2; scalePDF = gen->scalePDF; weightPDF = gen->weight; } else { id_1 = -999; id_2 = -999; x_1 = -999; x_2 = -999; xPDF_1 = -999; xPDF_2 = -999; scalePDF = -999; weightPDF = -999; } // // Fill tree // runNum = info->runNum; lumiSec = info->lumiSec; evtNum = info->evtNum; if (hasGenMatch) matchGen=1; else matchGen=0; category = icat; vertexArr->Clear(); vertexBr->GetEntry(ientry); npv = vertexArr->GetEntries(); npu = info->nPUmean; genWeight= hasGen ? gen->weight: 1.; PUWeight = puWeight; scale1fb = weight; scale1fbUp = weightUp; scale1fbDown = weightDown; met = info->pfMETC; metPhi = info->pfMETCphi; sumEt = 0; tkMet = info->trkMET; tkMetPhi = info->trkMETphi; tkSumEt = 0; mvaMet = info->mvaMET; mvaMetPhi = info->mvaMETphi; mvaSumEt = 0; TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi())); puppiMet = info->puppET; puppiMetPhi = info->puppETphi; puppiSumEt = 0; lep1 = &vTag; lep2 = &vProbe; dilep = &vDilep; sc1 = &vTagSC; sc2 = &vProbeSC; TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi)); TVector2 vU = -1.0*(vMet+vZPt); u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi)); TVector2 vTkU = -1.0*(vTkMet+vZPt); tkU1 = ((vDilep.Px())*(vTkU.Px()) + (vDilep.Py())*(vTkU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| tkU2 = ((vDilep.Px())*(vTkU.Py()) - (vDilep.Py())*(vTkU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi)); TVector2 vMvaU = -1.0*(vMvaMet+vZPt); mvaU1 = ((vDilep.Px())*(vMvaU.Px()) + (vDilep.Py())*(vMvaU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| mvaU2 = ((vDilep.Px())*(vMvaU.Py()) - (vDilep.Py())*(vMvaU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| TVector2 vPuppiMet((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi)); TVector2 vPuppiU = -1.0*(vPuppiMet+vZPt); puppiU1 = ((vDilep.Px())*(vPuppiU.Px()) + (vDilep.Py())*(vPuppiU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| puppiU2 = ((vDilep.Px())*(vPuppiU.Py()) - (vDilep.Py())*(vPuppiU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| outTree->Fill(); delete genV; genV=0, dilep=0, lep1=0, lep2=0, sc1=0, sc2=0; } delete infile; infile=0, eventTree=0; cout << nsel << " +/- " << sqrt(nselvar); if(!isData) cout << " per 1/fb"; cout << endl; } outFile->Write(); outFile->Close(); } delete h_rw; delete f_rw; delete info; delete gen; delete genPartArr; delete electronArr; delete scArr; delete vertexArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " Z -> e e" << endl; cout << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; cout << endl; cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("selectZee"); }
void computeAccSelZeeBinned(const TString conf, // input file const TString outputDir // output directory ) { gBenchmark->Start("computeAccSelZeeBinned"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t MASS_LOW = 60; const Double_t MASS_HIGH = 120; const Double_t PT_CUT = 25; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ETA_BARREL = 1.4442; const Double_t ETA_ENDCAP = 1.566; // efficiency files const TString dataHLTEffName = "../Efficiency/May23_EleHLTEff/analysis/eff.root"; const TString dataHLTEffName_pos = "../Efficiency/May23_EleHLTEff_pos/analysis/eff.root"; const TString dataHLTEffName_neg = "../Efficiency/May23_EleHLTEff_neg/analysis/eff.root"; const TString zeeHLTEffName = "../Efficiency/Zee_EleHLTEff/analysis/eff.root"; const TString zeeHLTEffName_pos = "../Efficiency/Zee_EleHLTEff_pos/analysis/eff.root"; const TString zeeHLTEffName_neg = "../Efficiency/Zee_EleHLTEff_neg/analysis/eff.root"; const TString dataGsfSelEffName = "../Efficiency/May23_EleGsfSelEff/analysis/eff.root"; const TString dataGsfSelEffName_pos = "../Efficiency/May23_EleGsfSelEff_pos/analysis/eff.root"; const TString dataGsfSelEffName_neg = "../Efficiency/May23_EleGsfSelEff_neg/analysis/eff.root"; const TString zeeGsfSelEffName = "../Efficiency/Zee_EleGsfSelEff/analysis/eff.root"; const TString zeeGsfSelEffName_pos = "../Efficiency/Zee_EleGsfSelEff_pos/analysis/eff.root"; const TString zeeGsfSelEffName_neg = "../Efficiency/Zee_EleGsfSelEff_neg/analysis/eff.root"; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== vector<TString> fnamev; // file name per input file vector<TString> labelv; // TLegend label per input file vector<Int_t> colorv; // plot color per input file vector<Int_t> linev; // plot line style per input file // // parse .conf file // ifstream ifs; ifs.open(conf.Data()); assert(ifs.is_open()); string line; while(getline(ifs,line)) { if(line[0]=='#') continue; string fname; Int_t color, linesty; stringstream ss(line); ss >> fname >> color >> linesty; string label = line.substr(line.find('@')+1); fnamev.push_back(fname); labelv.push_back(label); colorv.push_back(color); linev.push_back(linesty); } ifs.close(); // Create output directory gSystem->mkdir(outputDir,kTRUE); TH2D *h=0; // // HLT efficiency // cout << "Loading trigger efficiencies..." << endl; TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos); CEffUser2D dataHLTEff_pos; dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt")); TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg); CEffUser2D dataHLTEff_neg; dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt")); TFile *zeeHLTEffFile_pos = new TFile(zeeHLTEffName_pos); CEffUser2D zeeHLTEff_pos; zeeHLTEff_pos.loadEff((TH2D*)zeeHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrhEtaPt")); TFile *zeeHLTEffFile_neg = new TFile(zeeHLTEffName_neg); CEffUser2D zeeHLTEff_neg; zeeHLTEff_neg.loadEff((TH2D*)zeeHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrhEtaPt")); h =(TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"); TH2D *hHLTErr_pos = new TH2D("hHLTErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); TH2D *hHLTErr_neg = new TH2D("hHLTErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); // // Selection efficiency // cout << "Loading GSF+selection efficiencies..." << endl; TFile *dataGsfSelEffFile_pos = new TFile(dataGsfSelEffName_pos); CEffUser2D dataGsfSelEff_pos; dataGsfSelEff_pos.loadEff((TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrhEtaPt")); TFile *dataGsfSelEffFile_neg = new TFile(dataGsfSelEffName_neg); CEffUser2D dataGsfSelEff_neg; dataGsfSelEff_neg.loadEff((TH2D*)dataGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrhEtaPt")); TFile *zeeGsfSelEffFile_pos = new TFile(zeeGsfSelEffName_pos); CEffUser2D zeeGsfSelEff_pos; zeeGsfSelEff_pos.loadEff((TH2D*)zeeGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrhEtaPt")); TFile *zeeGsfSelEffFile_neg = new TFile(zeeGsfSelEffName_neg); CEffUser2D zeeGsfSelEff_neg; zeeGsfSelEff_neg.loadEff((TH2D*)zeeGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrhEtaPt")); h =(TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"); TH2D *hGsfSelErr_pos = new TH2D("hGsfSelErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); TH2D *hGsfSelErr_neg = new TH2D("hGsfSelErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(), h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax()); // Data structures to store info from TTrees mithep::TEventInfo *info = new mithep::TEventInfo(); mithep::TGenInfo *gen = new mithep::TGenInfo(); TClonesArray *electronArr = new TClonesArray("mithep::TElectron"); TFile *infile=0; TTree *eventTree=0; // Variables to store acceptances and uncertainties (per input file) vector<Double_t> nEvtsv, nSelv, nSelCorrv; vector<Double_t> statErr2v, effErr2v; vector<Double_t> accv, accCorrv; vector<Double_t> accErrv, accCorrErrv; // // loop through files // for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { // Read input file and get the TTrees cout << "Processing " << fnamev[ifile] << " ..." << endl; infile = new TFile(fnamev[ifile]); assert(infile); eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Gen", &gen); TBranch *genBr = eventTree->GetBranch("Gen"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); nEvtsv.push_back(0); nSelv.push_back(0); nSelCorrv.push_back(0); statErr2v.push_back(0); // // loop over events // for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { genBr->GetEntry(ientry); if(gen->vmass<MASS_LOW || gen->vmass>MASS_HIGH) continue; infoBr->GetEntry(ientry); Double_t weight=1; nEvtsv[ifile]+=weight; // trigger requirement ULong_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL; ULong_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj; if(!(info->triggerBits & trigger)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; electronArr->Clear(); electronBr->GetEntry(ientry); for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) { const mithep::TElectron *ele1 = (mithep::TElectron*)((*electronArr)[i1]); // check ECAL gap if(fabs(ele1->scEta)>=ETA_BARREL && fabs(ele1->scEta)<=ETA_ENDCAP) continue; if(ele1->scEt < PT_CUT) continue; // lepton pT cut if(fabs(ele1->scEta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(ele1,info->rhoLowEta)) continue; // lepton selection LorentzVector vEle1(ele1->pt, ele1->eta, ele1->phi, ELE_MASS); Bool_t isB1 = (fabs(ele1->scEta)<ETA_BARREL) ? kTRUE : kFALSE; for(Int_t i2=i1+1; i2<electronArr->GetEntriesFast(); i2++) { const mithep::TElectron *ele2 = (mithep::TElectron*)((*electronArr)[i2]); // check ECAL gap if(fabs(ele2->scEta)>=ETA_BARREL && fabs(ele2->scEta)<=ETA_ENDCAP) continue; if(ele2->scEt < PT_CUT) continue; // lepton pT cut if(fabs(ele2->scEta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(ele2,info->rhoLowEta)) continue; // lepton selection LorentzVector vEle2(ele2->pt, ele2->eta, ele2->phi, ELE_MASS); Bool_t isB2 = (fabs(ele2->scEta)<ETA_BARREL) ? kTRUE : kFALSE; // trigger match if(!(ele1->hltMatchBits & trigObj) && !(ele2->hltMatchBits & trigObj)) continue; // mass window LorentzVector vDilep = vEle1 + vEle2; if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue; /******** We have a Z candidate! HURRAY! ********/ Double_t effdata, effmc; Double_t sceta1 = (fabs(ele1->scEta)<2.5) ? ele1->scEta : 0.99*(ele1->scEta); Double_t sceta2 = (fabs(ele2->scEta)<2.5) ? ele2->scEta : 0.99*(ele2->scEta); Double_t corr=1; effdata=1; effmc=1; if(ele1->q>0) { effdata *= (1.-dataHLTEff_pos.getEff(sceta1, ele1->scEt)); effmc *= (1.-zeeHLTEff_pos.getEff(sceta1, ele1->scEt)); } else { effdata *= (1.-dataHLTEff_neg.getEff(sceta1, ele1->scEt)); effmc *= (1.-zeeHLTEff_neg.getEff(sceta1, ele1->scEt)); } if(ele2->q>0) { effdata *= (1.-dataHLTEff_pos.getEff(sceta2, ele2->scEt)); effmc *= (1.-zeeHLTEff_pos.getEff(sceta2, ele2->scEt)); } else { effdata *= (1.-dataHLTEff_neg.getEff(sceta2, ele2->scEt)); effmc *= (1.-zeeHLTEff_neg.getEff(sceta2, ele2->scEt)); } effdata = 1.-effdata; effmc = 1.-effmc; corr *= effdata/effmc; effdata=1; effmc=1; if(ele1->q>0) { effdata *= dataGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); effmc *= zeeGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); } else { effdata *= dataGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); effmc *= zeeGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); } if(ele2->q>0) { effdata *= dataGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); effmc *= zeeGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); } else { effdata *= dataGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); effmc *= zeeGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); } corr *= effdata/effmc; nSelv[ifile]+=weight; nSelCorrv[ifile]+=weight*corr; statErr2v[ifile]+=weight*weight*corr*corr; // scale factor uncertainties // Double_t dataerr=0, mcerr=0; // if(ele1->q>0) { // effdata = dataGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); // errdata = TMath::Max(dataGsfSelEff_pos.getErrl(fabs(sceta1), ele1->scEt), dataGsfSelEff_pos.getErrh(fabs(sceta1), ele1->scEt)); // effmc = zeeGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); // errmc = TMath::Max(zeeGsfSelEff_pos.getErrl(fabs(sceta1), ele1->scEt), zeeGsfSelEff_pos.getErrh(fabs(sceta1), ele1->scEt)); // Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); // hGsfSelErr_pos->Fill(fabs(sceta1), ele1->scEt, errGsfSel); // // } else { // effdata = dataGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); // errdata = TMath::Max(dataGsfSelEff_neg.getErrl(fabs(sceta1), ele1->scEt), dataGsfSelEff_neg.getErrh(fabs(sceta1), ele1->scEt)); // effmc = zeeGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); // errmc = TMath::Max(zeeGsfSelEff_neg.getErrl(fabs(sceta1), ele1->scEt), zeeGsfSelEff_neg.getErrh(fabs(sceta1), ele1->scEt)); // Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); // hGsfSelErr_neg->Fill(fabs(sceta1), ele1->scEt, errGsfSel); // } // if(ele2->q>0) { // effdata = dataGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); // errdata = TMath::Max(dataGsfSelEff_pos.getErrl(fabs(sceta2), ele2->scEt), dataGsfSelEff_pos.getErrh(fabs(sceta2), ele2->scEt)); // effmc = zeeGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); // errmc = TMath::Max(zeeGsfSelEff_pos.getErrl(fabs(sceta2), ele2->scEt), zeeGsfSelEff_pos.getErrh(fabs(sceta2), ele2->scEt)); // Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); // hGsfSelErr_pos->Fill(fabs(sceta2), ele2->scEt, errGsfSel); // // } else { // effdata = dataGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); // errdata = TMath::Max(dataGsfSelEff_neg.getErrl(fabs(sceta2), ele2->scEt), dataGsfSelEff_neg.getErrh(fabs(sceta2), ele2->scEt)); // effmc = zeeGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); // errmc = TMath::Max(zeeGsfSelEff_neg.getErrl(fabs(sceta2), ele2->scEt), zeeGsfSelEff_neg.getErrh(fabs(sceta2), ele2->scEt)); // Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc); // hGsfSelErr_neg->Fill(fabs(sceta2), ele2->scEt, errGsfSel); // } } } } // Double_t err2=0; // for(Int_t iy=0; iy<=hGsfSelErr_pos->GetNbinsY(); iy++) { // for(Int_t ix=0; ix<=hGsfSelErr_pos->GetNbinsX(); ix++) { // err=hSelErr_pos->GetBinContent(ix,iy); // err2+=err*err; // } // } // for(Int_t iy=0; iy<=hGsfSelErr_neg->GetNbinsY(); iy++) { // for(Int_t ix=0; ix<=hGsfSelErr_neg->GetNbinsX(); ix++) { // err=hSelErr_neg->GetBinContent(ix,iy); // err2+=err*err; // } // } // effErr2v.push_back(err2); // compute acceptances accv.push_back(nSelv[ifile]/nEvtsv[ifile]); accErrv.push_back(sqrt(accv[ifile]*(1.-accv[ifile])/nEvtsv[ifile])); accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accCorrErrv.push_back(sqrt(accCorrv[ifile]*(1.-accCorrv[ifile])/nEvtsv[ifile])); delete infile; infile=0, eventTree=0; } delete info; delete gen; delete electronArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " Z -> e e" << endl; cout << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; cout << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { cout << " ================================================" << endl; cout << " Label: " << labelv[ifile] << endl; cout << " File: " << fnamev[ifile] << endl; cout << endl; cout << " *** Acceptance ***" << endl; cout << " nominal: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile] << endl; cout << " SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl; cout << endl; } char txtfname[100]; sprintf(txtfname,"%s/binned.txt",outputDir.Data()); ofstream txtfile; txtfile.open(txtfname); txtfile << "*" << endl; txtfile << "* SUMMARY" << endl; txtfile << "*--------------------------------------------------" << endl; txtfile << " Z -> e e" << endl; txtfile << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; txtfile << " pT > " << PT_CUT << endl; txtfile << " |eta| < " << ETA_CUT << endl; txtfile << endl; for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { txtfile << " ================================================" << endl; txtfile << " Label: " << labelv[ifile] << endl; txtfile << " File: " << fnamev[ifile] << endl; txtfile << endl; txtfile << " *** Acceptance ***" << endl; txtfile << " nominal: " << setw(12) << nSelv[ifile] << " / " << nEvtsv[ifile] << " = " << accv[ifile] << " +/- " << accErrv[ifile] << endl; txtfile << " SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl; txtfile << endl; } txtfile.close(); cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("computeAccSelZeeBinned"); }
void selectZee(const TString conf, // input file const TString outputDir, // output directory const Bool_t doScaleCorr // apply energy scale corrections? ) { gBenchmark->Start("selectZee"); //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== const Double_t MASS_LOW = 40; const Double_t MASS_HIGH = 200; const Double_t PT_CUT = 20; const Double_t ETA_CUT = 2.5; const Double_t ELE_MASS = 0.000511; const Double_t ECAL_GAP_LOW = 1.4442; const Double_t ECAL_GAP_HIGH = 1.566; const Double_t escaleNbins = 6; const Double_t escaleEta[] = { 0.4, 0.8, 1.2, 1.4442, 2, 2.5 }; const Double_t escaleCorr[] = { 1.00284, 1.00479, 1.00734, 1.00851, 1.00001, 0.982898 }; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== enum { eEleEle2HLT=1, eEleEle1HLT, eEleEleNoSel, eEleSC }; // event category enum vector<TString> snamev; // sample name (for output files) vector<CSample*> samplev; // data/MC samples // // parse .conf file // confParse(conf, snamev, samplev); const Bool_t hasData = (samplev[0]->fnamev.size()>0); // Create output directory gSystem->mkdir(outputDir,kTRUE); const TString ntupDir = outputDir + TString("/ntuples"); gSystem->mkdir(ntupDir,kTRUE); // // Declare output ntuple variables // UInt_t runNum, lumiSec, evtNum; UInt_t matchGen; UInt_t category; UInt_t npv, npu; Float_t genVPt, genVPhi, genVy, genVMass; Float_t scale1fb; Float_t met, metPhi, sumEt, u1, u2; Int_t q1, q2; LorentzVector *dilep=0, *lep1=0, *lep2=0; ///// electron specific ///// Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2; Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2; Float_t sigieie1, hovere1, eoverp1, fbrem1, ecalE1, sigieie2, hovere2, eoverp2, fbrem2, ecalE2; Float_t dphi1, deta1, dphi2, deta2; Float_t d01, dz1, d02, dz2; UInt_t isConv1, nexphits1, typeBits1, isConv2, nexphits2, typeBits2; LorentzVector *sc1=0, *sc2=0; // Data structures to store info from TTrees mithep::TEventInfo *info = new mithep::TEventInfo(); mithep::TGenInfo *gen = new mithep::TGenInfo(); TClonesArray *electronArr = new TClonesArray("mithep::TElectron"); TClonesArray *scArr = new TClonesArray("mithep::TPhoton"); TClonesArray *pvArr = new TClonesArray("mithep::TVertex"); TFile *infile=0; TTree *eventTree=0; // // loop over samples // for(UInt_t isam=0; isam<samplev.size(); isam++) { // Assume data sample is first sample in .conf file // If sample is empty (i.e. contains no ntuple files), skip to next sample if(isam==0 && !hasData) continue; // Assume signal sample is given name "zee" // If it's the signal sample, toggle flag to store GEN W kinematics Bool_t isSignal = (snamev[isam].CompareTo("zee",TString::kIgnoreCase)==0); CSample* samp = samplev[isam]; // // Set up output ntuple // TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root"); if(isam==0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root"); TFile *outFile = new TFile(outfilename,"RECREATE"); TTree *outTree = new TTree("Events","Events"); outTree->Branch("runNum", &runNum, "runNum/i"); // event run number outTree->Branch("lumiSec", &lumiSec, "lumiSec/i"); // event lumi section outTree->Branch("evtNum", &evtNum, "evtNum/i"); // event number outTree->Branch("matchGen", &matchGen, "matchGen/i"); // event has both leptons matched to MC Z->ll outTree->Branch("category", &category, "category/i"); // dilepton category outTree->Branch("npv", &npv, "npv/i"); // number of primary vertices outTree->Branch("npu", &npu, "npu/i"); // number of in-time PU events (MC) outTree->Branch("genVPt", &genVPt, "genVPt/F"); // GEN boson pT (signal MC) outTree->Branch("genVPhi", &genVPhi, "genVPhi/F"); // GEN boson phi (signal MC) outTree->Branch("genVy", &genVy, "genVy/F"); // GEN boson rapidity (signal MC) outTree->Branch("genVMass", &genVMass, "genVMass/F"); // GEN boson mass (signal MC) outTree->Branch("scale1fb", &scale1fb, "scale1fb/F"); // event weight per 1/fb (MC) outTree->Branch("met", &met, "met/F"); // MET outTree->Branch("metPhi", &metPhi, "metPhi/F"); // phi(MET) outTree->Branch("sumEt", &sumEt, "sumEt/F"); // Sum ET outTree->Branch("u1", &u1, "u1/F"); // parallel component of recoil outTree->Branch("u2", &u2, "u2/F"); // perpendicular component of recoil outTree->Branch("q1", &q1, "q1/I"); // charge of tag lepton outTree->Branch("q2", &q2, "q2/I"); // charge of probe lepton outTree->Branch("dilep", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &dilep); // dilepton 4-vector outTree->Branch("lep1", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep1); // tag lepton 4-vector outTree->Branch("lep2", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep2); // probe lepton 4-vector ///// electron specific ///// outTree->Branch("trkIso1", &trkIso1, "trkIso1/F"); // track isolation of tag lepton outTree->Branch("trkIso2", &trkIso2, "trkIso2/F"); // track isolation of probe lepton outTree->Branch("emIso1", &emIso1, "emIso1/F"); // ECAL isolation of tag lepton outTree->Branch("emIso2", &emIso2, "emIso2/F"); // ECAL isolation of probe lepton outTree->Branch("hadIso1", &hadIso1, "hadIso1/F"); // HCAL isolation of tag lepton outTree->Branch("hadIso2", &hadIso2, "hadIso2/F"); // HCAL isolation of probe lepton outTree->Branch("pfChIso1", &pfChIso1, "pfChIso1/F"); // PF charged hadron isolation of tag lepton outTree->Branch("pfChIso2", &pfChIso2, "pfChIso2/F"); // PF charged hadron isolation of probe lepton outTree->Branch("pfGamIso1", &pfGamIso1, "pfGamIso1/F"); // PF photon isolation of tag lepton outTree->Branch("pfGamIso2", &pfGamIso2, "pfGamIso2/F"); // PF photon isolation of probe lepton outTree->Branch("pfNeuIso1", &pfNeuIso1, "pfNeuIso1/F"); // PF neutral hadron isolation of tag lepton outTree->Branch("pfNeuIso2", &pfNeuIso2, "pfNeuIso2/F"); // PF neutral hadron isolation of probe lepton outTree->Branch("pfCombIso1", &pfCombIso1, "pfCombIso1/F"); // PF combine isolation of tag lepton outTree->Branch("pfCombIso2", &pfCombIso2, "pfCombIso2/F"); // PF combined isolation of probe lepton outTree->Branch("sigieie1", &sigieie1, "sigieie1/F"); // sigma-ieta-ieta of tag outTree->Branch("sigieie2", &sigieie2, "sigieie2/F"); // sigma-ieta-ieta of probe outTree->Branch("hovere1", &hovere1, "hovere1/F"); // H/E of tag outTree->Branch("hovere2", &hovere2, "hovere2/F"); // H/E of probe outTree->Branch("eoverp1", &eoverp1, "eoverp1/F"); // E/p of tag outTree->Branch("eoverp2", &eoverp2, "eoverp2/F"); // E/p of probe outTree->Branch("fbrem1", &fbrem1, "fbrem1/F"); // brem fraction of tag outTree->Branch("fbrem2", &fbrem2, "fbrem2/F"); // brem fraction of probe outTree->Branch("dphi1", &dphi1, "dphi1/F"); // GSF track - ECAL dphi of tag outTree->Branch("dphi2", &dphi2, "dphi2/F"); // GSF track - ECAL dphi of probe outTree->Branch("deta1", &deta1, "deta1/F"); // GSF track - ECAL deta of tag outTree->Branch("deta2", &deta2, "deta2/F"); // GSF track - ECAL deta of probe outTree->Branch("ecalE1", &ecalE1, "ecalE1/F"); // ECAL energy of tag outTree->Branch("ecalE2", &ecalE2, "ecalE2/F"); // ECAL energy of probe outTree->Branch("d01", &d01, "d01/F"); // transverse impact parameter of tag outTree->Branch("d02", &d02, "d02/F"); // transverse impact parameter of probe outTree->Branch("dz1", &dz1, "dz1/F"); // longitudinal impact parameter of tag outTree->Branch("dz2", &dz2, "dz2/F"); // longitudinal impact parameter of probe outTree->Branch("isConv1", &isConv1, "isConv1/i"); // conversion filter flag of tag lepton outTree->Branch("isConv2", &isConv2, "isConv2/i"); // conversion filter flag of probe lepton outTree->Branch("nexphits1", &nexphits1, "nexphits1/i"); // number of missing expected inner hits of tag lepton outTree->Branch("nexphits2", &nexphits2, "nexphits2/i"); // number of missing expected inner hits of probe lepton outTree->Branch("typeBits1", &typeBits1, "typeBits1/i"); // electron type of tag lepton outTree->Branch("typeBits2", &typeBits2, "typeBits2/i"); // electron type of probe lepton outTree->Branch("sc1", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc1); // tag Supercluster 4-vector outTree->Branch("sc2", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc2); // probe Supercluster 4-vector // // loop through files // const UInt_t nfiles = samp->fnamev.size(); for(UInt_t ifile=0; ifile<nfiles; ifile++) { // Read input file and get the TTrees cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush(); infile = new TFile(samp->fnamev[ifile]); assert(infile); Bool_t hasJSON = kFALSE; mithep::RunLumiRangeMap rlrm; if(samp->jsonv[ifile].CompareTo("NONE")!=0) { hasJSON = kTRUE; rlrm.AddJSONFile(samp->jsonv[ifile].Data()); } eventTree = (TTree*)infile->Get("Events"); assert(eventTree); eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron"); eventTree->SetBranchAddress("Photon", &scArr); TBranch *scBr = eventTree->GetBranch("Photon"); eventTree->SetBranchAddress("PV", &pvArr); TBranch *pvBr = eventTree->GetBranch("PV"); Bool_t hasGen = eventTree->GetBranchStatus("Gen"); TBranch *genBr=0; if(hasGen) { eventTree->SetBranchAddress("Gen", &gen); genBr = eventTree->GetBranch("Gen"); } // Compute MC event weight per 1/fb Double_t weight = 1; const Double_t xsec = samp->xsecv[ifile]; if(xsec>0) weight = 1000.*xsec/(Double_t)eventTree->GetEntries(); // // loop over events // Double_t nsel=0, nselvar=0; for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { infoBr->GetEntry(ientry); if(genBr) genBr->GetEntry(ientry); // check for certified lumi (if applicable) mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec); if(hasJSON && !rlrm.HasRunLumi(rl)) continue; // trigger requirement ULong64_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL; ULong64_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj; if(!(info->triggerBits & trigger)) continue; // good vertex requirement if(!(info->hasGoodPV)) continue; pvArr->Clear(); pvBr->GetEntry(ientry); // // SELECTION PROCEDURE: // (1) Find a good electron matched to trigger -> this will be the "tag" // (2) Pair the tag with Supercluster probes which form a tag+probe mass inside // the Z window and divide candidates into exclusive categories as follows: // (a) if probe SC is part of a good electron matched to trigger -> EleEle2HLT category // (b) if probe SC is part of a good electron not matched to trigger -> EleEle1HLT category // (c) if probe SC is part of an electron failing selection cuts -> EleEleNoSel category // (d) if probe SC is not part of an ECAL driven electron -> EleSC category // electronArr->Clear(); electronBr->GetEntry(ientry); scArr->Clear(); scBr->GetEntry(ientry); for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) { const mithep::TElectron *tag = (mithep::TElectron*)((*electronArr)[i1]); // check ECAL gap if(fabs(tag->scEta)>=ECAL_GAP_LOW && fabs(tag->scEta)<=ECAL_GAP_HIGH) continue; Double_t escale1=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(tag->scEta)<escaleEta[ieta]) { escale1 = escaleCorr[ieta]; break; } } } if(escale1*(tag->scEt) < PT_CUT) continue; // lepton pT cut if(fabs(tag->scEta) > ETA_CUT) continue; // lepton |eta| cut if(!passEleID(tag,info->rhoLowEta)) continue; // lepton selection if(!(tag->hltMatchBits & trigObj)) continue; // check trigger matching LorentzVector vTag(escale1*(tag->pt), tag->eta, tag->phi, ELE_MASS); LorentzVector vTagSC(escale1*(tag->scEt), tag->scEta, tag->scPhi, ELE_MASS); for(Int_t j=0; j<scArr->GetEntriesFast(); j++) { const mithep::TPhoton *scProbe = (mithep::TPhoton*)((*scArr)[j]); if(scProbe->scID == tag->scID) continue; // check ECAL gap if(fabs(scProbe->scEta)>=ECAL_GAP_LOW && fabs(scProbe->scEta)<=ECAL_GAP_HIGH) continue; Double_t escale2=1; if(doScaleCorr && isam==0) { for(UInt_t ieta=0; ieta<escaleNbins; ieta++) { if(fabs(scProbe->scEta)<escaleEta[ieta]) { escale2 = escaleCorr[ieta]; break; } } } if(escale2*(scProbe->pt) < PT_CUT) continue; // Supercluster ET cut ("pt" = corrected by PV position) if(fabs(scProbe->scEta) > ETA_CUT) continue; // Supercluster |eta| cuts const mithep::TElectron *eleProbe=0; Int_t iprobe=-1; for(Int_t i2=0; i2<electronArr->GetEntriesFast(); i2++) { if(i1==i2) continue; const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i2]); if(!(ele->typeBits & kEcalDriven)) continue; if(scProbe->scID==ele->scID) { eleProbe = ele; iprobe = i2; break; } } LorentzVector vProbe((eleProbe) ? escale2*(eleProbe->pt) : escale2*(scProbe->pt), (eleProbe) ? eleProbe->eta : scProbe->eta, (eleProbe) ? eleProbe->phi : scProbe->phi, ELE_MASS); LorentzVector vProbeSC((eleProbe) ? escale2*(eleProbe->scEt) : escale2*(scProbe->pt), scProbe->scEta, scProbe->scPhi, ELE_MASS); // mass window LorentzVector vDilep = vTag + vProbe; if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue; // determine event category UInt_t icat=0; if(eleProbe) { if(passEleID(eleProbe,info->rhoLowEta)) { if(eleProbe->hltMatchBits & trigObj) { if(i1>iprobe) continue; // make sure we don't double count EleEle2HLT category icat=eEleEle2HLT; } else { icat=eEleEle1HLT; } } else { icat=eEleEleNoSel; } } else { icat=eEleSC; } if(icat==0) continue; /******** We have a Z candidate! HURRAY! ********/ nsel+=weight; nselvar+=weight*weight; // Perform matching of dileptons to GEN leptons from Z decay Bool_t hasGenMatch = kFALSE; if(isSignal) { Bool_t match1 = ( (abs(gen->id_1)==EGenType::kElectron) && ((toolbox::deltaR(tag->eta, tag->phi, gen->eta_1, gen->phi_1) < 0.5)) ) || ( (abs(gen->id_2)==EGenType::kElectron) && ((toolbox::deltaR(tag->eta, tag->phi, gen->eta_2, gen->phi_2) < 0.5)) ); Bool_t match2 = ( (abs(gen->id_1)==EGenType::kElectron) && ((toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), gen->eta_1, gen->phi_1) < 0.5)) ) || ( (abs(gen->id_2)==EGenType::kElectron) && ((toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), gen->eta_2, gen->phi_2) < 0.5)) ); if(match1 && match2) hasGenMatch = kTRUE; }; // // Fill tree // runNum = info->runNum; lumiSec = info->lumiSec; evtNum = info->evtNum; matchGen = hasGenMatch ? 1 : 0; category = icat; npv = pvArr->GetEntriesFast(); npu = info->nPU; genVPt = (hasGen) ? gen->vpt : 0; genVPhi = (hasGen) ? gen->vphi : 0; genVy = (hasGen) ? gen->vy : 0; genVMass = (hasGen) ? gen->vmass : 0; scale1fb = weight; met = info->pfMET; metPhi = info->pfMETphi; sumEt = info->pfSumET; lep1 = &vTag; q1 = tag->q; lep2 = &vProbe; q2 = (eleProbe) ? eleProbe->q : -(tag->q); dilep = &vDilep; TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi())); TVector2 vMet((info->pfMET)*cos(info->pfMETphi), (info->pfMET)*sin(info->pfMETphi)); TVector2 vU = -1.0*(vMet+vZPt); u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt()); // u1 = (pT . u)/|pT| u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt()); // u2 = (pT x u)/|pT| ///// electron specific ///// sc1 = &vTagSC; trkIso1 = tag->trkIso03; emIso1 = tag->emIso03; hadIso1 = tag->hadIso03; pfChIso1 = tag->pfChIso03; pfGamIso1 = tag->pfGamIso03; pfNeuIso1 = tag->pfNeuIso03; pfCombIso1 = tag->pfChIso03 + TMath::Max(tag->pfNeuIso03 + tag->pfGamIso03 - (info->rhoLowEta)*getEffArea(tag->scEta), 0.); sigieie1 = tag->sigiEtaiEta; hovere1 = tag->HoverE; eoverp1 = tag->EoverP; fbrem1 = tag->fBrem; dphi1 = tag->deltaPhiIn; deta1 = tag->deltaEtaIn; ecalE1 = tag->ecalE; d01 = tag->d0; dz1 = tag->dz; isConv1 = tag->isConv; nexphits1 = tag->nExpHitsInner; typeBits1 = tag->typeBits; sc2 = &vProbeSC; trkIso2 = (eleProbe) ? eleProbe->trkIso03 : -1; emIso2 = (eleProbe) ? eleProbe->emIso03 : -1; hadIso2 = (eleProbe) ? eleProbe->hadIso03 : -1; pfChIso2 = (eleProbe) ? eleProbe->pfChIso03 : -1; pfGamIso2 = (eleProbe) ? eleProbe->pfGamIso03 : -1; pfNeuIso2 = (eleProbe) ? eleProbe->pfNeuIso03 : -1; pfCombIso2 = (eleProbe) ? eleProbe->pfChIso03 + TMath::Max(eleProbe->pfNeuIso03 + eleProbe->pfGamIso03 - (info->rhoLowEta)*getEffArea(eleProbe->scEta), 0.) : -1; sigieie2 = (eleProbe) ? eleProbe->sigiEtaiEta : scProbe->sigiEtaiEta; hovere2 = (eleProbe) ? eleProbe->HoverE : scProbe->HoverE; eoverp2 = (eleProbe) ? eleProbe->EoverP : -1; fbrem2 = (eleProbe) ? eleProbe->fBrem : -1; dphi2 = (eleProbe) ? eleProbe->deltaPhiIn : -999; deta2 = (eleProbe) ? eleProbe->deltaEtaIn : -999; ecalE2 = (eleProbe) ? eleProbe->ecalE : -999; d02 = (eleProbe) ? eleProbe->d0 : -999; dz2 = (eleProbe) ? eleProbe->dz : -999; isConv2 = (eleProbe) ? eleProbe->isConv : 0; nexphits2 = (eleProbe) ? eleProbe->nExpHitsInner : 0; typeBits2 = (eleProbe) ? eleProbe->typeBits : 0; outTree->Fill(); } } } delete infile; infile=0, eventTree=0; cout << nsel << " +/- " << sqrt(nselvar); if(isam!=0) cout << " per 1/fb"; cout << endl; } outFile->Write(); outFile->Close(); } delete info; delete gen; delete electronArr; delete scArr; delete pvArr; //-------------------------------------------------------------------------------------------------------------- // Output //============================================================================================================== cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << " Z -> e e" << endl; cout << " Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl; cout << " pT > " << PT_CUT << endl; cout << " |eta| < " << ETA_CUT << endl; if(doScaleCorr) cout << " *** Scale corrections applied ***" << endl; cout << endl; cout << endl; cout << " <> Output saved in " << outputDir << "/" << endl; cout << endl; gBenchmark->Show("selectZee"); }