ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitHzz4l/Selection/src/ReferenceSelection.cc
Revision: 1.26
Committed: Sun Feb 24 12:59:58 2013 UTC (12 years, 2 months ago) by anlevin
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.25: +45 -39 lines
Log Message:
made changes to synchronize on 2011 monte carlo

File Contents

# Content
1 #include "ReferenceSelection.h"
2
3 extern vector<SimpleLepton> failingLeptons;
4 extern vector<SimpleLepton> passingLeptons;
5
6 extern map<unsigned,float> evtrhoMap;
7 extern bool passes_HLT;
8 extern map<TString, map<TString,int>* > counts;
9 extern ElectronMomentumCorrection electron_momentum_correction;
10 extern MuCorr *muCorr;
11 extern TrigInfo ti;
12
13
14 //we need to store the fsr photons because they are used to veto jets in the vbf selection
15 //the leptons in the lepton pair include the fsr photons
16 struct ZCandidate
17 {
18 pair<SimpleLepton,SimpleLepton> lepton_pair;
19 unsigned int which_lepton_has_fsr; //0 means neither lepton has an fsr photon, 1 means the first lepton in the pair has the fsr photon, 2 means second lepton in the pair has the fsr photon
20 TLorentzVector fsr_photon;
21 };
22
23 //----------------------------------------------------------------------------------------
24 void updateSimpleLepton(SimpleLepton &tmplep);
25 //--------------------------------------------------------------------------------------------------
26 EventData apply_HZZ4L_reference_selection(ControlFlags &ctrl, // input control
27 const EventHeader *info, // input event info
28 const Array<Vertex> * vtxArr ,
29 const Array<PFCandidate> *pfCandidates,
30 const Array<PileupEnergyDensity> *puEnergyDensity,
31 const Array<Electron> *electronArr, // input electrons
32 SelectionStatus (*ElectronPreSelector)( ControlFlags &,
33 const Electron*,
34 const Vertex *),
35 SelectionStatus (*ElectronIDSelector)( ControlFlags &,
36 const Electron*,
37 const Vertex *),
38 SelectionStatus (*ElectronIsoSelector)( ControlFlags &,
39 const Electron*,
40 const Vertex *,
41 const Array<PFCandidate> *,
42 const Array<PileupEnergyDensity> *,
43 ElectronTools::EElectronEffectiveAreaTarget,
44 vector<const PFCandidate*>),
45 const Array<Muon> *muonArr, // input muons
46 SelectionStatus (*MuonPreSelector)( ControlFlags &,
47 const Muon*,
48 const Vertex *,
49 const Array<PFCandidate> *),
50 SelectionStatus (*MuonIDSelector)( ControlFlags &,
51 const Muon*,
52 // const Vertex &),
53 const Vertex *,
54 const Array<PFCandidate> *),
55 SelectionStatus (*MuonIsoSelector)( ControlFlags &,
56 const Muon*,
57 const Vertex *,
58 const Array<PFCandidate> *,
59 const Array<PileupEnergyDensity> *,
60 MuonTools::EMuonEffectiveAreaTarget,
61 vector<const PFCandidate*>)
62 )
63 //--------------------------------------------------------------------------------------------------
64 {
65 EventData ret;
66 failingLeptons.clear();
67 passingLeptons.clear();
68
69 MuonTools::EMuonEffectiveAreaTarget eraMu;
70 ElectronTools::EElectronEffectiveAreaTarget eraEle;
71 getEATargets(ctrl,eraMu,eraEle);
72
73 if( ctrl.debug ) {
74 cout << "presel nlep: " << muonArr->GetEntries() + electronArr->GetEntries()
75 << "\tnmuon: " << muonArr->GetEntries()
76 << "\tnelectron: " << electronArr->GetEntries()
77 << endl;
78 }
79
80 // correct muon momentum
81 if(ctrl.correct_muon_momentum) {
82 assert(muCorr->corr2011 && muCorr->corr2012);
83 if(ctrl.debug) cout << "mu corr: " << endl;
84 for(int i=0; i<muonArr->GetEntries(); i++) {
85 const Muon *const_mu = (Muon*)((*muonArr)[i]);
86 Muon *mu = const_cast<Muon*>(const_mu);
87 double ptBefore = mu->Pt();
88 correct_muon_momentum(ctrl,muCorr,mu,info->RunNum());
89 if(ctrl.debug) cout << " " << setw(12) << ptBefore << " --> " << setw(12) << mu->Pt() << " (" << fabs(ptBefore-mu->Pt())/ptBefore << ")" << endl;
90 }
91 }
92
93 const Vertex * vtx;
94 bool goodVertex = setPV( ctrl, vtxArr, vtx );
95 if(!goodVertex) {
96 if(ctrl.debug) cout << "found bad vertex" << endl;
97 ret.status.setStatus(SelectionStatus::FAIL);
98 return ret;
99 }
100 if(ctrl.debug)
101 cout << "vtx :: ntrks: " << vtx->NTracksFit() << endl;
102
103 //***********************************************************
104 // Trigger Selection
105 //***********************************************************
106 if( passes_HLT ) {
107 increment(counts,"trigger");
108 } else {
109 if(ctrl.debug) cout << "fails trigger" << endl;
110 ret.status.setStatus(SelectionStatus::FAIL);
111 return ret;
112 }
113
114 //***********************************************************
115 // Lepton Selection
116 //***********************************************************
117 vector<SimpleLepton> lepvec;
118 vector<const PFCandidate*> photonsToVeto;
119
120 if( ctrl.debug ) cout << "\tnMuons: " << muonArr->GetEntries() << endl;
121 for(int i=0; i<muonArr->GetEntries(); i++)
122 {
123 const Muon *mu = (Muon*)((*muonArr)[i]);
124
125 SelectionStatus musel;
126 musel |= (*MuonPreSelector)(ctrl,mu,vtx,pfCandidates);
127
128 if(ctrl.fakeScheme == "none") { // regular selection
129 if( !musel.passPre() ) continue;
130 } else { // fake denominator selection
131 SelectionStatus denomSel;
132 denomSel |= muonReferencePreSelection(ctrl,mu,vtx,pfCandidates);
133 if(ctrl.muSele != "none") { // don't apply *any* preselection, to get a super hi stat fake sample for BDT training
134 if( !denomSel.passPre() ) continue;
135 }
136 }
137
138 if(ctrl.debug) cout << "muon:: pt: " << mu->Pt() << "\teta: " << mu->Eta() << endl;
139
140 musel |= (*MuonIDSelector)(ctrl,mu,vtx,pfCandidates );
141
142 // NOTE: if we do FSR this is *changed* later on
143 musel |= (*MuonIsoSelector)(ctrl,mu,vtx,pfCandidates,puEnergyDensity,eraMu,photonsToVeto);
144 if(ctrl.debug) cout << "mu status after iso (before fsr) " << musel.getStatus() << endl;
145
146 SimpleLepton tmplep;
147 tmplep.vec.SetPtEtaPhiM(mu->Pt(), mu->Eta(), mu->Phi(), MUON_MASS);
148 tmplep.type = 13;
149 tmplep.index = i;
150 tmplep.charge = mu->Charge();
151 tmplep.ip3dSig = mu->Ip3dPVSignificance();
152 tmplep.is4l = false;
153 tmplep.isEB = (fabs(mu->Eta()) < 1.479 ? 1 : 0 );
154 tmplep.isLoose = musel.loose();
155 tmplep.isTight = mu->IsPFMuon() || mu->IsGlobalMuon();
156 tmplep.status = musel;
157 tmplep.fsrRecoveryAttempted = false; // NOTE: this is *used* inside FSR.cc
158 lepvec.push_back(tmplep);
159 if( ctrl.debug ) cout << endl;
160 }
161
162 if( ctrl.debug ) { cout << "\tnElectron: " << electronArr->GetEntries() << endl; }
163 for(int i=0; i<electronArr->GetEntries(); i++)
164 {
165 const Electron *const_ele = (Electron*)((*electronArr)[i]);
166 Electron *ele = const_cast<Electron*>(const_ele);
167
168 if(ctrl.debug) cout << setprecision(8) << "el:: scEt " << setw(12) << ele->SCluster()->Et() << " P: "
169 << setw(12) << ele->P() << " pT: " << setw(12) << ele->Pt() << " scEta " << setw(12) << ele->SCluster()->Eta() << setprecision(5) << endl;
170
171 // evaluate MVA *before* regression correction (but cut on mvaVal *after*)
172 double mvaVal = getElectronIDMVAval(ctrl, ele, vtx);
173
174 float combination_perr;
175 if(ctrl.era == 2011)
176 combination_perr = electron_momentum_correction.correct_electron_momentum(ctrl, ele, info, puEnergyDensity->At(0)->RhoKt6PFJetsForIso25(), vtxArr->GetEntries());
177 else if (ctrl.era == 2012)
178 combination_perr = electron_momentum_correction.correct_electron_momentum(ctrl, ele, info, puEnergyDensity->At(0)->RhoKt6PFJets(), vtxArr->GetEntries());
179 else
180 assert(0);
181
182 if(ctrl.debug) cout << setprecision(8) << " corr el: scEt " << setw(12) << ele->SCluster()->Et() << " P: "
183 << setw(12) << ele->P() << " pT: " << setw(12) << ele->Pt() << " scEta " << setw(12) << ele->SCluster()->Eta() << setprecision(5) << endl;
184
185 SelectionStatus elesel;
186
187 elesel |= (*ElectronPreSelector)(ctrl,ele,vtx);
188
189 if(ctrl.fakeScheme == "none") { // regular selection
190 if( !elesel.passPre() ) continue;
191 } else { // fake denominator selection
192 SelectionStatus denomSel;
193 denomSel |= electronReferencePreSelection(ctrl,ele,vtx);
194 if(ctrl.eleSele != "none") { // don't apply *any* preselection, to get a super hi stat fake sample for BDT training
195 if( !denomSel.passPre() ) continue;
196 }
197 }
198
199
200 elesel |= passElectronIDMVA(ctrl, mvaVal, ele);
201
202 // NOTE: if we do FSR this is *changed* later on
203 elesel |= (*ElectronIsoSelector)(ctrl,ele,vtx,pfCandidates,puEnergyDensity,eraEle,photonsToVeto);
204 if( ctrl.debug ) cout << "el status after iso (no fsr) " << hex << elesel.getStatus() << dec << endl;
205
206 SimpleLepton tmplep;
207 tmplep.vec.SetPtEtaPhiM( ele->Pt(), ele->Eta(), ele->Phi(), ELECTRON_MASS );
208 tmplep.type = 11;
209 tmplep.index = i;
210 tmplep.perr = combination_perr;
211 tmplep.charge = ele->Charge();
212 tmplep.ip3dSig = ele->Ip3dPVSignificance();
213 tmplep.is4l = false;
214 tmplep.isEB = ele->IsEB();
215 tmplep.scID = ele->SCluster()->GetUniqueID();
216 tmplep.isTight = elesel.tight();
217 tmplep.isLoose = elesel.loose();
218 tmplep.status = elesel;
219 tmplep.fsrRecoveryAttempted = false; // NOTE: this is *used* inside FSR.cc
220 lepvec.push_back(tmplep);
221 if( ctrl.debug ) cout << endl;
222 }
223
224 //********************************************************
225 // Dump Stuff
226 //********************************************************
227 sort( lepvec.begin(), lepvec.end(), SimpleLepton::lep_pt_sort );
228 int nmu=0, nele=0;
229 for( int i=0; i<lepvec.size(); i++ ) {
230 if(ctrl.debug) {
231 bitset<16> tmpbits(lepvec[i].status.getStatus());
232 cout << "lepvec :: evt: " << setw(8) << info->EvtNum() << " index: " << setw(3) << i << " type: " << setw(4) << lepvec[i].type
233 << " pt: " << setw(11) << lepvec[i].vec.Pt() << " eta: " << setw(11) << lepvec[i].vec.Eta() << " status: " << tmpbits;
234 if(!ctrl.doFSR)
235 cout << "\tpf: " << lepvec[i].status.isoPF04 << "\tch: " << lepvec[i].status.chisoPF04 << "\tga: " << lepvec[i].status.gaisoPF04
236 << "\tne: " << lepvec[i].status.neisoPF04 << endl;
237 if( abs(lepvec[i].type) == 11 ) {
238 const Electron *tmpele = (Electron*)((*electronArr)[lepvec[i].index]);
239 cout << "\tSCeta: " << tmpele->SCluster()->Eta()
240 << "\tidMVA: " << lepvec[i].status.idMVA;
241 }
242 cout << endl;
243 }
244 if( abs(lepvec[i].type) == 11 ) nele++;
245 else nmu++;
246 }
247 if( ctrl.debug ) {
248 cout << "postsel nlep: " << lepvec.size()
249 << "\tnmuon: " << nmu
250 << "\tnelectron: " << nele
251 << endl;
252 }
253
254 //********************************************************
255 // Step 2: Lepton Cross-Cleaning: remove electrons that are next to 'good'ish muons
256 //********************************************************
257 vector<vector<SimpleLepton>::iterator> electrons_to_erase;
258 for (vector<SimpleLepton>::iterator it1=lepvec.begin();
259 it1 != lepvec.end(); it1++ ) {
260 if ( abs(it1->type) != 11 ) continue;
261 TVector3 evec = it1->vec.Vect();
262
263 bool erase_this_electron=false;
264 for (vector<SimpleLepton>::iterator it2=lepvec.begin();
265 it2 != lepvec.end(); it2++ ) {
266 if ( it2 == it1 ) continue;
267 if ( abs(it2->type) != 13 ) continue;
268 if( !it2->status.passPre() ) continue;
269 if( !it2->isTight ) continue; // NOTE: isTight is set to it2->isPFMuon || it2->isGlobalMuon
270
271 TVector3 mvec = it2->vec.Vect();
272 if ( evec.DrEtaPhi(mvec) < 0.05 ) {
273 erase_this_electron=true;
274 break;
275 }
276 }
277 if( erase_this_electron ) {
278 if( ctrl.debug ) cout << "erasing electron with pt " << it1->vec.Pt() << endl;
279 electrons_to_erase.push_back(it1);
280 }
281 }
282 for( int i=0; i<electrons_to_erase.size(); i++ ) {
283 lepvec.erase(electrons_to_erase[i]);
284 }
285
286 // fill passing and failing leptons for fakes
287 // (NOTE: isolation hasn't been corrected post-fsr, so this isn't strictly correct)
288 // also note: sip cut not applied
289 for (int i=0; i<lepvec.size(); i++ ) {
290 if( lepvec[i].isLoose )
291 passingLeptons.push_back(lepvec[i]);
292 else
293 failingLeptons.push_back(lepvec[i]);
294 }
295
296 //********************************************************
297 // Step 3: Good Leptons (remove non-id-and-pre'd leptons, and apply |ip3ds| < 4)
298 //********************************************************
299 vector<double> pt_of_leptons_to_erase;
300 for (int i=0; i<lepvec.size(); i++ ) {
301 bool already_pushed=false;
302 if( !(lepvec[i].status.looseIDAndPre()) ) {
303 pt_of_leptons_to_erase.push_back(lepvec[i].vec.Pt());
304 already_pushed = true;
305 if(ctrl.debug)
306 cout << "pushing failed lepton type: " << lepvec[i].type
307 << "\tpt: " << lepvec[i].vec.Pt()
308 << "\teta: " << lepvec[i].vec.Eta()
309 << endl;
310 // failingLeptons.push_back(lepvec[i]); // these should pass preselection
311 } else {
312 // passingLeptons.push_back(lepvec[i]);
313 }
314 if( !already_pushed && fabs(lepvec[i].ip3dSig)>4 )
315 pt_of_leptons_to_erase.push_back(lepvec[i].vec.Pt());
316 }
317 for( int i=0; i<pt_of_leptons_to_erase.size(); i++ ) {
318 for( vector<SimpleLepton>::iterator it=lepvec.begin();
319 it != lepvec.end(); it++ ) {
320 SimpleLepton flep = *it;
321 if( flep.vec.Pt() != pt_of_leptons_to_erase[i] ) continue;
322 if(ctrl.debug) cout << "erasing lepton : "
323 << flep.vec.Pt() << "\t"
324 << flep.type << "\t"
325 << endl;
326 lepvec.erase(it);
327 break;
328 }
329 }
330 if( ctrl.debug ) cout << "good leptons : " << lepvec.size() << endl;
331
332 //********************************************************
333 // Ghost Removal
334 //********************************************************
335 vector<vector<SimpleLepton>::iterator> leptons_to_erase;
336 for (vector<SimpleLepton>::iterator it1=lepvec.begin(); it1 != lepvec.end(); it1++ ) {
337 TVector3 lep1 = it1->vec.Vect();
338
339 bool erase_this_lepton=false;
340 for (vector<SimpleLepton>::iterator it2=it1+1; it2 != lepvec.end(); it2++ ) {
341 TVector3 lep2 = it2->vec.Vect();
342
343 if ( lep1.DrEtaPhi(lep2) <= 0.02 ) {
344 erase_this_lepton=true;
345 break;
346 }
347 }
348 if( erase_this_lepton ) {
349 if( ctrl.debug ) cout << "erasing ghost with pt " << it1->vec.Pt() << endl;
350 leptons_to_erase.push_back(it1);
351 }
352 }
353 for( int i=0; i<leptons_to_erase.size(); i++ ) {
354 lepvec.erase(leptons_to_erase[i]);
355 }
356
357 //********************************************************
358 // Step 4: Z candidate preselection
359 //********************************************************
360 vector<pair<int,int> > ZCandidates; // indices in lepvec of the two leptons
361 vector<ZCandidate > ZCandidatesLeptons; // fsr-corrected leptons that form the Z
362 vector<pair<SelectionStatus,SelectionStatus> > ZCandidatesSelectionStatus;
363 for(int i = 0; i < lepvec.size(); ++i) {
364 for(int j = i+1; j < lepvec.size(); ++j) {
365 if( abs(lepvec[i].type) != abs(lepvec[j].type) ) continue;
366 if( lepvec[i].charge == lepvec[j].charge ) continue;
367
368 TLorentzVector Zvec = (lepvec[i].vec+lepvec[j].vec);
369
370 // copies of lepvec that have 1) the photons added to the momenta and 2) the fsrRecoveryAttempted flag set
371 vector<SimpleLepton> lepvec_i = lepvec;
372 vector<SimpleLepton> lepvec_j = lepvec;
373
374 ZCandidate cand;
375 cand.which_lepton_has_fsr = 0; //default value for when neither lepton has an fsr photon
376
377 if( ctrl.doFSR ) {
378 if(ctrl.debug) cout << endl << "----------------> FSR ("<<i<<","<<j<<") <----------------------" << endl;
379 photonsToVeto.clear();
380 float old_pt_i = lepvec[i].vec.Pt();
381 float old_pt_j = lepvec[j].vec.Pt();
382 float old_M = Zvec.M();
383
384 const ChargedParticle *lepton(NULL);
385 if(ctrl.debug) cout << "i: " << i << endl;
386 if(abs(lepvec[i].type) == 13) lepton = dynamic_cast<const ChargedParticle *>((*muonArr)[lepvec[i].index]);
387 else lepton = dynamic_cast<const ChargedParticle *>((*electronArr)[lepvec[i].index]);
388 pair<TLorentzVector,int> photon_i = findFsrPhoton(ctrl, ret, lepton, i, lepvec_i, pfCandidates, electronArr, &Zvec);
389 if(photon_i.second>=0 && ctrl.debug) cout << " FSR :: oldpt: " << old_pt_i << "\tnewpt: " << lepvec_i[i].vec.Pt() << "\tindex: " << i << endl;
390
391 lepton = NULL;
392 if(ctrl.debug) cout << "j: " << j << endl;
393 if( abs(lepvec[j].type) == 13 ) lepton = dynamic_cast<const ChargedParticle *>((*muonArr)[lepvec[j].index]);
394 else lepton = dynamic_cast<const ChargedParticle *>((*electronArr)[lepvec[j].index]);
395 pair<TLorentzVector,int> photon_j = findFsrPhoton(ctrl, ret, lepton, j, lepvec_j, pfCandidates, electronArr, &Zvec);
396
397 bool useI(false),useJ(false);
398 if(photon_i.second >= 0) { // photon for i
399 if(photon_j.second < 0) {
400 useI = true;
401 } else { // both have photons
402 TLorentzVector lep_i(lepvec_i[i].vec),lep_j(lepvec_j[j].vec);
403 float oldM = (lep_i + lep_j).M();
404 float newM_i = (lep_i + photon_i.first + lep_j).M();
405 float newM_j = (lep_i + lep_j + photon_j.first).M();
406 if(ctrl.debug) cout << " two FSRs " << setw(12) << oldM << setw(12) << newM_i << setw(12) << newM_j << endl;
407 if(fabs(newM_i - Z_MASS) < fabs(newM_j - Z_MASS)) { // if mass with photon i is closer to z pole than with photon j
408 useI = true;
409 } else {
410 useJ = true;
411 }
412 }
413 } else if(photon_j.second >= 0) { // photon for j
414 useJ = true;
415 }
416
417 assert(!(useI && useJ));
418 if(useI) {
419 cand.fsr_photon = photon_i.first;
420 cand.which_lepton_has_fsr = 1;
421 lepvec_i[i].vec += photon_i.first;
422 lepvec_i[i].fsrRecoveryAttempted = true;
423 //the photon_i.second index could actually be a muon not a photon; see the findFsrPhoton function
424 if(abs((*(const PFCandidate*)(pfCandidates->At(photon_i.second))).PFType()) == PFCandidate::eGamma)
425 photonsToVeto.push_back((const PFCandidate*)(pfCandidates->At(photon_i.second)));
426 } else if(useJ) {
427 cand.fsr_photon = photon_j.first;
428 cand.which_lepton_has_fsr = 2;
429 lepvec_j[j].vec += photon_j.first;
430 lepvec_j[j].fsrRecoveryAttempted = true;
431 //the photon_j.second index could actually be a muon not a photon; see the findFsrPhoton function
432 if(abs((*(const PFCandidate*)(pfCandidates->At(photon_j.second))).PFType()) == PFCandidate::eGamma)
433 photonsToVeto.push_back((const PFCandidate*)(pfCandidates->At(photon_j.second)));
434 }
435
436 // recompute isolation excluding the fsr photons
437 if( abs(lepvec[i].type) == 11 ) {
438 const Electron *el = (Electron*)((*electronArr)[lepvec_i[i].index]);
439 lepvec_i[i].status |= (*ElectronIsoSelector)(ctrl,el,vtx,pfCandidates,puEnergyDensity,eraEle,photonsToVeto);
440
441 } else {
442 const Muon *mu = (Muon*)((*muonArr)[lepvec_i[i].index]);
443 lepvec_i[i].status |= (*MuonIsoSelector)(ctrl,mu,vtx,pfCandidates,puEnergyDensity,eraMu,photonsToVeto);
444 }
445 updateSimpleLepton(lepvec_i[i]);
446
447 if( abs(lepvec[j].type) == 11 ) {
448 const Electron *el = (Electron*)((*electronArr)[lepvec_j[j].index]);
449 lepvec_j[j].status |= (*ElectronIsoSelector)(ctrl,el,vtx,pfCandidates,puEnergyDensity,eraEle,photonsToVeto);
450 } else {
451 const Muon *mu = (Muon*)((*muonArr)[lepvec_j[j].index]);
452 lepvec_j[j].status |= (*MuonIsoSelector)(ctrl,mu,vtx,pfCandidates,puEnergyDensity,eraMu,photonsToVeto);
453 }
454 updateSimpleLepton(lepvec_j[j]);
455
456 float new_M = (lepvec_i[i].vec+lepvec_j[j].vec).M();
457 float new_pt_i = lepvec_i[i].vec.Pt();
458 float new_pt_j = lepvec_j[j].vec.Pt();
459 if( ctrl.debug && ret.fsrPhotons.size() > 0) {
460 cout << " ----> post FSR Z:";
461 cout << " oldM: " << setprecision(8) << old_M << "\tnewM:" << setprecision(8) << new_M << endl;
462 cout << " old_pt_i: " << setprecision(8) << old_pt_i << "\tnew_pt_i:" << setprecision(8) << new_pt_i << endl;
463 cout << " old_pt_j: " << setprecision(8) << old_pt_j << "\tnew_pt_j:" << setprecision(8) << new_pt_j << endl;
464 }
465
466 } // doFSR
467
468 // apply isolation criteria with recomputed isolation
469 if( !(lepvec_i[i].status.loose()) || !(lepvec_j[j].status.loose()) ) {
470 if(ctrl.debug) {
471 bitset<16> tmpbits_i(lepvec_i[i].status.getStatus()),tmpbits_j(lepvec_j[j].status.getStatus());
472 cout << " leptons fail selection (i: " << tmpbits_i << ", j: " << tmpbits_j << ")" << endl;
473 }
474 continue;
475 }
476
477 ZCandidates.push_back(pair<int,int> (i,j) );
478 cand.lepton_pair = pair<SimpleLepton,SimpleLepton> (lepvec_i[i],lepvec_j[j]);
479
480 ZCandidatesLeptons.push_back(cand );
481 if( ctrl.debug ) cout << "cand.fsr_photon.Pt() = " << cand.fsr_photon.Pt() << endl;
482 if( ctrl.debug ) cout << "Z candidate ("<< i << "," << j << ")" << "\tmass: " << (lepvec_i[i].vec+lepvec_j[j].vec).M() << endl;
483 }
484 }
485
486 if( ZCandidates.size() > 0 ) {
487 ret.status.selectionBits.flip(PASS_ZCANDIDATE);
488 if( ctrl.debug ) cout << "event has >0 Z candidates (" << ZCandidates.size() << " of em)" << endl;
489 } else {
490 ret.status.setStatus(SelectionStatus::FAIL);
491 return ret;
492 }
493
494 //
495 // Select Z1
496 //
497 int best_Z1_index;
498 float best_Z1_mass = 9999.;
499 TLorentzVector Z1vec;
500 for( int i=0; i<ZCandidates.size(); i++ ) {
501 TLorentzVector tmpZ1vec = (ZCandidatesLeptons[i].lepton_pair.first.vec) + (ZCandidatesLeptons[i].lepton_pair.second.vec);
502 if( fabs(tmpZ1vec.M()-Z_MASS) < fabs(best_Z1_mass-Z_MASS) ) {
503 best_Z1_index=i;
504 best_Z1_mass=tmpZ1vec.M();
505 Z1vec = tmpZ1vec;
506 }
507 }
508 ret.Z1leptons.push_back(ZCandidatesLeptons[best_Z1_index].lepton_pair.first);
509 ret.Z1leptons.push_back(ZCandidatesLeptons[best_Z1_index].lepton_pair.second);
510 if(ZCandidatesLeptons[best_Z1_index].which_lepton_has_fsr != 0){
511 SimpleLepton photon;
512 photon.vec.SetPtEtaPhiM( ZCandidatesLeptons[best_Z1_index].fsr_photon.Pt(), ZCandidatesLeptons[best_Z1_index].fsr_photon.Eta(), ZCandidatesLeptons[best_Z1_index].fsr_photon.Phi(), 0);
513 ret.fsrPhotons.push_back(photon);
514 }
515
516 if(ctrl.debug)
517 cout << "best mZ1: " << best_Z1_mass << " from (" << ZCandidates[best_Z1_index].first << "," << ZCandidates[best_Z1_index].second << ")" << endl;
518
519 //******************************************************************************
520 // Step 6.3 : require Z1 with 40<m<120
521 //******************************************************************************
522 if( Z1vec.M() > 40. && Z1vec.M() < 120. ) {
523 ret.status.selectionBits.flip(PASS_GOODZ1);
524 } else {
525 ret.status.setStatus(SelectionStatus::FAIL);
526 return ret;
527 }
528
529 //******************************************************************************
530 // Step 6.3 : 4 good leptons
531 //******************************************************************************
532 if( lepvec.size() >= 4 ) {
533 if( ctrl.debug) cout << "four leps" << endl;
534 ret.status.selectionBits.flip(PASS_4L);
535 } else {
536 ret.status.setStatus(SelectionStatus::FAIL);
537 return ret;
538 }
539
540 //********************************************************
541 // Step 5: ZZ candidates
542 //********************************************************
543 int nZZCandidates=0;
544 vector<pair<int,int> > ZZCandidates;
545 if(ctrl.debug) cout << "looping over " << ZCandidates.size() << " Z candidates: " << endl;
546 for(int z2index=0; z2index<ZCandidates.size(); ++z2index) {
547 int z1index = best_Z1_index;
548 if ( z2index == z1index ) { if(ctrl.debug) cout << " Z2 fails z2i = z1i" << endl; continue; }
549 if( ZCandidates[z1index].first == ZCandidates[z2index].first ) { if(ctrl.debug) cout << " Z2 fails icheck1" << endl; continue; }
550 if( ZCandidates[z1index].first == ZCandidates[z2index].second ) { if(ctrl.debug) cout << " Z2 fails icheck2" << endl; continue; }
551 if( ZCandidates[z1index].second == ZCandidates[z2index].first ) { if(ctrl.debug) cout << " Z2 fails icheck3" << endl; continue; }
552 if( ZCandidates[z1index].second == ZCandidates[z2index].second ) { if(ctrl.debug) cout << " Z2 fails icheck4" << endl; continue; }
553
554 ZZCandidates.push_back(pair<int,int> (z1index,z2index));
555 }
556 if(ZZCandidates.size() > 0) {
557 ret.status.selectionBits.flip(PASS_ZZCANDIDATE);
558 if(ctrl.debug) {
559 cout << ZZCandidates.size() << " zz cands" << endl;
560 cout << "-------------------------------------------------------" << endl;
561 // for( int l=0; l<lepvec.size(); l++ ) lepvec[l].print();
562 for(unsigned ican=0; ican<ZCandidatesLeptons.size(); ican++) {
563 ZCandidatesLeptons[ican].lepton_pair.first.print();
564 ZCandidatesLeptons[ican].lepton_pair.second.print();
565 }
566 cout << "-------------------------------------------------------" << endl;
567 if(ctrl.debug)
568 for(unsigned iph=0; iph<ret.fsrPhotons.size(); iph++)
569 cout << " fsr photon "
570 << setw(12) << ret.fsrPhotons[iph].vec.Pt()
571 << " eta: " << setw(12) << ret.fsrPhotons[iph].vec.Eta()
572 << " phi: " << setw(12) << ret.fsrPhotons[iph].vec.Phi() << endl;
573 }
574 } else {
575 if(ctrl.debug) cout << "no zz cands" << endl;
576 ret.status.setStatus(SelectionStatus::FAIL);
577 return ret;
578 }
579
580 //
581 // Select z2
582 //
583 int best_Z2_index;
584 float best_Z2_pt_sum = -1.;
585 for( int i=0; i<ZZCandidates.size(); i++ ) {
586 int z2index = ZZCandidates[i].second;
587 double pt_sum = ZCandidatesLeptons[z2index].lepton_pair.first.vec.Pt() +
588 ZCandidatesLeptons[z2index].lepton_pair.second.vec.Pt();
589 if( pt_sum > best_Z2_pt_sum ) {
590 best_Z2_index=z2index;
591 best_Z2_pt_sum=pt_sum;
592 }
593 }
594 ret.Z2leptons.push_back(ZCandidatesLeptons[best_Z2_index].lepton_pair.first); // push back the *fsr-corrected* leptons
595 ret.Z2leptons.push_back(ZCandidatesLeptons[best_Z2_index].lepton_pair.second);
596 if(ZCandidatesLeptons[best_Z2_index].which_lepton_has_fsr != 0){
597 SimpleLepton photon;
598 photon.vec.SetPtEtaPhiM( ZCandidatesLeptons[best_Z2_index].fsr_photon.Pt(), ZCandidatesLeptons[best_Z2_index].fsr_photon.Eta(), ZCandidatesLeptons[best_Z2_index].fsr_photon.Phi(), 0);
599 ret.fsrPhotons.push_back(photon);
600 }
601
602
603 int theZ1type = abs(ZCandidatesLeptons[best_Z1_index].lepton_pair.first.type);
604 int theZ2type = abs(ZCandidatesLeptons[best_Z2_index].lepton_pair.first.type);
605
606 if(ctrl.debug) cout << "best mZ2: " << (ret.Z2leptons[0].vec+ret.Z2leptons[1].vec).M() << " from ("
607 << ZCandidates[best_Z2_index].first << "," << ZCandidates[best_Z2_index].second << ")" << endl;
608
609 increment(counts,"sfOsHiPt",theZ1type,theZ2type);
610
611 if(ctrl.debug) cout << "ZZ :: evt: " << info->EvtNum()
612 << "\tmZ1: " << (ret.Z1leptons[0].vec+ret.Z1leptons[1].vec).M()
613 << "\tmZ2: " << (ret.Z2leptons[0].vec+ret.Z2leptons[1].vec).M()
614 << endl;
615
616
617 //******************************************************************************
618 // Step 6.4 : require Z2 with 4<m<120
619 //******************************************************************************
620 TLorentzVector Z2vec = (ZCandidatesLeptons[best_Z2_index].lepton_pair.first.vec) +
621 (ZCandidatesLeptons[best_Z2_index].lepton_pair.second.vec);
622 if( Z2vec.M() > 4 && Z2vec.M() < 120 ) {
623 ret.status.selectionBits.flip(PASS_GOODZ2);
624 increment(counts,"4<mZ2<120",theZ1type,theZ2type);
625 } else {
626 ret.status.setStatus(SelectionStatus::FAIL);
627 return ret;
628 }
629
630 //the resonance killing and the 10/20 pt cuts is done based on the leptons without fsr recovered to them
631 vector<SimpleLepton > zzleptons_nofsr;
632
633 //add all of the leptons to a vector and remove the fsr photon if there is one
634 if(ZCandidatesLeptons[best_Z1_index].which_lepton_has_fsr == 1){
635 SimpleLepton no_fsr_lepton = ZCandidatesLeptons[best_Z1_index].lepton_pair.first;
636 TLorentzVector photon_vec;
637 photon_vec.SetPtEtaPhiM(ZCandidatesLeptons[best_Z1_index].fsr_photon.Pt(),ZCandidatesLeptons[best_Z1_index].fsr_photon.Eta(),ZCandidatesLeptons[best_Z1_index].fsr_photon.Phi(),0);
638 no_fsr_lepton.vec = no_fsr_lepton.vec - photon_vec;
639 zzleptons_nofsr.push_back( no_fsr_lepton );
640 ret.Z1leptons_without_fsr.push_back(no_fsr_lepton);
641 }
642 else {
643 zzleptons_nofsr.push_back( ZCandidatesLeptons[best_Z1_index].lepton_pair.first);
644 ret.Z1leptons_without_fsr.push_back(ZCandidatesLeptons[best_Z1_index].lepton_pair.first);
645 }
646
647 if(ZCandidatesLeptons[best_Z1_index].which_lepton_has_fsr == 2){
648 SimpleLepton no_fsr_lepton = ZCandidatesLeptons[best_Z1_index].lepton_pair.second;
649 TLorentzVector photon_vec;
650 photon_vec.SetPtEtaPhiM(ZCandidatesLeptons[best_Z1_index].fsr_photon.Pt(),ZCandidatesLeptons[best_Z1_index].fsr_photon.Eta(),ZCandidatesLeptons[best_Z1_index].fsr_photon.Phi(),0);
651 no_fsr_lepton.vec = no_fsr_lepton.vec - photon_vec;
652 zzleptons_nofsr.push_back( no_fsr_lepton );
653 ret.Z1leptons_without_fsr.push_back(no_fsr_lepton);
654 }
655 else{
656 zzleptons_nofsr.push_back( ZCandidatesLeptons[best_Z1_index].lepton_pair.second);
657 ret.Z1leptons_without_fsr.push_back(ZCandidatesLeptons[best_Z1_index].lepton_pair.second);
658 }
659
660 if(ZCandidatesLeptons[best_Z2_index].which_lepton_has_fsr == 1){
661 SimpleLepton no_fsr_lepton = ZCandidatesLeptons[best_Z2_index].lepton_pair.first;
662 TLorentzVector photon_vec;
663 photon_vec.SetPtEtaPhiM(ZCandidatesLeptons[best_Z2_index].fsr_photon.Pt(),ZCandidatesLeptons[best_Z2_index].fsr_photon.Eta(),ZCandidatesLeptons[best_Z2_index].fsr_photon.Phi(),0);
664 no_fsr_lepton.vec = no_fsr_lepton.vec - photon_vec;
665 zzleptons_nofsr.push_back( no_fsr_lepton );
666 ret.Z2leptons_without_fsr.push_back(no_fsr_lepton);
667 }
668 else {
669 zzleptons_nofsr.push_back( ZCandidatesLeptons[best_Z2_index].lepton_pair.first);
670 ret.Z2leptons_without_fsr.push_back(ZCandidatesLeptons[best_Z2_index].lepton_pair.first);
671 }
672
673 if(ZCandidatesLeptons[best_Z2_index].which_lepton_has_fsr == 2){
674 SimpleLepton no_fsr_lepton = ZCandidatesLeptons[best_Z2_index].lepton_pair.second;
675 TLorentzVector photon_vec;
676 photon_vec.SetPtEtaPhiM(ZCandidatesLeptons[best_Z2_index].fsr_photon.Pt(),ZCandidatesLeptons[best_Z2_index].fsr_photon.Eta(),ZCandidatesLeptons[best_Z2_index].fsr_photon.Phi(),0);
677 no_fsr_lepton.vec = no_fsr_lepton.vec - photon_vec;
678 zzleptons_nofsr.push_back( no_fsr_lepton );
679 ret.Z2leptons_without_fsr.push_back(no_fsr_lepton);
680 }
681 else{
682 zzleptons_nofsr.push_back( ZCandidatesLeptons[best_Z2_index].lepton_pair.second);
683 ret.Z2leptons_without_fsr.push_back( ZCandidatesLeptons[best_Z2_index].lepton_pair.second);
684 }
685
686 //******************************************************************************
687 // Step 6.1 : any two leptons 20/10
688 //******************************************************************************
689
690 int nlep_above_10=0,nlep_above_20=0;
691 for( int i=0; i<zzleptons_nofsr.size(); i++ ) {
692 if(ctrl.debug){
693 }
694 if( zzleptons_nofsr[i].vec.Pt() > 10 ) nlep_above_10++;
695 if( zzleptons_nofsr[i].vec.Pt() > 20 ) nlep_above_20++;
696 }
697 if( nlep_above_10 > 1 && nlep_above_20 > 0 ) {
698 ret.status.selectionBits.flip(PASS_ZZ_20_10);
699 increment(counts,"pt>20,10",theZ1type,theZ2type);
700 if( ctrl.debug ) cout << "passess 20/10 ..." << endl;
701 } else {
702 ret.status.setStatus(SelectionStatus::FAIL);
703 return ret;
704 }
705
706
707 //******************************************************************************
708 // Step 6.5 : resonance killing (4/4)
709 //******************************************************************************
710
711 bool resonance = false;
712 for( int i=0; i<zzleptons_nofsr.size(); i++ ) {
713 for( int j=i+1; j<zzleptons_nofsr.size(); j++ ) {
714 if( zzleptons_nofsr[i].charge == zzleptons_nofsr[j].charge ) continue; // 4/4
715
716 if( (zzleptons_nofsr[i].vec+zzleptons_nofsr[j].vec).M() <= 4. ) {
717 resonance = true;
718 break;
719 }
720 }
721 }
722 if( !resonance ) {
723 ret.status.selectionBits.flip(PASS_RESONANCE);
724 increment(counts,"mll>4",theZ1type,theZ2type);
725 if( ctrl.debug ) cout << "\tpasses resonance killing ... " << endl;
726 } else {
727 ret.status.setStatus(SelectionStatus::FAIL);
728 return ret;
729 }
730
731
732
733 //******************************************************************************
734 // Step 6.6 : m(4l) > 70 , m(4l) > 100
735 //******************************************************************************
736 TLorentzVector zzvec = (ZCandidatesLeptons[best_Z1_index].lepton_pair.first.vec) +
737 (ZCandidatesLeptons[best_Z1_index].lepton_pair.second.vec) +
738 (ZCandidatesLeptons[best_Z2_index].lepton_pair.first.vec) +
739 (ZCandidatesLeptons[best_Z2_index].lepton_pair.second.vec);
740
741 if(ctrl.debug)
742 cout << "forming zz from: "
743 << setw(9) << (ZCandidatesLeptons[best_Z1_index].lepton_pair.first.vec).Pt()
744 << setw(9) << (ZCandidatesLeptons[best_Z1_index].lepton_pair.second.vec).Pt()
745 << setw(9) << (ZCandidatesLeptons[best_Z2_index].lepton_pair.first.vec).Pt()
746 << setw(9) << (ZCandidatesLeptons[best_Z2_index].lepton_pair.second.vec).Pt() << endl;
747
748 if( zzvec.M() > 70. ) {
749 if(ctrl.debug) cout << "passes mzz > 70, mzz: " << zzvec.M() << endl;
750 ret.status.selectionBits.flip(PASS_m4l_GT_70);
751 increment(counts,"m4l>70",theZ1type,theZ2type);
752 } else {
753 ret.status.setStatus(SelectionStatus::FAIL);
754 return ret;
755 }
756
757 if( (ret.Z2leptons[0].vec+ret.Z2leptons[1].vec).M() > 12 ){
758 if(ctrl.debug) cout << "passes mZ2 > 12" << endl;
759 increment(counts,"mZ2>12",theZ1type,theZ2type);
760 } else {
761 ret.status.setStatus(SelectionStatus::FAIL);
762 return ret;
763 }
764
765 if( zzvec.M() > 100 ) {
766 if(ctrl.debug) cout << "passes mzz > 100, mzz: " << zzvec.M() << endl;
767 increment(counts,"m4l>100",theZ1type,theZ2type);
768 } else {
769 ret.status.setStatus(SelectionStatus::FAIL);
770 //return ret;
771 // cout << "NOTE: failed m4l>100 (" << zzvec.M() << "), but saving to ntuple anyway" << endl;
772 }
773
774 //***************************************************************
775 // finish
776 //***************************************************************
777
778 TLorentzVector theZ1 = (ZCandidatesLeptons[best_Z1_index].lepton_pair.first.vec) +
779 (ZCandidatesLeptons[best_Z1_index].lepton_pair.second.vec);
780 TLorentzVector theZ2 = (ZCandidatesLeptons[best_Z2_index].lepton_pair.first.vec) +
781 (ZCandidatesLeptons[best_Z2_index].lepton_pair.second.vec);
782 TLorentzVector theZZ = theZ1 + theZ2;
783
784 // if(ret.fsrPhotons.size() > 0) {
785 // if(ctrl.debug)
786 // cout << " fsr photon! pt: "
787 // << setw(12) << ret.fsrPhotons[0].vec.Pt()
788 // << " eta: " << setw(12) << ret.fsrPhotons[0].vec.Eta()
789 // << " phi: " << setw(12) << ret.fsrPhotons[0].vec.Phi() << endl;
790 // }
791 // if(ret.fsrPhotons.size() > 1) {
792 // if(ctrl.debug)
793 // cout << " fsr photon! pt: "
794 // << setw(12) << ret.fsrPhotons[1].vec.Pt()
795 // << " eta: " << setw(12) << ret.fsrPhotons[1].vec.Eta()
796 // << " phi: " << setw(12) << ret.fsrPhotons[1].vec.Phi() << endl;
797 // }
798 if( ctrl.debug ) cout << "run: " << info->RunNum()
799 << "\tevt: " << info->EvtNum()
800 << "\tZ1channel: " << theZ1type
801 << "\tZ2channel: " << theZ2type
802 << "\tmZ1: " << theZ1.M()
803 << "\tmZ2: " << theZ2.M()
804 << "\tm4l: " << theZZ.M()
805 << endl;
806
807 ret.status.setStatus(SelectionStatus::EVTPASS);
808
809 return ret;
810 }
811 //----------------------------------------------------------------------------
812 void updateSimpleLepton(SimpleLepton &tmplep)
813 //----------------------------------------------------------------------------
814 {
815 tmplep.isTight = tmplep.status.tight();
816 tmplep.isLoose = tmplep.status.loose();
817 }