ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/FGolf/rf/selections.cc
Revision: 1.1
Committed: Wed Dec 23 17:33:25 2009 UTC (15 years, 4 months ago) by benhoob
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 benhoob 1.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     }