ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Betchart/TopRefTuple/python/pf2pat.py
(Generate patch)

Comparing UserCode/Betchart/TopRefTuple/python/pf2pat.py (file contents):
Revision 1.1 by bbetchar, Fri Nov 2 21:40:49 2012 UTC vs.
Revision 1.12 by bbetchar, Fri Jan 11 16:23:24 2013 UTC

# Line 10 | Line 10 | class TopRefPF2PAT(object) :
10      '''Implement the Top Reference configuration of PF2PAT.
11  
12      https://twiki.cern.ch/twiki/bin/viewauth/CMS/TWikiTopRefEventSel
13 +    Modify the PF selections to match the PAT selections, for consistent TopProjection cross-cleaning.
14      '''
15  
16      def __init__(self, process, options) :
17          self.stdout = sys.stdout
18          sys.stdout = open(os.devnull, 'w')
19 <        print >>self.stdout, "usePF2PAT() output suppressed."
19 >        print >>self.stdout, "usePF2PAT() output suppressed. (%s)"%__file__
20  
21          self.before = set(dir(process))
22          process.load( "PhysicsTools.PatAlgos.patSequences_cff" )
# Line 28 | Line 29 | class TopRefPF2PAT(object) :
29                             jetAlgo = 'AK5',
30                             jetCorrections = ('AK5PFchs', ['L1FastJet','L2Relative','L3Absolute','L2L3Residual'][:None if options.isData else -1] )
31                             )
32 +
33 +        getattr( process, 'pfPileUp'+options.postfix).checkClosestZVertex = False # https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyCorrections#JetEnCorPFnoPU2012
34          getattr( process, 'pfPileUpIso'+options.postfix).checkClosestZVertex = True
35 +        getattr( process, 'patJetCorrFactors'+options.postfix).flavorType = 'T' # top events, not dijets, but only relevant for L5Flavor,L7Parton
36 +        #getattr( process, 'patJetCorrFactors'+options.postfix).levels.append('L5Flavor') # apparently not available in GlobalTags
37          if options.isData: coreTools.runOnData( process, names = [ 'PFAll' ], postfix = options.postfix )
38          coreTools.removeSpecificPATObjects( process, names = [ 'Photons', 'Taus' ], postfix = options.postfix )
39  
40 +        self.isoValues = {'el':0.15,'mu':0.20}
41 +        self.eleID = 'mvaTrigV0'
42 +        self.minEleID = 0.
43 +        self.isoEA = 'elPFIsoValueEA03'
44 +        self.dBFactorEl = -1.0 if options.doElectronEA else -0.5
45 +        self.dBFactorMu = -0.5
46 +        self.cuts = {'el': ['abs(eta)<2.5',
47 +                            'pt>20.',
48 +                            'gsfTrackRef.isNonnull',
49 +                            'gsfTrackRef.trackerExpectedHitsInner.numberOfLostHits<2',
50 +                            '(chargedHadronIso+max(0.,neutralHadronIso+photonIso%+.1f*%s))/pt < %.2f'%(self.dBFactorEl, 'userIsolation("User1Iso")' if options.doElectronEA else 'puChargedHadronIso',self.isoValues['el']),
51 +                            'electronID("%s") > %.2f'%(self.eleID,self.minEleID),
52 +                            ],
53 +                     'mu' :['abs(eta)<2.5',
54 +                            'pt>10.',
55 +                            '(chargedHadronIso+neutralHadronIso+photonIso%+.2f*puChargedHadronIso)/pt < %.2f'%(self.dBFactorMu, self.isoValues['mu']),
56 +                            '(isPFMuon && (isGlobalMuon || isTrackerMuon) )',
57 +                            ],
58 +                     'jet' : ['abs(eta)<2.5', # Careful! these jet cuts affect the typeI met corrections
59 +                              'pt > 15.',
60 +                              # PF jet ID:
61 +                              'numberOfDaughters > 1',
62 +                              'neutralHadronEnergyFraction < 0.99',
63 +                              'neutralEmEnergyFraction < 0.99',
64 +                              '(chargedEmEnergyFraction < 0.99   || abs(eta) >= 2.4)',
65 +                              '(chargedHadronEnergyFraction > 0. || abs(eta) >= 2.4)',
66 +                              '(chargedMultiplicity > 0          || abs(eta) >= 2.4)']
67 +                     }
68 +
69          self.process = process
70          self.options = options
71          self.fix = options.postfix
72          self.patSeq = getattr(process, 'patPF2PATSequence' + self.fix)
73 <        self.btags = ['combinedSecondaryVertex','jetProbability']
73 >        self.btags = self.options.btags
74          self.taginfos = ["impactParameter","secondaryVertex"]
75  
76          self.configTopProjections()
# Line 45 | Line 79 | class TopRefPF2PAT(object) :
79          self.configPatMuons()
80          self.configPatElectrons()
81          self.configPatJets()
82 +        self.configLeptonFilter()
83          self.removeCruft()
84          sys.stdout = self.stdout
85          
86      def attr(self, item) : return getattr(self.process, item)
87 <    def show(self, item) : print >>self.stdout, item, '=', self.attr(item).dumpPython()
87 >    def show(self, item) : print >> (sys.stdout if self.options.quiet else self.stdout), item, '=', self.attr(item).dumpPython() if hasattr(self.process, item) else 'Not Found.'
88  
89      def configTopProjections(self) :
90          '''Enable TopProjections except for Taus (do not remove tau cands from jet collection).'''
91  
92          for key,val in {'PileUp':1,'Muon':1,'Electron':1,'Jet':1,'Tau':0}.items() :
93              self.attr('pfNo'+key+self.fix).enable = bool(val)
94 <
60 <        for lep in ['Muon','Electron'] :
61 <            sub = (lep,self.fix)
62 <            pfNo = self.attr('pfNo%s%s'%sub)
63 <            pfNo.topCollection = 'selectedPat%ss%s'%sub
64 <            mods = [ self.attr( item) for item in [ lep.lower() + 'Match'+self.fix,
65 <                                                    'pat%ss%s'%sub,
66 <                                                    'selectedPat%ss%s'%sub]][int(self.options.isData):]
67 <            for mod in mods : self.patSeq.remove(mod)
68 <            self.patSeq.replace( pfNo, reduce(operator.mul, mods) * pfNo )
69 <            pfNo.verbose = True
70 <            self.show('pfNo%s%s'%sub)
94 >        self.attr('pfNoElectron').verbose = True
95          return
96  
97      def configPfLepton(self, lep, iso3) :
98          full = {'el':'Electrons','mu':'Muons'}[lep] + self.fix
99          iso = self.attr('pfIsolated'+full)
100 <        iso.isolationCut = 0.2
100 >        iso.isolationCut = self.isoValues[lep]
101          iso.doDeltaBetaCorrection = True
102 <        iso.deltaBetaFactor = -0.5
102 >        iso.deltaBetaFactor = getattr(self, 'dBFactor' + full[:2])
103 >        sel = self.attr('pfSelected'+full)
104 >        sel.cut = ' && '.join(self.cuts[lep][:-2])
105 >        isoEA = getattr(self.process, self.isoEA)
106 >        print >>self.stdout, ""
107 >        if lep == 'el' :
108 >            idName = 'pfIdentifiedElectrons'+self.fix
109 >            id = cms.EDFilter("ElectronIDPFCandidateSelector",
110 >                              src = cms.InputTag('pfElectronsFromVertex'+self.fix),
111 >                              recoGsfElectrons = cms.InputTag("gsfElectrons"),
112 >                              electronIdMap = cms.InputTag(self.eleID),
113 >                              electronIdCut = cms.double(self.minEleID))
114 >            setattr(self.process, idName, id )
115 >            self.patSeq.replace( sel, id*sel*isoEA)
116 >            sel.src = idName
117 >            isoEA.pfElectrons = 'pfSelectedElectrons'+self.fix
118 >            if not iso3 : isoEA.EffectiveAreaType = "kEleGammaAndNeutralHadronIso04"
119 >            self.show(idName)
120 >        
121          if iso3:
122              pf = {'el':'PFId','mu':''}[lep] + self.fix
123              for item in ['pf','pfIsolated'] :
# Line 89 | Line 131 | class TopRefPF2PAT(object) :
131              val.pfPUChargedHadrons = tags( lep+'PFIsoValuePU03' + pf )
132              val.pfPhotons          = tags( lep+'PFIsoValueGamma03' + pf )
133              val.pfChargedHadrons   = tags( lep+'PFIsoValueCharged03' + pf )
134 +
135 +        if lep == 'el' and self.options.doElectronEA :
136 +            self.attr( 'pfIsolated' + full).deltaBetaIsolationValueMap = self.isoEA
137 +
138 +        self.show('pfSelected'+full)
139 +        self.show('pfIsolated'+full)
140          return
141  
142      def configPatMuons(self) :
95        muonCuts = ['isPFMuon',                                                                      # general reconstruction property
96                    '(isGlobalMuon || isTrackerMuon)',                                               # general reconstruction property
97                    'pt > 10.',                                                                      # transverse momentum
98                    'abs(eta) < 2.5',                                                                # pseudo-rapisity range
99                    '(chargedHadronIso+neutralHadronIso+photonIso-0.5*puChargedHadronIso)/pt < 0.20']# relative isolation w/ Delta beta corrections (factor 0.5)
100
143          for mod,attr,val in [('patMuons','usePV',False),     # use beam spot rather than PV, which is necessary for 'dB' cut
144                               ('patMuons','embedTrack',True), # embedded track needed for muon ID cuts
145 <                             ('selectedPatMuons','cut', ' && '.join(muonCuts)),
145 >                             ('selectedPatMuons','cut', ' && '.join(self.cuts['mu'])),
146                               ] : setattr( self.attr(mod+self.fix), attr, val )
147          self.show('selectedPatMuons'+self.fix)
148          return
149  
150      def configPatElectrons(self) :
151 <        electronIDSources = cms.PSet(**dict([(i,tags(i)) for i in ['mvaTrigV0','mvaNonTrigV0']]))
152 <        electronCuts = ['pt > 20.',                                                                              # transverse energy
153 <                        'abs(eta) < 2.5',                                                                        # pseudo-rapidity range
112 <                        'electronID("mvaTrigV0") > 0.',                                                          # MVA electrons ID
113 <                        '(chargedHadronIso+max(0.,neutralHadronIso)+photonIso-0.5*puChargedHadronIso)/et < 0.15']# relative isolation with Delta beta corrections
114 <
115 <        for mod,attr,val in [('patElectrons','electronIDSources',electronIDSources),
116 <                             ('selectedPatElectrons','cut', ' && '.join(electronCuts)),
151 >        electronIDSources = cms.PSet(**dict([(i,tags(i)) for i in [self.eleID]]))
152 >        for mod,attr,val in [('patElectrons','electronIDSources', electronIDSources),
153 >                             ('selectedPatElectrons','cut', ' && '.join(c for c in self.cuts['el'] if 'gsfTrackRef' not in c)),
154                               ] : setattr( self.attr( mod+self.fix), attr, val )
155 +        self.attr('patElectrons'+self.fix).isolationValues.user = tags( [self.isoEA] )
156 +
157          self.show('selectedPatElectrons'+self.fix)
158          return
159  
160      def configPatJets(self) :
122        # Careful! these jet cuts affect the typeI met corrections
123        jetCuts = ['abs(eta) < 2.5',
124                   'pt > 15.',
125                   # PF jet ID:
126                   'numberOfDaughters > 1',
127                   'neutralHadronEnergyFraction < 0.99',
128                   'neutralEmEnergyFraction < 0.99',
129                   '(chargedEmEnergyFraction < 0.99   || abs(eta) >= 2.4)',
130                   '(chargedHadronEnergyFraction > 0. || abs(eta) >= 2.4)',
131                   '(chargedMultiplicity > 0          || abs(eta) >= 2.4)']
132
161          for mod,attr,val in [('patJets','discriminatorSources',[tags(tag+'BJetTagsAOD'+self.fix) for tag in self.btags]),
162                               ('patJets','tagInfoSources',[tags(tag+'TagInfosAOD'+self.fix) for tag in self.taginfos]),
163                               ('patJets','addTagInfos',True),
164 <                             ('selectedPatJets','cut', ' && '.join(jetCuts)),
164 >                             ('selectedPatJets','cut', ' && '.join(self.cuts['jet'])),
165                               ] : setattr( self.attr(mod+self.fix), attr, val )
166          self.show('selectedPatJets'+self.fix)
167          return
168  
169 +    def configLeptonFilter(self) :
170 +        if not self.options.requireLepton : return
171 +        muons20Name = 'pfIsolatedMuons20'+self.fix
172 +        leptonsName = 'pfLeptons'+self.fix
173 +        requireLeptonName = 'requireLepton'+self.fix
174 +
175 +        muons20 = cms.EDFilter("GenericPFCandidateSelector", src = tags('pfIsolatedMuons'+self.fix), cut = cms.string('pt>20 && abs(eta) < 2.4'))
176 +        leptons = cms.EDProducer("CandViewMerger", src = tags(['pfIsolated%s%s'%(lep,self.fix) for lep in ['Electrons','Muons20']]))
177 +        requireLepton = cms.EDFilter("CandViewCountFilter", src = tags(leptonsName), minNumber = cms.uint32(1) )
178 +
179 +        setattr(self.process, muons20Name, muons20)
180 +        setattr(self.process, leptonsName, leptons)
181 +        setattr(self.process, requireLeptonName, requireLepton)
182 +        
183 +        jets = self.attr('pfJets'+self.fix)
184 +        self.patSeq.replace(jets, muons20*leptons*requireLepton*jets)
185 +
186 +        self.show(muons20Name)
187 +        self.show(leptonsName)
188 +        self.show(requireLeptonName)
189 +        return
190  
191      def removeCruft(self) :
192          nothanks = [mod for mod in set(str(self.patSeq).split('+'))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines