ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitHzz4l/NonMCBackground/src/select_fakes.cc
Revision: 1.16
Committed: Mon Dec 17 17:25:55 2012 UTC (12 years, 5 months ago) by dkralph
Content type: text/plain
Branch: MAIN
CVS Tags: compiled
Changes since 1.15: +11 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 dkralph 1.2 //
2     // System headers
3     //
4     #include <vector> // STL vector class
5     #include <iostream> // standard I/O
6     #include <iomanip> // functions to format standard I/O
7     #include <bitset>
8     #include <map>
9     using namespace std;
10    
11     //
12     // root headers
13     //
14     #include <TFile.h>
15     #include <TTree.h>
16     #include <TChain.h>
17     #include <TBranch.h>
18     #include <TClonesArray.h>
19    
20     //
21     // TMVA
22     //
23     #include "TMVA/Reader.h"
24     #include "TMVA/Tools.h"
25     #include "TMVA/Config.h"
26     #include "TMVA/MethodBDT.h"
27    
28     //
29     // ntuple format headers
30     //
31     #include "EventHeader.h"
32     #include "PFMet.h"
33     #include "Electron.h"
34     #include "Muon.h"
35 dkralph 1.15 #include "ChargedParticle.h"
36 dkralph 1.2 #include "Vertex.h"
37     #include "PFCandidate.h"
38     #include "PFCandidateCol.h"
39     #include "PileupInfoCol.h"
40     #include "PileupEnergyDensity.h"
41     #include "MCParticle.h"
42     #include "MCEventInfo.h"
43     #include "TriggerMask.h"
44     #include "TriggerTable.h"
45     #include "Names.h"
46     #include "BaseMod.h"
47    
48     //
49     // our headers
50     //
51     #include "ParseArgs.h"
52     #include "MuonSelection.h"
53     #include "ElectronSelection.h"
54     #include "IsolationSelection.h"
55 dkralph 1.3 #include "SelectionFuncs.h"
56 dkralph 1.9 #include "CommonDefs.h"
57     #include "Angles.h"
58     #include "AngleTuple.h"
59     #include "FOTuple.h"
60 dkralph 1.2 #include "TriggerUtils.h"
61     #include "PassHLT.h"
62     #include "RunLumiRangeMap.h"
63 dkralph 1.3 #include "fake_defs.h"
64 dkralph 1.5 #include "Various.h"
65 dkralph 1.15 #include "SampleWeight.h"
66 dkralph 1.2 #include "CommonDefs.h"
67    
68     #ifndef CMSSW_BASE
69     #define CMSSW_BASE "../"
70     #endif
71    
72     using namespace mithep;
73     //
74     // globals
75     //----------------------------------------------------------------------------
76 khahn 1.6 TH1D *hpu_2011, *hpu_2012;
77 dkralph 1.15 RunLumiRangeMap rlrm;
78 dkralph 1.2 vector<SimpleLepton> failingLeptons ; // for fake estimation
79     vector<SimpleLepton> passingLeptons; // for fake estimation
80     vector<unsigned> cutvec;
81     vector<vector<unsigned> > zcutvec;
82     vector<vector<unsigned> > zzcutvec;
83     map<unsigned,float> evtrhoMap;
84     vector<string> cutstrs;
85     bool passes_HLT_MC;
86     vector<bool> PFnoPUflag;;
87    
88     //
89     // prototypes
90     //----------------------------------------------------------------------------
91 dkralph 1.15 bool passResKill(const Muon *zmu1, const Muon *zmu2, const Electron *zele1, const Electron *zele2,
92     const Muon *mu, const Electron *ele);
93     bool passGhost(vector<const Muon*> goodMuons, const Muon *mu);
94     SelectionStatus denominatorSelection(ControlFlags &ctrl, const Muon *mu, const Electron *ele, const Vertex *vtx, Array<PFCandidate> *pfArr);
95     SelectionStatus analysisSelection(ControlFlags &ctrl, const Muon *mu, const Vertex *vtx, Array<PFCandidate> *pfArr,
96     Array<PileupEnergyDensity> *puDArr);
97     SelectionStatus analysisSelection(ControlFlags &ctrl, const Electron *ele, const Vertex *vtx, Array<PFCandidate> *pfArr,
98     Array<PileupEnergyDensity> *puDArr);
99 dkralph 1.7 void initRunLumiRangeMap(ControlFlags &ctrl);
100 dkralph 1.15 float getMass(const Muon *zmu1, const Muon *zmu2, const Electron *zele1, const Electron *zele2);
101     MuonTools::EMuonEffectiveAreaTarget eraMu;
102     ElectronTools::EElectronEffectiveAreaTarget eraEle;
103     vector<const PFCandidate*> photonsToVeto;
104 dkralph 1.9 vector<SimpleLepton> findFakes(ControlFlags &ctrl,
105 dkralph 1.15 Array<Muon> *muonArr,
106     Array<Electron> *electronArr,
107     Array<PFJet> *jetArr,
108     Array<PFCandidate> *pfArr,
109     Array<PileupInfo> *puArr,
110     Array<PileupEnergyDensity> *puDArr,
111     Array<Vertex> *vtxArr,
112     const Vertex *vtx,
113     const Muon *zmu1,
114     const Muon *zmu2,
115     const Electron *zele1,
116     const Electron *zele2);
117 dkralph 1.14 SimpleLepton fillSimpleLepton(const Muon *mu, const Electron *ele, SelectionStatus *ctrl, const Vertex *vtx);
118 dkralph 1.1 //=== MAIN =================================================================================================
119     int main(int argc, char** argv)
120     {
121 dkralph 1.2
122     string cmsswpath(CMSSW_BASE);
123     cmsswpath.append("/src");
124     std::bitset<1024> triggerBits;
125 dkralph 1.1 vector<vector<string> > inputFiles;
126     inputFiles.push_back(vector<string>());
127 dkralph 1.2 map<string,unsigned> entrymap; // number of unskimmed entries in each file
128 dkralph 1.1
129     //
130     // args
131     //--------------------------------------------------------------------------------------------------------------
132     ControlFlags ctrl;
133     parse_args( argc, argv, ctrl );
134     ctrl.dump();
135    
136     //
137     // File I/O
138     //--------------------------------------------------------------------------------------------------------------
139     TChain * chain = new TChain("Events");
140 dkralph 1.2 TChain * hltchain = new TChain("HLT");
141    
142 dkralph 1.1 string fname;
143 dkralph 1.2 unsigned total_unskimmed=0;
144     if( !ctrl.inputfiles.empty() ) {
145     ifstream f(ctrl.inputfiles.c_str());
146     while (f >> fname) {
147     if( !(strncmp( fname.c_str(), "#", 1 ) ) ) continue; // skip commented lines
148 dkralph 1.15 if(fname.find("/store/") != string::npos) fname = "root://eoscms//"+fname;
149 dkralph 1.2 cout << "adding inputfile : " << fname.c_str() << endl;
150     entrymap[string(fname.c_str())] = unskimmedEntries(fname.c_str());
151     total_unskimmed += entrymap[string(fname.c_str())];
152     chain->AddFile(fname.c_str());
153     hltchain->AddFile(fname.c_str());
154     }
155     } else {
156 dkralph 1.15 if(ctrl.inputfile.find("/store/") != string::npos) ctrl.inputfile = "root://eoscms//"+ctrl.inputfile;
157 dkralph 1.2 cout << "adding inputfile : " << ctrl.inputfile.c_str() << endl;
158     unsigned unsk_ents = unskimmedEntries(ctrl.inputfile.c_str());
159     entrymap[string(ctrl.inputfile.c_str())] = unsk_ents;
160     total_unskimmed += unsk_ents;
161     chain->AddFile(ctrl.inputfile.c_str());
162     hltchain->AddFile(ctrl.inputfile.c_str());
163 dkralph 1.1 }
164 dkralph 1.2 // write the total number of unskimmed events that went into making this output file to a text file
165     writeEntries(ctrl,total_unskimmed);
166 dkralph 1.1
167 dkralph 1.9 UInt_t nEvents=0,nMuDenom=0,nMuNumer=0,nEleDenom=0,nEleNumer=0;
168 dkralph 1.1
169 dkralph 1.9 // move this to compute_fakes
170     // double metMax = 25;
171 dkralph 1.1
172     //
173     // Setup
174     //--------------------------------------------------------------------------------------------------------------
175     const char * ofname;
176     if( strcmp( ctrl.outputfile.c_str(), "") ) {
177     ofname = ctrl.outputfile.c_str();
178     } else {
179     ofname = "fo.root";
180     }
181    
182 dkralph 1.9 // TFile *outFile = new TFile(ofname, "RECREATE");
183    
184     Angles angles;
185     KinematicsStruct kinematics;
186     InfoStruct evtinfo;
187     // GenInfoStruct geninfo;
188    
189     AngleTuple nt( (const char*)ofname, (const char*)"zznt");
190     nt.makeAngleBranch(angles);
191     nt.makeKinematicsBranch(kinematics);
192     nt.makeInfoBranch(evtinfo);
193    
194     vector<SimpleLepton> failingLeptons,passingLeptons;
195     FOTuple foTree( nt.getFile(), (const char*)"FOtree");
196     foTree.makeFailedLeptonBranch(failingLeptons);
197     foTree.makePassedLeptonBranch(passingLeptons);
198    
199     NtuplerBase foFlatTree( nt.getFile(), (const char*)"FO");
200     const char * brname = "FO";
201     const char * varlist = VAR_LIST_FOINFO;
202     foinfo foi;
203     foFlatTree.makeBranch( brname, (void*) &foi, varlist);
204 dkralph 1.2
205     // initMuonIDMVA();
206 dkralph 1.9 // getEATargets(ctrl,eraMu,eraEle);
207 dkralph 1.2 initElectronIDMVAV1();
208 dkralph 1.15 // initMuonIsoMVA();
209     // initElectronIDMVA();
210     // initElectronIsoMVA();
211 dkralph 1.2 initTrigger();
212     if(!ctrl.mc)
213 dkralph 1.7 initRunLumiRangeMap(ctrl);
214 dkralph 1.1
215     //
216     // Access samples and fill histograms
217     TFile *inputFile=0;
218     TTree *eventTree=0;
219 dkralph 1.2 string currentFile("");
220 dkralph 1.1
221 dkralph 1.15 EventHeader *info = new EventHeader();
222     Array<PFMet> *metArr = new Array<PFMet>();
223     Array<Electron> *electronArr = new Array<Electron>();
224     Array<Muon> *muonArr = new Array<Muon>();
225     Array<Vertex> *vtxArr = new Array<Vertex>();
226     Array<PFCandidate> *pfArr = new Array<PFCandidate>();
227     Array<PFJet> *jetArr = new Array<PFJet>();
228     Array<PileupInfo> *puArr = new Array<PileupInfo>();
229     Array<PileupEnergyDensity> *puDArr = new Array<PileupEnergyDensity>();
230     Array<Track> *trkArr = new Array<Track>();
231     Array<MCParticle> *mcArr = new Array<MCParticle>();
232     MCEventInfo *mcEvtInfo = new MCEventInfo();
233     TriggerMask *trigMask = new TriggerMask();
234     TriggerTable *hltTable = new TriggerTable();
235 dkralph 1.2 vector<string> *hltTableStrings = new vector<string>();
236    
237     TString fElectronName(Names::gkElectronBrn);
238     TString fMuonName(Names::gkMuonBrn);
239     TString fInfoName(Names::gkEvtHeaderBrn);
240     TString fPFMetName("PFMet");
241     TString fPrimVtxName(Names::gkPVBrn);
242     TString fPFCandidateName(Names::gkPFCandidatesBrn);
243     TString fPFJetName(Names::gkPFJetBrn);
244     TString fPileupInfoName(Names::gkPileupInfoBrn);
245     TString fPileupEnergyDensityName(Names::gkPileupEnergyDensityBrn);
246     TString fTrackName(Names::gkTrackBrn);
247     TString fMCParticleName(Names::gkMCPartBrn);
248     TString fMCEvtInfoName(Names::gkMCEvtInfoBrn);
249     TString fTriggerMaskName(Names::gkHltBitBrn);
250     TString fTriggerTableName(Names::gkHltTableBrn);
251    
252     chain->SetBranchAddress(fInfoName, &info);
253     chain->SetBranchAddress(fPFMetName, &metArr);
254     chain->SetBranchAddress(fElectronName, &electronArr);
255     chain->SetBranchAddress(fMuonName, &muonArr);
256     chain->SetBranchAddress(fPrimVtxName, &vtxArr);
257     chain->SetBranchAddress(fPFCandidateName, &pfArr);
258     chain->SetBranchAddress(fPFJetName, &jetArr);
259     if( ctrl.mc ) {
260     chain->SetBranchAddress(fPileupInfoName, &puArr);
261     chain->SetBranchAddress(fMCParticleName, &mcArr);
262     chain->SetBranchAddress(fMCEvtInfoName, &mcEvtInfo);
263     }
264     chain->SetBranchAddress(fPileupEnergyDensityName, &puDArr);
265     chain->SetBranchAddress(fTrackName, &trkArr);
266     chain->SetBranchAddress(fTriggerMaskName, &trigMask);
267     cout << "hlttable: " << fTriggerTableName << endl;
268     hltchain->SetBranchAddress(fTriggerTableName, &hltTableStrings);
269    
270 dkralph 1.15 const Vertex *vtx; // best primary vertex in the event
271 dkralph 1.1
272 dkralph 1.2 // ginfo = NULL;
273     // if( ctrl.mc ) { chain->SetBranchAddress("Gen", &ginfo);}
274    
275     // only 1 HLT table / file ???
276     hltchain->GetEntry(0);
277    
278     int imax = chain->GetEntries();
279     cout << "nEntries: " << imax << endl;
280 dkralph 1.1 for(UInt_t ientry=0; ientry<imax; ientry++) {
281     chain->GetEntry(ientry);
282 dkralph 1.2 if(!(ientry%10000)) cout << "entry: " << ientry << "\tfrac: " << setw(15) << float(ientry)/chain->GetEntries() << endl;
283    
284 dkralph 1.9 string fname = string(chain->GetFile()->GetEndpointUrl()->GetFile());
285     if( ctrl.era == 0 )
286     setEra( fname, ctrl );
287     getEATargets(ctrl,eraMu,eraEle);
288    
289 dkralph 1.2 // pfNoPU
290     PFnoPUflag.clear();
291     int pfnopu_size = makePFnoPUArray( pfArr, PFnoPUflag, vtxArr );
292     assert(pfnopu_size == pfArr->GetEntries());
293    
294 dkralph 1.7 if(!(ctrl.noJSON) ) {
295     RunLumiRangeMap::RunLumiPairType rl(info->RunNum(), info->LumiSec());
296     if( !(rlrm.HasRunLumi(rl)) ) continue;
297     }
298 dkralph 1.2
299 dkralph 1.9 nEvents++;
300 dkralph 1.1
301 dkralph 1.10 bool goodVertex = setPV( ctrl, vtxArr, vtx );
302     if(!goodVertex) continue;
303 dkralph 1.1
304 dkralph 1.2 // good lepton selection
305 dkralph 1.9 failingLeptons.clear();
306     passingLeptons.clear();
307 dkralph 1.15 vector<const Muon*> goodMuons;
308     vector<const Electron*> goodElectrons;
309 dkralph 1.9 vector<SelectionStatus> muselv,eleselv;
310 dkralph 1.2 for(int imu=0; imu<muonArr->GetEntries(); imu++) {
311 dkralph 1.15 const Muon *mu = (*muonArr)[imu];
312 dkralph 1.11 SelectionStatus denomsel;
313 dkralph 1.15 denomsel |= denominatorSelection(ctrl,mu,NULL,vtx,pfArr);
314 dkralph 1.11 if( !denomsel.passPre() ) continue;
315 dkralph 1.15 if(!passGhost(goodMuons,mu)) continue;
316 dkralph 1.9 SelectionStatus status = analysisSelection(ctrl,mu,vtx,pfArr,puDArr);
317     if(status.loose()) {
318     goodMuons.push_back(mu);
319     muselv.push_back(status);
320 dkralph 1.14 passingLeptons.push_back(fillSimpleLepton(mu,&status,vtx));
321 dkralph 1.9 } else {
322 dkralph 1.14 failingLeptons.push_back(fillSimpleLepton(mu,&status,vtx));
323 dkralph 1.9 }
324 dkralph 1.2 }
325 dkralph 1.1 for(Int_t i=0; i<electronArr->GetEntries(); i++) {
326 dkralph 1.15 const Electron *ele = (*electronArr)[i];
327 dkralph 1.4 bool muonMatch=false;
328     for(unsigned imu=0; imu<muonArr->GetEntries(); imu++) {
329 dkralph 1.15 const Muon *mu = (*muonArr)[imu];
330 dkralph 1.4 if(dr(mu,ele) < 0.05) muonMatch = true;
331     }
332 dkralph 1.9 if(muonMatch) continue;
333 dkralph 1.11 SelectionStatus denomsel;
334 dkralph 1.15 denomsel |= denominatorSelection(ctrl,NULL,ele,vtx,NULL);
335 dkralph 1.11 if( !denomsel.passPre() ) continue;
336 dkralph 1.9 SelectionStatus status = analysisSelection(ctrl,ele,vtx,pfArr,puDArr);
337     if(status.loose()) {
338     goodElectrons.push_back(ele);
339     eleselv.push_back(status);
340 dkralph 1.14 passingLeptons.push_back(fillSimpleLepton(ele,&status,vtx));
341 dkralph 1.9 } else {
342 dkralph 1.14 failingLeptons.push_back(fillSimpleLepton(ele,&status,vtx));
343 dkralph 1.9 }
344 dkralph 1.1 }
345    
346 dkralph 1.2 // look for z pairs
347     int NZCandidates=0;
348 dkralph 1.9 float bestMass=-999;
349 dkralph 1.15 const Muon *zmu1=0,*zmu2=0;
350     const Electron *zele1=0,*zele2=0;
351 dkralph 1.9 SelectionStatus *status1,*status2;
352 dkralph 1.2 for(unsigned imu=0; imu<goodMuons.size(); imu++) {
353     for(unsigned jmu=imu+1; jmu<goodMuons.size(); jmu++) {
354     if(goodMuons[imu]->Charge() == goodMuons[jmu]->Charge()) continue;
355 dkralph 1.15 float mass = getMass(goodMuons[imu],goodMuons[jmu],NULL,NULL);
356 dkralph 1.9 if( fabs(mass - Z_MASS) < fabs(bestMass - Z_MASS)) {
357     bestMass = mass;
358     zmu1 = goodMuons[imu]; status1 = &muselv[imu];
359     zmu2 = goodMuons[jmu]; status2 = &muselv[jmu];
360     }
361 dkralph 1.2 }
362     }
363     for(unsigned iele=0; iele<goodElectrons.size(); iele++) {
364     for(unsigned jele=iele+1; jele<goodElectrons.size(); jele++) {
365     if(goodElectrons[iele]->Charge() == goodElectrons[jele]->Charge()) continue;
366 dkralph 1.15 float mass = getMass(NULL,NULL,goodElectrons[iele],goodElectrons[jele]);
367 dkralph 1.9 if( fabs(mass - Z_MASS) < fabs(bestMass - Z_MASS)) {
368     bestMass = mass;
369     zele1 = goodElectrons[iele]; status1 = &eleselv[iele];
370     zele2 = goodElectrons[jele]; status2 = &eleselv[jele];
371     zmu1 = zmu2 = 0;
372     }
373 dkralph 1.1 }
374 dkralph 1.2 }
375 dkralph 1.9 if(bestMass < 0) continue;
376     assert( (zmu1 && zmu2) || (zele1 && zele2));
377     assert( !(zmu1!=0 && zele1!=0) );
378     assert( !(zmu2!=0 && zele2!=0) );
379    
380     EventData data;
381 dkralph 1.14 data.Z1leptons.push_back(fillSimpleLepton(zmu1,zele1,status1,vtx));
382     data.Z1leptons.push_back(fillSimpleLepton(zmu2,zele2,status2,vtx));
383     data.Z2leptons.push_back(fillSimpleLepton(zmu1,zele1,status1,vtx));
384     data.Z2leptons.push_back(fillSimpleLepton(zmu2,zele2,status2,vtx));
385 dkralph 1.9
386     // loop over fakes
387     vector<SimpleLepton> fakes = findFakes(ctrl,muonArr,electronArr,jetArr,pfArr,puArr,puDArr,vtxArr,vtx,zmu1,zmu2,zele1,zele2);
388 dkralph 1.10 //????????????????????????????????????????????????????????????????????????????????????????
389     // if(fakes.size() > 1) continue;
390     //????????????????????????????????????????????????????????????????????????????????????????
391 dkralph 1.9 for(unsigned ifake=0; ifake<fakes.size(); ifake++) {
392     SimpleLepton fake = fakes[ifake];
393 dkralph 1.2
394 dkralph 1.9 if(abs(fake.type) == 13) {
395     nMuDenom++;
396     if(fake.isLoose) nMuNumer++;
397     } else {
398     nEleDenom++;
399     if(fake.isLoose) nEleNumer++;
400     }
401 dkralph 1.1
402 dkralph 1.9 // fill output TTree
403 dkralph 1.10 fillKinematics(data,kinematics);
404     TLorentzVector pfmet; pfmet.SetPxPyPzE(metArr->At(0)->Mex(),metArr->At(0)->Mey(),0,0);
405     fillEventInfo( info, pfmet, evtinfo, ctrl.mc ? getNPU(puArr) : 0, vtxArr->GetEntries());
406     foTree.Fill();
407     nt.Fill();
408    
409 dkralph 1.9 foi.run = info->RunNum();
410     foi.evt = info->EvtNum();
411     foi.lumi = info->LumiSec();
412     foi.type = fake.type;
413     foi.npu = ctrl.mc ? getNPU(puArr) : 0;
414     foi.npv = vtxArr->GetEntries(); // note: should maybe apply some selection here
415     foi.fopt = fake.vec.Pt();
416     foi.foeta = fake.vec.Eta();
417     foi.fophi = fake.vec.Phi();
418     foi.fopass = fake.isLoose ? 1 : 0;
419     foi.mass = getMass(zmu1,zmu2,zele1,zele2);
420     foi.l1pt = zmu1 ? zmu1->Pt() : zele1->Pt();
421     foi.l2pt = zmu2 ? zmu2->Pt() : zele2->Pt();
422     foi.met = pfmet.Pt();
423     foFlatTree.Fill();
424     }
425 dkralph 1.2 }
426    
427 dkralph 1.9 // outFile->Write();
428     // outFile->Close();
429     foTree.getFile()->cd();
430     foTree.getTree()->Write();
431     foFlatTree.getFile()->cd();
432     foFlatTree.getTree()->Write();
433     nt.WriteClose();
434 dkralph 1.2
435 dkralph 1.1 //--------------------------------------------------------------------------------------------------------------
436     // Summary print out
437     //==============================================================================================================
438     cout << endl;
439     cout << "*" << endl;
440     cout << "* SUMMARY" << endl;
441     cout << "*--------------------------------------------------" << endl;
442     cout << endl;
443    
444 dkralph 1.9 cout << " >>> No. of events processed: " << nEvents << endl;
445     cout << " >>> No. of denominator muons: " << nMuDenom << endl;
446     cout << " >>> No. of numerator muons: " << nMuNumer << endl;
447     cout << " >>> ratio: " << float(nMuNumer)/nMuDenom << endl;
448     cout << " >>> No. of denominator eles: " << nEleDenom << endl;
449     cout << " >>> No. of numerator eles: " << nEleNumer << endl;
450     cout << " >>> ratio: " << float(nEleNumer)/nEleDenom << endl;
451 dkralph 1.1 cout << endl;
452    
453 dkralph 1.2 TString outputDir(ofname);
454     outputDir = outputDir(0,outputDir.Last('/'));
455 dkralph 1.1 ofstream txtfile;
456     char txtfname[100];
457 dkralph 1.2 TString txtname(ctrl.outputfile);
458     txtname.ReplaceAll(".root",".txt");
459     cout << "writing text to: " << txtname << endl;
460     txtfile.open(txtname);
461 dkralph 1.1 txtfile << "*" << endl;
462     txtfile << "* SUMMARY" << endl;
463     txtfile << "*--------------------------------------------------" << endl;
464     txtfile << endl;
465    
466 dkralph 1.9 txtfile << " >>> No. of events processed: " << nEvents << endl;
467     txtfile << " >>> No. of denominator muons: " << nMuDenom << endl;
468     txtfile << " >>> No. of numerator muons: " << nMuNumer << endl;
469     txtfile << " >>> ratio: " << float(nMuNumer)/nMuDenom << endl;
470     txtfile << " >>> No. of denominator eles: " << nEleDenom << endl;
471     txtfile << " >>> No. of numerator eles: " << nEleNumer << endl;
472     txtfile << " >>> ratio: " << float(nEleNumer)/nEleDenom << endl;
473 dkralph 1.1 txtfile << endl;
474     txtfile.close();
475    
476     cout << " <> Output saved in " << outputDir << "/" << endl;
477     cout << endl;
478    
479     cout << "done!" << endl;
480 dkralph 1.2 }
481 dkralph 1.9 //----------------------------------------------------------------------------
482     void initRunLumiRangeMap(ControlFlags &ctrl)
483     {
484 dkralph 1.15 if(ctrl.jsonFile != "")
485     rlrm.AddJSONFile(string(ctrl.jsonFile));
486     }
487 dkralph 1.9 //----------------------------------------------------------------------------------------
488 dkralph 1.15 float getMass(const Muon *zmu1, const Muon *zmu2, const Electron *zele1, const Electron *zele2)
489 dkralph 1.9 {
490     TLorentzVector lep1,lep2;
491     if(zmu1 && zmu2) {
492     lep1.SetPtEtaPhiM(zmu1->Pt(),zmu1->Eta(),zmu1->Phi(),MUON_MASS);
493     lep2.SetPtEtaPhiM(zmu2->Pt(),zmu2->Eta(),zmu2->Phi(),MUON_MASS);
494     } else if(zele1 && zele2) {
495     lep1.SetPtEtaPhiM(zele1->Pt(),zele1->Eta(),zele1->Phi(),ELECTRON_MASS);
496     lep2.SetPtEtaPhiM(zele2->Pt(),zele2->Eta(),zele2->Phi(),ELECTRON_MASS);
497 dkralph 1.15 } else if(zmu1 && zele1) {
498     lep1.SetPtEtaPhiM(zmu1->Pt(),zmu1->Eta(),zmu1->Phi(),MUON_MASS);
499     lep2.SetPtEtaPhiM(zele1->Pt(),zele1->Eta(),zele1->Phi(),ELECTRON_MASS);
500 dkralph 1.9 } else assert(0);
501    
502     return (lep1 + lep2).M();
503     }
504     //----------------------------------------------------------------------------------------
505 dkralph 1.15 SelectionStatus denominatorSelection(ControlFlags &ctrl, const Muon *mu, const Electron *ele, const Vertex *vtx, Array<PFCandidate> *pfArr)
506     {
507     assert(mu || ele);
508     assert(!(mu && ele));
509     if(mu) {
510     assert(pfArr);
511 dkralph 1.16 if(ctrl.muSele=="noD0Ip")
512     return muonPreSelectionNoD0IP(ctrl,mu,vtx,pfArr);
513     else if(ctrl.muSele=="d0Ip")
514     return muonReferencePreSelection(ctrl,mu,vtx,pfArr);
515     else assert(0);
516 dkralph 1.15 } else if(ele) {
517 dkralph 1.16 if(ctrl.eleSele=="noD0Ip")
518     return electronPreSelectionNoD0IP(ctrl,ele,vtx);
519     else if(ctrl.eleSele=="d0Ip")
520     return electronReferencePreSelection(ctrl,ele,vtx);
521     else assert(0);
522 dkralph 1.15 } else assert(0);
523     }
524     //----------------------------------------------------------------------------------------
525     SelectionStatus analysisSelection(ControlFlags &ctrl, const Muon *mu, const Vertex *vtx, Array<PFCandidate> *pfArr,
526     Array<PileupEnergyDensity> *puDArr)
527 dkralph 1.9 {
528     SelectionStatus status;
529     status |= muonReferencePreSelection(ctrl,mu,vtx,pfArr);
530     status |= muonIDPFSelection(ctrl,mu,vtx,pfArr);
531     status |= muonReferenceIsoSelection(ctrl,mu,vtx,pfArr,puDArr,eraMu,photonsToVeto);
532     return status;
533     }
534 dkralph 1.2 //----------------------------------------------------------------------------------------
535 dkralph 1.15 SelectionStatus analysisSelection(ControlFlags &ctrl, const Electron *ele, const Vertex *vtx, Array<PFCandidate> *pfArr,
536     Array<PileupEnergyDensity> *puDArr)
537 dkralph 1.9 {
538     SelectionStatus status;
539     status |= electronReferencePreSelection(ctrl,ele,vtx);
540     status |= electronReferenceIDMVASelectionV1(ctrl,ele,vtx);
541     status |= electronReferenceIsoSelection(ctrl,ele,vtx,pfArr,puDArr,eraEle,photonsToVeto);
542     return status;
543     }
544     //----------------------------------------------------------------------------------------
545     vector<SimpleLepton> findFakes(ControlFlags &ctrl,
546 dkralph 1.15 Array<Muon> *muonArr,
547     Array<Electron> *electronArr,
548     Array<PFJet> *jetArr,
549     Array<PFCandidate> *pfArr,
550     Array<PileupInfo> *puArr,
551     Array<PileupEnergyDensity> *puDArr,
552     Array<Vertex> *vtxArr,
553     const Vertex *vtx,
554     const Muon *zmu1,
555     const Muon *zmu2,
556     const Electron *zele1,
557     const Electron *zele2)
558 dkralph 1.9 {
559     vector<SimpleLepton> fakes;
560    
561 dkralph 1.2 for(Int_t imu=0; imu<muonArr->GetEntries(); imu++) {
562 dkralph 1.15 const Muon* mu = (*muonArr)[imu];
563 dkralph 1.2
564 dkralph 1.9 if(mu==zmu1 || mu==zmu2) continue;
565 dkralph 1.15 if(!passResKill(zmu1,zmu2,zele1,zele2,mu,NULL)) continue;
566 dkralph 1.2
567 dkralph 1.7 SelectionStatus denomsel;
568 dkralph 1.15 denomsel |= denominatorSelection(ctrl,mu,NULL,vtx,pfArr);
569 dkralph 1.8 if( !denomsel.passPre() ) continue;
570 dkralph 1.2
571 dkralph 1.9 SelectionStatus status = analysisSelection(ctrl,mu,vtx,pfArr,puDArr);
572 dkralph 1.2
573 dkralph 1.9 SimpleLepton fake;
574     fake.vec.SetPtEtaPhiM(mu->Pt(),mu->Eta(),mu->Phi(),MUON_MASS);
575     fake.type = 13;
576     fake.isLoose = status.loose();
577    
578     fakes.push_back(fake);
579 dkralph 1.2 }
580     for(Int_t iele=0; iele<electronArr->GetEntries(); iele++) {
581 dkralph 1.15 const Electron* ele = (*electronArr)[iele];
582 dkralph 1.2
583 dkralph 1.4 bool muonMatch=false;
584     for(unsigned imu=0; imu<muonArr->GetEntries(); imu++) {
585 dkralph 1.15 const Muon *mu = (*muonArr)[imu];
586 dkralph 1.4 if(dr(mu,ele) < 0.05) muonMatch = true;
587     }
588 dkralph 1.9 if(muonMatch) continue;
589 dkralph 1.4
590 dkralph 1.9 if(ele==zele1 || ele==zele2) continue;
591 dkralph 1.15 if(!passResKill(zmu1,zmu2,zele1,zele2,NULL,ele)) continue;
592 dkralph 1.2
593 dkralph 1.7 SelectionStatus denomsel;
594 dkralph 1.15 denomsel |= denominatorSelection(ctrl,NULL,ele,vtx,NULL);
595 dkralph 1.8 if( !denomsel.passPre() ) continue;
596 dkralph 1.2
597 dkralph 1.9 SelectionStatus status = analysisSelection(ctrl,ele,vtx,pfArr,puDArr);
598    
599     SimpleLepton fake;
600     fake.vec.SetPtEtaPhiM(ele->Pt(),ele->Eta(),ele->Phi(),ELECTRON_MASS);
601     fake.type = 11;
602     fake.isLoose = status.loose();
603 dkralph 1.8
604 dkralph 1.9 fakes.push_back(fake);
605     }
606 dkralph 1.2
607 dkralph 1.9 return fakes;
608 dkralph 1.1 }
609 dkralph 1.9 //----------------------------------------------------------------------------------------
610 dkralph 1.14 SimpleLepton fillSimpleLepton(const Muon *mu, const Electron *ele, SelectionStatus *ctrl, const Vertex *vtx)
611 dkralph 1.2 {
612 dkralph 1.14 if(mu) return fillSimpleLepton(mu, ctrl, vtx);
613     else if(ele) return fillSimpleLepton(ele,ctrl, vtx);
614 dkralph 1.9 else assert(0);
615     return SimpleLepton();
616     }
617 dkralph 1.15 //----------------------------------------------------------------------------------------
618     bool passGhost(vector<const Muon*> goodMuons, const Muon *mu)
619     {
620     for(unsigned imu=0; imu<goodMuons.size(); imu++) {
621     const Muon *goodMu = goodMuons[imu];
622     if(dr(goodMu,mu) < 0.02) return false;
623     }
624     return true;
625     }
626     //----------------------------------------------------------------------------------------
627     bool passResKill(const Muon *zmu1, const Muon *zmu2, const Electron *zele1, const Electron *zele2,
628     const Muon *mu, const Electron *ele)
629 dkralph 1.16 // require mll > 4 between a lepton (either mu or ele) and the OS lepton from the Z
630 dkralph 1.15 {
631     float lepCharge = mu ? mu->Charge() : ele->Charge();
632     float mass(0);
633     if(zmu1) {
634     if(zmu1->Charge()*lepCharge < 0) mass = getMass(zmu1, mu ? mu : NULL, mu ? NULL : ele, NULL);
635     else if(zmu2->Charge()*lepCharge < 0) mass = getMass(zmu2, mu ? mu : NULL, mu ? NULL : ele, NULL);
636     else assert(0);
637     } else if(zele1) {
638     if(zele1->Charge()*lepCharge < 0) mass = getMass(mu ? mu : NULL, NULL, zele1, mu ? NULL : ele);
639     else if(zele2->Charge()*lepCharge < 0) mass = getMass(mu ? mu : NULL, NULL, zele2, mu ? NULL : ele);
640     else assert(0);
641     } else assert(0);
642    
643     return mass > 4;
644     }