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

# Content
1 //
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 #include "ChargedParticle.h"
36 #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 #include "SelectionFuncs.h"
56 #include "CommonDefs.h"
57 #include "Angles.h"
58 #include "AngleTuple.h"
59 #include "FOTuple.h"
60 #include "TriggerUtils.h"
61 #include "PassHLT.h"
62 #include "RunLumiRangeMap.h"
63 #include "fake_defs.h"
64 #include "Various.h"
65 #include "SampleWeight.h"
66 #include "CommonDefs.h"
67
68 #ifndef CMSSW_BASE
69 #define CMSSW_BASE "../"
70 #endif
71
72 using namespace mithep;
73 //
74 // globals
75 //----------------------------------------------------------------------------
76 TH1D *hpu_2011, *hpu_2012;
77 RunLumiRangeMap rlrm;
78 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 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 void initRunLumiRangeMap(ControlFlags &ctrl);
100 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 vector<SimpleLepton> findFakes(ControlFlags &ctrl,
105 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 SimpleLepton fillSimpleLepton(const Muon *mu, const Electron *ele, SelectionStatus *ctrl, const Vertex *vtx);
118 //=== MAIN =================================================================================================
119 int main(int argc, char** argv)
120 {
121
122 string cmsswpath(CMSSW_BASE);
123 cmsswpath.append("/src");
124 std::bitset<1024> triggerBits;
125 vector<vector<string> > inputFiles;
126 inputFiles.push_back(vector<string>());
127 map<string,unsigned> entrymap; // number of unskimmed entries in each file
128
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 TChain * hltchain = new TChain("HLT");
141
142 string fname;
143 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 if(fname.find("/store/") != string::npos) fname = "root://eoscms//"+fname;
149 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 if(ctrl.inputfile.find("/store/") != string::npos) ctrl.inputfile = "root://eoscms//"+ctrl.inputfile;
157 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 }
164 // write the total number of unskimmed events that went into making this output file to a text file
165 writeEntries(ctrl,total_unskimmed);
166
167 UInt_t nEvents=0,nMuDenom=0,nMuNumer=0,nEleDenom=0,nEleNumer=0;
168
169 // move this to compute_fakes
170 // double metMax = 25;
171
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 // 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
205 // initMuonIDMVA();
206 // getEATargets(ctrl,eraMu,eraEle);
207 initElectronIDMVAV1();
208 // initMuonIsoMVA();
209 // initElectronIDMVA();
210 // initElectronIsoMVA();
211 initTrigger();
212 if(!ctrl.mc)
213 initRunLumiRangeMap(ctrl);
214
215 //
216 // Access samples and fill histograms
217 TFile *inputFile=0;
218 TTree *eventTree=0;
219 string currentFile("");
220
221 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 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 const Vertex *vtx; // best primary vertex in the event
271
272 // 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 for(UInt_t ientry=0; ientry<imax; ientry++) {
281 chain->GetEntry(ientry);
282 if(!(ientry%10000)) cout << "entry: " << ientry << "\tfrac: " << setw(15) << float(ientry)/chain->GetEntries() << endl;
283
284 string fname = string(chain->GetFile()->GetEndpointUrl()->GetFile());
285 if( ctrl.era == 0 )
286 setEra( fname, ctrl );
287 getEATargets(ctrl,eraMu,eraEle);
288
289 // pfNoPU
290 PFnoPUflag.clear();
291 int pfnopu_size = makePFnoPUArray( pfArr, PFnoPUflag, vtxArr );
292 assert(pfnopu_size == pfArr->GetEntries());
293
294 if(!(ctrl.noJSON) ) {
295 RunLumiRangeMap::RunLumiPairType rl(info->RunNum(), info->LumiSec());
296 if( !(rlrm.HasRunLumi(rl)) ) continue;
297 }
298
299 nEvents++;
300
301 bool goodVertex = setPV( ctrl, vtxArr, vtx );
302 if(!goodVertex) continue;
303
304 // good lepton selection
305 failingLeptons.clear();
306 passingLeptons.clear();
307 vector<const Muon*> goodMuons;
308 vector<const Electron*> goodElectrons;
309 vector<SelectionStatus> muselv,eleselv;
310 for(int imu=0; imu<muonArr->GetEntries(); imu++) {
311 const Muon *mu = (*muonArr)[imu];
312 SelectionStatus denomsel;
313 denomsel |= denominatorSelection(ctrl,mu,NULL,vtx,pfArr);
314 if( !denomsel.passPre() ) continue;
315 if(!passGhost(goodMuons,mu)) continue;
316 SelectionStatus status = analysisSelection(ctrl,mu,vtx,pfArr,puDArr);
317 if(status.loose()) {
318 goodMuons.push_back(mu);
319 muselv.push_back(status);
320 passingLeptons.push_back(fillSimpleLepton(mu,&status,vtx));
321 } else {
322 failingLeptons.push_back(fillSimpleLepton(mu,&status,vtx));
323 }
324 }
325 for(Int_t i=0; i<electronArr->GetEntries(); i++) {
326 const Electron *ele = (*electronArr)[i];
327 bool muonMatch=false;
328 for(unsigned imu=0; imu<muonArr->GetEntries(); imu++) {
329 const Muon *mu = (*muonArr)[imu];
330 if(dr(mu,ele) < 0.05) muonMatch = true;
331 }
332 if(muonMatch) continue;
333 SelectionStatus denomsel;
334 denomsel |= denominatorSelection(ctrl,NULL,ele,vtx,NULL);
335 if( !denomsel.passPre() ) continue;
336 SelectionStatus status = analysisSelection(ctrl,ele,vtx,pfArr,puDArr);
337 if(status.loose()) {
338 goodElectrons.push_back(ele);
339 eleselv.push_back(status);
340 passingLeptons.push_back(fillSimpleLepton(ele,&status,vtx));
341 } else {
342 failingLeptons.push_back(fillSimpleLepton(ele,&status,vtx));
343 }
344 }
345
346 // look for z pairs
347 int NZCandidates=0;
348 float bestMass=-999;
349 const Muon *zmu1=0,*zmu2=0;
350 const Electron *zele1=0,*zele2=0;
351 SelectionStatus *status1,*status2;
352 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 float mass = getMass(goodMuons[imu],goodMuons[jmu],NULL,NULL);
356 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 }
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 float mass = getMass(NULL,NULL,goodElectrons[iele],goodElectrons[jele]);
367 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 }
374 }
375 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 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
386 // loop over fakes
387 vector<SimpleLepton> fakes = findFakes(ctrl,muonArr,electronArr,jetArr,pfArr,puArr,puDArr,vtxArr,vtx,zmu1,zmu2,zele1,zele2);
388 //????????????????????????????????????????????????????????????????????????????????????????
389 // if(fakes.size() > 1) continue;
390 //????????????????????????????????????????????????????????????????????????????????????????
391 for(unsigned ifake=0; ifake<fakes.size(); ifake++) {
392 SimpleLepton fake = fakes[ifake];
393
394 if(abs(fake.type) == 13) {
395 nMuDenom++;
396 if(fake.isLoose) nMuNumer++;
397 } else {
398 nEleDenom++;
399 if(fake.isLoose) nEleNumer++;
400 }
401
402 // fill output TTree
403 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 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 }
426
427 // 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
435 //--------------------------------------------------------------------------------------------------------------
436 // Summary print out
437 //==============================================================================================================
438 cout << endl;
439 cout << "*" << endl;
440 cout << "* SUMMARY" << endl;
441 cout << "*--------------------------------------------------" << endl;
442 cout << endl;
443
444 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 cout << endl;
452
453 TString outputDir(ofname);
454 outputDir = outputDir(0,outputDir.Last('/'));
455 ofstream txtfile;
456 char txtfname[100];
457 TString txtname(ctrl.outputfile);
458 txtname.ReplaceAll(".root",".txt");
459 cout << "writing text to: " << txtname << endl;
460 txtfile.open(txtname);
461 txtfile << "*" << endl;
462 txtfile << "* SUMMARY" << endl;
463 txtfile << "*--------------------------------------------------" << endl;
464 txtfile << endl;
465
466 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 txtfile << endl;
474 txtfile.close();
475
476 cout << " <> Output saved in " << outputDir << "/" << endl;
477 cout << endl;
478
479 cout << "done!" << endl;
480 }
481 //----------------------------------------------------------------------------
482 void initRunLumiRangeMap(ControlFlags &ctrl)
483 {
484 if(ctrl.jsonFile != "")
485 rlrm.AddJSONFile(string(ctrl.jsonFile));
486 }
487 //----------------------------------------------------------------------------------------
488 float getMass(const Muon *zmu1, const Muon *zmu2, const Electron *zele1, const Electron *zele2)
489 {
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 } 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 } else assert(0);
501
502 return (lep1 + lep2).M();
503 }
504 //----------------------------------------------------------------------------------------
505 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 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 } else if(ele) {
517 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 } else assert(0);
523 }
524 //----------------------------------------------------------------------------------------
525 SelectionStatus analysisSelection(ControlFlags &ctrl, const Muon *mu, const Vertex *vtx, Array<PFCandidate> *pfArr,
526 Array<PileupEnergyDensity> *puDArr)
527 {
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 //----------------------------------------------------------------------------------------
535 SelectionStatus analysisSelection(ControlFlags &ctrl, const Electron *ele, const Vertex *vtx, Array<PFCandidate> *pfArr,
536 Array<PileupEnergyDensity> *puDArr)
537 {
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 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 {
559 vector<SimpleLepton> fakes;
560
561 for(Int_t imu=0; imu<muonArr->GetEntries(); imu++) {
562 const Muon* mu = (*muonArr)[imu];
563
564 if(mu==zmu1 || mu==zmu2) continue;
565 if(!passResKill(zmu1,zmu2,zele1,zele2,mu,NULL)) continue;
566
567 SelectionStatus denomsel;
568 denomsel |= denominatorSelection(ctrl,mu,NULL,vtx,pfArr);
569 if( !denomsel.passPre() ) continue;
570
571 SelectionStatus status = analysisSelection(ctrl,mu,vtx,pfArr,puDArr);
572
573 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 }
580 for(Int_t iele=0; iele<electronArr->GetEntries(); iele++) {
581 const Electron* ele = (*electronArr)[iele];
582
583 bool muonMatch=false;
584 for(unsigned imu=0; imu<muonArr->GetEntries(); imu++) {
585 const Muon *mu = (*muonArr)[imu];
586 if(dr(mu,ele) < 0.05) muonMatch = true;
587 }
588 if(muonMatch) continue;
589
590 if(ele==zele1 || ele==zele2) continue;
591 if(!passResKill(zmu1,zmu2,zele1,zele2,NULL,ele)) continue;
592
593 SelectionStatus denomsel;
594 denomsel |= denominatorSelection(ctrl,NULL,ele,vtx,NULL);
595 if( !denomsel.passPre() ) continue;
596
597 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
604 fakes.push_back(fake);
605 }
606
607 return fakes;
608 }
609 //----------------------------------------------------------------------------------------
610 SimpleLepton fillSimpleLepton(const Muon *mu, const Electron *ele, SelectionStatus *ctrl, const Vertex *vtx)
611 {
612 if(mu) return fillSimpleLepton(mu, ctrl, vtx);
613 else if(ele) return fillSimpleLepton(ele,ctrl, vtx);
614 else assert(0);
615 return SimpleLepton();
616 }
617 //----------------------------------------------------------------------------------------
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 // require mll > 4 between a lepton (either mu or ele) and the OS lepton from the Z
630 {
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 }