ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/FGolf/tcmet/selections.cc
Revision: 1.1
Committed: Sat Dec 5 02:59:03 2009 UTC (15 years, 5 months ago) by fgolf
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Error occurred while calculating annotation data.
Log Message:
looper for studying tcMET in CMSSW_3_1_2

File Contents

# Content
1 //===========================================================
2 //
3 // Various selection functions are kept here
4 //
5 //============================================================
6 #include <assert.h>
7 #include <algorithm>
8 #include "Math/LorentzVector.h"
9 #include "Math/VectorUtil.h"
10 #include "TMath.h"
11 #include "TLorentzVector.h"
12 #include "TDatabasePDG.h"
13 #include "selections.h"
14
15 // CMS2 includes
16 #include "CMS2.h"
17 #include "utilities.h"
18
19 typedef ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > LorentzVector;
20
21 //----------------------------------------------------------------
22 // Simple function that tells you whether or not a track passed
23 // a particular quality flag.
24 //----------------------------------------------------------------
25 bool isTrackQuality( int index, int cuts ) {
26 return ( ( cms2.trks_qualityMask().at(index) & cuts ) == cuts );
27 }
28
29
30 //----------------------------------------------------------------
31 // A ridicolusly simple function, but since the Z veto is used
32 // in two places, might as well centralize it to keep consistency
33 //----------------------------------------------------------------
34 bool inZmassWindow (float mass) {
35 if (mass > 76. && mass < 106.) return true;
36 return false;
37 }
38 //----------------------------------------------------------------
39 // true electron
40 //----------------------------------------------------------------
41 bool trueElectron(int index) {
42 if ( TMath::Abs(cms2.els_mc_id()[index]) != 11 ) return false;
43 // if ( TMath::Abs(cms2.els_mc_motherid()[index]) == 23 || TMath::Abs(cms2.els_mc_motherid()[index]) == 24) return true;
44 return true;
45 }
46 // //----------------------------------------------------------------
47 // // true muon
48 // //----------------------------------------------------------------
49 bool trueMuon(int index) {
50 if ( TMath::Abs(cms2.mus_mc_id()[index]) != 13 ) return false;
51 // if ( TMath::Abs(cms2.mus_mc_motherid()[index]) == 23 || TMath::Abs(cms2.mus_mc_motherid()[index]) == 24) return true;
52 return true;
53 }
54 //----------------------------------------------------------------
55 // Electron ID without isolation
56 //----------------------------------------------------------------
57 bool goodElectronWithoutIsolation(int index) {
58 if ( cms2.els_egamma_tightId().at(index) != 1) return false;
59 if ( cms2.els_closestMuon().at(index) != -1) return false;
60 if ( TMath::Abs(cms2.els_d0corr().at(index)) > 0.025) return false;
61 return true;
62 }
63
64 //----------------------------------------------------------------
65 // MC truth tag - Muon from W
66 //----------------------------------------------------------------
67 bool trueMuonFromW_WJets(int index) {
68
69 // added requirement for muon to have pt>20
70 double pt_cut = 20.;
71 // double pt_cut = 0.;
72
73 // try to find out if there is a muon
74 // from W. Currently valid ONLY on WJets!!
75 if ( TMath::Abs(cms2.mus_mc_id()[index]) == 13 && ( TMath::Abs(cms2.mus_mc_motherid()[index]) == 24) && cms2.mus_p4().at(index).pt() > pt_cut ) {
76 // std::cout<<"best match - part id: "<<(cms2.mus_mc_id()[index])<<" mother: "<<(cms2.mus_mc_motherid()[index])<<std::endl;
77 return true;
78 }
79 // need additional loop over status 3 particles
80 // if it contains a W and an muon from W, we claim
81 // that the muon is from W - valid for WJets
82 unsigned int nGen = cms2.genps_id().size();
83 for( unsigned int iGen = 0; iGen < nGen; ++iGen){
84 // just in case the mother link does work :)
85 if ( cms2.genps_status()[iGen] == 3 && TMath::Abs(cms2.genps_id()[iGen]) == 13 && TMath::Abs(cms2.genps_id_mother()[iGen]) == 24 && cms2.genps_p4()[iGen].pt() > pt_cut ) {
86 // std::cout<<"2nd best match part id: "<<cms2.genps_id()[iGen]<<" mother: "<<cms2.genps_id_mother()[iGen]<<std::endl;
87 return true;
88 }
89 // also return true if there is a status 3 muon
90 if ( cms2.genps_status()[iGen] == 3 && TMath::Abs(cms2.genps_id()[iGen]) == 13 && cms2.genps_p4()[iGen].pt() > pt_cut ) {
91 // std::cout<<"3rd best match part id: "<<cms2.genps_id()[iGen]<<" mother: NOT CHECKED"<<std::endl;
92 return true;
93 }
94 // if ( TMath::Abs(cms2.genps_id_mother()[iGen]) == 23 ) return true;
95 // if ( TMath::Abs(cms2.genps_id_mother()[iGen]) == 24 ) return true;
96 }
97
98 return false;
99 }
100
101
102 //----------------------------------------------------------------
103 // MC truth tag - Electron from W
104 //----------------------------------------------------------------
105 bool trueElectronFromW_WJets(int index) {
106 // try to find out if there is a electron
107 // from W. Currently valid ONLY on WJets!!
108 if ( TMath::Abs(cms2.els_mc_id()[index]) == 11 && ( TMath::Abs(cms2.els_mc_motherid()[index]) == 24) ) {
109 // std::cout<<"best match - part id: "<<(cms2.els_mc_id()[index])<<" mother: "<<(cms2.els_mc_motherid()[index])<<std::endl;
110 return true;
111 }
112 // need additional loop over status 3 particles
113 // if it contains a W and an electron from W, we claim
114 // that the electron is from W - valid for WJets
115 unsigned int nGen = cms2.genps_id().size();
116 for( unsigned int iGen = 0; iGen < nGen; ++iGen){
117 // just in case the mother link does work :)
118 if ( cms2.genps_status()[iGen] == 3 && TMath::Abs(cms2.genps_id()[iGen]) == 11 && TMath::Abs(cms2.genps_id_mother()[iGen]) == 24 ) {
119 // std::cout<<"2nd best match part id: "<<cms2.genps_id()[iGen]<<" mother: "<<cms2.genps_id_mother()[iGen]<<std::endl;
120 return true;
121 }
122 // also return true if there is a status 3 electron
123 if ( cms2.genps_status()[iGen] == 3 && TMath::Abs(cms2.genps_id()[iGen]) == 11 ) {
124 // std::cout<<"3rd best match part id: "<<cms2.genps_id()[iGen]<<" mother: NOT CHECKED"<<std::endl;
125 return true;
126 }
127 }
128
129 return false;
130 }
131
132
133 //----------------------------------------------------------------
134 // Electron ID without isolation or d0 cut
135 //----------------------------------------------------------------
136 bool goodElectronWithoutIsolationWithoutd0(int index) {
137 if ( cms2.els_egamma_tightId().at(index) != 1) return false;
138 if ( cms2.els_closestMuon().at(index) != -1) return false;
139 return true;
140 }
141 //----------------------------------------------------------------
142 // loose Electron ID without isolation
143 //----------------------------------------------------------------
144 bool goodLooseElectronWithoutIsolation(int index) {
145 if ( cms2.els_egamma_looseId().at(index) != 1) return false;
146 if ( cms2.els_closestMuon().at(index) != -1) return false;
147 if ( TMath::Abs(cms2.els_d0corr().at(index)) > 0.025) return false;
148 return true;
149 }
150 //----------------------------------------------------------------
151 // Muon ID without isolation
152 //---------------------------------------------------------------
153 bool goodMuonWithoutIsolation(int index) {
154 if (cms2.mus_gfit_chi2().at(index)/cms2.mus_gfit_ndof().at(index) > 10.) return false;
155 if (TMath::Abs(cms2.mus_d0corr().at(index)) > 0.2) return false;
156 if (cms2.mus_validHits().at(index) < 11) return false;
157 if ( (cms2.mus_type().at(index)&0x2)==0 ) return false;
158 return true;
159 }
160 //-----------------------------------------------------------
161 // Electron Isolation using pat iso
162 //-----------------------------------------------------------
163 double el_rel_iso (int index, bool use_calo_iso)
164 {
165 double sum = cms2.els_pat_trackIso().at(index);
166 if (use_calo_iso)
167 sum += cms2.els_pat_ecalIso()[index] + cms2.els_pat_hcalIso()[index];
168
169 double pt = cms2.els_p4().at(index).pt();
170 return pt / (pt + sum + 1e-5);
171 }
172 bool passElectronIsolation(int index, bool use_calo_iso)
173 {
174 const double cut = 0.92;
175 return el_rel_iso(index, use_calo_iso) > cut;
176 }
177
178 bool passElectronIsolationLoose(int index, bool use_calo_iso)
179 {
180 const double cut = 0.8; // leads to 91 pred, 81 obs
181 return el_rel_iso(index, use_calo_iso) > cut;
182 }
183
184 bool passElectronIsolationLoose2(int index, bool use_calo_iso)
185 {
186 // const double cut = 0.85; leads to 107 pred, 81 obs
187 const double cut = 0.75;
188 return el_rel_iso(index, use_calo_iso) > cut;
189 }
190
191 //=================================================
192 // lepton isolation: use id of the lepton do decode
193 //-------------------------------------------------
194 bool passLeptonIsolation(int id, int index, bool use_ele_calo_iso){
195 if (abs(id)==11) return passElectronIsolation(index, use_ele_calo_iso);
196 if (abs(id)==13) return passMuonIsolation(index);
197 return false;
198 }
199
200 //-----------------------------------------------------------
201 // Electron Isolation using ECAL clusters
202 //-----------------------------------------------------------
203 double el_rel_iso_1_6 (int index, bool use_calo_iso)
204 {
205 double sum = cms2.els_tkIso().at(index);
206 if (use_calo_iso)
207 sum += cms2.els_ecalJuraIso()[index] + cms2.els_hcalConeIso()[index];
208 double pt = cms2.els_p4().at(index).pt();
209 return pt / (pt + sum+1e-5);
210 }
211
212 bool passElectronIsolation_1_6 (int index, bool use_calo_iso)
213 {
214 const double cut = 0.92;
215 return el_rel_iso_1_6(index, use_calo_iso) > cut;
216 }
217
218 bool passElectronIsolationLoose_1_6 (int index, bool use_calo_iso)
219 {
220 const double cut = 0.8; // leads to 91 pred, 81 obs
221 return el_rel_iso_1_6(index, use_calo_iso) > cut;
222 }
223
224 bool passElectronIsolationLoose2_1_6 (int index, bool use_calo_iso)
225 {
226 // const double cut = 0.85; leads to 107 pred, 81 obs
227 const double cut = 0.75;
228 return el_rel_iso_1_6(index, use_calo_iso) > cut;
229 }
230 //-----------------------------------------------------------
231 // Muon Isolation
232 //-----------------------------------------------------------
233 double mu_rel_iso (int index)
234 {
235 double sum = cms2.mus_iso03_sumPt().at(index) +
236 cms2.mus_iso03_emEt().at(index) +
237 cms2.mus_iso03_hadEt().at(index);
238 double pt = cms2.mus_p4().at(index).pt();
239 return pt / (pt+sum+1e-5);
240
241 }
242 bool passMuonIsolation(int index)
243 {
244 return mu_rel_iso(index) > 0.92;
245 }
246
247 bool passMuonIsolationLoose(int index)
248 {
249 // const double cut = 0.85; leads to 107 pred, 81 obs
250 const double cut = 0.75;
251 return mu_rel_iso(index) > cut;
252 }
253
254 //--------------------------------------------
255 // Muon ID with isolation
256 //--------------------------------------------
257 bool goodMuonIsolated(int index) {
258 if (!goodMuonWithoutIsolation(index)) return false;
259 if (!passMuonIsolation(index)) return false;
260 return true;
261 }
262 //--------------------------------------------
263 // Electron ID with isolation
264 //--------------------------------------------
265 bool goodElectronIsolated(int index, bool use_calo_iso) {
266 // if (!goodElectronWithoutIsolationWithoutd0(index)) return false;
267 if (!goodElectronWithoutIsolation(index)) return false;
268 if (!passElectronIsolation(index, use_calo_iso)) return false;
269 return true;
270 }
271 //--------------------------------------------
272 // "super-tight" Electron ID (to kill EM fakes)
273 //--------------------------------------------
274 bool supertightElectron (int index)
275 {
276 if (TMath::Abs(cms2.els_p4()[index].eta()) > 1.479)
277 return false;
278 if (cms2.els_sigmaPhiPhi()[index] > 0.018)
279 return false;
280 if (cms2.els_sigmaEtaEta()[index] > 0.009)
281 return false;
282 if (cms2.els_eOverPIn()[index] > 2 || cms2.els_eOverPIn()[index] < 0.75)
283 return false;
284 if (cms2.els_charge()[index] * cms2.els_dPhiIn()[index] > 0.04)
285 return false;
286 if (cms2.els_charge()[index] * cms2.els_dPhiOut()[index] < -1e-3)
287 return false;
288 if (cms2.els_dEtaIn()[index] > 0.0025 || cms2.els_dEtaIn()[index] < -0.0025)
289 return false;
290 return true;
291 }
292 //--------------------------------------------
293 // tighter cut on delta phi in (to kill more fakes)
294 //--------------------------------------------
295 bool deltaPhiInElectron (int index)
296 {
297 return cms2.els_charge()[index] * cms2.els_dPhiIn()[index] < 0.04;
298 }
299
300 //--------------------------------------------
301 // Fudge to reject events where the LT muon
302 // has a badly measured momentum
303 //--------------------------------------------
304 bool muonReconstructionCleaning(int i_hyp, float threshold)
305 {
306 // only apply to mm hyp type
307 if (cms2.hyp_type()[i_hyp] == 0)
308 {
309 if (fabs((cms2.hyp_lt_trk_p4()[i_hyp].Pt()
310 /cms2.hyp_lt_p4()[i_hyp].Pt()) - 1) > threshold) return false;
311 }
312 return true;
313 }
314
315 //
316 // Refactorized MET cuts
317 //
318 //--------------------------------------------
319 // 'simple' MET selection
320 //--------------------------------------------
321 bool metSimple (float threshold, const TVector3& corr) {
322 TVector3 hyp_met;
323 hyp_met.SetPtEtaPhi(cms2.evt_tcmet(), 0, cms2.evt_tcmetPhi());
324 hyp_met += corr;
325 if (hyp_met.Pt() < threshold) return false;
326 return true;
327 }
328 //--------------------------------------------
329 // pT(ll)/MET ratio selection
330 //--------------------------------------------
331 bool metBalance (int i_hyp, const TVector3& corr) {
332 TVector3 hyp_met;
333 hyp_met.SetPtEtaPhi(cms2.evt_tcmet(), 0, cms2.evt_tcmetPhi());
334 hyp_met += corr;
335 if(hyp_met.Pt()/cms2.hyp_p4()[i_hyp].pt() < 0.6 &&
336 acos(cos(hyp_met.Phi()-cms2.hyp_p4()[i_hyp].phi() - 3.1416)) < 0.25 ) return false;
337 return true;
338 }
339 //--------------------------------------------
340 // pMET selection
341 //--------------------------------------------
342 bool metProjected (int i_hyp, const TVector3& corr) {
343 TVector3 hyp_met;
344 hyp_met.SetPtEtaPhi(cms2.evt_tcmet(), 0, cms2.evt_tcmetPhi());
345 hyp_met += corr;
346 double metspec = MetSpecial(hyp_met.Pt(), hyp_met.Phi(), i_hyp);
347 if ( metspec < 20 ) return false;
348 return true;
349 }
350 //--------------------------------------------
351 // PASS5 MET
352 //--------------------------------------------
353 bool pass5Met (int i_hyp, const TVector3& corr) {
354 // for e-e and mu-mu
355 if (cms2.hyp_type()[i_hyp] == 0 || cms2.hyp_type()[i_hyp] == 3) {
356 if(!metSimple(45.0, corr)) return false;
357 if(!metBalance(i_hyp, corr)) return false;
358 if(!metProjected(i_hyp, corr)) return false;
359 }
360 // for e-mu and mu-e
361 if (cms2.hyp_type()[i_hyp] == 1 || cms2.hyp_type()[i_hyp] == 2) {
362 if(!metSimple(20.0, corr)) return false;
363 if(!metProjected(i_hyp, corr)) return false;
364 }
365 return true;
366 }
367 //
368 // end refactorized MET cuts
369 //
370
371 //--------------------------------------------
372 // Pass 2 MET selection
373 //--------------------------------------------
374 bool pass2Met (int i_hyp, const TVector3& corr) {
375 // for e-e and mu-mu
376 TVector3 hyp_met;
377 hyp_met.SetPtEtaPhi(cms2.evt_tcmet(), 0, cms2.evt_tcmetPhi());
378 hyp_met += corr;
379 if (cms2.hyp_type()[i_hyp] == 0 || cms2.hyp_type()[i_hyp] == 3) {
380 if (hyp_met.Pt() < 30) return false;
381 // if ( TMath::Abs(hyp_p4[i_hyp]->mass()-90.0)<10.0) return false;
382 if( hyp_met.Pt()/cms2.hyp_p4()[i_hyp].pt()<0.6 &&
383 acos(cos(hyp_met.Phi()-cms2.hyp_p4()[i_hyp].phi()-3.1416))<0.25 ) return false;
384 }
385 // for e-mu and mu-e
386 if (cms2.hyp_type()[i_hyp] == 1 || cms2.hyp_type()[i_hyp] == 2) {
387 if (hyp_met.Pt() < 20) return false;
388 }
389 return true;
390 }
391
392 double nearestDeltaPhiJet(double Phi, int i_hyp) {
393
394 double result = TMath::Pi();
395
396 std::vector<LorentzVector> jets = JPTsTrilep(i_hyp, 20);
397
398 for ( unsigned int jet = 0;
399 jet < jets.size();
400 ++jet ) {
401 double delta = TMath::Min(TMath::Abs(jets[jet].Phi() - Phi), 2*TMath::Pi() - TMath::Abs(jets[jet].Phi() - Phi));
402 if ( delta < result )
403 result = delta;
404 }
405
406 return result;
407 }
408
409 double nearestDeltaPhi(double Phi, int i_hyp)
410 {
411 //WARNING! This was designed to work in a dilepton environment - NOT a trilepton
412 double tightDPhi = TMath::Min(TMath::Abs(cms2.hyp_lt_p4()[i_hyp].Phi() - Phi), 2*TMath::Pi() - TMath::Abs(cms2.hyp_lt_p4()[i_hyp].Phi() - Phi));
413 double looseDPhi = TMath::Min(TMath::Abs(cms2.hyp_ll_p4()[i_hyp].Phi() - Phi), 2*TMath::Pi() - TMath::Abs(cms2.hyp_ll_p4()[i_hyp].Phi() - Phi));
414
415 return TMath::Min(tightDPhi, looseDPhi);
416
417 }//END nearest DeltaPhi
418
419 double nearestDeltaPhiTrilep(double Phi, int i_hyp)
420 {
421 //WARNING! This was designed to work in a trilepton environment - NOT a dilepton
422
423 LorentzVector first,second,third;
424 if (abs(cms2.hyp_trilep_first_type()[i_hyp]) == 1) {
425 first = cms2.mus_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
426 } else {
427 first = cms2.els_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
428 }
429 if (abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1) {
430 second = cms2.mus_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
431 } else {
432 second = cms2.els_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
433 }
434 if (abs(cms2.hyp_trilep_third_type()[i_hyp]) == 1) {
435 third = cms2.mus_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
436 } else {
437 third = cms2.els_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
438 }
439
440 double firstDPhi = TMath::Min(TMath::Abs(first.Phi() - Phi), 2*TMath::Pi() - TMath::Abs(first.Phi() - Phi));
441 double secondDPhi = TMath::Min(TMath::Abs(second.Phi() - Phi), 2*TMath::Pi() - TMath::Abs(second.Phi() - Phi));
442 double thirdDPhi = TMath::Min(TMath::Abs(third.Phi() - Phi), 2*TMath::Pi() - TMath::Abs(third.Phi() - Phi));
443
444 return TMath::Min(TMath::Min(firstDPhi, secondDPhi),thirdDPhi);
445
446 }//END nearest DeltaPhi
447
448 double MetSpecial(double Met, double MetPhi, int i_hyp)
449 {
450 //Warning, this was designed to work in a dilepton environment - NOT a trilepton
451 double DeltaPhi = nearestDeltaPhi(MetPhi,i_hyp);
452
453 if (DeltaPhi < TMath::Pi()/2) return Met*TMath::Sin(DeltaPhi);
454 else return Met;
455
456 return -1.0;
457 }//END MetSpecial calculation
458
459 double MetSpecialTrilep(double Met, double MetPhi, int i_hyp)
460 {
461 //Warning, this was designed to work in a trilepton environment - NOT a dilepton
462 double DeltaPhi = nearestDeltaPhiTrilep(MetPhi,i_hyp);
463
464 if (DeltaPhi < TMath::Pi()/2) return Met*TMath::Sin(DeltaPhi);
465 else return Met;
466
467 return -1.0;
468 }//END MetSpecial calculation
469
470 //--------------------------------------------
471 // Pass 4 MET selection
472 // Use MetSpecial from CDF for now
473 //--------------------------------------------
474 bool pass4Met(int i_hyp, const TVector3& corr) {
475 TVector3 hyp_met;
476 hyp_met.SetPtEtaPhi(cms2.evt_tcmet(), 0, cms2.evt_tcmetPhi());
477 hyp_met += corr;
478 double metspec = MetSpecial(hyp_met.Pt(), hyp_met.Phi(), i_hyp);
479 if (cms2.hyp_type()[i_hyp] == 0 || cms2.hyp_type()[i_hyp] == 3) {
480 if ( metspec < 20 ) return false;
481 //if ( metspec < 20 && hyp_p4->mass() < 90 ) return false;
482 if ( hyp_met.Pt() < 45 ) return false;
483 }
484 else if (cms2.hyp_type()[i_hyp] == 1 || cms2.hyp_type()[i_hyp] == 2) {
485 //if ( metspec < 20 && hyp_p4->mass() < 90 ) return false;
486 if ( metspec < 20 ) return false;
487 }
488 return true;
489 }
490
491 //-------------------------------------------
492 // plain SUMET cut for reducing SM contribution
493 // in WW selection to 10%
494 //-------------------------------------------
495 bool sumEt10(double sumEt) {
496 // std::cout<<"cutting on sumEt10: "<<sumEt<<std::endl;
497 if ( sumEt < 225 ) return false;
498 return true;
499 }
500
501 //-------------------------------------------
502 // plain SUMET cut for reducing SM contribution
503 // in WW selection to 1%
504 //-------------------------------------------
505 bool sumEt1(double sumEt) {
506 if ( sumEt < 525 ) return false; // good for ~1%? currently "optimizing"
507 return true;
508 }
509
510 //-------------------------------------------------
511 // Auxiliary function to scan the doc line and
512 // identify DY-> ee vs mm vs tt
513 //-------------------------------------------------
514 int getDrellYanType() {
515 bool foundEP = false;
516 bool foundEM = false;
517 bool foundMP = false;
518 bool foundMM = false;
519 bool foundTP = false;
520 bool foundTM = false;
521 for (unsigned int i = 0; i < cms2.genps_id().size(); ++i) {
522 if ( cms2.genps_id_mother().at(i) == 23 ){
523 switch ( TMath::Abs(cms2.genps_id().at(i)) ){
524 case 11:
525 return 0;
526 break;
527 case 13:
528 return 1;
529 break;
530 case 15:
531 return 2;
532 break;
533 default:
534 break;
535 }
536 }
537 switch ( cms2.genps_id().at(i) ){
538 case 11:
539 foundEM = true;
540 break;
541 case -11:
542 foundEP = true;
543 break;
544 case 13:
545 foundMM = true;
546 break;
547 case -13:
548 foundMP = true;
549 break;
550 case 15:
551 foundTM = true;
552 break;
553 case -15:
554 foundTP = true;
555 break;
556 default:
557 break;
558 }
559 }
560
561 if ( foundEP && foundEM ) return 0; //DY->ee
562 if ( foundMP && foundMM ) return 1; //DY->mm
563 if ( foundTP && foundTM ) return 2; //DY->tautau
564 std::cout << "Does not look like a DY event" << std::endl;
565 return 999;
566 }
567
568 int getVVType() {
569 // types:
570 // 0 - WW
571 // 1 - WZ
572 // 2 - ZZ
573 unsigned int nZ(0);
574 unsigned int nW(0);
575 std::vector<std::vector<int> > leptons;
576 std::vector<int> mothers;
577
578 bool verbose = false;
579
580 for (unsigned int i = 0; i < cms2.genps_id().size(); ++i) {
581 int pid = cms2.genps_id().at(i);
582 int mid = cms2.genps_id_mother().at(i);
583 if ( verbose ) std::cout << "Gen particle id: " << pid << ",\t mother id: " << mid <<std::endl;
584 if ( abs(pid)<11 || abs(pid)>16 ) continue;
585 if ( mid == 23 ) ++nZ;
586 if ( abs(mid) == 24 ) ++nW;
587 // now we need to really understand the pattern.
588 unsigned int mIndex = 0;
589 while ( mIndex < mothers.size() && mid != mothers[mIndex] ) ++mIndex;
590 if ( mIndex == mothers.size() ) {
591 mothers.push_back(mid);
592 leptons.push_back(std::vector<int>());
593 }
594 leptons[mIndex].push_back(pid);
595 if (mothers.size()>3){
596 if (verbose) std::cout << "WARNING: failed to identify event (too many mothers)" << std::endl;
597 return 999;
598 }
599 }
600
601 if ( nZ == 4 ) {
602 if ( verbose ) std::cout << "Event type ZZ" << std::endl;
603 return 2;
604 }
605 if ( nW == 4 ) {
606 if ( verbose ) std::cout << "Event type WW" << std::endl;
607 return 0;
608 }
609 if ( nW == 2 && nZ == 2 ) {
610 if ( verbose ) std::cout << "Event type WZ" << std::endl;
611 return 1;
612 }
613 unsigned int nNus(0);
614 for ( unsigned int i=0; i<mothers.size(); ++i ){
615 nNus += leptons[i].size();
616 }
617 if ( mothers.size() < 3 && nNus == 4){
618 for ( unsigned int i=0; i<mothers.size(); ++i ){
619 if ( mothers[i] != 23 && abs(mothers[i]) != 24 ){
620 if( leptons[i].size() != 2 && leptons[i].size() != 4){
621 if (verbose) std::cout << "WARNING: failed to identify event (unexpected number of daughters)" << std::endl;
622 if (verbose) std::cout << "\tnumber of daughters for first mother: " << leptons[0].size() << std::endl;
623 if (verbose) std::cout << "\tnumber of daughters for second mother: " << leptons[1].size() << std::endl;
624 return 999;
625 }
626 if ( abs(leptons[i][0]) == abs(leptons[i][1]) )
627 nZ += 2;
628 else
629 nW += 2;
630 if ( leptons[i].size()==4 ){
631 // now it's a wild guess, it's fraction should be small
632 if ( abs(leptons[i][2]) == abs(leptons[i][3]) )
633 nZ += 2;
634 else
635 nW += 2;
636 }
637 }
638 }
639 } else {
640 // here be dragons
641
642 // if we have 2 leptons and 3 neutrinos and they all of the same
643 // generation, we assume it's ZZ (can be WZ also), but if
644 // neutrinos are from different generations, than we conclude it's
645 // WZ.
646
647 std::set<int> nus;
648 for ( unsigned int i=0; i<mothers.size(); ++i )
649 for ( unsigned int j=0; j<leptons[i].size(); ++j )
650 if ( abs(leptons[i][j]) == 12 ||
651 abs(leptons[i][j]) == 14 ||
652 abs(leptons[i][j]) == 16 )
653 nus.insert(abs(leptons[i][j]));
654
655 if ( nNus == 5 ){
656 if ( nus.size() == 1 ) return 2;
657 if ( nus.size() == 2 ) return 1;
658 }
659
660 if ( verbose ) std::cout << "WARNING: failed to identify event" << std::endl;
661 return 999;
662 }
663
664 if ( nZ+nW != 4 ){
665 if (verbose) std::cout << "WARNING: failed to identify event (wrong number of bosons)" << std::endl;
666 if (verbose) std::cout << "\tfirst mother id: " << mothers[0] << std::endl;
667 if (verbose) std::cout << "\tsecond mother id: " << mothers[1] << std::endl;
668 if (verbose) std::cout << "\tnumber of daughters for first mother: " << leptons[0].size() << std::endl;
669 if (verbose) std::cout << "\tnumber of daughters for second mother: " << leptons[1].size() << std::endl;
670 if (verbose) std::cout << "\tnumber of Zs: " << nZ << std::endl;
671 if (verbose) std::cout << "\tnumber of Ws: " << nW << std::endl;
672 return 999;
673 }
674
675 if ( nZ == 4 ) {
676 if ( verbose ) std::cout << "Event type ZZ" << std::endl;
677 return 2;
678 }
679 if ( nW == 4 ) {
680 if ( verbose ) std::cout << "Event type WW" << std::endl;
681 return 0;
682 }
683 // this covers screws in logic, i.e. most hard to identify events end up being WZ
684 if ( verbose ) std::cout << "Event type WZ (can be wrong)" << std::endl;
685 return 1;
686 }
687
688 //-------------------------------------------------
689 // Auxiliary function to scan the doc line and
690 // identify DY-> ee vs mm vs tt
691 //-------------------------------------------------
692 int getWType()
693 {
694 bool foundE = false;
695 bool foundNuE = false;
696 bool foundM = false;
697 bool foundNuM = false;
698 bool foundT = false;
699 bool foundNuT = false;
700 for (unsigned int i = 0; i < cms2.genps_id().size(); ++i) {
701 if ( abs(cms2.genps_id_mother().at(i)) == 24 ){
702 switch ( TMath::Abs(cms2.genps_id().at(i)) ){
703 case 11:
704 return 0;
705 break;
706 case 13:
707 return 1;
708 break;
709 case 15:
710 return 2;
711 break;
712 default:
713 break;
714 }
715 }
716 switch ( abs(cms2.genps_id().at(i)) ){
717 case 11:
718 foundE = true;
719 break;
720 case 12:
721 foundNuE = true;
722 break;
723 case 13:
724 foundM = true;
725 break;
726 case 14:
727 foundNuM = true;
728 break;
729 case 15:
730 foundT = true;
731 break;
732 case 16:
733 foundNuT = true;
734 break;
735 default:
736 break;
737 }
738 }
739
740 if ( foundE && foundNuE ) return 0; //W->e
741 if ( foundM && foundNuM ) return 1; //W->m
742 if ( foundT && foundNuT ) return 2; //W->t
743 std::cout << "Does not look like a W event" << std::endl;
744 return 999;
745 }
746
747 //--------------------------------------------
748 // Booleans for DY
749 //------------------------------------------
750 bool isDYee() {
751 if (getDrellYanType() == 0) return true;
752 return false;
753 }
754 bool isDYmm() {
755 if (getDrellYanType() == 1) return true;
756 return false;
757 }
758 bool isDYtt() {
759 if (getDrellYanType() == 2) return true;
760 return false;
761 }
762
763 //--------------------------------------------
764 // Booleans for Wjets
765 //------------------------------------------
766 bool isWe()
767 {
768 if (getWType() == 0) return true;
769 return false;
770 }
771 bool isWm()
772 {
773 if (getWType() == 1) return true;
774 return false;
775 }
776 bool isWt()
777 {
778 if (getWType() == 2) return true;
779 return false;
780 }
781
782 //--------------------------------------------
783 // Booleans for VVjets
784 //------------------------------------------
785
786 bool isWW() {
787 if (getVVType() == 0) return true;
788 return false;
789 }
790
791 bool isWZ() {
792 if (getVVType() == 1) return true;
793 return false;
794 }
795
796 bool isZZ() {
797 if (getVVType() == 2) return true;
798 return false;
799 }
800
801 //--------------------------------------------
802 // ZZ type:
803 // 0 for Z1 --> ee, mm; Z2 --> ee, mm
804 // 1 for Z1 --> ee, mm; Z2 --> tt (and v.v.)
805 // 2 for Z1 --> tt; Z2 --> tt
806 // 995 to 999 otherwise
807 //------------------------------------------
808 int getZZType()
809 {
810 int foundEP = 0;
811 int foundEM = 0;
812 int foundMP = 0;
813 int foundMM = 0;
814 int foundTP = 0;
815 int foundTM = 0;
816 for (unsigned int i = 0; i < cms2.genps_id().size(); ++i) {
817 switch ( cms2.genps_id().at(i) ){
818 case 11:
819 foundEM++;
820 break;
821 case -11:
822 foundEP++;
823 break;
824 case 13:
825 foundMM++;
826 break;
827 case -13:
828 foundMP++;
829 break;
830 case 15:
831 foundTM++;
832 break;
833 case -15:
834 foundTP++;
835 break;
836 default:
837 break;
838 }
839 }
840
841 if (foundEM == foundEP && foundMM == foundMP && (foundEM != 0 || foundMM != 0)) {
842 // both Zs decay to e or mu
843 if (foundEM + foundMM == 2)
844 return 0;
845 // one Z decays to e or mu
846 else if (foundEM + foundMM == 1)
847 // other Z decays to tau
848 if (foundTP == 1 && foundTM == 1)
849 return 1;
850 else return 995;
851 else return 996;
852 } else if (foundEM == 0 && foundEP == 0 && foundMM == 0 && foundMP == 0) {
853 // both Zs decay to tau
854 if (foundTP == 2 && foundTM == 2)
855 return 2;
856 else return 997;
857 } else return 998;
858 return 999;
859 }
860
861 bool additionalZveto() {
862 //--------------------------------------------------------------------
863 // Veto events if there are two leptons in the
864 // event that make the Z mass. This uses additionalZcounter below...
865 //---------------------------------------------------------------------
866 bool veto = false;
867 if (additionalZcounter() > 0) veto = true;
868 return veto;
869 }
870
871
872 //--------------------------------------------------------------------
873 // Count Z candidets into two leptons in the
874 // event that make the Z mass. This uses the mus and els
875 // blocks,
876 //
877 // Both leptons must be 20 GeV, and pass the same cuts as
878 // the hypothesis leptons, except that one of them can be non-isolated
879 //---------------------------------------------------------------------
880 int additionalZcounter() {
881
882 // true if we want to veto this event
883 int Zcount = 0;
884
885 // first, look for Z->mumu
886 for (unsigned int i=0; i < cms2.mus_p4().size(); i++) {
887 if (cms2.mus_p4().at(i).pt() < 20.) continue;
888 if (!goodMuonWithoutIsolation(i)) continue;
889
890 for (unsigned int j=i+1; j < cms2.mus_p4().size(); j++) {
891 if (cms2.mus_p4().at(j).pt() < 20.) continue;
892 if (!goodMuonWithoutIsolation(j)) continue;
893 if (cms2.mus_charge().at(i) == cms2.mus_charge().at(j)) continue;
894
895 // At least one of them has to pass isolation
896 if (!passMuonIsolation(i) && !passMuonIsolation(j)) continue;
897
898 // Make the invariant mass
899 LorentzVector vec = cms2.mus_p4().at(i) + cms2.mus_p4().at(j);
900 if ( inZmassWindow(vec.mass()) ) Zcount++;
901
902 }
903 }
904
905 // now, look for Z->ee
906 for (unsigned int i=0; i < cms2.els_p4().size(); i++) {
907 if (cms2.els_p4().at(i).pt() < 20.) continue;
908 if (!goodElectronWithoutIsolation(i)) continue;
909
910 for (unsigned int j=i+1; j<cms2.els_p4().size(); j++) {
911 if (cms2.els_p4().at(j).pt() < 20.) continue;
912 if (!goodElectronWithoutIsolation(j)) continue;
913 if (cms2.els_charge().at(i) == cms2.els_charge().at(j)) continue;
914
915 // At least one of them has to pass isolation
916 if (!passElectronIsolation(i, false) && !passElectronIsolation(j, false)) continue;
917
918 // Make the invariant mass
919 LorentzVector vec = cms2.els_p4().at(i) + cms2.els_p4().at(j);
920 if ( inZmassWindow(vec.mass()) ) Zcount++;
921
922 }
923 }
924 // done
925 return Zcount;
926 }
927
928 //------------------------------------------------------------
929 // Not a selection function per se, but useful nonetheless:
930 // dumps the documentation lines for this event
931 //------------------------------------------------------------
932 void dumpDocLines() {
933 int size = cms2.genps_id().size();
934 // Initialize particle database
935 TDatabasePDG *pdg = new TDatabasePDG();
936 std::cout << "------------------------------------------" << std::endl;
937 for (int j=0; j<size; j++) {
938 cout << setw(9) << left << pdg->GetParticle(cms2.genps_id().at(j))->GetName() << " "
939 << setw(7) << right << setprecision(4) << cms2.genps_p4().at(j).pt() << " "
940 << setw(7) << right << setprecision(4) << cms2.genps_p4().at(j).phi() << " "
941 << setw(10) << right << setprecision(4) << cms2.genps_p4().at(j).eta() << " "
942 << setw(10) << right << setprecision(4) << cms2.genps_p4().at(j).mass() << endl;
943 }
944 // Clean up
945 delete pdg;
946 }
947
948 //----------------------------------------------------------------------
949 // search and destroy extra muons. If they're stiff and isolated,
950 // they're probably from WZ, ZZ or (in emu) DYmm (with a spurious
951 // electron). If they're soft or non-isolated, use them to tag top
952 // events
953 // ----------------------------------------------------------------------
954 bool passTriLepVeto (int i_dilep)
955 {
956 double tag_mu_pt = tagMuonPt(i_dilep);
957 if (tag_mu_pt < 0) // no mu
958 return true;
959 if (tag_mu_pt < 20) // soft
960 return true;
961 double tag_mu_iso = tagMuonRelIso(i_dilep);
962 if (tag_mu_iso < 0.9) // non-isolated
963 return true;
964 // we've found a muon that's stiff and isolated. Fail the veto.
965 return false;
966 }
967
968 //int numberOfExtraMuons(int i_hyp, bool nonisolated = false){
969 int numberOfExtraMuons(int i_hyp, bool nonisolated){
970 unsigned int nMuons = 0;
971 for (int imu=0; imu < int(cms2.mus_charge().size()); ++imu) {
972 // quality cuts
973 if ( ((cms2.mus_goodmask()[imu]) & (1<<14)) == 0 ) continue; // TMLastStationOptimizedLowPtTight
974 if ( cms2.mus_p4()[imu].pt() < 3 ) continue;
975 if ( TMath::Abs(cms2.mus_d0corr()[imu]) > 0.2) continue;
976 if ( cms2.mus_validHits()[imu] < 11) continue;
977 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13 && cms2.hyp_lt_index()[i_hyp] == imu ) continue;
978 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13 && cms2.hyp_ll_index()[i_hyp] == imu ) continue;
979 if ( nonisolated && mu_rel_iso(imu) > 0.90 && cms2.mus_p4()[imu].pt()>20 ) continue;
980 ++nMuons;
981 }
982 return nMuons;
983 }
984
985 bool passMuonBVeto_1_6 (int i_dilep, bool soft_nonisolated)
986 {
987 if (soft_nonisolated) {
988 double tag_mu_pt = tagMuonPt(i_dilep);
989 if (tag_mu_pt < 0) // no mu
990 return true;
991 if (tag_mu_pt < 20) // soft
992 return false;
993 return true;
994 } else {
995 unsigned int mus_in_hyp = 0;
996 if (TMath::Abs(cms2.hyp_lt_id()[i_dilep]) == 13)
997 mus_in_hyp++;
998 if (TMath::Abs(cms2.hyp_ll_id()[i_dilep]) == 13)
999 mus_in_hyp++;
1000 return cms2.mus_p4().size() <= mus_in_hyp;
1001 }
1002 assert(false);
1003 return false;
1004 }
1005
1006 // If there is an extra muon in the event, return its index. (Otherwise -1)
1007 int tagMuonIdx (int i_dilep)
1008 {
1009 for (unsigned int i = 0; i < cms2.mus_p4().size(); ++i) {
1010 if (TMath::Abs(cms2.hyp_lt_id()[i_dilep]) == 13 &&
1011 cms2.hyp_lt_index()[i_dilep] == int(i))
1012 continue;
1013 if (TMath::Abs(cms2.hyp_ll_id()[i_dilep]) == 13 &&
1014 cms2.hyp_ll_index()[i_dilep] == int(i))
1015 continue;
1016 return i;
1017 }
1018 return -1;
1019 }
1020
1021 // return the pt of the first muon that's not lt or ll
1022 double tagMuonPt (int i_dilep)
1023 {
1024 int idx = tagMuonIdx(i_dilep);
1025 if (idx == -1)
1026 return -1;
1027 return cms2.mus_p4()[idx].pt();
1028 }
1029
1030 // same for rel iso
1031 double tagMuonRelIso (int i_dilep)
1032 {
1033 int idx = tagMuonIdx(i_dilep);
1034 if (idx == -1)
1035 return -1;
1036 return mu_rel_iso(idx);
1037 }
1038
1039 //--------------------------------
1040 //
1041 // Functions related to trkjet veto
1042 // This needs ot be rewritten once we
1043 // have added appropriate variables into ntuple itself.
1044 //
1045 //--------------------------------
1046 int NjetVeto(std::vector<TLorentzVector>& Jet, double min_et) {
1047 int njets = 0;
1048 for(unsigned int i=0; i<Jet.size() ; ++i) {
1049 if ( Jet[i].Perp() >= min_et) {
1050 njets++;
1051 }
1052 }
1053 return njets;
1054 }
1055
1056 int nTrkJets(int i_hyp){
1057 std::vector<TLorentzVector> trkjets;
1058 double jetet = 0;
1059 double jeteta = 3.0;
1060 // TrkJets & CaloJet save it after the lepton subtraction
1061
1062 for ( unsigned int itrkjet=0; itrkjet<cms2.trkjets_p4().size(); ++itrkjet) {
1063 if ((TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11 && dRbetweenVectors(cms2.hyp_lt_p4()[i_hyp],cms2.trkjets_p4()[itrkjet]) < 0.4)||
1064 (TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11 && dRbetweenVectors(cms2.hyp_ll_p4()[i_hyp],cms2.trkjets_p4()[itrkjet]) < 0.4)
1065 ) continue;
1066 TLorentzVector p(cms2.trkjets_p4()[itrkjet].Px(), cms2.trkjets_p4()[itrkjet].Py(), cms2.trkjets_p4()[itrkjet].Pz(), cms2.trkjets_p4()[itrkjet].E());
1067 if (p.Perp() < jetet) continue;
1068 if (TMath::Abs(p.Eta()) > jeteta) continue;
1069 trkjets.push_back(p);
1070 }
1071
1072 return NjetVeto(trkjets, 15);
1073 }
1074
1075 // count JPT jets excluding those that are close to the hypothesis leptons
1076 unsigned int nJPTs (int i_hyp)
1077 {
1078 return nJPTs(i_hyp, 20);
1079 }
1080
1081 std::vector<LorentzVector> JPTs(int i_hyp, double etThreshold)
1082 {
1083 std::vector<LorentzVector> ret;
1084 const double etaMax = 3.0;
1085 const double vetoCone = 0.4;
1086
1087 for ( unsigned int i=0; i < cms2.jpts_p4().size(); ++i) {
1088 if ( cms2.jpts_p4()[i].Et() < etThreshold ) continue;
1089 if ( TMath::Abs(cms2.jpts_p4()[i].eta()) > etaMax ) continue;
1090 if ( TMath::Abs(ROOT::Math::VectorUtil::DeltaR(cms2.hyp_lt_p4()[i_hyp],cms2.jpts_p4()[i])) < vetoCone ||
1091 TMath::Abs(ROOT::Math::VectorUtil::DeltaR(cms2.hyp_ll_p4()[i_hyp],cms2.jpts_p4()[i])) < vetoCone ) continue;
1092 ret.push_back(cms2.jpts_p4()[i]);
1093 }
1094 return ret;
1095 }
1096
1097 unsigned int nJPTs(int i_hyp, double etThreshold)
1098 {
1099 return JPTs(i_hyp, etThreshold).size();
1100 }
1101
1102 std::vector<LorentzVector> JPTsTrilep(int i_hyp, double etThreshold)
1103 {
1104 std::vector<LorentzVector> ret;
1105 const double etaMax = 3.0;
1106 const double vetoCone = 0.4;
1107
1108 LorentzVector first,second,third;
1109 if (abs(cms2.hyp_trilep_first_type()[i_hyp]) == 1) {
1110 first = cms2.mus_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
1111 } else {
1112 first = cms2.els_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
1113 }
1114 if (abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1) {
1115 second = cms2.mus_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
1116 } else {
1117 second = cms2.els_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
1118 }
1119 if (abs(cms2.hyp_trilep_third_type()[i_hyp]) == 1) {
1120 third = cms2.mus_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
1121 } else {
1122 third = cms2.els_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
1123 }
1124
1125 for ( unsigned int i=0; i < cms2.jpts_p4().size(); ++i) {
1126 if ( cms2.jpts_p4()[i].Et() < etThreshold ) continue;
1127 if ( TMath::Abs(cms2.jpts_p4()[i].eta()) > etaMax ) continue;
1128 if ( TMath::Abs(ROOT::Math::VectorUtil::DeltaR(first,cms2.jpts_p4()[i])) < vetoCone ||
1129 TMath::Abs(ROOT::Math::VectorUtil::DeltaR(second,cms2.jpts_p4()[i])) < vetoCone ||
1130 TMath::Abs(ROOT::Math::VectorUtil::DeltaR(third,cms2.jpts_p4()[i])) < vetoCone ) continue;
1131 ret.push_back(cms2.jpts_p4()[i]);
1132 }
1133 return ret;
1134 }
1135
1136 unsigned int nJPTsTrilep(int i_hyp, double etThreshold)
1137 {
1138 return JPTsTrilep(i_hyp, etThreshold).size();
1139 }
1140
1141 bool passTrkJetVeto(int i_hyp)
1142 {
1143 return nTrkJets(i_hyp) == 0;
1144 }
1145
1146 double reliso_lt (int i_hyp, bool use_calo_iso)
1147 {
1148 // muons do it one way:
1149 if (TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13) {
1150 return mu_rel_iso(cms2.hyp_lt_index()[i_hyp]);
1151 }
1152 // electrons do it another way:
1153 if (TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11) {
1154 return el_rel_iso(cms2.hyp_lt_index()[i_hyp], use_calo_iso);
1155 }
1156 // mysterions are not well handled:
1157 return 0;
1158 }
1159
1160 double reliso_ll (int i_hyp, bool use_calo_iso)
1161 {
1162 // muons do it one way:
1163 if (TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13) {
1164 return mu_rel_iso(cms2.hyp_ll_index()[i_hyp]);
1165 }
1166 // electrons do it another way:
1167 if (TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11) {
1168 return el_rel_iso(cms2.hyp_ll_index()[i_hyp], use_calo_iso);
1169 }
1170 // mysterions are not well handled:
1171 return 0;
1172 }
1173
1174 bool trueMuonFromW(int index) {
1175
1176 bool muIsFromW = false;
1177
1178 if( TMath::Abs(cms2.mus_mc_id()[index]) == 13 && TMath::Abs(cms2.mus_mc_motherid()[index]) == 24 ) muIsFromW = true;
1179
1180 return muIsFromW;
1181 }
1182
1183 bool trueElectronFromW(int index) {
1184
1185 bool elIsFromW = false;
1186
1187 if( TMath::Abs(cms2.els_mc_id()[index]) == 11 && TMath::Abs(cms2.els_mc_motherid()[index]) == 24 ) elIsFromW = true;
1188
1189 return elIsFromW;
1190 }
1191
1192 int conversionPartner (int i_el)
1193 {
1194 LorentzVector el_p4 = cms2.els_p4()[i_el];
1195 double min_dcottheta = 5e-4;
1196 int idx = -1;
1197 const double el_cottheta = el_p4.pz() / el_p4.pt();
1198 for (unsigned int i = 0; i < cms2.trks_trk_p4().size(); ++i) {
1199 // if the track is within some ratio of the electron momentum,
1200 // reject it
1201 if (cms2.trks_trk_p4()[i].pt() > 0.1 * el_p4.pt())
1202 continue;
1203 const double tk_cottheta = cms2.trks_trk_p4()[i].pz() /
1204 cms2.trks_trk_p4()[i].pt();
1205 if (TMath::Abs(tk_cottheta - el_cottheta) < min_dcottheta) {
1206 min_dcottheta = TMath::Abs(tk_cottheta - el_cottheta);
1207 idx = i;
1208 }
1209 }
1210 if (min_dcottheta < 5e-4)
1211 return idx;
1212 return -1;
1213 }
1214
1215 double conversionDeltaPhi (int i_conv, int i_el)
1216 {
1217 if (i_conv == -1)
1218 return -1;
1219 double dphi = ROOT::Math::VectorUtil::DeltaPhi(cms2.trks_trk_p4()[i_conv],
1220 cms2.els_p4()[i_el]);
1221 return TMath::Abs(dphi);
1222 }
1223
1224 /* missing ntuple variables
1225 bool passCaloTrkjetCombo ()
1226 {
1227 double dr = 999;
1228 double max_sumpt = 0;
1229 for (unsigned int i = 0; i < cms2.jets_p4().size(); ++i) {
1230 double min_dr = 999;
1231 double sumpt = 0;
1232 for (unsigned int j = 0; j < cms2.trkjets_p4().size(); ++j) {
1233 double dr = ROOT::Math::VectorUtil::DeltaR(cms2.trkjets_p4()[j],
1234 cms2.jets_p4()[i]);
1235 if (dr < min_dr) {
1236 min_dr = dr;
1237 sumpt = cms2.trkjets_p4()[j].pt() +
1238 cms2.jets_p4()[i].pt() * cms2.jets_tq_noCorrF()[i];
1239 }
1240 }
1241 if (sumpt > max_sumpt) {
1242 max_sumpt = sumpt;
1243 dr = min_dr;
1244 }
1245 }
1246 if (max_sumpt > 15 && dr < 0.5)
1247 return false;
1248 return true;
1249 }
1250 */
1251
1252 //-------------------------------------------
1253 // plain MET cut for reducing SM contribution
1254 // in WW selection to 10%
1255 //-------------------------------------------
1256 bool met10(int i_hyp, const TVector3& corr) {
1257 TVector3 hyp_met;
1258 hyp_met.SetPtEtaPhi(cms2.evt_metMuonJESCorr(), 0, cms2.evt_metMuonJESCorrPhi());
1259 hyp_met += corr;
1260 if ( hyp_met.Pt() < 110 ) return false;
1261 return true;
1262 }
1263
1264 //-------------------------------------------
1265 // plain MET cut for reducing SM contribution
1266 // in WW selection to 1%
1267 //-------------------------------------------
1268 bool met1(int i_hyp, const TVector3& corr) {
1269 TVector3 hyp_met;
1270 hyp_met.SetPtEtaPhi(cms2.evt_metMuonJESCorr(), 0, cms2.evt_metMuonJESCorrPhi());
1271 hyp_met += corr;
1272 if ( hyp_met.Pt() < 175 ) return false;
1273 return true;
1274 }
1275
1276 bool passTrackIsolation(int index){
1277 //
1278 // track isolation
1279 //
1280 const double cut = 0.92;
1281 double pt = cms2.trks_trk_p4()[index].pt();
1282 return (pt / (pt + trkIsolation(index))) > cut;
1283 }
1284
1285 int passTrackZVeto(int hyp_index) {
1286 //
1287 // build list of trk-isolated tracks with minimal quality cuts for dilepton hypothesis
1288 // nHits > 7
1289 // pT >= 1.0
1290 //
1291 // combine tracks to Z candidates and check invariant mass window for 3 modi:
1292 // 1: combine one track with either lt or ll of dilepton hyp, if a cand. is within the z window, reject event (return 1)
1293 // 2: combine two tracks, if a cand. is within the z window ,reject event (return 2)
1294 // 3: 1 && 2
1295 //
1296 // when combining 2 objects, require:
1297 // - delta z0 < 0.5 cm.
1298 // - delta R > 0.1
1299 // - opposite sign
1300
1301 double dZCut = 0.5;
1302 bool mode1 = false;
1303 bool mode2 = false;
1304
1305 // store trk indices of ll and lt
1306 unsigned int llTrkIdx = 1000000;
1307 unsigned int ltTrkIdx = 1000000;
1308 if ( TMath::Abs(cms2.hyp_lt_id()[hyp_index]) == 13 )
1309 ltTrkIdx = cms2.mus_trkidx()[cms2.hyp_lt_index()[hyp_index]];
1310 else if ( TMath::Abs(cms2.hyp_lt_id()[hyp_index]) == 11 )
1311 ltTrkIdx = cms2.els_trkidx()[cms2.hyp_lt_index()[hyp_index]];
1312 if ( TMath::Abs(cms2.hyp_ll_id()[hyp_index]) == 13 )
1313 llTrkIdx = cms2.mus_trkidx()[cms2.hyp_ll_index()[hyp_index]];
1314 else if ( TMath::Abs(cms2.hyp_ll_id()[hyp_index]) == 11 )
1315 llTrkIdx = cms2.els_trkidx()[cms2.hyp_ll_index()[hyp_index]];
1316
1317 // form trk-isolated track collection
1318 std::vector<int> isoTrks;
1319 for ( unsigned int trk = 0;
1320 trk < cms2.trks_trk_p4().size();
1321 ++trk ) {
1322 // exclude lt or ll
1323 if ( trk == llTrkIdx ) continue;
1324 if ( trk == ltTrkIdx ) continue;
1325 // require at least 8 hits
1326 if ( cms2.trks_validHits()[trk] <= 7 ) continue;
1327 // require pt >= 1. GeV
1328 if ( cms2.trks_trk_p4()[trk].pt() < 1.0 ) continue;
1329 // require trk-isolation
1330 if ( ! passTrackIsolation(trk) ) continue;
1331 isoTrks.push_back(trk);
1332 }
1333
1334 // loop over all selected trk-isolated tracks
1335 for ( unsigned int trk1 = 0;
1336 trk1 < isoTrks.size();
1337 ++trk1 ) {
1338 // try to combine with ll or lt, if in Z mass window, veto event
1339 if ( !mode1 ) {
1340 // require opposite sign
1341 if ( (cms2.hyp_lt_charge()[hyp_index] * cms2.trks_charge()[trk1]) < 0 ) {
1342 // require delta z0 < 0.5 cm
1343 double dZ = TMath::Abs(cms2.hyp_lt_z0()[hyp_index] - cms2.trks_z0()[trk1]);
1344 if ( dZ < dZCut ) {
1345 // require delta R > 0.1
1346 double dR = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_lt_p4()[hyp_index], cms2.trks_trk_p4()[trk1]);
1347 if ( dR > 0.1 ) {
1348 // if inv. mass of candidate within z mass window, veto event
1349 LorentzVector vec = cms2.hyp_lt_p4()[hyp_index] + cms2.trks_trk_p4()[trk1];
1350 if ( inZmassWindow(vec.mass()) ) {
1351 mode1 = true;
1352 }
1353 }
1354 }
1355 }
1356 // require opposite sign
1357 if ( (cms2.hyp_ll_charge()[hyp_index] * cms2.trks_charge()[trk1]) < 0 ) {
1358 // require delta z0 < 0.5 cm
1359 double dZ = TMath::Abs(cms2.hyp_ll_z0()[hyp_index] - cms2.trks_z0()[trk1]);
1360 if ( dZ < dZCut ) {
1361 // require delta R > 0.1
1362 double dR = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_ll_p4()[hyp_index], cms2.trks_trk_p4()[trk1]);
1363 if ( dR > 0.1 ) {
1364 // if inv. mass of candidate within z mass window, veto event
1365 LorentzVector vec = cms2.hyp_ll_p4()[hyp_index] + cms2.trks_trk_p4()[trk1];
1366 if ( inZmassWindow(vec.mass()) ) {
1367 mode1 = true;
1368 }
1369 }
1370 }
1371 }
1372 // try to combine one track with another track from the collection of selected trk-isolated tracks
1373 }
1374 for ( unsigned int trk2 = trk1+1;
1375 trk2 < isoTrks.size();
1376 ++trk2 ) {
1377 if ( !mode2 ) {
1378 // require opposite sign
1379 if ( (cms2.trks_charge()[trk2] * cms2.trks_charge()[trk1]) < 0 ) {
1380 // require delta z0 < 0.5 cm
1381 double dZ = TMath::Abs(cms2.trks_z0()[trk2] - cms2.trks_z0()[trk1]);
1382 if ( dZ < dZCut ) {
1383 // require delta R > 0.1
1384 double dR = ROOT::Math::VectorUtil::DeltaR(cms2.trks_trk_p4()[trk2], cms2.trks_trk_p4()[trk1]);
1385 if ( dR > 0.1 ) {
1386 // if inv. mass of candidate within z mass window, veto event
1387 LorentzVector vec = cms2.trks_trk_p4()[trk2] + cms2.trks_trk_p4()[trk1];
1388 if ( inZmassWindow(vec.mass()) ) {
1389 mode2 = true;
1390 }
1391 }
1392 }
1393 }
1394 }
1395 }
1396 }
1397
1398 if ( mode1 && mode2 ) return 3;
1399 if ( mode1 ) return 1;
1400 if ( mode2 ) return 2;
1401
1402 return -1;
1403 }
1404
1405
1406 // count genp leptons
1407 //--------------------------------------------------
1408 // Returns the number of e,mu, and tau in the doc lines
1409 //-----------------------------------------------------
1410 void leptonGenpCount(int& nele, int& nmuon, int& ntau) {
1411 nele=0;
1412 nmuon=0;
1413 ntau=0;
1414 int size = cms2.genps_id().size();
1415 for (int jj=0; jj<size; jj++) {
1416 if (abs(cms2.genps_id().at(jj)) == 11) nele++;
1417 if (abs(cms2.genps_id().at(jj)) == 13) nmuon++;
1418 if (abs(cms2.genps_id().at(jj)) == 15) ntau++;
1419 }
1420 }
1421
1422
1423 // TTbar-->dilepton selections for Fall08-based analysis
1424 double muonTrkIsolationPAT(int index){
1425 double sum = cms2.mus_pat_trackIso().at(index);
1426 double pt = cms2.mus_p4().at(index).pt();
1427 return pt/(pt+sum);
1428 }
1429 double muonCalIsolationPAT(int index){
1430 double sum = cms2.mus_pat_caloIso().at(index);
1431 double pt = cms2.mus_p4().at(index).pt();
1432 return pt/(pt+sum);
1433 }
1434
1435 // hyp-dependent met variables: make sure that the MET is corrected for the muon used in the hypothesis
1436 // in case it's not: return corrected value
1437 double met_pat_metCor_hyp(unsigned int hypIdx){
1438 if (cms2.hyp_type()[hypIdx] ==3) return cms2.met_pat_metCor();
1439 double lmetx = cms2.met_pat_metCor()*cos(cms2.met_pat_metPhiCor());
1440 double lmety = cms2.met_pat_metCor()*sin(cms2.met_pat_metPhiCor());
1441
1442 unsigned int i_lt = cms2.hyp_lt_index()[hypIdx];
1443 unsigned int i_ll = cms2.hyp_ll_index()[hypIdx];
1444 if (abs(cms2.hyp_lt_id()[hypIdx])==13 && cms2.mus_met_flag()[i_lt] == 0){
1445 lmetx+= - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1446 lmety+= - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1447 }
1448 if (abs(cms2.hyp_ll_id()[hypIdx])==13 && cms2.mus_met_flag()[i_ll] == 0){
1449 lmetx+= - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1450 lmety+= - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_ll].y();
1451 }
1452 return sqrt(lmetx*lmetx+lmety*lmety);
1453 }
1454 double met_pat_metPhiCor_hyp(unsigned int hypIdx){
1455 if (cms2.hyp_type()[hypIdx] ==3) return cms2.met_pat_metPhiCor();
1456 double lmetx = cms2.met_pat_metCor()*cos(cms2.met_pat_metPhiCor());
1457 double lmety = cms2.met_pat_metCor()*sin(cms2.met_pat_metPhiCor());
1458
1459 unsigned int i_lt = cms2.hyp_lt_index()[hypIdx];
1460 unsigned int i_ll = cms2.hyp_ll_index()[hypIdx];
1461 if (abs(cms2.hyp_lt_id()[hypIdx])==13 && cms2.mus_met_flag()[i_lt] == 0){
1462 lmetx+= - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1463 lmety+= - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1464 }
1465 if (abs(cms2.hyp_ll_id()[hypIdx])==13 && cms2.mus_met_flag()[i_ll] == 0){
1466 lmetx+= - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1467 lmety+= - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_lt].y();
1468 }
1469 return atan2(lmety,lmetx);
1470 }
1471 // do the same with tcmet now
1472 double evt_tcmet_hyp(unsigned int hypIdx){
1473 if (cms2.hyp_type()[hypIdx] ==3) return cms2.evt_tcmet();
1474 double lmetx = cms2.evt_tcmet()*cos(cms2.evt_tcmetPhi());
1475 double lmety = cms2.evt_tcmet()*sin(cms2.evt_tcmetPhi());
1476
1477 unsigned int i_lt = cms2.hyp_lt_index()[hypIdx];
1478 unsigned int i_ll = cms2.hyp_ll_index()[hypIdx];
1479 if (abs(cms2.hyp_lt_id()[hypIdx])==13){
1480 if(cms2.mus_tcmet_flag()[i_lt] == 0){
1481 lmetx+= - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1482 lmety+= - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1483 } else if (cms2.mus_tcmet_flag()[i_lt] == 4){
1484 lmetx+= - cms2.mus_tcmet_deltax()[i_lt] - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1485 lmety+= - cms2.mus_tcmet_deltay()[i_lt] - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1486 }
1487 }
1488 if (abs(cms2.hyp_ll_id()[hypIdx])==13){
1489 if(cms2.mus_tcmet_flag()[i_ll] == 0){
1490 lmetx+= - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1491 lmety+= - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_ll].y();
1492 } else if (cms2.mus_tcmet_flag()[i_ll] == 4){
1493 lmetx+= - cms2.mus_tcmet_deltax()[i_ll] - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1494 lmety+= - cms2.mus_tcmet_deltay()[i_ll] - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_ll].y();
1495 }
1496 }
1497 return sqrt(lmetx*lmetx+lmety*lmety);
1498 }
1499 double evt_tcmetPhi_hyp(unsigned int hypIdx){
1500 if (cms2.hyp_type()[hypIdx] ==3) return cms2.evt_tcmetPhi();
1501 double lmetx = cms2.evt_tcmet()*cos(cms2.evt_tcmetPhi());
1502 double lmety = cms2.evt_tcmet()*sin(cms2.evt_tcmetPhi());
1503
1504 unsigned int i_lt = cms2.hyp_lt_index()[hypIdx];
1505 unsigned int i_ll = cms2.hyp_ll_index()[hypIdx];
1506 if (abs(cms2.hyp_lt_id()[hypIdx])==13){
1507 if(cms2.mus_tcmet_flag()[i_lt] == 0){
1508 lmetx+= - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1509 lmety+= - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1510 } else if (cms2.mus_tcmet_flag()[i_lt] == 4){
1511 lmetx+= - cms2.mus_tcmet_deltax()[i_lt] - cms2.mus_met_deltax()[i_lt] - cms2.mus_p4()[i_lt].x();
1512 lmety+= - cms2.mus_tcmet_deltay()[i_lt] - cms2.mus_met_deltay()[i_lt] - cms2.mus_p4()[i_lt].y();
1513 }
1514 }
1515 if (abs(cms2.hyp_ll_id()[hypIdx])==13){
1516 if(cms2.mus_tcmet_flag()[i_ll] == 0){
1517 lmetx+= - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1518 lmety+= - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_ll].y();
1519 } else if (cms2.mus_tcmet_flag()[i_ll] == 4){
1520 lmetx+= - cms2.mus_tcmet_deltax()[i_ll] - cms2.mus_met_deltax()[i_ll] - cms2.mus_p4()[i_ll].x();
1521 lmety+= - cms2.mus_tcmet_deltay()[i_ll] - cms2.mus_met_deltay()[i_ll] - cms2.mus_p4()[i_ll].y();
1522 }
1523 }
1524 return atan2(lmety,lmetx);
1525 }
1526
1527 // met cut for ttbar dilepton analysis...
1528 // includes a boolean to switch to tcmet
1529 bool passMet_OF20_SF30(int hypIdx, bool useTcMet) {
1530 float mymet;
1531 if (useTcMet) {
1532 mymet = evt_tcmet_hyp(hypIdx);
1533 } else {
1534 mymet = met_pat_metCor_hyp(hypIdx);
1535 }
1536 if (cms2.hyp_type().at(hypIdx) == 0 || cms2.hyp_type().at(hypIdx) == 3) {
1537 if (mymet < 30) return false;
1538 }
1539
1540 if (cms2.hyp_type().at(hypIdx) == 1 || cms2.hyp_type().at(hypIdx) == 2) {
1541 if (mymet < 20) return false;
1542 }
1543 return true;
1544 }
1545 // ***** The following two functions should be deprecated *********************
1546 // ***** and substituted by the preceeding one *********************
1547 // event-level pat-met: emu met >20, mm,em met>30
1548 bool passPatMet_OF20_SF30(float metx, float mety, int hypIdx){
1549 float mymet = sqrt(metx*metx + mety*mety);
1550 if (cms2.hyp_type().at(hypIdx) == 0 || cms2.hyp_type().at(hypIdx) == 3) {
1551 if (mymet < 30) return false;
1552 }
1553
1554 if (cms2.hyp_type().at(hypIdx) == 1 || cms2.hyp_type().at(hypIdx) == 2) {
1555 if (mymet < 20) return false;
1556 }
1557 return true;
1558 }
1559 // event-level pat-met: emu met >20, mm,em met>30
1560 bool passPatMet_OF20_SF30(int hypIdx){
1561 return passPatMet_OF20_SF30(met_pat_metCor_hyp(hypIdx)*cos(met_pat_metPhiCor_hyp(hypIdx)),
1562 met_pat_metCor_hyp(hypIdx)*sin(met_pat_metPhiCor_hyp(hypIdx)),
1563 hypIdx);
1564 }
1565 //**************************************************************************
1566 // met cut for ttbar dilepton analysis...
1567 // includes a boolean to switch to tcmet
1568 bool passMet_OF30_SF50(int hypIdx, bool useTcMet) {
1569 float mymet;
1570 if (useTcMet) {
1571 mymet = evt_tcmet_hyp(hypIdx);
1572 } else {
1573 mymet = met_pat_metCor_hyp(hypIdx);
1574 }
1575 if (cms2.hyp_type().at(hypIdx) == 0 || cms2.hyp_type().at(hypIdx) == 3) {
1576 if (mymet < 50) return false;
1577 }
1578
1579 if (cms2.hyp_type().at(hypIdx) == 1 || cms2.hyp_type().at(hypIdx) == 2) {
1580 if (mymet < 30) return false;
1581 }
1582 return true;
1583 }
1584 // ***** The following two functions should be deprecated *********************
1585 // ***** and substituted by the preceeding one *********************
1586 // event-level pat-met: emu met >20, mm,em met>30
1587 bool passPatMet_OF30_SF50(float metx, float mety, int hypIdx){
1588 float mymet = sqrt(metx*metx + mety*mety);
1589 if (cms2.hyp_type().at(hypIdx) == 0 || cms2.hyp_type().at(hypIdx) == 3) {
1590 if (mymet < 50) return false;
1591 }
1592
1593 if (cms2.hyp_type().at(hypIdx) == 1 || cms2.hyp_type().at(hypIdx) == 2) {
1594 if (mymet < 30) return false;
1595 }
1596 return true;
1597 }
1598 // event-level pat-met: emu met >30, mm,em met>50
1599 bool passPatMet_OF30_SF50(int hypIdx){
1600 return passPatMet_OF30_SF50(met_pat_metCor_hyp(hypIdx)*cos(met_pat_metPhiCor_hyp(hypIdx)),
1601 met_pat_metCor_hyp(hypIdx)*sin(met_pat_metPhiCor_hyp(hypIdx)),
1602 hypIdx);
1603 }
1604
1605 //**************************************************************************
1606
1607 //-----------------------------------------------------------------------------------------------
1608 //New selections for the common TTDil working group
1609 //-----------------------------------------------------------------------------------------------
1610 //
1611 // loose lepton definitions
1612 //
1613
1614 bool electron20Eta2p4(int index){
1615 if (cms2.els_p4().at(index).pt() < 20 ) return false;
1616 if (fabs(cms2.els_p4().at(index).eta()) > 2.4 ) return false;
1617
1618 return true;
1619 }
1620
1621
1622 bool looseElectronSelectionNoIsoTTDil08(int index) {
1623 if ( ! electron20Eta2p4(index) ) return false;
1624 if ( cms2.els_egamma_looseId().at(index) != 1) return false;
1625 if ( fabs(cms2.els_d0corr().at(index)) > 0.040) return false;
1626 if ( cms2.els_closestMuon().at(index) != -1) return false;
1627
1628 return true;
1629 }
1630
1631 //
1632 double electronTrkIsolationPAT(int index){
1633 double sum = cms2.els_pat_trackIso().at(index);
1634 double pt = cms2.els_p4().at(index).pt();
1635 return pt/(pt+sum);
1636 }
1637 double electronCalIsolationPAT(int index){
1638 double sum = cms2.els_pat_caloIso().at(index);
1639 double pt = cms2.els_p4().at(index).pt();
1640 return pt/(pt+sum);
1641 }
1642
1643
1644 // factorize this stuff out
1645 float electronTrkIsolationTTDil08(int index){
1646 return electronTrkIsolationPAT(index);
1647 }
1648 float electronCalIsolationTTDil08(int index){
1649 return electronCalIsolationPAT(index);
1650 }
1651
1652 bool looseElectronSelectionTTDil08(int index) {
1653 if ( ! looseElectronSelectionNoIsoTTDil08(index) ) return false;
1654
1655 if ( electronTrkIsolationTTDil08(index) < 0.5 ) return false;
1656 if ( electronCalIsolationTTDil08(index) < 0.5 ) return false;
1657
1658 return true;
1659 }
1660
1661 bool passElectronIsolationTTDil08(int index){
1662 if ( electronTrkIsolationTTDil08(index) < 0.9 ) return false;
1663 if ( electronCalIsolationTTDil08(index) < 0.8 ) return false;
1664
1665 return true;
1666 }
1667
1668 bool muon20Eta2p4(int index){
1669 if (cms2.mus_p4().at(index).pt() < 20 ) return false;
1670 if (fabs(cms2.mus_p4().at(index).eta()) >2.4 ) return false;
1671
1672 return true;
1673 }
1674
1675 bool looseMuonSelectionNoIsoTTDil08(int index) {
1676
1677 if (! muon20Eta2p4(index) ) return false;
1678
1679 if(!(2 & cms2.mus_type().at(index))) return false;
1680 if (cms2.mus_gfit_chi2().at(index)/cms2.mus_gfit_ndof().at(index) > 10.) return false;
1681 // if (fabs(cms2.mus_d0corr().at(index)) > 0.25) return false;
1682 if (cms2.mus_validHits().at(index) < 11) return false;
1683
1684 return true;
1685 }
1686
1687 bool lepton20Eta2p4(int id, int index){
1688 if (abs(id)==11) return electron20Eta2p4(index);
1689 if (abs(id)==13) return muon20Eta2p4(index);
1690 return false;
1691 }
1692
1693 // factorize this stuff out
1694 float muonTrkIsolationTTDil08(int index){
1695 return muonTrkIsolationPAT(index);
1696 }
1697 float muonCalIsolationTTDil08(int index){
1698 return muonCalIsolationPAT(index);
1699 }
1700
1701 float leptonTrkIsolationTTDil08(int id, int index){
1702 if (abs(id) == 11) return electronTrkIsolationTTDil08(index);
1703 if (abs(id) == 13) return muonTrkIsolationTTDil08(index);
1704 return -1;
1705 }
1706 float leptonCalIsolationTTDil08(int id, int index){
1707 if (abs(id) == 11) return electronCalIsolationTTDil08(index);
1708 if (abs(id) == 13) return muonCalIsolationTTDil08(index);
1709 return -1;
1710 }
1711
1712 bool looseMuonSelectionTTDil08(int index) {
1713 if (! looseMuonSelectionNoIsoTTDil08(index) ) return false;
1714
1715 if ( muonTrkIsolationTTDil08(index) < 0.5 ) return false;
1716 if ( muonCalIsolationTTDil08(index) < 0.5 ) return false;
1717
1718 return true;
1719 }
1720
1721 bool passMuonIsolationTTDil08(int index) {
1722 if ( muonTrkIsolationTTDil08(index) < 0.9 ) return false;
1723 if ( muonCalIsolationTTDil08(index) < 0.9 ) return false;
1724
1725 return true;
1726 }
1727
1728 //now make it figure out which lepton type it is
1729 bool passLeptonIsolationTTDil08(int id, int index){
1730 if (abs(id) == 11) return passElectronIsolationTTDil08(index);
1731 if (abs(id) == 13) return passMuonIsolationTTDil08(index);
1732 return false;
1733 }
1734
1735 bool looseLeptonSelectionNoIsoTTDil08(int id, int index){
1736 if (abs(id) == 11) return looseElectronSelectionNoIsoTTDil08(index);
1737 if (abs(id) == 13) return looseMuonSelectionNoIsoTTDil08(index);
1738 return false;
1739 }
1740 bool looseLeptonSelectionTTDil08(int id, int index){
1741 if (abs(id) == 11) return looseElectronSelectionTTDil08(index);
1742 if (abs(id) == 13) return looseMuonSelectionTTDil08(index);
1743 return false;
1744 }
1745
1746 //-----------------------------------------------------------------------------------------------
1747 //New selections for the common SUSY Dilepton working group
1748 //-----------------------------------------------------------------------------------------------
1749 //
1750 double inv_mu_rel_iso(int index)
1751 {
1752 double sum = cms2.mus_iso03_sumPt().at(index) +
1753 cms2.mus_iso03_emEt().at(index) +
1754 cms2.mus_iso03_hadEt().at(index);
1755 double pt = cms2.mus_p4().at(index).pt();
1756 return sum/pt;
1757 }
1758
1759 double inv_el_rel_iso(int index, bool use_calo_iso)
1760 {
1761 double sum = cms2.els_tkIso().at(index);
1762 if (use_calo_iso)
1763 sum += cms2.els_ecalIso()[index] + cms2.els_hcalIso()[index];
1764 double pt = cms2.els_p4().at(index).pt();
1765 return sum/pt;
1766 }
1767
1768 bool passMuonIsolationVJets09(int index)
1769 {
1770 const double cut = 0.1;
1771 return inv_mu_rel_iso(index) < cut;
1772 }
1773
1774 bool passElectronIsolationVJets09(int index, bool use_calo_iso)
1775 {
1776 const double cut = 0.1;
1777 return inv_el_rel_iso(index, use_calo_iso) < cut;
1778 }
1779
1780 bool passLeptonIsolationVJets09(int id, int index){
1781 if (abs(id) == 11) return passElectronIsolationVJets09(index, true);
1782 if (abs(id) == 13) return passMuonIsolationVJets09(index);
1783 return false;
1784 }
1785
1786 bool looseElectronSelectionVJets09(int index) {
1787 if (fabs(cms2.els_p4().at(index).eta()) > 2.5) return false;
1788 // if ( cms2.els_egamma_tightId().at(index) != 1) return false;
1789 // if ( cms2.els_egamma_looseId().at(index) != 1) return false;
1790 if ( cms2.els_pat_robustTightId().at(index) < 0.5 ) return false; // SUSY group
1791
1792 if ( fabs(cms2.els_d0corr().at(index)) >= 0.2) return false; // check if it is 0.2
1793 // if ( cms2.els_closestMuon().at(index) != -1) return false;
1794 return true;
1795 }
1796
1797 bool looseMuonSelectionVJets09(int index) {
1798 if (fabs(cms2.mus_p4().at(index).eta()) > 2.1) return false;
1799 if (((cms2.mus_type().at(index)) & (1<<1)) == 0) return false;
1800 if (cms2.mus_gfit_chi2().at(index)/cms2.mus_gfit_ndof().at(index) >= 10) return false; // should < 10
1801 if (fabs(cms2.mus_d0corr().at(index)) >= 0.2) return false;
1802 if (cms2.mus_validHits().at(index) < 11) return false;
1803 if (cms2.mus_pat_ecalvetoDep().at(index) >= 4) return false; // ECalE < 4
1804 if (cms2.mus_pat_hcalvetoDep().at(index) >= 6) return false; // HCalE < 6
1805 return true;
1806 }
1807 bool passLeptonIDVJets09(int id, int index){
1808 if (abs(id) == 11) return looseElectronSelectionVJets09(index);
1809 if (abs(id) == 13) return looseMuonSelectionVJets09(index);
1810 return false;
1811 }
1812
1813 bool passMetVJets09(float value, bool useTcMet) {
1814 float mymet;
1815 if (useTcMet) {
1816 mymet = cms2.evt_tcmet();
1817 } else {
1818 mymet = cms2.met_pat_metCor();
1819 }
1820 if (mymet <= value) return false;
1821 return true;
1822 }
1823
1824 int numberOfExtraMuonsVJets09(int i_hyp){
1825 unsigned int nMuons = 0;
1826 for (int imu=0; imu < int(cms2.mus_p4().size()); imu++) {
1827 // quality cuts
1828 if ( cms2.mus_p4()[imu].pt() < 20 ) continue;
1829 if ( fabs(cms2.mus_p4()[imu].eta()) > 2.1 ) continue;
1830 if ((( cms2.mus_type()[imu]) & (1<<1)) == 0) continue;
1831 if (cms2.mus_gfit_chi2()[imu]/cms2.mus_gfit_ndof()[imu] >= 10) continue;
1832 if ( fabs(cms2.mus_d0corr()[imu]) >= 0.2) continue;
1833 if ( cms2.mus_validHits()[imu] < 11) continue;
1834 if (cms2.mus_pat_ecalvetoDep()[imu] >= 4) continue;
1835 if (cms2.mus_pat_hcalvetoDep()[imu] >= 6) continue;
1836 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13 && cms2.hyp_lt_index()[i_hyp] == imu ) continue;
1837 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13 && cms2.hyp_ll_index()[i_hyp] == imu ) continue;
1838 if ( inv_mu_rel_iso(imu) >= 0.1 ) continue;
1839 nMuons++;
1840 }
1841 return nMuons;
1842 }
1843
1844
1845 int numberOfExtraElectronsVJets09(int i_hyp){
1846 unsigned int nElec = 0;
1847 for (int iel=0; iel < int(cms2.els_p4().size()); iel++) {
1848 // quality cuts
1849 if ( cms2.els_p4()[iel].pt() < 20 ) continue;
1850 if ( fabs(cms2.els_p4()[iel].eta()) > 2.5 ) continue;
1851 if ( cms2.els_pat_robustTightId()[iel] < 0.5 ) continue; // check
1852 if ( fabs(cms2.els_d0corr()[iel]) >= 0.2) continue;
1853 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11 && cms2.hyp_lt_index()[i_hyp] == iel ) continue;
1854 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11 && cms2.hyp_ll_index()[i_hyp] == iel ) continue;
1855 if ( inv_el_rel_iso(iel, true) >= 0.1 ) continue;
1856 nElec++;
1857 }
1858 return nElec;
1859 }
1860
1861 //------------------------------------------------------------------------------------
1862 // SUSY dilepton cuts 09 for TAS
1863
1864 bool comparePt (const LorentzVector &lv1,
1865 const LorentzVector &lv2)
1866 {
1867 return lv1.pt() > lv2.pt();
1868 }
1869
1870 bool GoodSusyElectronWithoutIsolation(int index) {
1871 if ( cms2.els_egamma_tightId().at(index) != 1) return false;
1872 if ( fabs(cms2.els_d0corr().at(index)) >= 0.02) return false;
1873 if ( cms2.els_closestMuon().at(index) != -1) return false;
1874 if ( TMath::Abs(cms2.els_p4()[index].eta()) > 2.4) return false;
1875 // New
1876 // if ( conversionElectron(index)) return false;
1877 // if ( isChargeFlip(index)) return false;
1878
1879 return true;
1880 }
1881
1882 bool GoodSusyElectronWithoutIsolationNoD0(int index) {
1883 if ( cms2.els_egamma_tightId().at(index) != 1) return false;
1884 if ( cms2.els_closestMuon().at(index) != -1) return false;
1885 if ( TMath::Abs(cms2.els_p4()[index].eta()) > 2.4) return false;
1886 return true;
1887 }
1888
1889 bool GoodSusyMuonWithoutIsolation(int index) {
1890 if (((cms2.mus_type().at(index)) & (1<<1)) == 0) return false; // global muon
1891 if (((cms2.mus_type().at(index)) & (1<<2)) == 0) return false; // tracker muon
1892 if (cms2.mus_validHits().at(index) < 11) return false;
1893 if (cms2.mus_gfit_chi2().at(index)/cms2.mus_gfit_ndof().at(index) >= 10) return false;
1894 if (fabs(cms2.mus_d0corr().at(index)) >= 0.02) return false;
1895 if (cms2.mus_pat_ecalvetoDep().at(index) >= 4) return false; // ECalE < 4
1896 if (cms2.mus_pat_hcalvetoDep().at(index) >= 6) return false; // HCalE < 6
1897 if ( TMath::Abs(cms2.mus_p4()[index].eta()) > 2.4) return false;
1898 return true;
1899 }
1900
1901 bool isNumElSUSY09(int iEl) {
1902 Double_t pt = cms2.els_p4()[iEl].Pt();
1903 if( pt < 10) return false;
1904 if (!GoodSusyElectronWithoutIsolation(iEl)) return false;
1905 if (!PassSusyElectronIsolation(iEl, true)) return false;
1906 return true;
1907 }
1908
1909 bool isNumMuSUSY09(int iMu) {
1910 Double_t pt = cms2.mus_p4()[iMu].Pt();
1911 if (pt < 10) return false;
1912 if (!GoodSusyMuonWithoutIsolation(iMu)) return false;
1913 if (!PassSusyMuonIsolation(iMu)) return false;
1914
1915 return true;
1916 }
1917
1918 double inv_mu_relsusy_iso(int index)
1919 {
1920 double sum = cms2.mus_iso03_sumPt().at(index) +
1921 cms2.mus_iso03_emEt().at(index) +
1922 cms2.mus_iso03_hadEt().at(index);
1923 double pt = cms2.mus_p4().at(index).pt();
1924 return sum/max(pt,20.);
1925 }
1926
1927 double inv_el_relsusy_iso(int index, bool use_calo_iso)
1928 {
1929 double sum = cms2.els_pat_trackIso().at(index);
1930 if (use_calo_iso)
1931 sum += max(0., (cms2.els_pat_ecalIso().at(index) -2.)) + cms2.els_pat_hcalIso().at(index);
1932 double pt = cms2.els_p4().at(index).pt();
1933 return sum/max(pt,20.);
1934 }
1935
1936 bool GoodSusyMuonWithIsolation(int index)
1937 {
1938 // const double cut = 0.1;
1939 return GoodSusyMuonWithoutIsolation(index) && PassSusyMuonIsolation(index);
1940 }
1941
1942 bool PassSusyMuonIsolation(int index)
1943 {
1944 const double cut = 0.1;
1945 return inv_mu_relsusy_iso(index) < cut;
1946 }
1947
1948 bool GoodSusyElectronWithIsolation(int index, bool use_calo_iso)
1949 {
1950 // const double cut = 0.1;
1951 return GoodSusyElectronWithoutIsolation(index) && PassSusyElectronIsolation(index, use_calo_iso);
1952 }
1953
1954 bool PassSusyElectronIsolation(int index, bool use_calo_iso)
1955 {
1956 const double cut = 0.1;
1957 return inv_el_relsusy_iso(index, use_calo_iso) < cut;
1958 }
1959
1960 bool PassSusyElectronIsolationLoose(int index, bool use_calo_iso)
1961 {
1962 const double cut = 0.4; //v50_0
1963 // const double cut = 0.25; //v50_1
1964 return inv_el_relsusy_iso(index, use_calo_iso) < cut;
1965 }
1966
1967 bool GoodSusyLeptonWithIsolation(int id, int index){
1968 if (abs(id) == 11) return GoodSusyElectronWithIsolation(index, true);
1969 if (abs(id) == 13) return GoodSusyMuonWithIsolation(index);
1970 return false;
1971 }
1972
1973 bool PassSusyLeptonIsolation(int id, int index){
1974 if (abs(id) == 11) return PassSusyElectronIsolation(index, true);
1975 if (abs(id) == 13) return PassSusyMuonIsolation(index);
1976 return false;
1977 }
1978
1979 bool GoodSusyLeptonID(int id, int index){
1980 if (abs(id) == 11) return GoodSusyElectronWithoutIsolation(index);
1981 if (abs(id) == 13) return GoodSusyMuonWithoutIsolation(index);
1982 return false;
1983 }
1984
1985 bool GoodSusyTrigger(int dilType){
1986 bool hlt_ele15_lw_l1r = cms2.passHLTTrigger("HLT_Ele15_SW_L1R");
1987 bool hltMu9 = cms2.passHLTTrigger("HLT_Mu9");
1988 // bool hltdiMu3 = cms2.passHLTTrigger("HLT_DoubleMu3");
1989 // bool hltdiEle10 = cms2.passHLTTrigger("HLT_DoubleEle10_SWL1R");
1990 // bool hltdiEle10 = cms2.passHLTTrigger("HLT_DoubleEle5_SW_L1R");
1991
1992 if (dilType == 0 && ! (hltMu9) ) return false;
1993 if ((dilType == 1 || dilType == 2) && ! (hltMu9 || hlt_ele15_lw_l1r)) return false;
1994 if (dilType == 3 && ! hlt_ele15_lw_l1r) return false;
1995
1996 return true;
1997 }
1998
1999 int numberOfExtraElectronsSUSY(int i_hyp){
2000 unsigned int nElec = 0;
2001 for (int iel=0; iel < int(cms2.els_p4().size()); iel++) {
2002 if ( cms2.els_p4()[iel].pt() < 10 ) continue;
2003 if (fabs(cms2.els_p4()[iel].eta()) > 2.4 ) continue;
2004 if (!GoodSusyElectronWithoutIsolation(iel)) continue;
2005 if (!PassSusyElectronIsolation(iel, true)) continue;
2006 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11 && cms2.hyp_lt_index()[i_hyp] == iel ) continue;
2007 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11 && cms2.hyp_ll_index()[i_hyp] == iel ) continue;
2008 nElec++;
2009 }
2010 return nElec;
2011 }
2012
2013 int numberOfExtraMuonsSUSY(int i_hyp){
2014 unsigned int nMuons = 0;
2015 for (int imu=0; imu < int(cms2.mus_p4().size()); imu++) {
2016 if ( cms2.mus_p4()[imu].pt() < 10 ) continue;
2017 if ( fabs(cms2.mus_p4()[imu].eta()) > 2.4 ) continue;
2018 if (!GoodSusyMuonWithoutIsolation(imu)) continue;
2019 if (!PassSusyMuonIsolation(imu)) continue;
2020 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13 && cms2.hyp_lt_index()[i_hyp] == imu ) continue;
2021 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13 && cms2.hyp_ll_index()[i_hyp] == imu ) continue;
2022 nMuons++;
2023 }
2024 return nMuons;
2025 }
2026 // jets_p4
2027 std::vector<LorentzVector> getCaloJets(int i_hyp) {
2028 std::vector<LorentzVector> calo_jets;
2029 calo_jets.clear();
2030
2031 for (unsigned int jj=0; jj < cms2.jets_p4().size(); ++jj) {
2032 if ((dRbetweenVectors(cms2.hyp_lt_p4()[i_hyp],cms2.jets_p4()[jj]) < 0.4)||
2033 (dRbetweenVectors(cms2.hyp_ll_p4()[i_hyp],cms2.jets_p4()[jj]) < 0.4)
2034 ) continue;
2035 if (cms2.jets_p4()[jj].pt() < 30) continue;
2036 if (fabs(cms2.jets_p4()[jj].Eta()) > 2.4) continue;
2037 //fkw July21 2009 if (cms2.jets_emFrac()[jj] < 0.1) continue;
2038 calo_jets.push_back(cms2.jets_p4()[jj]);
2039 }
2040
2041 if (calo_jets.size() > 1) {
2042 sort(calo_jets.begin(), calo_jets.end(), comparePt);
2043 }
2044 return calo_jets;
2045 }
2046
2047
2048 std::vector<LorentzVector> getJPTJets(int i_hyp) {
2049 std::vector<LorentzVector> jpt_jets;
2050 jpt_jets.clear();
2051
2052 for (unsigned int jj=0; jj < cms2.jpts_p4().size(); ++jj) {
2053 if ((dRbetweenVectors(cms2.hyp_lt_p4()[i_hyp],cms2.jpts_p4()[jj]) < 0.4)||
2054 (dRbetweenVectors(cms2.hyp_ll_p4()[i_hyp],cms2.jpts_p4()[jj]) < 0.4)
2055 ) continue;
2056 if (cms2.jpts_p4()[jj].pt() < 30) continue;
2057 if (fabs(cms2.jpts_p4()[jj].Eta()) > 2.4) continue;
2058 // if (cms2.jpts_emFrac()[jj] < 0.1) continue;
2059 jpt_jets.push_back(cms2.jpts_p4()[jj]);
2060 }
2061
2062 if (jpt_jets.size() > 1) {
2063 sort(jpt_jets.begin(), jpt_jets.end(), comparePt);
2064 }
2065 return jpt_jets;
2066 }
2067
2068 int ttbarconstituents(int i_hyp){
2069 // Categories:
2070 //WW = both leptons from W = 1
2071 //WO = one of the two leptons from W and the other not = 2
2072 //OO = neither of the two leptons is from a W = 3
2073
2074 int lttype = leptonIsFromW(cms2.hyp_lt_index()[i_hyp],cms2.hyp_lt_id()[i_hyp],cms2.hyp_lt_p4()[i_hyp] );
2075 int lltype = leptonIsFromW(cms2.hyp_ll_index()[i_hyp],cms2.hyp_ll_id()[i_hyp],cms2.hyp_ll_p4()[i_hyp] );
2076 if (lltype > 0 && lttype > 0) return 1;
2077 else if( (lltype >0 && lttype <= 0) || (lttype >0 && lltype <=0) ) return 2;
2078 else if( (lltype <=0 && lttype <=0) )return 3;
2079 else { cout << "bug in ttbarconstituents"; return -999;}
2080 }
2081
2082 //--------------------------------------------------------
2083 // Determines if the lepton in question is from W/Z
2084 // and if its charge is correct
2085 //
2086 // Note that if we have
2087 // W->lepton->lepton gamma
2088 // where the gamma is at large angles and it is the
2089 // gamma that gives the lepton signature in the detector,
2090 // then this returns "not from W/Z". This is by design.
2091 //
2092 // Note W->tau->lepton is tagged as "from W"
2093 //
2094 // Inputs: idx = index in the els or mus block
2095 // id = lepton ID (11 or 13 or -11 or -13)
2096 // v = 4-vector of reco lepton
2097 //
2098 // Output: 2 = from W/Z incorrect charge
2099 // 1 = from W/Z correct charge
2100 // 0 = not matched to a lepton (= fake)
2101 // -1 = lepton from b decay
2102 // -2 = lepton from c decay
2103 // -3 = lepton from some other source
2104 //
2105 // Authors: Claudio in consultation with fkw 22-july-09
2106 //---------------------------------------------------------
2107 int leptonIsFromW(int idx, int id, LorentzVector v) {
2108
2109 // get the matches to status=1 and status=3
2110 int st1_id = 0;
2111 int st3_id = 0;
2112 int st1_motherid = 0;
2113 if (abs(id) == 11) {
2114 st1_id = cms2.els_mc_id()[idx];
2115 st3_id = cms2.els_mc3_id()[idx];
2116 st1_motherid = cms2.els_mc_motherid()[idx];
2117 } else if (abs(id) == 13) {
2118 st1_id = cms2.mus_mc_id()[idx];
2119 st3_id = cms2.mus_mc3_id()[idx];
2120 st1_motherid = cms2.mus_mc_motherid()[idx];
2121 } else {
2122 std::cout << "You fool. Give me +/- 11 or +/- 13 please" << std::endl;
2123 return false;
2124 }
2125
2126 // Step 0
2127 // The match to status=3 in DR<0.1 from the ntuple is too tight.
2128 // If there is no match to status=3, we try the match again with DR<0.2
2129 // But we only match to leptons
2130 if (st3_id == -999) {
2131 float drmin = 999.;
2132 for (int j=0; j<cms2.genps_id().size(); j++) {
2133 int genId = cms2.genps_id().at(j);
2134 if (abs(genId) == 15 || abs(genId) == 13 || abs(genId) == 11) {
2135 LorentzVector vgen = cms2.genps_p4().at(j);
2136 float dr = dRbetweenVectors(v, vgen);
2137 if (dr < 0.2 && dr < drmin) {
2138 drmin = dr;
2139 st3_id = genId;
2140 }
2141 }
2142 }
2143 }
2144
2145 // debug
2146 // std::cout << "id=" << id << " st1_id=" << st1_id;
2147 // std::cout << " st3_id=" << st3_id;
2148 // std::cout << " st1_motherid=" << st1_motherid << std::endl;
2149
2150 // Step 1
2151 // Look at status 1 match, it should be either a lepton or
2152 // a photon if it comes from W/Z.
2153 // The photon case takes care of collinear FSR
2154 if ( !(abs(st1_id) == abs(id) || st1_id == 22)) return 0;
2155
2156 // Step 2
2157 // If the status 1 match is a photon, its mother must be
2158 // a lepton. Otherwise it is not FSR
2159 if (st1_id == 22) {
2160 if (abs(st1_motherid) != abs(id)) return 0;
2161 }
2162
2163 // At this point we are matched (perhaps via FSR) to
2164 // a status 1 lepton. This means that we are left with
2165 // leptons from W, taus, bottom, charm, as well as dalitz decays
2166
2167 // Step 3
2168 // A no-brainer: pick up vanilla W->lepton decays
2169 // (should probably add Higgs, SUSY, W' etc...not for now)
2170 if (st1_id == id && abs(st1_motherid) == 24) return 1; // W
2171 if (st1_id == -id && abs(st1_motherid) == 24) return 2; // W
2172 if (st1_id == id && st1_motherid == 23) return 1; // Z
2173 if (st1_id == -id && st1_motherid == 23) return 2; // Z
2174
2175 // Step 4
2176 // Another no-brainer: pick up leptons matched to status=3
2177 // leptons. This should take care of collinear FSR
2178 if (st3_id == id) return 1;
2179 if (st3_id == -id) return 2;
2180
2181 // Step 5
2182 // Now we need to go after the W->tau->lepton.
2183 // We exploit the fact that in t->W->tau the tau shows up
2184 // at status=3. We also use the fact that the tau decay products
2185 // are highly boosted, so the direction of the status=3 tau and
2186 // the lepton from tau decays are about the same
2187 //
2188 // We do not use the status=1 links because there is not
2189 // enough information to distinguish
2190 // W->tau->lepton or W->tau->lepton gamma
2191 // from
2192 // B->tau->lepton or B->tau->lepton gamma
2193 if (abs(st3_id) == 15 && id*st3_id > 0) return 1;
2194 if (abs(st3_id) == 15 && id*st3_id < 0) return 2;
2195
2196 // Step 6
2197 // If we get here, we have a non-W lepton
2198 // Now we figure out if it is from b, c, or "other"
2199 // There are a couple of caveats
2200 // (a) b/c --> lepton --> lepton gamma (ie FSR) is labelled as "other"
2201 // (b) b --> tau --> lepton is labelled as "other"
2202 if ( abs(st1_id) == abs(id) && idIsBeauty(st1_motherid)) return -1;
2203 if ( abs(st1_id) == abs(id) && idIsCharm(st1_motherid)) return -2;
2204 return -3;
2205 }
2206 //---------------------------------------------------------
2207
2208
2209 bool additionalZvetoSUSY09(int i_hyp) {
2210
2211 // true if we want to veto this event
2212 bool veto=false;
2213
2214 // first, look for Z->mumu
2215 for (unsigned int i=0; i < cms2.mus_p4().size(); i++) {
2216 bool hypLep1 = false;
2217 if (cms2.mus_p4().at(i).pt() < 10.) continue;
2218 if (!GoodSusyMuonWithoutIsolation(i)) continue;
2219 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13 && cms2.hyp_lt_index()[i_hyp] == i ) hypLep1 = true;
2220 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13 && cms2.hyp_ll_index()[i_hyp] == i ) hypLep1 = true;
2221
2222 for (unsigned int j=i+1; j < cms2.mus_p4().size(); j++) {
2223 bool hypLep2 = false;
2224 if (cms2.mus_p4().at(j).pt() < 10.) continue;
2225 if (!GoodSusyMuonWithoutIsolation(j)) continue;
2226 if (cms2.mus_charge().at(i) == cms2.mus_charge().at(j)) continue;
2227 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 13 && cms2.hyp_lt_index()[i_hyp] == j ) hypLep2 = true;
2228 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 13 && cms2.hyp_ll_index()[i_hyp] == j ) hypLep2 = true;
2229 // At least one of them has to pass isolation
2230 if (!PassSusyMuonIsolation(i) && !PassSusyMuonIsolation(j)) continue;
2231 if ( hypLep1 && hypLep2 ) continue;
2232 if ( !hypLep1 && !hypLep2 ) continue;
2233 // Make the invariant mass
2234 LorentzVector vec = cms2.mus_p4().at(i) + cms2.mus_p4().at(j);
2235 if ( inZmassWindow(vec.mass()) ) return true;
2236
2237 }
2238 }
2239
2240 // now, look for Z->ee
2241 for (unsigned int i=0; i < cms2.els_p4().size(); i++) {
2242 bool hypLep1 = false;
2243 if (cms2.els_p4().at(i).pt() < 10.) continue;
2244 if (! GoodSusyElectronWithoutIsolation(i)) continue;
2245 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11 && cms2.hyp_lt_index()[i_hyp] == i ) hypLep1 = true;
2246 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11 && cms2.hyp_ll_index()[i_hyp] == i ) hypLep1 = true;
2247 for (unsigned int j=i+1; j<cms2.els_p4().size(); j++) {
2248 bool hypLep2 = false;
2249 if (cms2.els_p4().at(j).pt() < 10.) continue;
2250 if (! GoodSusyElectronWithoutIsolation(j)) continue;
2251 if (cms2.els_charge().at(i) == cms2.els_charge().at(j)) continue;
2252 // At least one of them has to pass isolation
2253 if (!PassSusyElectronIsolation(i, true) && ! PassSusyElectronIsolation(j, true)) continue;
2254 if ( TMath::Abs(cms2.hyp_lt_id()[i_hyp]) == 11 && cms2.hyp_lt_index()[i_hyp] == j ) hypLep2 = true;
2255 if ( TMath::Abs(cms2.hyp_ll_id()[i_hyp]) == 11 && cms2.hyp_ll_index()[i_hyp] == j ) hypLep2 = true;
2256 if ( hypLep1 && hypLep2 ) continue;
2257 if ( !hypLep1 && !hypLep2 ) continue;
2258 // Make the invariant mass
2259 LorentzVector vec = cms2.els_p4().at(i) + cms2.els_p4().at(j);
2260 if ( inZmassWindow(vec.mass()) ) return true;
2261
2262 }
2263 }
2264 // done
2265 return veto;
2266 }
2267
2268 // For Fake rates
2269
2270 bool isFakeableElSUSY09(int iEl){
2271
2272 Double_t pt = cms2.els_p4()[iEl].Pt();
2273 Double_t eta = cms2.els_p4()[iEl].Eta();
2274
2275 if( pt < 10) return false;
2276 if( fabs( eta ) > 2.4 ) return false;
2277 // New
2278 if ( conversionElectron(iEl)) return false;
2279 if ( isChargeFlip(iEl)) return false;
2280
2281 //reject if electron is close to muon;
2282 if ( cms2.els_closestMuon()[iEl] > -1) return false;
2283 // Isolation
2284 if (inv_el_relsusy_iso(iEl, true) > 0.4) return false;
2285 // H/E
2286 if ( cms2.els_hOverE()[iEl] > 0.2 ) return false;
2287
2288 return true;
2289 }
2290
2291 // Muons
2292 bool isFakeableMuSUSY09(int iMu) {
2293
2294 Double_t pt = cms2.mus_p4()[iMu].Pt();
2295 Double_t eta = cms2.mus_p4()[iMu].Eta();
2296 if (!((cms2.mus_type().at(iMu)) & (1<<1)) ) return false; // global muon
2297 if (!((cms2.mus_type().at(iMu)) & (1<<2)) ) return false; // tracker muon
2298 if( pt < 10) return false;
2299 if( fabs( eta ) > 2.4 ) return false;
2300 if( cms2.mus_gfit_chi2()[iMu]/cms2.mus_gfit_ndof()[iMu] > 20) return false;
2301 if (inv_mu_relsusy_iso(iMu) > 0.4 ) return false;
2302 if (fabs(cms2.mus_d0corr().at(iMu)) >= 0.02) return false;
2303 return true;
2304
2305 }
2306
2307 //--------------------------------------------------------------------
2308 // Veto events if there are two leptons in the
2309 // event that make the Z mass. This uses the mus and els
2310 // blocks, ie, it is a veto that can use the 3rd (4th,5th,..)
2311 // lepton in the event.
2312 //
2313 // Both leptons must be 20 GeV, and pass the same cuts as
2314 // the hypothesis leptons, except that one of them can be non-isolated
2315 //---------------------------------------------------------------------
2316 bool additionalZvetoTTDil08() {
2317
2318 // true if we want to veto this event
2319 bool veto=false;
2320
2321 // first, look for Z->mumu
2322 for (unsigned int i=0; i<cms2.mus_p4().size(); i++) {
2323 if (cms2.mus_p4().at(i).pt() < 20.) continue;
2324 if (!looseMuonSelectionNoIsoTTDil08(i)) continue;
2325
2326 for (unsigned int j=i+1; j<cms2.mus_p4().size(); j++) {
2327 if (cms2.mus_p4().at(j).pt() < 20.) continue;
2328 if (!looseMuonSelectionNoIsoTTDil08(j)) continue;
2329
2330 if (cms2.mus_charge().at(i) == cms2.mus_charge().at(j)) continue;
2331
2332 // At least one of them has to pass isolation
2333 if (!passMuonIsolationTTDil08(i) && !passMuonIsolationTTDil08(j)) continue;
2334
2335 // Make the invariant mass
2336 LorentzVector vec = cms2.mus_p4().at(i) + cms2.mus_p4().at(j);
2337 if ( inZmassWindow(vec.mass()) ) return true;
2338
2339 }
2340 }
2341
2342 // now, look for Z->ee
2343 for (unsigned int i=0; i<cms2.evt_nels(); i++) {
2344 if (cms2.els_p4().at(i).pt() < 20.) continue;
2345 if (!looseElectronSelectionNoIsoTTDil08(i)) continue;
2346
2347 for (unsigned int j=i+1; j<cms2.evt_nels(); j++) {
2348 if (cms2.els_p4().at(j).pt() < 20.) continue;
2349 if (!looseElectronSelectionNoIsoTTDil08(j)) continue;
2350
2351 if (cms2.els_charge().at(i) == cms2.els_charge().at(j)) continue;
2352
2353 // At least one of them has to pass isolation
2354 if (!passElectronIsolationTTDil08(i) && !passElectronIsolationTTDil08(j)) continue;
2355
2356 // Make the invariant mass
2357 LorentzVector vec = cms2.els_p4().at(i) + cms2.els_p4().at(j);
2358 if ( inZmassWindow(vec.mass()) ) return true;
2359
2360 }
2361 }
2362 // done
2363 return veto;
2364 }
2365
2366 //
2367 // true if there is a muon not in the hypothesis
2368 bool haveExtraMuon(int hypIdx){
2369 bool result = false;
2370
2371 int nHMus = 0;
2372 if (abs(cms2.hyp_lt_id().at(hypIdx))==13){
2373 nHMus++;
2374 }
2375 if (abs(cms2.hyp_ll_id().at(hypIdx))==13){
2376 nHMus++;
2377 }
2378
2379 int nEvtMus = cms2.mus_p4().size();
2380 result = (nEvtMus - nHMus) > 0;
2381
2382 return result;
2383 }
2384
2385 // true if there is a muon not in the hypothesis
2386 bool haveExtraMuon5(int hypIdx){
2387 double minPtCut = 5;
2388 bool result = false;
2389
2390 int nHMus = 0;
2391 if (abs(cms2.hyp_lt_id().at(hypIdx))==13){
2392 if (cms2.hyp_lt_p4().at(hypIdx).pt() > minPtCut ) nHMus++;
2393 }
2394 if (abs(cms2.hyp_ll_id().at(hypIdx))==13){
2395 if (cms2.hyp_ll_p4().at(hypIdx).pt() > minPtCut) nHMus++;
2396 }
2397
2398 int nEvtMus = 0;
2399 for (unsigned int iMu = 0; iMu < cms2.mus_p4().size(); ++iMu){
2400 if (cms2.mus_p4().at(iMu).pt() > minPtCut) nEvtMus++;
2401 }
2402 result = (nEvtMus - nHMus) > 0;
2403
2404 return result;
2405 }
2406
2407
2408
2409 // Trigger-related selections
2410
2411 //Bits passing for hyp type
2412 bool passTriggersMu9orLisoE15(int dilType) {
2413 //old bit based method
2414 //bool hlt_ele15_lw_l1r = ((cms2.evt_HLT2() & (1<<(50-32))) != 0);
2415 //bool hltMu9 = ((cms2.evt_HLT3() & (1<<(82-64))) != 0);
2416
2417 //TString method
2418 bool hlt_ele15_lw_l1r = cms2.passHLTTrigger("HLT_Ele15_SW_L1R");
2419 bool hltMu9 = cms2.passHLTTrigger("HLT_Mu9");
2420
2421 if (dilType == 0 && ! (hltMu9) ) return false;
2422 if ((dilType == 1 || dilType == 2) && ! (hltMu9 || hlt_ele15_lw_l1r)) return false;
2423 if (dilType == 3 && ! hlt_ele15_lw_l1r) return false;
2424
2425 return true;
2426 }
2427
2428
2429 bool passTriggersTTDil08JanTrial(int dilType) {
2430 //trigger selections used in AN09/047 (at least as of v4 on 04-10-09
2431 bool hlt_Mu15_L1Mu7 = cms2.passHLTTrigger("HLT_Mu15_L1Mu7");
2432 bool hlt_DoubleMu3 = cms2.passHLTTrigger("HLT_DoubleMu3");
2433 bool hlt_IsoEle10_Mu10_L1R = cms2.passHLTTrigger("HLT_IsoEle10_Mu10_L1R");
2434 bool passMuMutriggers = (hlt_Mu15_L1Mu7 || hlt_DoubleMu3 || hlt_IsoEle10_Mu10_L1R);
2435
2436 bool hlt_IsoEle18_L1R = cms2.passHLTTrigger("HLT_IsoEle18_L1R");
2437 bool hlt_DoubleIsoEle12_L1R = cms2.passHLTTrigger("HLT_DoubleIsoEle12_L1R");
2438 bool passEEtriggers = (hlt_IsoEle18_L1R || hlt_DoubleIsoEle12_L1R );
2439
2440 bool passEMutriggers = (hlt_Mu15_L1Mu7 || hlt_IsoEle18_L1R || hlt_IsoEle10_Mu10_L1R || hlt_DoubleMu3);
2441
2442 if (dilType == 0 && ! passMuMutriggers ) return false;
2443 if ((dilType == 1 || dilType == 2) && ! passEMutriggers ) return false;
2444 if (dilType == 3 && ! passEEtriggers ) return false;
2445 return true;
2446 }
2447
2448
2449 int genpCountPDGId(int id0, int id1, int id2){
2450 int count = 0;
2451 int size = cms2.genps_id().size();
2452 for (int jj=0; jj<size; jj++) {
2453 if (abs(cms2.genps_id().at(jj)) == id0) count++;
2454 if (abs(cms2.genps_id().at(jj)) == id1) count++;
2455 if (abs(cms2.genps_id().at(jj)) == id2) count++;
2456 }
2457 return count;
2458 }
2459
2460 int genpCountPDGId_Pt20h24(int id0, int id1, int id2){
2461 int count = 0;
2462 int size = cms2.genps_id().size();
2463 for (int jj=0; jj<size; jj++) {
2464 if ( cms2.genps_p4()[jj].pt() < 20 || fabs(cms2.genps_p4()[jj].eta())>2.4) continue;
2465 if (abs(cms2.genps_id()[jj]) == id0) count++;
2466 if (abs(cms2.genps_id()[jj]) == id1) count++;
2467 if (abs(cms2.genps_id()[jj]) == id2) count++;
2468 }
2469 return count;
2470 }
2471
2472
2473
2474 int genpDileptonType(){
2475 //0 mumu; 1 emu; 2 ee
2476
2477 unsigned int nmus = 0;
2478 unsigned int nels = 0;
2479 int size = cms2.genps_id().size();
2480 for (int jj=0; jj<size; jj++) {
2481 if (abs(cms2.genps_id().at(jj)) == 11) nels++;
2482 if (abs(cms2.genps_id().at(jj)) == 13) nmus++;
2483 }
2484
2485 if ((nels + nmus) != 2){
2486 return -1;
2487 }
2488
2489 int dilType = -1;
2490 if (nmus == 2) dilType = 0;
2491 if (nels == 2) dilType = 2;
2492 if (nels == 1 && nmus == 1) dilType = 1;
2493 return dilType;
2494 }
2495
2496
2497 bool matchesMCTruthDilExtended(unsigned int hypIdx){
2498 //this better be in the selections.cc
2499 bool isTrueLepton_ll = false;
2500 bool isTrueLepton_lt = false;
2501 isTrueLepton_ll = ( (abs(cms2.hyp_ll_id()[hypIdx]) == abs(cms2.hyp_ll_mc_id()[hypIdx]) &&
2502 abs(cms2.hyp_ll_mc_motherid()[hypIdx]) < 50 //I wish I could match to W or Z explicitely, not in MGraph
2503 )
2504 || (cms2.hyp_ll_mc_id()[hypIdx]==22 &&
2505 TMath::Abs(ROOT::Math::VectorUtil::DeltaR(cms2.hyp_ll_p4()[hypIdx],cms2.hyp_ll_mc_p4()[hypIdx])) <0.05
2506 && abs(cms2.hyp_ll_id()[hypIdx]) == abs(cms2.hyp_ll_mc_motherid()[hypIdx])
2507 )
2508 );
2509 isTrueLepton_lt = ( (abs(cms2.hyp_lt_id()[hypIdx]) == abs(cms2.hyp_lt_mc_id()[hypIdx]) &&
2510 abs(cms2.hyp_lt_mc_motherid()[hypIdx]) < 50 //I wish I could match to W or Z explicitely, not in MGraph
2511 )
2512 || (cms2.hyp_lt_mc_id()[hypIdx]==22 &&
2513 TMath::Abs(ROOT::Math::VectorUtil::DeltaR(cms2.hyp_lt_p4()[hypIdx],cms2.hyp_lt_mc_p4()[hypIdx])) <0.05
2514 && abs(cms2.hyp_lt_id()[hypIdx]) == abs(cms2.hyp_lt_mc_motherid()[hypIdx])
2515 )
2516 );
2517 return (isTrueLepton_lt && isTrueLepton_ll);
2518 }
2519
2520
2521 int eventDilIndexByMaxMass(const std::vector<unsigned int>& goodHyps, bool printDebug){
2522 int result = -1;
2523 int strasbourgDilType = -1;
2524 unsigned int nGoodHyps = goodHyps.size();
2525 if ( nGoodHyps == 0 ) return result;
2526
2527 float maxWeight = -1;
2528 unsigned int maxWeightIndex = 9999;
2529
2530 for (unsigned int hypIdxL=0; hypIdxL < nGoodHyps; ++hypIdxL){
2531 unsigned int hypIdx = goodHyps[hypIdxL];
2532 float hypWeight = cms2.hyp_p4()[hypIdx].mass();
2533 if (hypWeight > maxWeight){
2534 maxWeight = hypWeight;
2535 maxWeightIndex = hypIdx;
2536 }
2537 }
2538
2539 if (printDebug){
2540 int genpDilType = genpDileptonType();
2541 if (genpDilType>=0 ){ std::cout<<"Dil type "<<genpDilType<<std::endl;
2542 if (nGoodHyps > 1){
2543 int maxWeightType = cms2.hyp_type()[maxWeightIndex];
2544 if ((maxWeightType == 0 && genpDilType == 0)
2545 || ( (maxWeightType == 1 || maxWeightType == 2) && genpDilType == 1)
2546 || (maxWeightType == 3 && genpDilType == 2)){
2547 std::cout<<"Dil type "<<genpDilType<<" ; Strasbourg dil type "<<strasbourgDilType
2548 <<" assigned correctly by maxWeight method";
2549 std::cout<<" out of"; for(unsigned int iih=0;iih<nGoodHyps;++iih)std::cout<<" "<<cms2.hyp_type()[goodHyps[iih]];
2550 std::cout<<std::endl;
2551 } else {
2552 std::cout<<"Dil type "<<genpDilType<<" ; Strasbourg dil type "<<strasbourgDilType
2553 <<" assigned incorrectly by maxWeight method";
2554 std::cout<<" out of"; for(unsigned int iih=0;iih<nGoodHyps;++iih)std::cout<<" "<<cms2.hyp_type()[goodHyps[iih]];
2555 std::cout<<std::endl;
2556 }
2557 }
2558 } else{
2559 if (genpCountPDGId(11,13,15) == 2){
2560 std::cout<<"TauDil type "<<std::endl;
2561 }
2562 }
2563 int nMCTruth = 0;
2564 for(unsigned int iih=0;iih<nGoodHyps;++iih) if (matchesMCTruthDilExtended(goodHyps[iih])) nMCTruth++;
2565 std::cout<<"Ne: "<<genpCountPDGId_Pt20h24(11)<<" nmu: "<<genpCountPDGId_Pt20h24(13)<<" ntau: "<<genpCountPDGId_Pt20h24(15)
2566 <<" ngood "<<nGoodHyps
2567 <<" hyp_typeM: "<<cms2.hyp_type()[maxWeightIndex]<<" matchMC "<<(matchesMCTruthDilExtended(maxWeightIndex)? 1 : 0)
2568 <<" nMatches "<<nMCTruth
2569 <<" ltid "<< cms2.hyp_lt_id()[maxWeightIndex]
2570 <<" ltmcid "<< cms2.hyp_lt_mc_id()[maxWeightIndex]<<" ltmcmid "<< cms2.hyp_lt_mc_motherid()[maxWeightIndex]
2571 <<" llid "<< cms2.hyp_ll_id()[maxWeightIndex]
2572 <<" llmcid "<< cms2.hyp_ll_mc_id()[maxWeightIndex]<<" llmcmid "<< cms2.hyp_ll_mc_motherid()[maxWeightIndex]
2573 <<std::endl;
2574 }
2575
2576 result = maxWeightIndex;
2577 return result;
2578 }
2579
2580 int eventDilIndexByWeightTTDil08(const std::vector<unsigned int>& goodHyps, int& strasbourgDilType, bool printDebug, bool usePtOnlyForWeighting){
2581 int result = -1;
2582 unsigned int nGoodHyps = goodHyps.size();
2583 if ( nGoodHyps == 0 ) return result;
2584
2585 float maxWeight = -1;
2586 unsigned int maxWeightIndex = 9999;
2587
2588 for (unsigned int hypIdxL=0; hypIdxL < nGoodHyps; ++hypIdxL){
2589 unsigned int hypIdx = goodHyps[hypIdxL];
2590 float hypWeight_lt = 0;
2591 float hypWeight_ll = 0;
2592 float hypWeight_iso = 0;
2593 float hypWeight = 0;
2594 unsigned int i_lt = cms2.hyp_lt_index().at(hypIdx);
2595 unsigned int i_ll = cms2.hyp_ll_index().at(hypIdx);
2596
2597 int id_lt = cms2.hyp_lt_id().at(hypIdx);
2598 int id_ll = cms2.hyp_ll_id().at(hypIdx);
2599
2600 float isoTk_lt = leptonTrkIsolationTTDil08(id_lt, i_lt);
2601 float isoTk_ll = leptonTrkIsolationTTDil08(id_ll, i_ll);
2602
2603 float isoCal_lt = leptonCalIsolationTTDil08(id_lt, i_lt);
2604 float isoCal_ll = leptonCalIsolationTTDil08(id_ll, i_ll);
2605
2606 //ad-hoc selection of weights
2607 if (abs(id_lt) == 11){
2608 //I want to select "trk & cal"-isolated ones
2609 hypWeight_iso += (isoTk_lt*isoCal_lt - 0.25); //shift by 0.25 to be positive-definite
2610 if (! usePtOnlyForWeighting && cms2.els_egamma_tightId().at(i_lt)) hypWeight_lt += 0.2;
2611 }
2612 if (abs(id_lt) == 13){
2613 //I want to select "trk & cal"-isolated ones
2614 hypWeight_iso += (isoTk_lt*isoCal_lt - 0.25);//shift by 0.25 to be positive-definite
2615 if (! usePtOnlyForWeighting) hypWeight_lt += 0.4;
2616 }
2617 if (abs(id_ll) == 11){
2618 //I want to select "trk & cal"-isolated ones
2619 hypWeight_iso *= (isoTk_ll*isoCal_ll - 0.25); //shift by 0.25 to be positive-definite
2620 if (! usePtOnlyForWeighting && cms2.els_egamma_tightId().at(i_ll)) hypWeight_ll += 0.2;
2621 }
2622 if (abs(id_ll) == 13){
2623 //I want to select "trk & cal"-isolated ones
2624 hypWeight_iso *= (isoTk_ll*isoCal_ll - 0.25); //shift by 0.25 to be positive-definite
2625 if (! usePtOnlyForWeighting) hypWeight_ll += 0.4;
2626 }
2627 float pt_lt = cms2.hyp_lt_p4().at(hypIdx).pt();
2628 float pt_ll = cms2.hyp_ll_p4().at(hypIdx).pt();
2629 hypWeight_lt += (1. - 20./pt_lt*20./pt_lt);
2630 hypWeight_ll += (1. - 20./pt_ll*20./pt_ll);
2631
2632 if (usePtOnlyForWeighting){
2633 hypWeight = hypWeight_ll*hypWeight_lt; //again, desire to have both good
2634 } else {
2635 hypWeight = hypWeight_ll*hypWeight_lt*hypWeight_iso; //again, desire to have both good
2636 }
2637
2638 if (hypWeight > maxWeight){
2639 maxWeight = hypWeight;
2640 maxWeightIndex = hypIdx;
2641 }
2642 }
2643
2644
2645 //Now let's implement the Strasbourg-type disambiguation/dispatch
2646 //ee
2647 {
2648 std::vector<unsigned int> looseEls(0);
2649 std::vector<unsigned int> looseMus(0);
2650 for (unsigned int iEl =0; iEl < cms2.els_p4().size(); ++iEl){
2651 if (looseElectronSelectionTTDil08(iEl)){
2652 looseEls.push_back(iEl);
2653 }
2654 }
2655 for (unsigned int iMu =0; iMu < cms2.mus_p4().size(); ++iMu){
2656 if (looseMuonSelectionTTDil08(iMu)){
2657 looseMus.push_back(iMu);
2658 }
2659 }
2660
2661 bool pass_elec = false;
2662 if (looseEls.size()>1){
2663 if (cms2.els_charge().at(looseEls[0]) != cms2.els_charge().at(looseEls[1])){
2664 pass_elec = true;
2665 }
2666 if (looseMus.size()>0 && cms2.mus_p4().at(looseMus[0]).pt() > cms2.els_p4().at(looseEls[1]).pt()) pass_elec = false;
2667 if (looseMus.size()>0 &&
2668 ( ( muonTrkIsolationTTDil08(looseMus[0]) > electronTrkIsolationTTDil08(looseEls[0])
2669 && cms2.mus_charge().at(looseMus[0]) != cms2.els_charge().at(looseEls[0]) )
2670 || ( muonTrkIsolationTTDil08(looseMus[0]) > electronTrkIsolationTTDil08(looseEls[1])
2671 && cms2.mus_charge().at(looseMus[0]) != cms2.els_charge().at(looseEls[0]))
2672 )
2673 ) pass_elec = false;
2674 }
2675 bool pass_muon = false;
2676 if (looseMus.size()>1){
2677 for (unsigned int iMu=0; iMu < looseMus.size(); ++iMu){
2678 for (unsigned int jMu=iMu+1; jMu < looseMus.size(); ++jMu){
2679 if (cms2.mus_charge().at(looseMus[iMu]) != cms2.mus_charge().at(looseMus[jMu])) pass_muon = true;
2680 }
2681 }
2682 if (looseEls.size()>0 && cms2.els_p4().at(looseEls[0]).pt() > cms2.mus_p4().at(looseMus[1]).pt()
2683 && cms2.mus_charge().at(looseMus[1]) != cms2.els_charge().at(looseEls[0])) pass_muon = false;
2684 }
2685 bool pass_elecmuon = false;
2686 if (looseMus.size() > 0 && looseEls.size() > 0){
2687 if (! pass_elec && ! pass_muon ){
2688 if (cms2.mus_charge().at(looseMus[0]) != cms2.els_charge().at(looseEls[0])) pass_elecmuon = true;
2689 if (! pass_elecmuon && looseEls.size()>1){
2690 if (cms2.mus_charge().at(looseMus[0]) != cms2.els_charge().at(looseEls[0])) pass_elecmuon = true;
2691 }
2692 }
2693 }
2694
2695 unsigned int passStatus = 0;
2696 if (pass_muon) passStatus++;
2697 if (pass_elecmuon) passStatus++;
2698 if (pass_elec) passStatus++;
2699 if (passStatus > 1) std::cout<<"ERROR: inconsistent assignment"<<std::endl;
2700 if (passStatus == 1){
2701 if (pass_muon) strasbourgDilType = 0;
2702 if (pass_elecmuon) strasbourgDilType = 1;
2703 if (pass_elec) strasbourgDilType = 2;
2704 }
2705 }
2706
2707 if (printDebug){
2708 int genpDilType = genpDileptonType();
2709 if (genpDilType>=0 ){ std::cout<<"Dil type "<<genpDilType<<std::endl;
2710 if (nGoodHyps > 1){
2711 int maxWeightType = cms2.hyp_type().at(maxWeightIndex);
2712 if ((maxWeightType == 0 && genpDilType == 0)
2713 || ( (maxWeightType == 1 || maxWeightType == 2) && genpDilType == 1)
2714 || (maxWeightType == 3 && genpDilType == 2)){
2715 std::cout<<"Dil type "<<genpDilType<<" ; Strasbourg dil type "<<strasbourgDilType
2716 <<" assigned correctly by maxWeight method";
2717 std::cout<<" out of"; for(unsigned int iih=0;iih<nGoodHyps;++iih)std::cout<<" "<<cms2.hyp_type().at(goodHyps[iih]);
2718 std::cout<<std::endl;
2719 } else {
2720 std::cout<<"Dil type "<<genpDilType<<" ; Strasbourg dil type "<<strasbourgDilType
2721 <<" assigned incorrectly by maxWeight method";
2722 std::cout<<" out of"; for(unsigned int iih=0;iih<nGoodHyps;++iih)std::cout<<" "<<cms2.hyp_type().at(goodHyps[iih]);
2723 std::cout<<std::endl;
2724 }
2725 }
2726 }
2727 int nMCTruth = 0;
2728 for(unsigned int iih=0;iih<nGoodHyps;++iih) if (matchesMCTruthDilExtended(goodHyps[iih])) nMCTruth++;
2729 std::cout<<"Ne: "<<genpCountPDGId_Pt20h24(11)<<" nmu: "<<genpCountPDGId_Pt20h24(13)<<" ntau: "<<genpCountPDGId_Pt20h24(15)
2730 <<" ngood "<<nGoodHyps<<" SBtype "<<strasbourgDilType
2731 <<" hyp_typeM: "<<cms2.hyp_type()[maxWeightIndex]<<" matchMC "<<(matchesMCTruthDilExtended(maxWeightIndex)? 1 : 0)
2732 <<" nMatches "<<nMCTruth
2733 <<" ltid "<< cms2.hyp_lt_id()[maxWeightIndex]
2734 <<" ltmcid "<< cms2.hyp_lt_mc_id()[maxWeightIndex]<<" ltmcmid "<< cms2.hyp_lt_mc_motherid()[maxWeightIndex]
2735 <<" llid "<< cms2.hyp_ll_id()[maxWeightIndex]
2736 <<" llmcid "<< cms2.hyp_ll_mc_id()[maxWeightIndex]<<" llmcmid "<< cms2.hyp_ll_mc_motherid()[maxWeightIndex]
2737 <<std::endl;
2738 }
2739
2740 result = maxWeightIndex;
2741 return result;
2742 }
2743
2744
2745
2746 //-------------------------------------------------------------
2747 // TTDil08 Fake Rate selections (FO, numerator selections)
2748 //-------------------------------------------------------------
2749
2750
2751 //Is the electron a Numerator electron?
2752 //Same selections as the TTDil selections for electrons
2753 bool isNumElTTDil08(int iEl) {
2754
2755 Double_t pt = cms2.els_p4()[iEl].Pt();
2756 Double_t eta = cms2.els_p4()[iEl].Eta();
2757
2758 if( pt < 20)
2759 return false;
2760 if( fabs( eta ) > 2.4 )
2761 return false;
2762 //reject if electron is close to muon;
2763 if( cms2.els_closestMuon()[iEl] > -1)
2764 return false;
2765
2766 //now the numerator cuts
2767 //add in track isolation
2768 if( pt/(pt + cms2.els_pat_trackIso()[iEl]) < 0.9)
2769 return false;
2770 //add in calo isolation
2771 if( pt/(pt + cms2.els_pat_caloIso()[iEl]) < 0.8)
2772 return false;
2773 //corrected d0 cut
2774 if( fabs(cms2.els_d0corr()[iEl]) > 0.04)
2775 return false;
2776 //electron id cut
2777 if( ! cms2.els_egamma_looseId()[iEl] )
2778 return false;
2779
2780 return true;
2781 }
2782 //------------------------------------------------------------
2783 // is it a FO electron?
2784 //------------------------------------------------------------
2785 bool isFakeableElTTDil08(int iEl) {
2786
2787 Double_t pt = cms2.els_p4()[iEl].Pt();
2788 Double_t eta = cms2.els_p4()[iEl].Eta();
2789
2790 //base selections:
2791 //make up some loose electron selection for now
2792 if( pt < 20)
2793 return false;
2794 if( fabs( eta ) > 2.4 )
2795 return false;
2796 //reject if electron is close to muon;
2797 if( cms2.els_closestMuon()[iEl] > -1)
2798 return false;
2799
2800 //check if the electron passes the FO
2801 //object selections
2802 //add in track isolation
2803 if( pt/(pt + cms2.els_pat_trackIso()[iEl]) < 0.7) //0.7
2804 return false;
2805 //add in calo isolation
2806 if( pt/(pt + cms2.els_pat_caloIso()[iEl]) < 0.6) //0.6
2807 return false;
2808
2809 return true;
2810 }
2811
2812 //------------------------------------------------------------
2813 //is numerator muon?
2814 //------------------------------------------------------------
2815
2816 bool isNumMuTTDil08(int iMu) {
2817
2818 Double_t pt = cms2.mus_p4()[iMu].Pt();
2819 Double_t eta = cms2.mus_p4()[iMu].Eta();
2820
2821 if(!(2 & cms2.mus_type()[iMu]))
2822 return false;
2823
2824 if( pt < 20)
2825 return false;
2826 if( fabs( eta ) > 2.4 )
2827 return false;
2828
2829 //now the numerator cuts
2830 if( cms2.mus_gfit_chi2()[iMu]/cms2.mus_gfit_ndof()[iMu] > 10)
2831 return false;
2832 //add in track isolation
2833 if( pt/(pt + cms2.mus_pat_trackIso()[iMu]) < 0.9)
2834 return false;
2835 //add in calo isolation
2836 if( pt/(pt + cms2.mus_pat_caloIso()[iMu]) < 0.9)
2837 return false;
2838
2839 //nHits cut
2840 if( cms2.mus_validHits()[iMu] < 11 )
2841 return false;
2842
2843 return true;
2844 }
2845
2846 //------------------------------------------------------------
2847 // is FO Mu
2848 //------------------------------------------------------------
2849
2850 bool isFakeableMuTTDil08(int iMu) {
2851
2852 Double_t pt = cms2.mus_p4()[iMu].Pt();
2853 Double_t eta = cms2.mus_p4()[iMu].Eta();
2854
2855 //base selections:
2856 //loose muon selection
2857 //only globalMuons
2858 if(!(2 & cms2.mus_type()[iMu]))
2859 return false;
2860
2861 if( pt < 20)
2862 return false;
2863 if( fabs( eta ) > 2.4 )
2864 return false;
2865 if( cms2.mus_gfit_chi2()[iMu]/cms2.mus_gfit_ndof()[iMu] > 20)
2866 return false;
2867 //check if the muon passes the FO
2868 //object selections
2869 //add in track isolation
2870 if( pt/(pt + cms2.mus_pat_trackIso()[iMu]) < 0.7)
2871 return false;
2872 //add in calo isolation
2873 if( pt/(pt + cms2.mus_pat_caloIso()[iMu]) < 0.7)
2874 return false;
2875
2876 return true;
2877 }
2878
2879 //------------------------------------------------------------
2880
2881 bool trueGammaFromMuon(int electron) {
2882 // true gamma reconstructed as electron
2883 // gamma coming from muon
2884 if(TMath::Abs(cms2.els_mc_id()[electron]) == 22 && TMath::Abs(cms2.els_mc_motherid()[electron]) == 13) { // ok, abs of photon makes no sense ;)
2885 // std::cout<<"Gamma from muon event - r: " << cms2.evt_run() << " e: " << cms2.evt_event() << " l: " << cms2.evt_lumiBlock() << std::endl;
2886 return true;
2887 }
2888 // if( cms2.els_mc_motherid()[electron] == 22 ) {
2889 // std::cout<<"Electron with gamma mother - r: " << cms2.evt_run() << " e: " << cms2.evt_event() << " l: " << cms2.evt_lumiBlock() << std::endl;
2890 // }
2891 // if( cms2.els_mc_id()[electron] == 22 ) {
2892 // std::cout<<"***"<<std::endl;
2893 // std::cout<<"Electron which is a really a gamma - r: " << cms2.evt_run() << " e: " << cms2.evt_event() << " l: " << cms2.evt_lumiBlock() << std::endl;
2894 // std::cout<<"el mc id: "<<cms2.els_mc_id()[electron]<<" el mother id "<< cms2.els_mc_motherid()[electron]<<std::endl;
2895 // std::cout<<"***"<<std::endl;
2896 // }
2897
2898 return false;
2899 }
2900 //----------------------------------------------------
2901 // Utility function to calculate dR between vectors
2902 //-----------------------------------------------------
2903 double dRBetweenVectors(LorentzVector v1, LorentzVector v2) {
2904 double deta = v1.eta() - v2.eta();
2905 double dphi = fabs(v1.phi() - v2.phi());
2906 if (dphi > TMath::Pi()) dphi = TMath::TwoPi() - dphi;
2907 return sqrt(deta*deta+dphi*dphi);
2908 }
2909 //----------------------------------------------------
2910 // Conversions stuff
2911 //----------------------------------------------------
2912
2913 //old cut to find conversions
2914 bool conversionElectron(int electron) {
2915 // true if electron is a conversion electron
2916 if( fabs(cms2.els_conv_dist()[electron]) < 0.02 && fabs(cms2.els_conv_dcot()[electron]) < 0.02)
2917 return true;
2918
2919 return false;
2920 }
2921
2922 //utility function to get the dist and delta cot theta
2923 std::pair<float, float> getConversionInfo(LorentzVector trk1_p4,
2924 int trk1_q, float trk1_d0,
2925 LorentzVector trk2_p4,
2926 int trk2_q, float trk2_d0,
2927 float bField) {
2928
2929
2930 double tk1Curvature = -0.3*bField*(trk1_q/trk1_p4.pt())/100.;
2931 double rTk1 = fabs(1./tk1Curvature);
2932 double xTk1 = (1./tk1Curvature - trk1_d0)*cos(trk1_p4.phi());
2933 double yTk1 = (1./tk1Curvature - trk1_d0)*sin(trk1_p4.phi());
2934
2935 double tk2Curvature = -0.3*bField*(trk2_q/trk2_p4.pt())/100.;
2936 double rTk2 = fabs(1./tk2Curvature);
2937 double xTk2 = (1./tk2Curvature - trk2_d0)*cos(trk2_p4.phi());
2938 double yTk2 = (1./tk2Curvature - trk2_d0)*sin(trk2_p4.phi());
2939
2940 double dist = sqrt(pow(xTk1-xTk2, 2) + pow(yTk1-yTk2 , 2));
2941 dist = dist - (rTk1 + rTk2);
2942
2943 double dcot = 1/tan(trk1_p4.theta()) - 1/tan(trk2_p4.theta());
2944
2945 return make_pair(dist, dcot);
2946
2947 }
2948
2949 //new conversion loop to determine if the electron is from a conversion or not
2950 bool isconversionElectron09(int elIdx) {
2951
2952 for(unsigned int tkIdx = 0; tkIdx < cms2.trks_trk_p4().size(); tkIdx++) {
2953 if(dRBetweenVectors(cms2.els_trk_p4()[elIdx], cms2.trks_trk_p4()[tkIdx]) > 0.3)
2954 continue;
2955 //skip the electron's track
2956 if(cms2.els_trkidx()[elIdx] == tkIdx && cms2.els_trkshFrac()[elIdx] > 0.45)
2957 continue;
2958 //ship non-opp sign candidates
2959 if(cms2.trks_charge()[tkIdx] + cms2.els_charge()[elIdx] != 0)
2960 continue;
2961
2962 std::pair<float, float> temp = getConversionInfo(cms2.els_trk_p4()[elIdx], cms2.els_charge()[elIdx], cms2.els_d0()[elIdx],
2963 cms2.trks_trk_p4()[tkIdx], cms2.trks_charge()[tkIdx], cms2.trks_d0()[tkIdx],
2964 cms2.evt_bField());
2965
2966 if(fabs(temp.first) < 0.02 && fabs(temp.second) < 0.02)
2967 return true;
2968
2969 }//track loop
2970
2971 return false;
2972
2973 }
2974 //---------------------------------------------------
2975 //End conversion functions
2976 //---------------------------------------------------
2977
2978
2979
2980
2981 // false if below ptcut, aboveabsEtaCut, below dRCut wrt hypothesis
2982 bool isGoodDilHypJet(unsigned int jetIdx, unsigned int hypIdx, double ptCut, double absEtaCut, double dRCut, bool muJetClean){
2983 if (cms2.jets_p4()[jetIdx].pt()< ptCut || fabs(cms2.jets_p4()[jetIdx].eta())> absEtaCut) return false;
2984 double dR_ll = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_ll_p4()[hypIdx],cms2.jets_p4()[jetIdx]);
2985 double dR_lt = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_lt_p4()[hypIdx],cms2.jets_p4()[jetIdx]);
2986
2987 if (abs(cms2.hyp_ll_id()[hypIdx]) == 11){
2988 if (dR_ll < dRCut) return false;
2989 }
2990 if (abs(cms2.hyp_lt_id()[hypIdx]) == 11){
2991 if (dR_lt < dRCut) return false;
2992 }
2993
2994 if (muJetClean){
2995 if (abs(cms2.hyp_ll_id()[hypIdx]) == 13){
2996 if (dR_ll < dRCut) return false;
2997 }
2998 if (abs(cms2.hyp_lt_id()[hypIdx]) == 13){
2999 if (dR_lt < dRCut) return false;
3000 }
3001 }
3002
3003 return true;
3004
3005 }
3006
3007 // false if below ptcut, aboveabsEtaCut, below dRCut wrt hypothesis
3008 bool isGoodDilHypJPTJet(unsigned int jetIdx, unsigned int hypIdx, double ptCut, double absEtaCut, double dRCut){
3009 if (cms2.jpts_p4()[jetIdx].pt()< ptCut || fabs(cms2.jpts_p4()[jetIdx].eta())> absEtaCut) return false;
3010 double dR_ll = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_ll_p4()[hypIdx],cms2.jpts_p4()[jetIdx]);
3011 double dR_lt = ROOT::Math::VectorUtil::DeltaR(cms2.hyp_lt_p4()[hypIdx],cms2.jpts_p4()[jetIdx]);
3012
3013 if (dR_ll < dRCut) return false;
3014 if (dR_lt < dRCut) return false;
3015
3016 return true;
3017
3018 }
3019
3020
3021 int findPrimTrilepZ(int i_hyp, double &mass) {
3022 // find primary Z candidate in trilepton hyp
3023 //
3024 // return: 1: first lepton was not used in Z candidate
3025 // 2: second lepton was not used in Z candidate
3026 // 3: second lepton was not used in Z candidate
3027 // 999: no Z candidate could be found
3028 //
3029 // 900: error code, something went wrong
3030
3031 // z mass array, coding:
3032 // index 0: first, second
3033 // index 1: first, third
3034 // index 2: second, third
3035 double z_mass[3] = {0.,0.,0.};
3036
3037 // check if first and second lepton form Z candidate
3038 if ( abs(cms2.hyp_trilep_first_type()[i_hyp]) == abs(cms2.hyp_trilep_second_type()[i_hyp]) ) {
3039 if ( abs(cms2.hyp_trilep_first_type()[i_hyp]) == 1 ) {
3040 if ( cms2.mus_charge()[cms2.hyp_trilep_first_index()[i_hyp]] != cms2.mus_charge()[cms2.hyp_trilep_second_index()[i_hyp]] ) {
3041 LorentzVector z = cms2.mus_p4()[cms2.hyp_trilep_first_index()[i_hyp]] + cms2.mus_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
3042 // if ( inZmassWindow(z.mass()) )
3043 z_mass[0] = z.mass();
3044 }
3045 } else {
3046 if ( cms2.els_charge()[cms2.hyp_trilep_first_index()[i_hyp]] != cms2.els_charge()[cms2.hyp_trilep_second_index()[i_hyp]] ) {
3047 LorentzVector z = cms2.els_p4()[cms2.hyp_trilep_first_index()[i_hyp]] + cms2.els_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
3048 // if ( inZmassWindow(z.mass()) )
3049 z_mass[0] = z.mass();
3050 }
3051 }
3052 }
3053 // check if first and third lepton form Z candidate
3054 if ( abs(cms2.hyp_trilep_first_type()[i_hyp]) == abs(cms2.hyp_trilep_third_type()[i_hyp]) ) {
3055 if ( abs(cms2.hyp_trilep_first_type()[i_hyp]) == 1 ) {
3056 if ( cms2.mus_charge()[cms2.hyp_trilep_first_index()[i_hyp]] != cms2.mus_charge()[cms2.hyp_trilep_third_index()[i_hyp]] ) {
3057 LorentzVector z = cms2.mus_p4()[cms2.hyp_trilep_first_index()[i_hyp]] + cms2.mus_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3058 // if ( inZmassWindow(z.mass()) )
3059 z_mass[1] = z.mass();
3060 }
3061 } else {
3062 if ( cms2.els_charge()[cms2.hyp_trilep_first_index()[i_hyp]] != cms2.els_charge()[cms2.hyp_trilep_third_index()[i_hyp]] ) {
3063 LorentzVector z = cms2.els_p4()[cms2.hyp_trilep_first_index()[i_hyp]] + cms2.els_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3064 // if ( inZmassWindow(z.mass()) )
3065 z_mass[1] = z.mass();
3066 }
3067 }
3068 }
3069 // check if second and third lepton form Z candidate
3070 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == abs(cms2.hyp_trilep_third_type()[i_hyp]) ) {
3071 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1 ) {
3072 if ( cms2.mus_charge()[cms2.hyp_trilep_second_index()[i_hyp]] != cms2.mus_charge()[cms2.hyp_trilep_third_index()[i_hyp]] ) {
3073 LorentzVector z = cms2.mus_p4()[cms2.hyp_trilep_second_index()[i_hyp]] + cms2.mus_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3074 // if ( inZmassWindow(z.mass()) )
3075 z_mass[2] = z.mass();
3076 }
3077 } else {
3078 if ( cms2.els_charge()[cms2.hyp_trilep_second_index()[i_hyp]] != cms2.els_charge()[cms2.hyp_trilep_third_index()[i_hyp]] ) {
3079 LorentzVector z = cms2.els_p4()[cms2.hyp_trilep_second_index()[i_hyp]] + cms2.els_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3080 // if ( inZmassWindow(z.mass()) )
3081 z_mass[2] = z.mass();
3082 }
3083 }
3084 }
3085
3086 // check which combination is nearest to Z mass and return unsused lepton
3087 // if ( z_mass[0] == 0 && z_mass[1] == 0 && z_mass[2] == 0 )
3088 // return 999;
3089 int ret = 0;
3090 if ( fabs( z_mass[0] - 91) <= fabs( z_mass[1] - 91) && fabs( z_mass[0] - 91) <= fabs( z_mass[2] - 91) ) {
3091 mass = z_mass[0];
3092 ret = 3;
3093 } else if ( fabs( z_mass[1] - 91) <= fabs( z_mass[0] - 91) && fabs( z_mass[1] - 91) <= fabs( z_mass[2] - 91) ) {
3094 mass = z_mass[1];
3095 ret = 2;
3096 } else if ( fabs( z_mass[2] - 91) <= fabs( z_mass[0] - 91) && fabs( z_mass[2] - 91) <= fabs( z_mass[1] - 91) ) {
3097 mass = z_mass[2];
3098 ret = 1;
3099 }
3100
3101 if ( !inZmassWindow(mass) ) {
3102 return 999;
3103 } else {
3104 return ret;
3105 }
3106
3107 return 900;
3108
3109 }
3110
3111 bool vetoAddZ(int i_hyp, int unusedLepton, double &mass) {
3112 // veto event if unused lepton (not used to form primary Z) and a isolated track form a second Z, only for trilepton
3113 LorentzVector lepton;
3114 if ( unusedLepton == 1 ) {
3115 if ( abs(cms2.hyp_trilep_first_type()[i_hyp]) == 1 )
3116 lepton = cms2.mus_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
3117 else
3118 lepton = cms2.els_p4()[cms2.hyp_trilep_first_index()[i_hyp]];
3119 } else if ( unusedLepton == 2 ) {
3120 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1 )
3121 lepton = cms2.mus_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
3122 else
3123 lepton = cms2.els_p4()[cms2.hyp_trilep_second_index()[i_hyp]];
3124 } else if ( unusedLepton == 3 ) {
3125 if ( abs(cms2.hyp_trilep_third_type()[i_hyp]) == 1 )
3126 lepton = cms2.mus_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3127 else
3128 lepton = cms2.els_p4()[cms2.hyp_trilep_third_index()[i_hyp]];
3129 }
3130
3131 mass = -1.;
3132
3133 for ( int track = 0;
3134 track < (int)cms2.trks_trk_p4().size();
3135 ++track ) {
3136
3137 // exclude track from first lepton
3138 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1 ) {
3139 if ( cms2.mus_trkidx()[cms2.hyp_trilep_first_index()[i_hyp]] == track ) continue;
3140 } else {
3141 if ( cms2.els_trkidx()[cms2.hyp_trilep_first_index()[i_hyp]] == track ) continue;
3142 }
3143
3144 // exclude track from second lepton
3145 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1 ) {
3146 if ( cms2.mus_trkidx()[cms2.hyp_trilep_second_index()[i_hyp]] == track ) continue;
3147 } else {
3148 if ( cms2.els_trkidx()[cms2.hyp_trilep_second_index()[i_hyp]] == track ) continue;
3149 }
3150
3151 // exclude track from third lepton
3152 if ( abs(cms2.hyp_trilep_second_type()[i_hyp]) == 1 ) {
3153 if ( cms2.mus_trkidx()[cms2.hyp_trilep_third_index()[i_hyp]] == track ) continue;
3154 } else {
3155 if ( cms2.els_trkidx()[cms2.hyp_trilep_third_index()[i_hyp]] == track ) continue;
3156 }
3157
3158 if ( passTrackIsolation(track) && cms2.trks_trk_p4()[track].Pt() >= 20. ) {
3159 LorentzVector z = lepton + cms2.trks_trk_p4()[track];
3160 if ( fabs(z.mass() - 91) <= fabs(mass - 91 ) )
3161 mass = z.mass();
3162 }
3163 }
3164
3165 if ( inZmassWindow(mass) ) return true;
3166
3167 return false;
3168
3169 }
3170
3171 bool isChargeFlip(int elIndex){
3172 //true if electron is likely to be a charge flip
3173 if ((cms2.els_trkidx().at(elIndex) >= 0) && (cms2.els_charge().at(elIndex) != cms2.trks_charge().at(cms2.els_trkidx().at(elIndex)))) return true;
3174
3175 return false;
3176 }
3177
3178 // heavy flavor Classification
3179
3180 bool idIsCharm(int id) {
3181 id = abs(id);
3182 if (
3183 id == 4 ||
3184 id == 411 ||
3185 id == 421 ||
3186 id == 10411 ||
3187 id == 10421 ||
3188 id == 413 ||
3189 id == 423 ||
3190 id == 10413 ||
3191 id == 10423 ||
3192 id == 20413 ||
3193 id == 20423 ||
3194 id == 415 ||
3195 id == 425 ||
3196 id == 431 ||
3197 id == 10431 ||
3198 id == 433 ||
3199 id == 10433 ||
3200 id == 20433 ||
3201 id == 435 ||
3202 id == 441 ||
3203 id == 10441 ||
3204 id == 100441 ||
3205 id == 443 ||
3206 id == 10443 ||
3207 id == 20443 ||
3208 id == 100443 ||
3209 id == 30443 ||
3210 id == 9000443 ||
3211 id == 9010443 ||
3212 id == 9020443 ||
3213 id == 445 ||
3214 id == 9000445 ||
3215 id == 4122 ||
3216 id == 4222 ||
3217 id == 4212 ||
3218 id == 4112 ||
3219 id == 4224 ||
3220 id == 4214 ||
3221 id == 4114 ||
3222 id == 4232 ||
3223 id == 4132 ||
3224 id == 4322 ||
3225 id == 4312 ||
3226 id == 4324 ||
3227 id == 4314 ||
3228 id == 4332 ||
3229 id == 4334 ||
3230 id == 4412 ||
3231 id == 4422 ||
3232 id == 4414 ||
3233 id == 4424 ||
3234 id == 4432 ||
3235 id == 4434 ||
3236 id == 4444
3237 ) {
3238 return true;
3239 }
3240 else return false;
3241 }
3242
3243 bool idIsBeauty(int id) {
3244 id = abs(id);
3245 if (
3246 id == 5 ||
3247 id == 511 ||
3248 id == 521 ||
3249 id == 10511 ||
3250 id == 10521 ||
3251 id == 513 ||
3252 id == 523 ||
3253 id == 10513 ||
3254 id == 10523 ||
3255 id == 20513 ||
3256 id == 20523 ||
3257 id == 515 ||
3258 id == 525 ||
3259 id == 531 ||
3260 id == 10531 ||
3261 id == 533 ||
3262 id == 10533 ||
3263 id == 20533 ||
3264 id == 535 ||
3265 id == 541 ||
3266 id == 10541 ||
3267 id == 543 ||
3268 id == 10543 ||
3269 id == 20543 ||
3270 id == 545 ||
3271 id == 551 ||
3272 id == 10551 ||
3273 id == 100551 ||
3274 id == 110551 ||
3275 id == 200551 ||
3276 id == 210551 ||
3277 id == 553 ||
3278 id == 10553 ||
3279 id == 20553 ||
3280 id == 30553 ||
3281 id == 100553 ||
3282 id == 110553 ||
3283 id == 120553 ||
3284 id == 130553 ||
3285 id == 200553 ||
3286 id == 210553 ||
3287 id == 220553 ||
3288 id == 300553 ||
3289 id == 9000553 ||
3290 id == 9010553 ||
3291 id == 555 ||
3292 id == 10555 ||
3293 id == 20555 ||
3294 id == 100555 ||
3295 id == 110555 ||
3296 id == 120555 ||
3297 id == 200555 ||
3298 id == 557 ||
3299 id == 100557 ||
3300 id == 5122 ||
3301 id == 5112 ||
3302 id == 5212 ||
3303 id == 5222 ||
3304 id == 5114 ||
3305 id == 5214 ||
3306 id == 5224 ||
3307 id == 5132 ||
3308 id == 5232 ||
3309 id == 5312 ||
3310 id == 5322 ||
3311 id == 5314 ||
3312 id == 5324 ||
3313 id == 5332 ||
3314 id == 5334 ||
3315 id == 5142 ||
3316 id == 5242 ||
3317 id == 5412 ||
3318 id == 5422 ||
3319 id == 5414 ||
3320 id == 5424 ||
3321 id == 5342 ||
3322 id == 5432 ||
3323 id == 5434 ||
3324 id == 5442 ||
3325 id == 5444 ||
3326 id == 5512 ||
3327 id == 5522 ||
3328 id == 5514 ||
3329 id == 5524 ||
3330 id == 5532 ||
3331 id == 5534 ||
3332 id == 5542 ||
3333 id == 5544 ||
3334 id == 5554
3335 ) {
3336 return true;
3337 }
3338 else return false;
3339 }