ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitHzz4l/NonMCBackground/src/SelectionEMU.cc
(Generate patch)

Comparing UserCode/MitHzz4l/NonMCBackground/src/SelectionEMU.cc (file contents):
Revision 1.2 by khahn, Tue Feb 14 21:29:18 2012 UTC vs.
Revision 1.9 by dkralph, Mon Jun 25 18:08:04 2012 UTC

# Line 1 | Line 1
1 + //***************************************************************************************************
2 + //
3 + // selection sync'ed with https://twiki.cern.ch/twiki/bin/viewauth/CMS/HiggsZZ4l2012SummerSync
4 + //
5 + //***************************************************************************************************
6 +
7 + // system headers
8 + #include <map>
9 + #include <utility>
10 +
11 + // mit headers
12 + #include "Vertex.h"
13 +
14 + // 4L stuff
15   #include "SelectionStatus.h"
16   #include "EventData.h"
17   #include "SimpleLepton.h"
18   #include "EfficiencyWeightsInterface.h"
19 <
20 < #include "HZZBDTElectronSelection.h"
19 > #include "ElectronSelection.h"
20 > #include "MuonSelection.h"
21   #include "IsolationSelection.h"
8 #include "PassHLT.h"
22   #include "SelectionEMU.h"
23 <
24 < #include "ExternData.h"
23 > #include "ReferenceSelection.h"
24 > #include "Selection.h"
25 > #include "CommonDefs.h"
26   #include "SelectionDefs.h"
27 + #include "FSR.h"
28 + #include "SelectionFuncs.h"
29  
30  
31 <
32 < // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33 < // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34 < EventData apply_EMU_selection(ControlFlags &ctrl,           // input control
35 <                              mithep::TEventInfo *info,     // input event info
36 <                              TClonesArray *electronArr,    // input electrons
37 <                              SelectionStatus (*ElectronPreSelector)( ControlFlags &, const mithep::TElectron*),
38 <                              SelectionStatus (*ElectronIDSelector)( ControlFlags &, const mithep::TElectron*),
39 <                              SelectionStatus (*ElectronIsoSelector)( ControlFlags &, const mithep::TElectron*),
40 <                              TClonesArray *muonArr,         // input muons
41 <                              SelectionStatus (*MuonPreSelector)( ControlFlags &, const mithep::TMuon*),
42 <                              SelectionStatus (*MuonIDSelector)( ControlFlags &, const mithep::TMuon*),
43 <                              SelectionStatus (*MuonIsoSelector)( ControlFlags &, const mithep::TMuon*) )
44 < // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
45 < // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 > extern vector<SimpleLepton> failingLeptons;
32 > extern vector<SimpleLepton> passingLeptons;
33 > extern vector<int> muTrigObjs,eleTrigObjs,muTriggers,eleTriggers;
34 > extern bitset<TRIGGER_BIG_NUMBER> triggerBits;
35 >
36 > //--------------------------------------------------------------------------------------------------
37 > EventData apply_HZZ4L_EMU_selection(ControlFlags &ctrl,           // input control
38 >                                    const mithep::EventHeader *info,     // input event info
39 >                                    mithep::TriggerTable *hltTable,
40 >                                    mithep::Array<mithep::TriggerObject> *hltObjArr,
41 >                                    mithep::TriggerObjectsTable *fTrigObjs,
42 >                                    const mithep::Array<mithep::Vertex>       * vtxArr ,
43 >                                    const mithep::Array<mithep::PFCandidate>  *pfCandidates,
44 >                                    const mithep::Array<mithep::PileupEnergyDensity>  *puEnergyDensity,
45 >                                    const mithep::Array<mithep::Electron> *electronArr,    // input electrons
46 >                                    SelectionStatus (*ElectronPreSelector)( ControlFlags &,
47 >                                                                            const mithep::Electron*,
48 >                                                                            const mithep::Vertex *),
49 >                                    SelectionStatus (*ElectronIDSelector)( ControlFlags &,
50 >                                                                           const mithep::Electron*,
51 >                                                                           const mithep::Vertex *),
52 >                                    SelectionStatus (*ElectronIsoSelector)( ControlFlags &,
53 >                                                                            const mithep::Electron*,
54 >                                                                            const mithep::Vertex *,
55 >                                                                            const mithep::Array<mithep::PFCandidate> *,
56 >                                                                            const mithep::Array<mithep::PileupEnergyDensity> *,
57 >                                                                            mithep::ElectronTools::EElectronEffectiveAreaTarget,
58 >                                                                            vector<const mithep::PFCandidate*>),
59 >                                    const mithep::Array<mithep::Muon> *muonArr,    // input muons
60 >                                    SelectionStatus (*MuonPreSelector)( ControlFlags &,
61 >                                                                        const mithep::Muon*,
62 >                                                                        const mithep::Vertex *,
63 >                                                                        const mithep::Array<mithep::PFCandidate> *),
64 >                                    SelectionStatus (*MuonIDSelector)( ControlFlags &,
65 >                                                                       const mithep::Muon*,
66 >                                                                       // const mithep::Vertex &),
67 >                                                                       const mithep::Vertex *,
68 >                                                                       const mithep::Array<mithep::PFCandidate> *),
69 >                                    SelectionStatus (*MuonIsoSelector)( ControlFlags &,
70 >                                                                        const mithep::Muon*,
71 >                                                                        const mithep::Vertex *,
72 >                                                                        const mithep::Array<mithep::PFCandidate> *,
73 >                                                                        const mithep::Array<mithep::PileupEnergyDensity> *,
74 >                                                                        mithep::MuonTools::EMuonEffectiveAreaTarget,
75 >                                                                        vector<const mithep::PFCandidate*>)
76 >                                    )
77 > //--------------------------------------------------------------------------------------------------
78   {      
79  
80    EventData ret;
81    unsigned evtfail = 0x0;
82    TRandom3 r;
35  
36  if( ctrl.debug ) {
37    cout << "Run: " << info->runNum
38         << "\tEvt: " << info->evtNum
39         << "\tLumi: " << info->lumiSec
40         << endl;
41  }
83  
84 <  if( !ctrl.mc ) {
85 <    // not accounting for overlap atm
45 <    RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
46 <    if( !(rlrm.HasRunLumi(rl)) )  {
47 <      if( ctrl.debug ) cout << "\tfails JSON" << endl;
48 <      ret.status.setStatus(0);
49 <      return ret;
50 <    }
51 <  }
52 <  
53 <  
54 <  //********************************************************
55 <  // Trigger
56 <  //********************************************************
57 < //   if( !ctrl.mc ) {
58 < //     if( !(passHLTSingleMuon(info->triggerBits) )  ) {
59 < //       if( ctrl.debug ) cout << "\tfails trigger" << endl;
60 < //       evtfail |= (1<<EVTFAIL_TRIGGER);
61 < //       ret.status.setStatus(0);
62 < //       return ret;
63 < //     }        
64 < //   }
65 <  if( ctrl.debug ) {
66 <    cout << "presel nlep: " << muonArr->GetEntries() + electronArr->GetEntries()
67 <         << "\tnmuon: "    << muonArr->GetEntries()
68 <         << "\tnelectron: " << electronArr->GetEntries()
69 <         << endl;
70 <  }
84 >  failingLeptons.clear();
85 >  passingLeptons.clear();
86  
87 <  //********************************************************
88 <  // Lepton Selection
89 <  //********************************************************
90 <  vector<SimpleLepton> lepvec;
91 <  if( muonArr->GetEntries() != 1 && electronArr->GetEntries() != 1 ) {
92 <    ret.status.setStatus(0);
87 >  mithep::MuonTools::EMuonEffectiveAreaTarget eraMu;
88 >  mithep::ElectronTools::EElectronEffectiveAreaTarget eraEle;
89 >  getEATargets(ctrl,eraMu,eraEle);
90 >
91 >  const mithep::Vertex * vtx;
92 >  bool goodVertex = setPV( ctrl, vtxArr, vtx );
93 >  if(goodVertex) {
94 >    ret.status.selectionBits.flip(PASS_SKIM2);
95 >  } else {
96 >    if(ctrl.debug) cout << "found bad vertex" << endl;
97 >    ret.status.setStatus(SelectionStatus::FAIL);
98      return ret;
99    }
100  
101 <  //    
101 >  //***********************************************************
102 >  // Lepton Selection
103 >  //***********************************************************
104 >  vector<SimpleLepton> lepvec;
105 >  vector<const mithep::PFCandidate*> photonsToVeto;
106 >
107 >
108    if( ctrl.debug ) cout << "\tnMuons: " << muonArr->GetEntries() << endl;
109    //----------------------------------------------------
110 <  for(Int_t i=0; i<muonArr->GetEntries(); i++)
110 >  for(int i=0; i<muonArr->GetEntries(); i++)
111      {
112 <      const mithep::TMuon *mu = (mithep::TMuon*)((*muonArr)[i]);      
112 >      const mithep::Muon *mu = (mithep::Muon*)((*muonArr)[i]);      
113        
114 +
115 +      SelectionStatus denomSel;
116 +      denomSel |= muonPreSelectionNoD0DzIP(ctrl,mu,vtx,pfCandidates);
117 +      if( !denomSel.passPre() ) continue;
118 +
119        SelectionStatus musel;
120 <      if(ctrl.debug) cout << "musel.status  before anything: " << musel.getStatus() << endl;
121 <      musel |= (*MuonPreSelector)(ctrl,mu);
122 <      if(ctrl.debug) cout << "musel.status  after presel: " << musel.getStatus() << endl;
123 <      musel |= (*MuonIDSelector)(ctrl,mu);
124 <      if(ctrl.debug) cout << "musel.status  after ID: " << musel.getStatus() << endl;
125 <      musel |= (*MuonIsoSelector)(ctrl,mu);
126 <      if(ctrl.debug) cout << "musel.status  after iso: " << musel.getStatus() << endl;
127 <
128 <      if( ctrl.debug ) {
129 <        cout << "muon:: pt: " << mu->pt
99 <             << "\teta: " << mu->eta
100 <             << "\tisorel: " <<  mu->pfIso03/mu->pt
101 <             << "\tstatus: " << hex << musel.getStatus() << dec
102 <             << endl;
103 <      }
120 >      musel |= (*MuonPreSelector)(ctrl,mu,vtx,pfCandidates);
121 >      musel |= (*MuonIDSelector)(ctrl,mu,vtx,pfCandidates );
122 >      musel |= (*MuonIsoSelector)(ctrl,mu,vtx,pfCandidates,puEnergyDensity,eraMu,photonsToVeto);
123 >
124 >      SimpleLepton tmplep;
125 >      float pt = mu->Pt();
126 >      tmplep.vec.SetPtEtaPhiM(pt,
127 >                               mu->Eta(),
128 >                               mu->Phi(),
129 >                               MUON_MASS);
130        
131 <      if ( musel.pass() ) {
131 >      tmplep.type    = 13;
132 >      tmplep.index   = i;
133 >      tmplep.charge  = mu->Charge();
134 >      tmplep.isoTrk  = mu->IsoR03SumPt();
135 >      tmplep.isoEcal = mu->IsoR03EmEt();
136 >      tmplep.isoHcal = mu->IsoR03HadEt();
137 >      tmplep.isoPF04 = musel.isoPF04;
138 >      tmplep.chisoPF04 = musel.chisoPF04;
139 >      tmplep.gaisoPF04 = musel.gaisoPF04;
140 >      tmplep.neisoPF04 = musel.neisoPF04;
141 >      // tmplep.isoPF03 = computePFMuonIso(mu,vtx,pfCandidates,0.3);
142 >      // tmplep.isoPF04 = computePFMuonIso(mu,vtx,pfCandidates,0.4);
143 >      tmplep.ip3dSig = mu->Ip3dPVSignificance();
144 >      tmplep.is4l    = false;
145 >      tmplep.isEB    = (fabs(mu->Eta()) < 1.479 ? 1 : 0 );
146 >      tmplep.isoMVA  = musel.isoMVA;
147 >      tmplep.isLoose = musel.loose();
148 >
149 >      bitset<TRIGGER_BIG_NUMBER> hltMatchBits = fillHLTMatchBits( mu->Eta(), mu->Phi(), hltTable, hltObjArr, fTrigObjs);
150 >      tmplep.isTight = testBits(ctrl,triggerBits,muTriggers,hltMatchBits,muTrigObjs);
151 >
152 >      tmplep.bdtfail = 0;
153 >      if(triggerBits.test(kHLT_IsoMu24_eta2p1))        tmplep.bdtfail |= 1;
154 >      if(hltMatchBits.test(kHLT_IsoMu24_eta2p1_MuObj)) tmplep.bdtfail |= 2;
155 >      if(triggerBits.test(kHLT_IsoMu24))               tmplep.bdtfail |= 4;
156 >      if(hltMatchBits.test(kHLT_IsoMu24_MuObj))        tmplep.bdtfail |= 8;
157 >
158 >      tmplep.status  = musel;    
159 >      tmplep.fsrRecoveryAttempted = false;
160 >      SelectionStatus tmpstat = PassWwMuonSel(mu,vtx,pfCandidates);
161 >      tmplep.tightCutsApplied = tmpstat.tight();
162 >      lepvec.push_back(tmplep);
163 >      if( ctrl.debug ) cout << endl;
164 >    }
165  
166 <        SimpleLepton tmplep;
167 <        float pt = mu->pt;
168 <        tmplep.vecorig->SetPtEtaPhiM(pt,
169 <                                    mu->eta,
170 <                                    mu->phi,
171 <                                    MUON_MASS);
166 >    if( ctrl.debug ) { cout << "\tnElectron: " << electronArr->GetEntries() << endl; }
167 >    // --------------------------------------------------------------------------------
168 >    for(int i=0; i<electronArr->GetEntries(); i++)
169 >      {
170 >        const mithep::Electron *ele = (mithep::Electron*)((*electronArr)[i]);
171 >
172 >        SelectionStatus denomSel;
173 >        denomSel |= electronPreSelectionNoD0DzIP(ctrl,ele,vtx);
174 >        if( !(denomSel.getStatus() & SelectionStatus::PRESELECTION) ) continue;
175          
176 <        if( ctrl.do_escale_up ) {
177 <          pt=scale_smear_muon_Up(pt, 1,  r);
178 <        }
179 <        if( ctrl.do_escale_down ) {
118 <          pt=scale_smear_muon_Down(pt, 1,  r);
119 <        }
176 >        SelectionStatus elesel;
177 >        elesel |= (*ElectronPreSelector)(ctrl,ele,vtx);
178 >        elesel |= (*ElectronIDSelector)(ctrl,ele,vtx);
179 >        elesel |= (*ElectronIsoSelector)(ctrl,ele,vtx,pfCandidates,puEnergyDensity,eraEle,photonsToVeto);
180          
181 <        tmplep.vec->SetPtEtaPhiM(pt,
182 <                                mu->eta,
183 <                                mu->phi,
184 <                                MUON_MASS);
181 >        SimpleLepton tmplep;
182 >        float pt = ele->Pt();
183 >        tmplep.vec.SetPtEtaPhiM( pt,
184 >                                 ele->Eta(),
185 >                                 ele->Phi(),
186 >                                 ELECTRON_MASS );
187          
188 <        tmplep.type    = 13;
188 >        tmplep.type    = 11;
189          tmplep.index   = i;
190 <        tmplep.charge  = mu->q;
191 <        tmplep.isoTrk  = mu->trkIso03;
192 <        tmplep.isoEcal = mu->emIso03;
193 <        tmplep.isoHcal = mu->hadIso03;
194 <        tmplep.isoPF03 = mu->pfIso03;
195 <        tmplep.isoPF04 = mu->pfIso04;
196 <        tmplep.ip3dSig = mu->ip3dSig;
190 >        tmplep.charge  = ele->Charge();
191 >        tmplep.isoTrk  = ele->TrackIsolationDr03();
192 >        tmplep.isoEcal = ele->EcalRecHitIsoDr03();
193 >        tmplep.isoHcal = ele->HcalTowerSumEtDr03();
194 >        tmplep.isoPF04 = elesel.isoPF04;
195 >        tmplep.chisoPF04 = elesel.chisoPF04;
196 >        tmplep.gaisoPF04 = elesel.gaisoPF04;
197 >        tmplep.neisoPF04 = elesel.neisoPF04;
198 >        // tmplep.isoPF03 = computePFEleIso(ele,vtx,pfCandidates,0.3);
199 >        // tmplep.isoPF04 = computePFEleIso(ele,vtx,pfCandidates,0.4);
200 >        tmplep.ip3dSig = ele->Ip3dPVSignificance();
201          tmplep.is4l    = false;
202 <        tmplep.isEB    = (fabs(mu->eta) < 1.479 ? 1 : 0 );
203 <        tmplep.isTight = musel.tight();
204 <        tmplep.isLoose = musel.loose();
202 >        tmplep.isEB    = ele->IsEB();
203 >        tmplep.scID    = ele->SCluster()->GetUniqueID();
204 >
205 >        bitset<TRIGGER_BIG_NUMBER> hltMatchBits = fillHLTMatchBits( ele->Eta(), ele->Phi(), hltTable, hltObjArr, fTrigObjs);
206 >        tmplep.isTight = testBits(ctrl,triggerBits,eleTriggers,hltMatchBits,eleTrigObjs);
207 >
208 >        tmplep.isTight = elesel.tight();
209 >        tmplep.isLoose = elesel.loose();
210 >        tmplep.status  = elesel;
211 >        tmplep.idMVA   = elesel.idMVA;
212 >        tmplep.isoMVA  = elesel.isoMVA;
213 >        tmplep.fsrRecoveryAttempted = false;
214 >        SelectionStatus tmpstat = electronTagSelection(ele,vtx,pfCandidates);
215 >        tmplep.tightCutsApplied   = tmpstat.tight();
216          lepvec.push_back(tmplep);
217 <        if( ctrl.debug ) { cout << "muon passes ... " << endl;}
217 >        if( ctrl.debug ) cout << endl;
218        }
142      //  }
143    }    
144  
145  
146    
147    //
148    if( ctrl.debug ) { cout << "\tnElectron: " << electronArr->GetEntries() << endl; }
149    // --------------------------------------------------------------------------------
150    for(Int_t i=0; i<electronArr->GetEntries(); i++)
151      {
152        const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i]);
153        
154        Bool_t isMuonOverlap = kFALSE;
155        for (int k=0; k<lepvec.size(); ++k) {
156          TVector3 tmplep;
157          tmplep.SetPtEtaPhi(ele->pt, ele->eta, ele->phi);
158          if ( abs(lepvec[k].type == 13) && lepvec[k].vec->Vect().DrEtaPhi(tmplep) < 0.15 ) {
159            if( ctrl.debug ) cout << "-----> isMuonOverlap! " << endl;
160            isMuonOverlap = kTRUE;
161            break;
162          }
163        }
164        
165        SelectionStatus elesel;
166        elesel |= (*ElectronPreSelector)(ctrl,ele);
167        elesel |= (*ElectronIDSelector)(ctrl,ele);
168        elesel |= (*ElectronIsoSelector)(ctrl,ele);
169        if( elesel.getStatus() & SelectionStatus::PRESELECTION )
170          elesel.setStatus(SelectionStatus::LOOSESELECTION);
171
172        if( ctrl.debug ){
173          cout << "\tscEt: " << ele->scEt
174               << "\tscEta: " << ele->scEta
175               << "\tncluster: " << ele->ncluster
176               << "\tisorel: " <<  ele->pfIso04/ele->pt
177               << "\tstatus: " << hex << elesel.getStatus() << dec
178               << endl;
179        }
219  
220 <        if ( elesel.pass() && !isMuonOverlap )
221 <          {
183 <            SimpleLepton tmplep;
184 <            
185 <            float pt = ele->pt;
186 <            tmplep.vecorig->SetPtEtaPhiM( pt,
187 <                                          ele->eta,
188 <                                          ele->phi,
189 <                                          ELECTRON_MASS );
190 <            
191 <            if( ctrl.do_escale ) {
192 <              pt=scale_smear_electron(pt, ele->isEB, r);
193 <            }
194 <            if( ctrl.do_escale_up ) {
195 <              pt=scale_smear_electron_Up(pt, ele->isEB,  r);
196 <            }
197 <            if( ctrl.do_escale_down ) {
198 <              pt=scale_smear_electron_Down(pt, ele->isEB,  r);
199 <            }
200 <
201 <            
202 <            tmplep.vec->SetPtEtaPhiM( pt,
203 <                                      ele->eta,
204 <                                      ele->phi,
205 <                                      ELECTRON_MASS );
206 <            
207 <            tmplep.type    = 11;
208 <            tmplep.index   = i;
209 <            tmplep.charge  = ele->q;
210 <            tmplep.isoTrk  = ele->trkIso03;
211 <            tmplep.isoEcal = ele->emIso03;
212 <            tmplep.isoHcal = ele->hadIso03;
213 <            tmplep.isoPF03 = ele->pfIso03;
214 <            tmplep.isoPF04 = ele->pfIso04;
215 <            tmplep.ip3dSig = ele->ip3dSig;
216 <            tmplep.is4l    = false;
217 <            tmplep.isEB    = ele->isEB;
218 <            tmplep.scID    = ele->scID;
219 <            tmplep.isTight = elesel.tight();
220 <            tmplep.isLoose = elesel.pass();
221 <            lepvec.push_back(tmplep);
222 <            if( ctrl.debug ) { cout << "\telectron passes ... " << endl; }
223 <          }
224 <      }
225 <    
226 <    
220 >    sort( lepvec.begin(), lepvec.end(), SimpleLepton::lep_pt_sort );
221 >
222      //********************************************************
223 <    // Dump Stuff
223 >    // Step 2: Lepton Cleaning
224      //********************************************************
225 <    sort( lepvec.begin(), lepvec.end(), SimpleLepton::lep_pt_sort );
226 <    int nmu=0, nele=0;
227 <    for( int i=0; i<lepvec.size(); i++ ) {
228 <      if(ctrl.debug) cout << "lepvec :: index: " << i
229 <                          << "\tpt: " << lepvec[i].vec->Pt()
230 <                          << "\ttype: " << lepvec[i].type
231 <                          << endl;
232 <      if( abs(lepvec[i].type) == 11 ) nele++;
233 <      else nmu++;
225 >    vector<vector<SimpleLepton>::iterator> electrons_to_erase;
226 >    for (vector<SimpleLepton>::iterator it1=lepvec.begin(); it1 != lepvec.end(); it1++ ) {
227 >      if ( abs(it1->type) != 11 ) continue;
228 >      TVector3 evec = it1->vec.Vect();
229 >      
230 >      bool erase_this_electron=false;
231 >      for (vector<SimpleLepton>::iterator it2=lepvec.begin(); it2 != lepvec.end(); it2++ ) {
232 >        if ( it2 == it1 )                       continue;
233 >        if ( abs(it2->type) != 13 )             continue;
234 >        // if( !(it2->status.looseIDAndPre()) )    continue;
235 >        TVector3 mvec = it2->vec.Vect();
236 >        
237 >        if ( evec.DrEtaPhi(mvec) < 0.05 ) {
238 >          erase_this_electron=true;
239 >          break;
240 >        }
241 >      }
242 >      if( erase_this_electron )
243 >        electrons_to_erase.push_back(it1);
244      }
245 <    if( ctrl.debug ) {
246 <      cout << "postsel nlep: " << lepvec.size()
242 <           << "\tnmuon: " << nmu
243 <           << "\tnelectron: " << nele
244 <           << endl;
245 >    for( int i=0; i<electrons_to_erase.size(); i++ ) {
246 >      lepvec.erase(electrons_to_erase[i]);
247      }
246    
247    
248    //******************************************************************************
249    // Selection
250    //******************************************************************************
251    float bestMass=-1; int best_mu_index=-1, best_ele_index=-1;
252    for(int i = 0; i<lepvec.size(); i++) {      // get a tight muon
253      if( abs(lepvec[i].type) != 13 ) continue;
254      if( !(lepvec[i].isTight) ) continue;
255      //      if( lepvec[i].vec->Pt() < 35 ) continue;
256      if( ctrl.debug ) cout << "got a muon, index: " << i << endl;
257
258      for(int j = 0; j<lepvec.size(); j++) {     // get a loose electron
259        if( j == i ) continue;
260        if( abs(lepvec[j].type) != 11 ) continue;
261        if( !(lepvec[j].isLoose) ) continue;
262        if (lepvec[i].charge == lepvec[j].charge) continue;          
263        //      if (lepvec[i].charge != lepvec[j].charge) continue;          
264        if( ctrl.debug ) cout << "got a electron, index: " << j << endl;
265
266        float tmpMass = ( *(lepvec[i].vec) + *(lepvec[j].vec) ).M();
267        if( ctrl.debug ) cout << "tmp vs best :: " << tmpMass << "," << bestMass << endl;
268        if( tmpMass > bestMass ) {
269          bestMass = tmpMass;
270          best_mu_index=i;
271          best_ele_index=j;
272        }
248  
249 +    //********************************************************
250 +    // Step 3: Good Leptons
251 +    //********************************************************
252 +    vector<double> pt_of_leptons_to_erase;
253 +    for (int i=0; i<lepvec.size(); i++ ) {
254 +      bool already_pushed=false;
255 +      if( !(lepvec[i].status.loose()) ) {
256 +        pt_of_leptons_to_erase.push_back(lepvec[i].vec.Pt());
257 +        already_pushed = true;
258 +        failingLeptons.push_back(lepvec[i]); // these should pass preselection
259 +      } else {
260 +        passingLeptons.push_back(lepvec[i]);
261        }
262 + #ifndef SYNC
263 +      if( !already_pushed && fabs(lepvec[i].ip3dSig)>4 )  
264 +        pt_of_leptons_to_erase.push_back(lepvec[i].vec.Pt());
265 + #endif      
266      }
267 <
268 <    if( bestMass > 0 ) {
269 <      if( ctrl.debug ) cout << "EMU candidate, mass : " << bestMass << endl;
270 <      if( lepvec[best_ele_index].isTight )
271 <        ret.status.setStatus(SelectionStatus::TIGHTSELECTION);
272 <      else
273 <        ret.status.setStatus(SelectionStatus::LOOSESELECTION);
283 <      ret.Z1leptons.push_back(lepvec[best_mu_index]);
284 <      ret.Z1leptons.push_back(lepvec[best_ele_index]);
285 <      ret.Z2leptons.push_back(lepvec[best_mu_index]);
286 <      ret.Z2leptons.push_back(lepvec[best_ele_index]);
287 <      return ret;
267 >    for( int i=0; i<pt_of_leptons_to_erase.size(); i++ ) {
268 >      for( vector<SimpleLepton>::iterator it=lepvec.begin(); it != lepvec.end(); it++ ) {
269 >        SimpleLepton flep = *it;
270 >        if( flep.vec.Pt() != pt_of_leptons_to_erase[i] ) continue;
271 >        lepvec.erase(it);
272 >        break;
273 >      }
274      }
275  
276 <    ret.status.setStatus(0);
276 >    //******************************************************************************
277 >    // W + (OF SS lepton) Selection
278 >    //******************************************************************************
279 >    if(has_ssof_lepton(ctrl)) {
280 >      ret.status.setStatus(SelectionStatus::EVTPASS);
281 >      ret.Z1leptons.push_back(passingLeptons[0]);
282 >      ret.Z1leptons.push_back(passingLeptons[0]);
283 >      ret.Z2leptons.push_back(passingLeptons[0]);
284 >      ret.Z2leptons.push_back(passingLeptons[0]);
285 >    } else {
286 >      ret.status.setStatus(SelectionStatus::FAIL);
287 >    }
288      return ret;
292
289   }
290 + //----------------------------------------------------------------------------------------
291 + bool has_ssof_lepton(ControlFlags &ctrl)
292 + {
293 +  bool has_ssof=false;
294 +  for(unsigned iw=0; iw<passingLeptons.size(); iw++) {
295 +    SimpleLepton w_lep = passingLeptons[iw];
296 +    //????????????????????????????????????????????????????????????????????????????????????????
297 +    // this is applied in skim (skim also applies ww muon id)
298 +    // if(abs(w_lep.type) == 11) {
299 +    //   if( !(w_lep.tightCutsApplied) )
300 +    //  continue;
301 +    // }
302 +    //????????????????????????????????????????????????????????????????????????????????????????
303 +    for(unsigned ifake=0; ifake<failingLeptons.size(); ifake++) {
304 +      SimpleLepton fake_lep = failingLeptons[ifake];
305 +      if(abs(fake_lep.type) == abs(w_lep.type)) continue;
306 +      if(fake_lep.charge != w_lep.charge) continue;
307 +      has_ssof = true;
308 +    }
309 +    for(unsigned ipass=0; ipass<passingLeptons.size(); ipass++) {
310 +      if(ipass == iw) continue;
311 +      SimpleLepton pass_lep = passingLeptons[ipass];
312 +      if(abs(pass_lep.type) == abs(w_lep.type)) continue;
313 +      if(pass_lep.charge != w_lep.charge) continue;
314 +      has_ssof = true;
315 +    }
316 +  }
317  
318 <
318 >  return has_ssof;
319 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines