CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/PhysicsTools/PatAlgos/python/tools/pfTools.py

Go to the documentation of this file.
00001 import FWCore.ParameterSet.Config as cms
00002 
00003 from PhysicsTools.PatAlgos.tools.coreTools import *
00004 from PhysicsTools.PatAlgos.tools.jetTools import *
00005 from PhysicsTools.PatAlgos.tools.tauTools import *
00006 
00007 from PhysicsTools.PatAlgos.tools.helpers import listModules, applyPostfix
00008 
00009 from copy import deepcopy
00010 
00011 #def applyPostfix(process, label, postfix):
00012 #    ''' If a module is in patDefaultSequence use the cloned module.
00013 #    Will crash if patDefaultSequence has not been cloned with 'postfix' beforehand'''
00014 #    result = None
00015 #    defaultLabels = [ m.label()[:-len(postfix)] for m in listModules( getattr(process,"patDefaultSequence"+postfix))]
00016 #    if label in defaultLabels:
00017 #        result = getattr(process, label+postfix)
00018 #    else:
00019 #        print "WARNING: called applyPostfix for module %s which is not in patDefaultSequence!"%label
00020 #        result = getattr(process, label)
00021 #    return result
00022 
00023 #def removeFromSequence(process, seq, postfix, baseSeq='patDefaultSequence'):
00024 #    defaultLabels = [ m.label()[:-len(postfix)] for m in listModules( getattr(process,baseSeq+postfix))]
00025 #    for module in listModules( seq ):
00026 #        if module.label() in defaultLabels:
00027 #            getattr(process,baseSeq+postfix).remove(getattr(process, module.label()+postfix))
00028 
00029 def warningIsolation():
00030     print "WARNING: particle based isolation must be studied"
00031 
00032 from CommonTools.ParticleFlow.Tools.pfIsolation import setupPFElectronIso, setupPFMuonIso
00033 
00034 def useGsfElectrons(process, postfix, dR = "04"):
00035     print "using Gsf Electrons in PF2PAT"
00036     print "WARNING: this will destory the feature of top projection which solves the ambiguity between leptons and jets because"
00037     print "WARNING: there will be overlap between non-PF electrons and jets even though top projection is ON!"
00038     print "********************* "
00039     module = applyPostfix(process,"patElectrons",postfix)
00040     module.useParticleFlow = False
00041     print "Building particle-based isolation for GsfElectrons in PF2PAT(PFBRECO)"
00042     print "********************* "
00043     adaptPFIsoElectrons( process, module, postfix+"PFIso", dR )
00044     getattr(process,'patDefaultSequence'+postfix).replace( getattr(process,"patElectrons"+postfix),
00045                                                    setupPFElectronIso(process, 'gsfElectrons', "PFIso", postfix, runPF2PAT=True) +
00046                                                    getattr(process,"patElectrons"+postfix) )
00047 
00048 def adaptPFIsoElectrons(process,module, postfix = "PFIso", dR = "04"):
00049     #FIXME: adaptPFElectrons can use this function.
00050     module.isoDeposits = cms.PSet(
00051         pfChargedHadrons = cms.InputTag("elPFIsoDepositCharged" + postfix),
00052         pfChargedAll = cms.InputTag("elPFIsoDepositChargedAll" + postfix),
00053         pfPUChargedHadrons = cms.InputTag("elPFIsoDepositPU" + postfix),
00054         pfNeutralHadrons = cms.InputTag("elPFIsoDepositNeutral" + postfix),
00055         pfPhotons = cms.InputTag("elPFIsoDepositGamma" + postfix)
00056         )
00057     module.isolationValues = cms.PSet(
00058         pfChargedHadrons = cms.InputTag("elPFIsoValueCharged"+dR+"PFId"+ postfix),
00059         pfChargedAll = cms.InputTag("elPFIsoValueChargedAll"+dR+"PFId"+ postfix),
00060         pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU"+dR+"PFId" + postfix),
00061         pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral"+dR+"PFId" + postfix),
00062         pfPhotons = cms.InputTag("elPFIsoValueGamma"+dR+"PFId" + postfix)
00063         )
00064     module.isolationValuesNoPFId = cms.PSet(
00065         pfChargedHadrons = cms.InputTag("elPFIsoValueCharged"+dR+"NoPFId"+ postfix),
00066         pfChargedAll = cms.InputTag("elPFIsoValueChargedAll"+dR+"NoPFId"+ postfix),
00067         pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU"+dR+"NoPFId" + postfix),
00068         pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral"+dR+"NoPFId" + postfix),
00069         pfPhotons = cms.InputTag("elPFIsoValueGamma"+dR+"NoPFId" + postfix)
00070         )
00071 
00072 def adaptPFIsoMuons(process,module, postfix = "PFIso", dR = "04"):
00073     #FIXME: adaptPFMuons can use this function.
00074     module.isoDeposits = cms.PSet(
00075         pfChargedHadrons = cms.InputTag("muPFIsoDepositCharged" + postfix),
00076         pfChargedAll = cms.InputTag("muPFIsoDepositChargedAll" + postfix),
00077         pfPUChargedHadrons = cms.InputTag("muPFIsoDepositPU" + postfix),
00078         pfNeutralHadrons = cms.InputTag("muPFIsoDepositNeutral" + postfix),
00079         pfPhotons = cms.InputTag("muPFIsoDepositGamma" + postfix)
00080         )
00081     module.isolationValues = cms.PSet(
00082         pfChargedHadrons = cms.InputTag("muPFIsoValueCharged" + dR + postfix),
00083         pfChargedAll = cms.InputTag("muPFIsoValueChargedAll" + dR + postfix),
00084         pfPUChargedHadrons = cms.InputTag("muPFIsoValuePU" + dR + postfix),
00085         pfNeutralHadrons = cms.InputTag("muPFIsoValueNeutral" + dR + postfix),
00086         pfPhotons = cms.InputTag("muPFIsoValueGamma" + dR + postfix)
00087         )
00088 
00089 def usePFIso(process, postfix = "PFIso"):
00090     print "Building particle-based isolation "
00091     print "***************** "
00092     process.eleIsoSequence = setupPFElectronIso(process, 'gsfElectrons', postfix)
00093     process.muIsoSequence = setupPFMuonIso(process, 'muons', postfix)
00094     adaptPFIsoMuons( process, applyPostfix(process,"patMuons",""), postfix)
00095     adaptPFIsoElectrons( process, applyPostfix(process,"patElectrons",""), postfix)
00096     getattr(process,'patDefaultSequence').replace( getattr(process,"patCandidates"),
00097                                                    process.pfParticleSelectionSequence +
00098                                                    process.eleIsoSequence +
00099                                                    process.muIsoSequence +
00100                                                    getattr(process,"patCandidates") )
00101 
00102 def adaptPFMuons(process,module,postfix="" ):
00103     print "Adapting PF Muons "
00104     print "***************** "
00105     warningIsolation()
00106     print
00107     module.useParticleFlow = True
00108     module.pfMuonSource    = cms.InputTag("pfIsolatedMuons" + postfix)
00109     module.userIsolation   = cms.PSet()
00110     module.isoDeposits = cms.PSet(
00111         pfChargedHadrons = cms.InputTag("muPFIsoDepositCharged" + postfix),
00112         pfChargedAll = cms.InputTag("muPFIsoDepositChargedAll" + postfix),
00113         pfPUChargedHadrons = cms.InputTag("muPFIsoDepositPU" + postfix),
00114         pfNeutralHadrons = cms.InputTag("muPFIsoDepositNeutral" + postfix),
00115         pfPhotons = cms.InputTag("muPFIsoDepositGamma" + postfix)
00116         )
00117     module.isolationValues = cms.PSet(
00118         pfChargedHadrons = cms.InputTag("muPFIsoValueCharged04"+ postfix),
00119         pfChargedAll = cms.InputTag("muPFIsoValueChargedAll04"+ postfix),
00120         pfPUChargedHadrons = cms.InputTag("muPFIsoValuePU04" + postfix),
00121         pfNeutralHadrons = cms.InputTag("muPFIsoValueNeutral04" + postfix),
00122         pfPhotons = cms.InputTag("muPFIsoValueGamma04" + postfix)
00123         )
00124     # matching the pfMuons, not the standard muons.
00125     applyPostfix(process,"muonMatch",postfix).src = module.pfMuonSource
00126 
00127     print " muon source:", module.pfMuonSource
00128     print " isolation  :",
00129     print module.isolationValues
00130     print " isodeposits: "
00131     print module.isoDeposits
00132     print
00133 
00134 
00135 def adaptPFElectrons(process,module, postfix):
00136     # module.useParticleFlow = True
00137     print "Adapting PF Electrons "
00138     print "********************* "
00139     warningIsolation()
00140     print
00141     module.useParticleFlow = True
00142     module.pfElectronSource = cms.InputTag("pfIsolatedElectrons" + postfix)
00143     module.userIsolation   = cms.PSet()
00144     module.isoDeposits = cms.PSet(
00145         pfChargedHadrons = cms.InputTag("elPFIsoDepositCharged" + postfix),
00146         pfChargedAll = cms.InputTag("elPFIsoDepositChargedAll" + postfix),
00147         pfPUChargedHadrons = cms.InputTag("elPFIsoDepositPU" + postfix),
00148         pfNeutralHadrons = cms.InputTag("elPFIsoDepositNeutral" + postfix),
00149         pfPhotons = cms.InputTag("elPFIsoDepositGamma" + postfix)
00150         )
00151     module.isolationValues = cms.PSet(
00152         pfChargedHadrons = cms.InputTag("elPFIsoValueCharged04PFId"+ postfix),
00153         pfChargedAll = cms.InputTag("elPFIsoValueChargedAll04PFId"+ postfix),
00154         pfPUChargedHadrons = cms.InputTag("elPFIsoValuePU04PFId" + postfix),
00155         pfNeutralHadrons = cms.InputTag("elPFIsoValueNeutral04PFId" + postfix),
00156         pfPhotons = cms.InputTag("elPFIsoValueGamma04PFId" + postfix)
00157         )
00158 
00159     # COLIN: since we take the egamma momentum for pat Electrons, we must
00160     # match the egamma electron to the gen electrons, and not the PFElectron.
00161     # -> do not uncomment the line below.
00162     # process.electronMatch.src = module.pfElectronSource
00163     # COLIN: how do we depend on this matching choice?
00164 
00165     print " PF electron source:", module.pfElectronSource
00166     print " isolation  :"
00167     print module.isolationValues
00168     print " isodeposits: "
00169     print module.isoDeposits
00170     print
00171 
00172     print "removing traditional isolation"
00173 
00174     removeIfInSequence(process,  "patElectronIsolation",  "patDefaultSequence", postfix)
00175 
00176 def adaptPFPhotons(process,module):
00177     raise RuntimeError, "Photons are not supported yet"
00178 
00179 from RecoTauTag.RecoTau.TauDiscriminatorTools import adaptTauDiscriminator, producerIsTauTypeMapper
00180 
00181 def reconfigurePF2PATTaus(process,
00182       tauType='shrinkingConePFTau',
00183       pf2patSelection=["DiscriminationByIsolation", "DiscriminationByLeadingPionPtCut"],
00184       selectionDependsOn=["DiscriminationByLeadingTrackFinding"],
00185       producerFromType=lambda producer: producer+"Producer",
00186       postfix = ""):
00187    print "patTaus will be produced from taus of type: %s that pass %s" \
00188          % (tauType, pf2patSelection)
00189 
00190    #get baseSequence
00191    baseSequence = getattr(process,"pfTausBaseSequence"+postfix)
00192    #clean baseSequence from old modules
00193    for oldBaseModuleName in baseSequence.moduleNames():
00194        oldBaseModule = getattr(process,oldBaseModuleName)
00195        baseSequence.remove(oldBaseModule)
00196 
00197    # Get the prototype of tau producer to make, i.e. fixedConePFTauProducer
00198    producerName = producerFromType(tauType)
00199    # Set as the source for the pf2pat taus (pfTaus) selector
00200    applyPostfix(process,"pfTaus", postfix).src = producerName+postfix
00201    # Start our pf2pat taus base sequence
00202    oldTauSansRefs = getattr(process,'pfTausProducerSansRefs'+postfix)
00203    oldTau = getattr(process,'pfTausProducer'+postfix)
00204    ## copy tau and setup it properly
00205    newTauSansRefs = None
00206    newTau = getattr(process,producerName).clone()
00207    ## adapted to new structure in RecoTauProducers PLEASE CHECK!!!
00208    if tauType=='shrinkingConePFTau':
00209        newTauSansRefs = getattr(process,producerName+"SansRefs").clone()
00210        newTauSansRefs.modifiers[1] = cms.PSet(
00211            pfTauTagInfoSrc = cms.InputTag("pfTauTagInfoProducer"+postfix),
00212            name = cms.string('pfTauTTIworkaround'+postfix),
00213            plugin = cms.string('RecoTauTagInfoWorkaroundModifer')
00214            )
00215        newTau.modifiers[1] = newTauSansRefs.modifiers[1]
00216        newTauSansRefs.piZeroSrc = "pfJetsLegacyTaNCPiZeros"+postfix
00217        newTau.piZeroSrc = newTauSansRefs.piZeroSrc
00218        newTauSansRefs.builders[0].pfCandSrc = oldTauSansRefs.builders[0].pfCandSrc
00219        newTauSansRefs.jetRegionSrc = oldTauSansRefs.jetRegionSrc
00220        newTauSansRefs.jetSrc = oldTauSansRefs.jetSrc
00221    elif tauType=='fixedConePFTau':
00222        newTau.piZeroSrc = "pfJetsLegacyTaNCPiZeros"+postfix
00223    elif tauType=='hpsPFTau':
00224        newTau = process.combinatoricRecoTaus.clone()
00225        newTau.piZeroSrc="pfJetsLegacyHPSPiZeros"+postfix
00226        newTau.modifiers[3] = cms.PSet(
00227            pfTauTagInfoSrc = cms.InputTag("pfTauTagInfoProducer"+postfix),
00228            name = cms.string('pfTauTTIworkaround'+postfix),
00229            plugin = cms.string('RecoTauTagInfoWorkaroundModifer')
00230            )
00231        from PhysicsTools.PatAlgos.tools.helpers import cloneProcessingSnippet
00232        cloneProcessingSnippet(process, process.produceHPSPFTaus, postfix)
00233        massSearchReplaceParam(getattr(process,"produceHPSPFTaus"+postfix),
00234                               "PFTauProducer",
00235                               cms.InputTag("combinatoricRecoTaus"),
00236                               cms.InputTag("pfTausBase"+postfix) )
00237        massSearchReplaceParam(getattr(process,"produceHPSPFTaus"+postfix),
00238                               "src",
00239                               cms.InputTag("combinatoricRecoTaus"),
00240                               cms.InputTag("pfTausBase"+postfix) )
00241 
00242    newTau.builders[0].pfCandSrc = oldTau.builders[0].pfCandSrc
00243    newTau.jetRegionSrc = oldTau.jetRegionSrc
00244    newTau.jetSrc = oldTau.jetSrc
00245 
00246    # replace old tau producer by new one put it into baseSequence
00247    setattr(process,"pfTausBase"+postfix,newTau)
00248    if tauType=='shrinkingConePFTau':
00249        setattr(process,"pfTausBaseSansRefs"+postfix,newTauSansRefs)
00250        getattr(process,"pfTausBase"+postfix).src = "pfTausBaseSansRefs"+postfix
00251        baseSequence += getattr(process,"pfTausBaseSansRefs"+postfix)
00252    baseSequence += getattr(process,"pfTausBase"+postfix)
00253    if tauType=='hpsPFTau':
00254        baseSequence += getattr(process,"produceHPSPFTaus"+postfix)
00255    #make custom mapper to take postfix into account (could have gone with lambda of lambda but... )
00256    def producerIsTauTypeMapperWithPostfix(tauProducer):
00257        return lambda x: producerIsTauTypeMapper(tauProducer)+x.group(1)+postfix
00258 
00259    def recoTauTypeMapperWithGroup(tauProducer):
00260        return "%s(.*)"%recoTauTypeMapper(tauProducer)
00261 
00262    # Get our prediscriminants
00263    for predisc in selectionDependsOn:
00264       # Get the prototype
00265       originalName = tauType+predisc # i.e. fixedConePFTauProducerDiscriminationByLeadingTrackFinding
00266       clonedName = "pfTausBase"+predisc+postfix
00267       clonedDisc = getattr(process, originalName).clone()
00268       # Register in our process
00269       setattr(process, clonedName, clonedDisc)
00270       baseSequence += getattr(process, clonedName)
00271 
00272       tauCollectionToSelect = None
00273       if tauType != 'hpsPFTau' :
00274           tauCollectionToSelect = "pfTausBase"+postfix
00275           #cms.InputTag(clonedDisc.PFTauProducer.value()+postfix)
00276       else:
00277           tauCollectionToSelect = "hpsPFTauProducer"+postfix
00278       # Adapt this discriminator for the cloned prediscriminators
00279       adaptTauDiscriminator(clonedDisc, newTauProducer="pfTausBase",
00280                             oldTauTypeMapper=recoTauTypeMapperWithGroup,
00281                             newTauTypeMapper=producerIsTauTypeMapperWithPostfix,
00282                             preservePFTauProducer=True)
00283       clonedDisc.PFTauProducer = tauCollectionToSelect
00284 
00285    # Reconfigure the pf2pat PFTau selector discrimination sources
00286    applyPostfix(process,"pfTaus", postfix).discriminators = cms.VPSet()
00287    for selection in pf2patSelection:
00288       # Get our discriminator that will be used to select pfTaus
00289       originalName = tauType+selection
00290       clonedName = "pfTausBase"+selection+postfix
00291       clonedDisc = getattr(process, originalName).clone()
00292       # Register in our process
00293       setattr(process, clonedName, clonedDisc)
00294 
00295       tauCollectionToSelect = None
00296 
00297       if tauType != 'hpsPFTau' :
00298           tauCollectionToSelect = cms.InputTag("pfTausBase"+postfix)
00299           #cms.InputTag(clonedDisc.PFTauProducer.value()+postfix)
00300       else:
00301           tauCollectionToSelect = cms.InputTag("hpsPFTauProducer"+postfix)
00302       #Adapt our cloned discriminator to the new prediscriminants
00303       adaptTauDiscriminator(clonedDisc, newTauProducer="pfTausBase",
00304                             oldTauTypeMapper=recoTauTypeMapperWithGroup,
00305                             newTauTypeMapper=producerIsTauTypeMapperWithPostfix,
00306                             preservePFTauProducer=True)
00307       clonedDisc.PFTauProducer = tauCollectionToSelect
00308       baseSequence += clonedDisc
00309       # Add this selection to our pfTau selectors
00310       applyPostfix(process,"pfTaus", postfix).discriminators.append(cms.PSet(
00311          discriminator=cms.InputTag(clonedName), selectionCut=cms.double(0.5)))
00312       # Set the input of the final selector.
00313       if tauType != 'hpsPFTau':
00314           applyPostfix(process,"pfTaus", postfix).src = "pfTausBase"+postfix
00315       else:
00316           # If we are using HPS taus, we need to take the output of the clenaed
00317           # collection
00318           applyPostfix(process,"pfTaus", postfix).src = "hpsPFTauProducer"+postfix
00319 
00320 
00321 
00322 def adaptPFTaus(process,tauType = 'shrinkingConePFTau', postfix = ""):
00323     # Set up the collection used as a preselection to use this tau type
00324     if tauType != 'hpsPFTau' :
00325         reconfigurePF2PATTaus(process, tauType, postfix=postfix)
00326     else:
00327         reconfigurePF2PATTaus(process, tauType,
00328                               ["DiscriminationByLooseCombinedIsolationDBSumPtCorr"],
00329                               ["DiscriminationByDecayModeFinding"],
00330                               postfix=postfix)
00331     # new default use unselected taus (selected only for jet cleaning)
00332     if tauType != 'hpsPFTau' :
00333         applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("pfTausBase"+postfix)
00334     else:
00335         applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("hpsPFTauProducer"+postfix)
00336     # to use preselected collection (old default) uncomment line below
00337     #applyPostfix(process,"patTaus", postfix).tauSource = cms.InputTag("pfTaus"+postfix)
00338 
00339 
00340     redoPFTauDiscriminators(process,
00341                             cms.InputTag(tauType+'Producer'),
00342                             applyPostfix(process,"patTaus", postfix).tauSource,
00343                             tauType, postfix=postfix)
00344 
00345     switchToPFTauByType(process, pfTauType=tauType,
00346                         pfTauLabelNew=applyPostfix(process,"patTaus", postfix).tauSource,
00347                         pfTauLabelOld=cms.InputTag(tauType+'Producer'),
00348                         postfix=postfix)
00349 
00350     applyPostfix(process,"makePatTaus", postfix).remove(
00351         applyPostfix(process,"patPFCandidateIsoDepositSelection", postfix)
00352         )
00353 
00354 #helper function for PAT on PF2PAT sample
00355 def tauTypeInPF2PAT(process,tauType='shrinkingConePFTau', postfix = ""):
00356     process.load("CommonTools.ParticleFlow.pfTaus_cff")
00357     applyPostfix(process, "pfTaus",postfix).src = cms.InputTag(tauType+'Producer'+postfix)
00358 
00359 
00360 def addPFCandidates(process,src,patLabel='PFParticles',cut="",postfix=""):
00361     from PhysicsTools.PatAlgos.producersLayer1.pfParticleProducer_cfi import patPFParticles
00362     # make modules
00363     producer = patPFParticles.clone(pfCandidateSource = src)
00364     filter   = cms.EDFilter("PATPFParticleSelector",
00365                     src = cms.InputTag("pat" + patLabel),
00366                     cut = cms.string(cut))
00367     counter  = cms.EDFilter("PATCandViewCountFilter",
00368                     minNumber = cms.uint32(0),
00369                     maxNumber = cms.uint32(999999),
00370                     src       = cms.InputTag("pat" + patLabel))
00371     # add modules to process
00372     setattr(process, "pat"         + patLabel, producer)
00373     setattr(process, "selectedPat" + patLabel, filter)
00374     setattr(process, "countPat"    + patLabel, counter)
00375     # insert into sequence
00376     getattr(process, "patDefaultSequence"+postfix).replace(
00377         applyPostfix(process, "patCandidateSummary", postfix),
00378         producer+applyPostfix(process, "patCandidateSummary", postfix)
00379     )
00380     getattr(process, "patDefaultSequence"+postfix).replace(
00381         applyPostfix(process, "selectedPatCandidateSummary", postfix),
00382         filter+applyPostfix(process, "selectedPatCandidateSummary", postfix)
00383     )
00384     index = len( applyPostfix( process, "patDefaultSequence", postfix ).moduleNames() )
00385     applyPostfix( process, "patDefaultSequence", postfix ).insert( index, counter )
00386     # summary tables
00387     applyPostfix(process, "patCandidateSummary", postfix).candidates.append(cms.InputTag('pat' + patLabel))
00388     applyPostfix(process, "selectedPatCandidateSummary", postfix).candidates.append(cms.InputTag('selectedPat' + patLabel))
00389 
00390 
00391 def switchToPFMET(process,input=cms.InputTag('pfMET'), type1=False, postfix=""):
00392     print 'MET: using ', input
00393     if( not type1 ):
00394         oldMETSource = applyPostfix(process, "patMETs",postfix).metSource
00395         applyPostfix(process, "patMETs",postfix).metSource = input
00396         applyPostfix(process, "patMETs",postfix).addMuonCorrections = False
00397         getattr(process, "patDefaultSequence"+postfix).remove(applyPostfix(process, "patMETCorrections",postfix))
00398     else:
00399         # type1 corrected MET
00400         # name of corrected MET hardcoded in PAT and meaningless
00401         print 'Apply TypeI corrections for MET'
00402         getattr(process, "patDefaultSequence"+postfix).remove(applyPostfix(process, "makePatMETs",postfix))
00403         jecLabel = getattr(process,'patJetCorrFactors'+postfix).levels
00404 
00405         if not hasattr(process,'producePatPFMETCorrections'):
00406             process.load("PhysicsTools.PatUtils.patPFMETCorrections_cff")
00407         #here add to the current path and give proper postfix
00408         if not hasattr(process,'producePatPFMETCorrections'+postfix):
00409             cloneProcessingSnippet(process,process.producePatPFMETCorrections,postfix)
00410         
00411         getattr(process,'patPFMet'+postfix).metSource = cms.InputTag('pfMET'+postfix)
00412 
00413         getattr(process,'selectedPatJetsForMETtype1p2Corr'+postfix).src = cms.InputTag('selectedPatJets'+postfix)
00414         getattr(process,'selectedPatJetsForMETtype2Corr'+postfix).src   = cms.InputTag('selectedPatJets'+postfix)
00415 
00416         getattr(process,'pfCandMETcorr'+postfix).src = cms.InputTag('pfNoJet'+postfix)
00417 
00418         getattr(process,'patPFJetMETtype1p2Corr'+postfix).offsetCorrLabel = cms.string(jecLabel[0])
00419         getattr(process,'patPFJetMETtype1p2Corr'+postfix).jetCorrLabel = cms.string(jecLabel[-1])
00420         getattr(process,'patPFJetMETtype1p2Corr'+postfix).type1JetPtThreshold = cms.double(10.0)
00421         getattr(process,'patPFJetMETtype1p2Corr'+postfix).skipEM    = cms.bool(False)
00422         getattr(process,'patPFJetMETtype1p2Corr'+postfix).skipMuons = cms.bool(False)
00423 
00424         getattr(process,'patPFJetMETtype2Corr'+postfix).offsetCorrLabel = cms.string(jecLabel[0])
00425         getattr(process,'patPFJetMETtype2Corr'+postfix).jetCorrLabel = cms.string(jecLabel[-1])
00426         getattr(process,'patPFJetMETtype2Corr'+postfix).type1JetPtThreshold = cms.double(10.0)
00427         getattr(process,'patPFJetMETtype2Corr'+postfix).skipEM    = cms.bool(False)
00428         getattr(process,'patPFJetMETtype2Corr'+postfix).skipMuons = cms.bool(False)
00429         
00430         getattr(process,'patType1CorrectedPFMet'+postfix).srcType1Corrections = cms.VInputTag(
00431             cms.InputTag("patPFJetMETtype1p2Corr"+postfix,"type1"),
00432             #cms.InputTag("patPFMETtype0Corr"+postfix),
00433             )
00434         getattr(process,'patType1p2CorrectedPFMet'+postfix).srcType1Corrections = cms.VInputTag(
00435             cms.InputTag("patPFJetMETtype1p2Corr"+postfix,"type1"),
00436             #cms.InputTag("patPFMETtype0Corr"+postfix),
00437             )
00438         
00439         getattr(process,'patMETs'+postfix).metSource = 'patType1CorrectedPFMet'+postfix
00440 
00441         getattr(process,"patDefaultSequence"+postfix).replace( getattr(process,'selectedPatJets'+postfix),
00442                                                                getattr(process,'selectedPatJets'+postfix)
00443                                                                *getattr(process,'producePatPFMETCorrections'+postfix)
00444                                                                *getattr(process,'patMETs'+postfix)
00445                                                               )
00446 
00447 def switchToPFJets(process, input=cms.InputTag('pfNoTau'), algo='AK5', postfix = "", jetCorrections=('AK5PFchs', ['L1FastJet','L2Relative', 'L3Absolute']), type1=False, outputModules=['out']):
00448 
00449     print "Switching to PFJets,  ", algo
00450     print "************************ "
00451     print "input collection: ", input
00452 
00453     if( algo == 'IC5' ):
00454         genJetCollection = cms.InputTag('iterativeCone5GenJetsNoNu')
00455     elif algo == 'AK5':
00456         genJetCollection = cms.InputTag('ak5GenJetsNoNu')
00457     elif algo == 'AK7':
00458         genJetCollection = cms.InputTag('ak7GenJetsNoNu')
00459     else:
00460         print 'bad jet algorithm:', algo, '! for now, only IC5, AK5 and AK7 are allowed. If you need other algorithms, please contact Colin'
00461         sys.exit(1)
00462 
00463     # changing the jet collection in PF2PAT:
00464     from CommonTools.ParticleFlow.Tools.jetTools import jetAlgo
00465     inputCollection = getattr(process,"pfJets"+postfix).src
00466     setattr(process,"pfJets"+postfix,jetAlgo(algo)) # problem for cfgBrowser
00467     getattr(process,"pfJets"+postfix).src = inputCollection
00468     inputJetCorrLabel=jetCorrections
00469     switchJetCollection(process,
00470                         input,
00471                         jetIdLabel = algo,
00472                         doJTA=True,
00473                         doBTagging=True,
00474                         jetCorrLabel=inputJetCorrLabel,
00475                         doType1MET=type1,
00476                         genJetCollection = genJetCollection,
00477                         doJetID = True,
00478                         postfix = postfix,
00479                         outputModules = outputModules
00480                         )
00481     # check whether L1FastJet is in the list of correction levels or not
00482     applyPostfix(process, "patJetCorrFactors", postfix).useRho = False
00483     for corr in inputJetCorrLabel[1]:
00484         if corr == 'L1FastJet':
00485             applyPostfix(process, "patJetCorrFactors", postfix).useRho = True
00486             applyPostfix(process, "pfJets", postfix).doAreaFastjet = True
00487             # do correct treatment for TypeI MET corrections
00488             if type1:
00489                 for mod in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
00490                     if mod.startswith("kt6") and mod.endswith("Jets"+postfix):
00491                         prefix = mod.replace(postfix,'')
00492                         prefix = prefix.replace('kt6PFJets','')
00493                         prefix = prefix.replace('kt6CaloJets','')
00494                         prefix = getattr(process,'patJetCorrFactors'+prefix+postfix).payload.pythonValue().replace("'","")
00495                         for essource in process.es_sources_().keys():
00496                             if essource == prefix+'L1FastJet':
00497                                 setattr(process,essource+postfix,getattr(process,essource).clone(srcRho=cms.InputTag(mod,'rho')))
00498                                 setattr(process,prefix+'CombinedCorrector'+postfix,getattr(process,prefix+'CombinedCorrector').clone())
00499                                 getattr(process,prefix+'CorMet'+postfix).corrector = prefix+'CombinedCorrector'+postfix
00500                                 for cor in getattr(process,prefix+'CombinedCorrector'+postfix).correctors:
00501                                     if cor == essource:
00502                                         idx = getattr(process,prefix+'CombinedCorrector'+postfix).correctors.index(essource);
00503                                         getattr(process,prefix+'CombinedCorrector'+postfix).correctors[idx] = essource+postfix
00504 
00505     applyPostfix(process, "patJets", postfix).embedCaloTowers   = False
00506     applyPostfix(process, "patJets", postfix).embedPFCandidates = True
00507 
00508 #-- Remove MC dependence ------------------------------------------------------
00509 def removeMCMatchingPF2PAT( process, postfix="", outputModules=['out'] ):
00510     from PhysicsTools.PatAlgos.tools.coreTools import removeMCMatching
00511     removeIfInSequence(process, "genForPF2PATSequence", "patDefaultSequence", postfix)
00512     removeMCMatching(process, names=['All'], postfix=postfix, outputModules=outputModules)
00513 
00514 
00515 def adaptPVs(process, pvCollection=cms.InputTag('offlinePrimaryVertices'), postfix=''):
00516 
00517     print "Switching PV collection for PF2PAT:", pvCollection
00518     print "***********************************"
00519 
00520     # PV sources to be exchanged:
00521     pvExchange = ['Vertices','vertices','pvSrc','primaryVertices','srcPVs']
00522     # PV sources NOT to be exchanged:
00523     #noPvExchange = ['src','PVProducer','primaryVertexSrc','vertexSrc','primaryVertex']
00524 
00525     # find out all added jet collections (they don't belong to PF2PAT)
00526     interPostfixes = []
00527     for m in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
00528         if m.startswith('patJets') and m.endswith(postfix) and not len(m)==len('patJets')+len(postfix):
00529             interPostfix = m.replace('patJets','')
00530             interPostfix = interPostfix.replace(postfix,'')
00531             interPostfixes.append(interPostfix)
00532 
00533     # exchange the primary vertex source of all relevant modules
00534     for m in getattr(process,'patPF2PATSequence'+postfix).moduleNames():
00535         modName = m.replace(postfix,'')
00536         # only if the module has a source with a relevant name
00537         for namePvSrc in pvExchange:
00538             if hasattr(getattr(process,m),namePvSrc):
00539                 # only if the module is not coming from an added jet collection
00540                 interPostFixFlag = False
00541                 for pfix in interPostfixes:
00542                     if modName.endswith(pfix):
00543                         interPostFixFlag = True
00544                         break
00545                 if not interPostFixFlag:
00546                     setattr(getattr(process,m),namePvSrc,deepcopy(pvCollection))
00547 
00548 
00549 def usePF2PAT(process, runPF2PAT=True, jetAlgo='AK5', runOnMC=True, postfix="", jetCorrections=('AK5PFchs', ['L1FastJet','L2Relative','L3Absolute']), pvCollection=cms.InputTag('offlinePrimaryVertices'), typeIMetCorrections=False, outputModules=['out']):
00550     # PLEASE DO NOT CLOBBER THIS FUNCTION WITH CODE SPECIFIC TO A GIVEN PHYSICS OBJECT.
00551     # CREATE ADDITIONAL FUNCTIONS IF NEEDED.
00552 
00553     """Switch PAT to use PF2PAT instead of AOD sources. if 'runPF2PAT' is true, we'll also add PF2PAT in front of the PAT sequence"""
00554 
00555     # -------- CORE ---------------
00556     if runPF2PAT:
00557         process.load("CommonTools.ParticleFlow.PF2PAT_cff")
00558         #add Pf2PAT *before* cloning so that overlapping modules are cloned too
00559         #process.patDefaultSequence.replace( process.patCandidates, process.PF2PAT+process.patCandidates)
00560         process.patPF2PATSequence = cms.Sequence( process.PF2PAT + process.patDefaultSequence)
00561     else:
00562         process.patPF2PATSequence = cms.Sequence( process.patDefaultSequence )
00563 
00564     if not postfix == "":
00565         from PhysicsTools.PatAlgos.tools.helpers import cloneProcessingSnippet
00566         cloneProcessingSnippet(process, process.patPF2PATSequence, postfix)
00567         #delete everything pat PF2PAT modules! if you want to test the postfixing for completeness
00568         #from PhysicsTools.PatAlgos.tools.helpers import listModules,listSequences
00569         #for module in listModules(process.patDefaultSequence):
00570         #    if not module.label() is None: process.__delattr__(module.label())
00571         #for sequence in listSequences(process.patDefaultSequence):
00572         #    if not sequence.label() is None: process.__delattr__(sequence.label())
00573         #del process.patDefaultSequence
00574 
00575     removeCleaning(process, postfix=postfix, outputModules=outputModules)
00576 
00577     # -------- OBJECTS ------------
00578     # Muons
00579     adaptPFMuons(process,
00580                  applyPostfix(process,"patMuons",postfix),
00581                  postfix)
00582 
00583     # Electrons
00584     adaptPFElectrons(process,
00585                      applyPostfix(process,"patElectrons",postfix),
00586                      postfix)
00587 
00588     # Photons
00589     print "Temporarily switching off photons completely"
00590 
00591     removeSpecificPATObjects(process,names=['Photons'],outputModules=outputModules,postfix=postfix)
00592     removeIfInSequence(process,"patPhotonIsolation","patDefaultSequence",postfix)
00593 
00594     # Jets
00595     if runOnMC :
00596         switchToPFJets( process, cms.InputTag('pfNoTau'+postfix), jetAlgo, postfix=postfix,
00597                         jetCorrections=jetCorrections, type1=typeIMetCorrections, outputModules=outputModules )
00598         applyPostfix(process,"patDefaultSequence",postfix).replace(
00599             applyPostfix(process,"patJetGenJetMatch",postfix),
00600             getattr(process,"genForPF2PATSequence") *
00601             applyPostfix(process,"patJetGenJetMatch",postfix)
00602             )
00603     else :
00604         if not 'L2L3Residual' in jetCorrections[1]:
00605             print '#################################################'
00606             print 'WARNING! Not using L2L3Residual but this is data.'
00607             print 'If this is okay with you, disregard this message.'
00608             print '#################################################'
00609         switchToPFJets( process, cms.InputTag('pfNoTau'+postfix), jetAlgo, postfix=postfix,
00610                         jetCorrections=jetCorrections, type1=typeIMetCorrections, outputModules=outputModules )
00611 
00612     # Taus
00613     #adaptPFTaus( process, tauType='shrinkingConePFTau', postfix=postfix )
00614     #adaptPFTaus( process, tauType='fixedConePFTau', postfix=postfix )
00615     adaptPFTaus( process, tauType='hpsPFTau', postfix=postfix )
00616 
00617     # MET
00618     switchToPFMET(process, cms.InputTag('pfMET'+postfix), type1=typeIMetCorrections, postfix=postfix)
00619     if not runOnMC :
00620         if hasattr(process,'patPFMet'+postfix):
00621             getattr(process,'patPFMet'+postfix).addGenMET = cms.bool(False)
00622 
00623     # Unmasked PFCandidates
00624     addPFCandidates(process,cms.InputTag('pfNoJet'+postfix),patLabel='PFParticles'+postfix,cut="",postfix=postfix)
00625 
00626     # adapt primary vertex collection
00627     adaptPVs(process, pvCollection=pvCollection, postfix=postfix)
00628 
00629     if runOnMC:
00630         process.load("CommonTools.ParticleFlow.genForPF2PAT_cff")
00631         getattr(process, "patDefaultSequence"+postfix).replace(
00632             applyPostfix(process,"patCandidates",postfix),
00633             process.genForPF2PATSequence+applyPostfix(process,"patCandidates",postfix)
00634             )
00635     else:
00636         removeMCMatchingPF2PAT(process,postfix=postfix,outputModules=outputModules)
00637 
00638     print "Done: PF2PAT interfaced to PAT, postfix=", postfix