ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitPhysics/FakeMods/src/GenFakeableObjsMod.cc
Revision: 1.1
Committed: Tue Jun 30 10:47:17 2009 UTC (15 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Log Message:
Added FakeMods.

File Contents

# User Rev Content
1 loizides 1.1 // $Id: $
2    
3     #include "MitPhysics/FakeMods/interface/GenFakeableObjsMod.h"
4     #include "MitAna/DataUtil/interface/Debug.h"
5     #include "MitCommon/MathTools/interface/MathUtils.h"
6     #include "MitPhysics/Init/interface/ModNames.h"
7     #include "MitPhysics/Utils/interface/IsolationTools.h"
8    
9     using namespace mithep;
10    
11     ClassImp(mithep::GenFakeableObjsMod)
12    
13     //--------------------------------------------------------------------------------------------------
14     GenFakeableObjsMod::GenFakeableObjsMod(const char *name, const char *title) :
15     BaseMod(name,title),
16     fVetoTriggerJet(false),
17     fVetoGenLeptons(true),
18     fVetoCleanLeptons(false),
19     fElectronFOType("GsfPlusSC"),
20     fMuonFOType("IsoTrack"),
21     fTriggerName("NotSpecified"),
22     fTriggerObjectsName("NotSpecified"),
23     fElectronBranchName(Names::gkElectronBrn),
24     fMuonBranchName(Names::gkMuonBrn),
25     fTrackBranchName(Names::gkTrackBrn),
26     fGsfTrackBranchName(Names::gkGsfTrackBrn),
27     fBarrelSuperClusterBranchName(Names::gkBarrelSuperClusterBrn),
28     fEndcapSuperClusterBranchName(Names::gkEndcapSuperClusterBrn),
29     fVertexBranchName(Names::gkPVBeamSpotBrn),
30     fConversionBranchName(Names::gkMvfConversionBrn),
31     fGoodJetsName(ModNames::gkGoodJetsName),
32     fCleanElectronsName(ModNames::gkCleanElectronsName),
33     fCleanMuonsName(ModNames::gkCleanMuonsName),
34     fMCLeptonsName(ModNames::gkMCLeptonsName),
35     fMCTausName(ModNames::gkMCTausName),
36     fElectronFakeableObjectsName(ModNames::gkElFakeableObjsName),
37     fMuonFakeableObjectsName(ModNames::gkMuFakeableObjsName),
38     fElFOType(kElFOUndef),
39     fMuFOType(kMuFOUndef),
40     fBarrelSuperClusters(0),
41     fEndcapSuperClusters(0),
42     fTracks(0),
43     fGsfTracks(0),
44     fVertices(0),
45     fConversions(0)
46     {
47     // Constructor.
48     }
49    
50     //--------------------------------------------------------------------------------------------------
51     void GenFakeableObjsMod::SlaveBegin()
52     {
53     // Run startup code on the computer (slave) doing the actual analysis. Here,
54     // we typically initialize histograms and other analysis objects and request
55     // branches. For this module, we request a branch of the MitTree.
56    
57     //------------------------------------------------------------------------------------------------
58     // Request the branches (no significant time safed by not doing this)
59     //------------------------------------------------------------------------------------------------
60     ReqBranch(fElectronBranchName, fElectrons);
61     ReqBranch(fMuonBranchName, fMuons);
62     ReqBranch(fTrackBranchName, fTracks);
63     ReqBranch(fGsfTrackBranchName, fGsfTracks);
64     ReqBranch(fBarrelSuperClusterBranchName, fBarrelSuperClusters);
65     ReqBranch(fEndcapSuperClusterBranchName, fEndcapSuperClusters);
66     ReqBranch(fConversionBranchName, fConversions);
67     ReqBranch(fVertexBranchName, fVertices);
68    
69     if (fElectronFOType.CompareTo("GsfPlusSC") == 0)
70     fElFOType = kElFOGsfPlusSC;
71     else if (fElectronFOType.CompareTo("Reco") == 0)
72     fElFOType = kElFOReco;
73     else if (fElectronFOType.CompareTo("Loose") == 0)
74     fElFOType = kElFOLoose;
75     else {
76     SendError(kAbortAnalysis, "SlaveBegin",
77     "The specified electron fakeable object %s is not defined.",
78     fElectronFOType.Data());
79     return;
80     }
81    
82     if (fMuonFOType.CompareTo("IsoTrack") == 0)
83     fMuFOType = kMuFOIsoTrack;
84     else if (fMuonFOType.CompareTo("Global") == 0)
85     fMuFOType = kMuFOGlobal;
86     else if (fMuonFOType.CompareTo("TrackerMuon") == 0)
87     fMuFOType = kMuFOTrackerMuon;
88     else {
89     SendError(kAbortAnalysis, "SlaveBegin",
90     "The specified muon fakeable object %s is not defined.",
91     fMuonFOType.Data());
92     return;
93     }
94    
95     }
96    
97     //--------------------------------------------------------------------------------------------------
98     void GenFakeableObjsMod::Process()
99     {
100     // Process entries of the tree.
101     LoadBranch(fElectronBranchName);
102     LoadBranch(fMuonBranchName);
103     LoadBranch(fTrackBranchName);
104     LoadBranch(fGsfTrackBranchName);
105     LoadBranch(fBarrelSuperClusterBranchName);
106     LoadBranch(fEndcapSuperClusterBranchName);
107     LoadBranch(fVertexBranchName);
108     LoadBranch(fConversionBranchName);
109    
110     //Load Trigger Objects
111     const TriggerObjectCol *triggerObjects = GetHLTObjects(fTriggerObjectsName);
112     if (!triggerObjects && fVetoTriggerJet) {
113     cout << "Error: Could not load Trigger Object Collection with name "
114     << fTriggerObjectsName << endl;
115     }
116    
117     // get input clean object collections
118     mithep::ParticleOArr *CleanLeptons = dynamic_cast<mithep::ParticleOArr*>
119     (FindObjThisEvt(ModNames::gkMergedLeptonsName));
120     const ElectronCol *CleanElectrons = 0;
121     if (!fCleanElectronsName.IsNull())
122     CleanElectrons = GetObjThisEvt<ElectronCol>(fCleanElectronsName);
123     const MuonCol *CleanMuons = 0;
124     if (!fCleanMuonsName.IsNull())
125     CleanMuons = GetObjThisEvt<MuonCol>(fCleanMuonsName);
126     const JetCol *GoodJets = 0;
127     if (!fGoodJetsName.IsNull())
128     GoodJets = GetObjThisEvt<JetCol>(fGoodJetsName);
129    
130     //get input MC collections
131     const MCParticleCol *GenLeptons = 0;
132     if (!fMCLeptonsName.IsNull())
133     GenLeptons = GetObjThisEvt<MCParticleCol>(fMCLeptonsName);
134     const MCParticleCol *GenTaus = 0;
135     if (!fMCTausName.IsNull())
136     GenTaus = GetObjThisEvt<MCParticleCol>(fMCTausName);
137     ObjArray<MCParticle> *GenLeptonsAndTaus = new ObjArray<MCParticle>;
138     for (UInt_t i=0; i<GenLeptons->GetEntries(); i++)
139     GenLeptonsAndTaus->Add(GenLeptons->At(i));
140     for (UInt_t i=0; i<GenTaus->GetEntries(); i++)
141     GenLeptonsAndTaus->Add(GenTaus->At(i));
142    
143     //Combine Barrel and Endcap superclusters into the same ObjArray
144     ObjArray <SuperCluster> *SuperClusters = new ObjArray <SuperCluster>;
145     for (UInt_t i=0; i<fBarrelSuperClusters->GetEntries(); i++) {
146     SuperClusters->Add(fBarrelSuperClusters->At(i));
147     }
148     for (UInt_t i=0; i<fEndcapSuperClusters->GetEntries(); i++) {
149     SuperClusters->Add(fEndcapSuperClusters->At(i));
150     }
151    
152     //collections for duplicate removed electrons
153     ObjArray<Electron> *DuplicateRemovedElectrons = new ObjArray<Electron>;
154     std::vector<const Electron*> tmpDuplicateRemovedElectrons;
155    
156     // create final output collection
157     ElectronArr *ElectronFakeableObjects = new ElectronArr;
158     MuonArr *MuonFakeableObjects = new MuonArr;
159    
160    
161     //***********************************************************************************************
162     //First do duplicate electron removal
163     //***********************************************************************************************
164     for (UInt_t i=0; i<fElectrons->GetEntries(); ++i) {
165     const Electron *e = fElectrons->At(i);
166     Bool_t isElectronOverlap = kFALSE;
167    
168     for (UInt_t j=0; j<tmpDuplicateRemovedElectrons.size(); ++j) {
169     Double_t deltaR = MathUtils::DeltaR(tmpDuplicateRemovedElectrons[j]->Mom(), e->Mom());
170     if (e->SCluster() == tmpDuplicateRemovedElectrons[j]->SCluster() ||
171     e->GsfTrk() == tmpDuplicateRemovedElectrons[j]->GsfTrk() ||
172     deltaR < 0.1) {
173     isElectronOverlap = kTRUE;
174     }
175    
176    
177     if (isElectronOverlap) {
178     if (TMath::Abs(tmpDuplicateRemovedElectrons[j]->ESuperClusterOverP() - 1) >
179     TMath::Abs(e->ESuperClusterOverP() - 1)) {
180     tmpDuplicateRemovedElectrons[j] = e;
181     }
182     break;
183     }
184     }
185    
186     if (!isElectronOverlap) {
187     tmpDuplicateRemovedElectrons.push_back(e);
188     }
189     }
190     for (UInt_t i=0; i<tmpDuplicateRemovedElectrons.size(); ++i) {
191     DuplicateRemovedElectrons->Add(tmpDuplicateRemovedElectrons[i]);
192     }
193    
194     //***********************************************************************************************
195     //Fakeable Objects for Electron Fakes
196     //Supercluster matched to nearest isolated track.
197     //***********************************************************************************************
198     if (fElFOType == kElFOGsfPlusSC) {
199    
200     std::vector<const Electron*> GsfTrackSCDenominators;
201    
202     //loop over all super clusters
203     for (UInt_t i=0; i<SuperClusters->GetEntries(); i++) {
204     const SuperCluster *cluster = SuperClusters->At(i);
205    
206     //find best matching track based on DR to the cluster
207     const Track *EOverPMatchedTrk = NULL;
208     double BestEOverP = 5000.0;
209     for (UInt_t j=0; j<fGsfTracks->GetEntries(); j++) {
210     const Track *trk = fGsfTracks->At(j);
211    
212     //Use best E/P matching within dR of 0.3
213     double dR = MathUtils::DeltaR(cluster->Phi(), cluster->Eta(), trk->Phi(), trk->Eta());
214     Double_t EOverP = cluster->Energy() / trk->P();
215     if( fabs(1-EOverP) < fabs(1-BestEOverP) && dR < 0.3 ) {
216     BestEOverP = EOverP;
217     EOverPMatchedTrk = trk;
218     }
219     }
220    
221     //****************************************************************************************
222     //Use Best E/P Matching and require the track is within 0.3 of the super cluster position
223     //****************************************************************************************
224     if( EOverPMatchedTrk ) {
225    
226     //calculate track isolation around the matched track
227     Double_t matchiso=0;
228     matchiso = IsolationTools::TrackIsolation(EOverPMatchedTrk, 0.3, 0.015, 1.0, 0.2,
229     fTracks);
230    
231     //Veto denominators matching to real electrons
232     Bool_t IsGenLepton = false;
233     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
234     if (MathUtils::DeltaR(EOverPMatchedTrk->Phi(), EOverPMatchedTrk->Eta(),
235     GenLeptonsAndTaus->At(l)->Phi(),
236     GenLeptonsAndTaus->At(l)->Eta()) < 0.1) {
237     IsGenLepton = true;
238     }
239     }
240    
241     //Veto denominators matching to clean leptons
242     Bool_t IsCleanLepton = false;
243     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
244     if (MathUtils::DeltaR(EOverPMatchedTrk->Phi(), EOverPMatchedTrk->Eta(),
245     CleanLeptons->At(l)->Phi(),
246     CleanLeptons->At(l)->Eta()) < 0.1) {
247     IsCleanLepton = true;
248     }
249     }
250    
251     //Veto on Leading jet
252     Bool_t IsTriggerJet = false;
253     if (fVetoTriggerJet) {
254     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
255     Double_t deltaR = MathUtils::DeltaR(EOverPMatchedTrk->Phi(), EOverPMatchedTrk->Eta(),
256     triggerObjects->At(l)->Phi(), triggerObjects->At(l)->Eta());
257     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
258     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
259     && deltaR < 0.3
260     ) {
261     IsTriggerJet = true;
262     break;
263     }
264     }
265     }
266    
267     //create new electron object for the denominator under consideration
268     Bool_t denominatorSaved = false;
269     Electron *denominator = new Electron();
270     Double_t p = TMath::Sqrt(cluster->Energy()*cluster->Energy()
271     - denominator->Mass()*denominator->Mass());
272     denominator->SetPtEtaPhi(TMath::Abs(p*TMath::Cos(EOverPMatchedTrk->Lambda())),
273     EOverPMatchedTrk->Eta(),EOverPMatchedTrk->Phi());
274     denominator->SetGsfTrk(EOverPMatchedTrk);
275     denominator->SetSuperCluster(cluster);
276    
277     //****************************************************************************************
278     // conversion filter
279     //****************************************************************************************
280     Bool_t isGoodConversion = kFALSE;
281     for (UInt_t ifc=0; ifc<fConversions->GetEntries(); ifc++) {
282     Bool_t ConversionMatchFound = kFALSE;
283     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
284     const Track *trk = dynamic_cast<const ChargedParticle*>
285     (fConversions->At(ifc)->Daughter(d))->Trk();
286     if (EOverPMatchedTrk == trk) {
287     ConversionMatchFound = kTRUE;
288     break;
289     }
290     }
291    
292     // if match between the gsftrack and one of the conversion legs
293     if (ConversionMatchFound == kTRUE){
294     isGoodConversion = (fConversions->At(ifc)->Prob() > 0.0005) &&
295     (fConversions->At(ifc)->Lxy() > 0) &&
296     (fConversions->At(ifc)->Lz() > 0);
297    
298     if (isGoodConversion == kTRUE) {
299     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
300     const Track *trk = dynamic_cast<const ChargedParticle*>
301     (fConversions->At(ifc)->Daughter(d))->Trk();
302    
303     if (trk) {
304     // These requirements are not used for the GSF track (d == 1)
305     if (!(trk->NHits() > 8 && trk->Prob() > 0.005) && d == 0)
306     isGoodConversion = kFALSE;
307    
308     const StableData *sd = dynamic_cast<const StableData*>
309     (fConversions->At(ifc)->DaughterDat(d));
310     if (sd->NWrongHits() != 0)
311     isGoodConversion = kFALSE;
312    
313     } else {
314     isGoodConversion = kFALSE;
315     }
316     }
317     }
318     }
319     if (isGoodConversion == kTRUE) break;
320     } // loop over all conversions
321    
322     //****************************************************************************************
323     // D0 Cut
324     //****************************************************************************************
325     double d0Min = 99999;
326     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
327     double pD0 = EOverPMatchedTrk->D0Corrected(*fVertices->At(i0));
328     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
329     }
330    
331     //****************************************************************************************
332     // Make denominator object cuts
333     //****************************************************************************************
334     if( matchiso <= 10.0 && denominator->Pt() > 10.0
335     && !isGoodConversion
336     && d0Min < 0.025
337     && !(fVetoCleanLeptons && IsCleanLepton)
338     && !(fVetoGenLeptons && IsGenLepton)
339     && !(fVetoTriggerJet && IsTriggerJet)
340     ) {
341    
342     //check whether we have duplicate denominators. If yes then choose best E/P one.
343     Bool_t foundDuplicate = false;
344     for (UInt_t d=0; d<GsfTrackSCDenominators.size();++d) {
345     if (GsfTrackSCDenominators[d]->GsfTrk() == denominator->GsfTrk()) {
346     if (fabs(denominator->SCluster()->Energy()/denominator->GsfTrk()->P() - 1)
347     < fabs(GsfTrackSCDenominators[d]->SCluster()->Energy()/
348     GsfTrackSCDenominators[d]->GsfTrk()->P() - 1)) {
349     //swap this one with previous one and delete the previous one
350     const Electron *denominatorToBeDeleted = GsfTrackSCDenominators[d];
351     GsfTrackSCDenominators[d] = denominator;
352     denominatorSaved = true;
353     foundDuplicate = true;
354     delete denominatorToBeDeleted;
355     break;
356     }
357     }
358     }
359     if (!foundDuplicate) {
360     GsfTrackSCDenominators.push_back(denominator);
361     denominatorSaved = true;
362     }
363     } //end if candidate passes denominator cuts
364     //delete denominator candidate object
365     if (!denominatorSaved) {
366     delete denominator;
367     }
368     }//end if track -> SC match was found
369     } //loop over SC
370    
371     //Save denominators permanently for export
372     for (UInt_t d=0; d<GsfTrackSCDenominators.size() ; ++d) {
373     Electron *tmpElectron = ElectronFakeableObjects->AddNew();
374     tmpElectron->SetPtEtaPhi(GsfTrackSCDenominators[d]->Pt(),
375     GsfTrackSCDenominators[d]->Eta(),GsfTrackSCDenominators[d]->Phi());
376     tmpElectron->SetGsfTrk(GsfTrackSCDenominators[d]->GsfTrk());
377     tmpElectron->SetSuperCluster(GsfTrackSCDenominators[d]->SCluster());
378     delete GsfTrackSCDenominators[d];
379     }
380     } else if (fElFOType == kElFOReco) {
381     for (UInt_t i=0; i<DuplicateRemovedElectrons->GetEntries(); i++) {
382     const Electron *denominator = DuplicateRemovedElectrons->At(i);
383     Double_t denominatorIso =
384     denominator->TrackIsolation() + denominator->EcalJurassicIsolation() - 1.5;
385    
386     //Veto denominators matching to real electrons
387     Bool_t IsGenLepton = false;
388     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
389     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
390     GenLeptonsAndTaus->At(l)->Phi(),
391     GenLeptonsAndTaus->At(l)->Eta()) < 0.1) {
392     IsGenLepton = true;
393     }
394     }
395    
396     //Veto denominators matching to clean leptons
397     Bool_t IsCleanLepton = false;
398     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
399     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
400     CleanLeptons->At(l)->Phi(),
401     CleanLeptons->At(l)->Eta()) < 0.1) {
402     IsCleanLepton = true;
403     }
404     }
405    
406     //Veto on Trigger jet
407     Bool_t IsTriggerJet = false;
408     if (fVetoTriggerJet) {
409     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
410     Double_t deltaR = MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
411     triggerObjects->At(l)->Phi(), triggerObjects->At(l)->Eta());
412     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
413     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
414     && deltaR < 0.3
415     ) {
416     IsTriggerJet = true;
417     break;
418     }
419     }
420     }
421    
422     //*************************************************************
423     // conversion filter
424     //*************************************************************
425     Bool_t isGoodConversion = kFALSE;
426     for (UInt_t ifc=0; ifc<fConversions->GetEntries(); ifc++) {
427     Bool_t ConversionMatchFound = kFALSE;
428     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
429     const Track *trk = dynamic_cast<const ChargedParticle*>
430     (fConversions->At(ifc)->Daughter(d))->Trk();
431     if (denominator->GsfTrk() == trk) {
432     ConversionMatchFound = kTRUE;
433     break;
434     }
435     }
436    
437     // if match between the gsftrack and one of the conversion legs
438     if (ConversionMatchFound == kTRUE){
439     isGoodConversion = (fConversions->At(ifc)->Prob() > 0.0005) &&
440     (fConversions->At(ifc)->Lxy() > 0) &&
441     (fConversions->At(ifc)->Lz() > 0);
442    
443     if (isGoodConversion == kTRUE) {
444     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
445     const Track *trk = dynamic_cast<const ChargedParticle*>
446     (fConversions->At(ifc)->Daughter(d))->Trk();
447    
448     if (trk) {
449     // These requirements are not used for the GSF track (d == 1)
450     if (!(trk->NHits() > 8 && trk->Prob() > 0.005) && d == 0)
451     isGoodConversion = kFALSE;
452    
453     const StableData *sd = dynamic_cast<const StableData*>
454     (fConversions->At(ifc)->DaughterDat(d));
455     if (sd->NWrongHits() != 0)
456     isGoodConversion = kFALSE;
457    
458     } else {
459     isGoodConversion = kFALSE;
460     }
461     }
462     }
463     }
464     if (isGoodConversion == kTRUE) break;
465     } // loop over all conversions
466    
467     //****************************************************************************************
468     // D0 Cut
469     //****************************************************************************************
470     double d0Min = 99999;
471     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
472     double pD0 = denominator->GsfTrk()->D0Corrected(*fVertices->At(i0));
473     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
474     }
475    
476     //****************************************************************************************
477     // Apply Denominator Cuts
478     //****************************************************************************************
479     if (denominator->Pt() > 10.0 &&
480     denominatorIso < 10.0
481     && !isGoodConversion
482     && d0Min < 0.025
483     && !(fVetoGenLeptons && IsGenLepton)
484     && !(fVetoCleanLeptons && IsCleanLepton)
485     && !(fVetoTriggerJet && IsTriggerJet)
486     ) {
487     Electron *tmpElectron = ElectronFakeableObjects->AddNew();
488     tmpElectron->SetPtEtaPhi(denominator->Pt(), denominator->Eta(),denominator->Phi());
489     tmpElectron->SetGsfTrk(denominator->GsfTrk());
490     tmpElectron->SetSuperCluster(denominator->SCluster());
491     }
492     }
493     } else if (fElFOType == kElFOLoose) {
494     for (UInt_t i=0; i<DuplicateRemovedElectrons->GetEntries(); i++) {
495     const Electron *denominator = DuplicateRemovedElectrons->At(i);
496     Double_t denominatorIso = denominator->TrackIsolation() + denominator->EcalJurassicIsolation() - 1.5;
497    
498     //Veto denominators matching to real electrons
499     Bool_t IsGenLepton = false;
500     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
501     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
502     GenLeptonsAndTaus->At(l)->Phi(),
503     GenLeptonsAndTaus->At(l)->Eta()) < 0.1) {
504     IsGenLepton = true;
505     }
506     }
507    
508     //Veto denominators matching to clean leptons
509     Bool_t IsCleanLepton = false;
510     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
511     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
512     CleanLeptons->At(l)->Phi(),
513     CleanLeptons->At(l)->Eta()) < 0.1) {
514     IsCleanLepton = true;
515     }
516     }
517    
518     //Veto on Trigger jet
519     Bool_t IsTriggerJet = false;
520     if (fVetoTriggerJet) {
521     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
522     Double_t deltaR = MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
523     triggerObjects->At(l)->Phi(), triggerObjects->At(l)->Eta());
524     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
525     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
526     && deltaR < 0.3
527     ) {
528     IsTriggerJet = true;
529     break;
530     }
531     }
532     }
533    
534     //****************************************************************************************
535     // conversion filter
536     //****************************************************************************************
537     Bool_t isGoodConversion = kFALSE;
538     for (UInt_t ifc=0; ifc<fConversions->GetEntries(); ifc++) {
539     Bool_t ConversionMatchFound = kFALSE;
540     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
541     const Track *trk = dynamic_cast<const ChargedParticle*>
542     (fConversions->At(ifc)->Daughter(d))->Trk();
543     if (denominator->GsfTrk() == trk) {
544     ConversionMatchFound = kTRUE;
545     break;
546     }
547     }
548    
549     // if match between the gsftrack and one of the conversion legs
550     if (ConversionMatchFound == kTRUE){
551     isGoodConversion = (fConversions->At(ifc)->Prob() > 0.0005) &&
552     (fConversions->At(ifc)->Lxy() > 0) &&
553     (fConversions->At(ifc)->Lz() > 0);
554    
555     if (isGoodConversion == kTRUE) {
556     for (UInt_t d=0; d<fConversions->At(ifc)->NDaughters(); d++) {
557     const Track *trk = dynamic_cast<const ChargedParticle*>
558     (fConversions->At(ifc)->Daughter(d))->Trk();
559    
560     if (trk) {
561     // These requirements are not used for the GSF track (d == 1)
562     if (!(trk->NHits() > 8 && trk->Prob() > 0.005) && d == 0)
563     isGoodConversion = kFALSE;
564    
565     const StableData *sd = dynamic_cast<const StableData*>
566     (fConversions->At(ifc)->DaughterDat(d));
567     if (sd->NWrongHits() != 0)
568     isGoodConversion = kFALSE;
569    
570     } else {
571     isGoodConversion = kFALSE;
572     }
573     }
574     }
575     }
576     if (isGoodConversion == kTRUE) break;
577     } // loop over all conversions
578    
579     //****************************************************************************************
580     // D0 Cut
581     //****************************************************************************************
582     double d0Min = 99999;
583     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
584     double pD0 = denominator->GsfTrk()->D0Corrected(*fVertices->At(i0));
585     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
586     }
587    
588     if (denominator->Pt() > 10.0 && denominatorIso < 10.0
589     && !isGoodConversion
590     && d0Min < 0.025
591     && denominator->PassLooseID()
592     && !(fVetoGenLeptons && IsGenLepton)
593     && !(fVetoCleanLeptons && IsCleanLepton)
594     && !(fVetoTriggerJet && IsTriggerJet)
595     ) {
596     Electron *tmpElectron = ElectronFakeableObjects->AddNew();
597     tmpElectron->SetPtEtaPhi(denominator->Pt(), denominator->Eta(),denominator->Phi());
598     tmpElectron->SetGsfTrk(denominator->GsfTrk());
599     tmpElectron->SetSuperCluster(denominator->SCluster());
600     }
601     }
602     }
603    
604     //***********************************************************************************************
605     //Fakeable Objects for Muon Fakes
606     //***********************************************************************************************
607     if (fMuFOType == kMuFOIsoTrack) {
608     for (UInt_t i=0; i<fTracks->GetEntries(); i++) {
609     const Track *track = fTracks->At(i);
610     Double_t trackIsolation = IsolationTools::TrackIsolation(track, 0.4, 0.015, 1.0,
611     0.2, fTracks);
612     //Determine if muon fakeable object matches a gen lepton
613     Bool_t IsGenLepton = false;
614     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
615     if (MathUtils::DeltaR(track->Phi(), track->Eta(),
616     GenLeptonsAndTaus->At(l)->Phi(),
617     GenLeptonsAndTaus->At(l)->Eta()) < 0.3) {
618     IsGenLepton = true;
619     }
620     }
621    
622     //Veto denominators matching to clean leptons
623     Bool_t IsCleanLepton = false;
624     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
625     if (MathUtils::DeltaR(track->Phi(), track->Eta(),
626     CleanLeptons->At(l)->Phi(),
627     CleanLeptons->At(l)->Eta()) < 0.1) {
628     IsCleanLepton = true;
629     }
630     }
631    
632     //Veto on Trigger jet
633     Bool_t IsTriggerJet = false;
634     if (fVetoTriggerJet) {
635     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
636     Double_t deltaR = MathUtils::DeltaR(track->Phi(), track->Eta(),
637     triggerObjects->At(l)->Phi(),
638     triggerObjects->At(l)->Eta());
639     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
640     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
641     && deltaR < 0.3
642     ) {
643     IsTriggerJet = true;
644     break;
645     }
646     }
647     }
648    
649     //****************************************************************************************
650     // D0 Cut
651     //****************************************************************************************
652     double d0Min = 99999;
653     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
654     double pD0 = track->D0Corrected(*fVertices->At(i0));
655     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
656     }
657    
658    
659     //define denominator cuts
660     if (track->Pt() > 10.0 && trackIsolation < 10.0
661     && d0Min < 0.025
662     && !(fVetoGenLeptons && IsGenLepton)
663     && !(fVetoCleanLeptons && IsCleanLepton)
664     && !(fVetoTriggerJet && IsTriggerJet)
665     ) {
666     //add to fakeable objects
667     Muon* tmpMuon = MuonFakeableObjects->AddNew();
668     tmpMuon->SetTrackerTrk(track);
669     }
670     }
671     } else if (fMuFOType == kMuFOGlobal) {
672     for (UInt_t i=0; i<fMuons->GetEntries(); i++) {
673     const Muon *denominator = fMuons->At(i);
674     Double_t totalIsolation = denominator->IsoR03SumPt() + denominator->IsoR03EmEt() +
675     denominator->IsoR03HadEt();
676    
677     //Determine if muon fakeable object matches a gen lepton
678     Bool_t IsGenLepton = false;
679     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
680     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
681     GenLeptonsAndTaus->At(l)->Phi(),
682     GenLeptonsAndTaus->At(l)->Eta()) < 0.3) {
683     IsGenLepton = true;
684     }
685     }
686    
687     //Veto denominators matching to clean leptons
688     Bool_t IsCleanLepton = false;
689     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
690     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
691     CleanLeptons->At(l)->Phi(),
692     CleanLeptons->At(l)->Eta()) < 0.1) {
693     IsCleanLepton = true;
694     }
695     }
696    
697     //Veto on Trigger jet
698     Bool_t IsTriggerJet = false;
699     if (fVetoTriggerJet) {
700     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
701     Double_t deltaR = MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
702     triggerObjects->At(l)->Phi(), triggerObjects->At(l)->Eta());
703     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
704     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
705     && deltaR < 0.3
706     ) {
707     IsTriggerJet = true;
708     break;
709     }
710     }
711     }
712    
713     //****************************************************************************************
714     // D0 Cut
715     //****************************************************************************************
716     double d0Min = 99999;
717     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
718     double pD0 = denominator->Trk()->D0Corrected(*fVertices->At(i0));
719     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
720     }
721    
722     if (denominator->Pt() > 10.0 && totalIsolation < 10.0 && denominator->HasGlobalTrk()
723     && d0Min < 0.025
724     && !(fVetoGenLeptons && IsGenLepton)
725     && !(fVetoCleanLeptons && IsCleanLepton)
726     && !(fVetoTriggerJet && IsTriggerJet)
727     ) {
728     Muon* tmpMuon = MuonFakeableObjects->AddNew();
729     tmpMuon->SetGlobalTrk(denominator->GlobalTrk());
730     tmpMuon->SetTrackerTrk(denominator->TrackerTrk());
731     }
732     }
733     } else if (fMuFOType == kMuFOTrackerMuon) {
734     for (UInt_t i=0; i<fMuons->GetEntries(); i++) {
735     const Muon *denominator = fMuons->At(i);
736     Double_t totalIsolation = denominator->IsoR03SumPt() + denominator->IsoR03EmEt() + denominator->IsoR03HadEt();
737    
738     //Determine if muon fakeable object matches a gen lepton
739     Bool_t IsGenLepton = false;
740     for (UInt_t l=0; l<GenLeptonsAndTaus->GetEntries(); l++) {
741     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
742     GenLeptonsAndTaus->At(l)->Phi(),
743     GenLeptonsAndTaus->At(l)->Eta()) < 0.3) {
744     IsGenLepton = true;
745     }
746     }
747    
748     //Veto denominators matching to clean leptons
749     Bool_t IsCleanLepton = false;
750     for (UInt_t l=0; l<CleanLeptons->GetEntries(); l++) {
751     if (MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
752     CleanLeptons->At(l)->Phi(),
753     CleanLeptons->At(l)->Eta()) < 0.1) {
754     IsCleanLepton = true;
755     }
756     }
757    
758     //Veto on Trigger jet
759     Bool_t IsTriggerJet = false;
760     if (fVetoTriggerJet) {
761     for (UInt_t l=0; l<triggerObjects->GetEntries(); l++) {
762     Double_t deltaR = MathUtils::DeltaR(denominator->Phi(), denominator->Eta(),
763     triggerObjects->At(l)->Phi(), triggerObjects->At(l)->Eta());
764     if (triggerObjects->At(l)->TrigName() == fTriggerName.Data()
765     && triggerObjects->At(l)->Type() == TriggerObject::TriggerJet
766     && deltaR < 0.3
767     ) {
768     IsTriggerJet = true;
769     break;
770     }
771     }
772     }
773    
774     //****************************************************************************************
775     // D0 Cut
776     //****************************************************************************************
777     double d0Min = 99999;
778     for(UInt_t i0 = 0; i0 < fVertices->GetEntries(); i0++) {
779     double pD0 = denominator->Trk()->D0Corrected(*fVertices->At(i0));
780     if(TMath::Abs(pD0) < TMath::Abs(d0Min)) d0Min = TMath::Abs(pD0);
781     }
782    
783     if (denominator->Pt() > 10.0 && totalIsolation < 10.0 && denominator->HasTrackerTrk()
784     && d0Min < 0.025
785     && !(fVetoGenLeptons && IsGenLepton)
786     && !(fVetoCleanLeptons && IsCleanLepton)
787     && !(fVetoTriggerJet && IsTriggerJet)
788     ) {
789     Muon* tmpMuon = MuonFakeableObjects->AddNew();
790     tmpMuon->SetTrackerTrk(denominator->TrackerTrk());
791     }
792     }
793     }
794    
795     //***********************************************************************************************
796     //Export the fakeable object collections for other modules to use
797     //***********************************************************************************************
798     ElectronFakeableObjects->SetName(fElectronFakeableObjectsName);
799     AddObjThisEvt(ElectronFakeableObjects);
800     MuonFakeableObjects->SetName(fMuonFakeableObjectsName);
801     AddObjThisEvt(MuonFakeableObjects);
802    
803     delete GenLeptonsAndTaus;
804     delete SuperClusters;
805     delete DuplicateRemovedElectrons;
806     }