CMS 3D CMS Logo

jetTools.py

Go to the documentation of this file.
00001 import FWCore.ParameterSet.Config as cms
00002 
00003 from PhysicsTools.PatAlgos.tools.helpers import *
00004 
00005 def switchJECSet(process,newName,oldName):
00006     """Replace tags in the JetCorrFactorsProducer
00007        For end-users, taking the process as first argument"""
00008     switchJECSet_(process.jetCorrFactors,newName,oldName)
00009     
00010 def switchJECSet_(jetCorrFactors,newName,oldName,
00011                   steps=['L1Offset', 'L2Relative', 'L3Absolute', 'L4EMF', 'L5Flavor', 'L6UE', 'L7Parton']):
00012     """Replace tags in the JetCorrFactorsProducer
00013        Inner implementation taking a jetCorrFactors object"""
00014     found = False
00015     for k in steps:
00016         vv = getattr(jetCorrFactors, k).value();
00017         if vv.find(oldName) != -1: found = True
00018         if (vv != "none"): 
00019             setattr(jetCorrFactors, k, vv.replace(oldName,newName))
00020             # the first replace is good for L2, L3; the last for L7 (which don't have type dependency, at least not in the name)
00021     if not found:
00022         raise RuntimeError, """None of the JEC steps uses old name %s, so I can't replace %s with %s.
00023                                The full configuration is %s""" % (newName,oldName,newName,jetCorrFactors.dumpPython())
00024 
00025 def switchJECParameters(jetCorrFactors,newalgo,newtype="Calo",oldalgo="IC5",oldtype="Calo"):
00026     """Replace tags in the JetCorrFactorsProducer -- L5Flavor is taken out as it is said not to be dependend on the specific jet algorithm"""
00027     for k in ['L1Offset', 'L2Relative', 'L3Absolute', 'L4EMF', 'L6UE', 'L7Parton']:
00028         vv = getattr(jetCorrFactors, k).value();
00029         if (vv != "none"): 
00030             setattr(jetCorrFactors, k, vv.replace(oldalgo+oldtype,newalgo+newtype).replace(oldalgo,newalgo) )
00031             # the first replace is good for L2, L3; the last for L7 (which don't have type dependency, at least not in the name)
00032 
00033 def runBTagging(process,jetCollection,label) :
00034     """Define a sequence to run BTagging on AOD on top of jet collection 'jetCollection', appending 'label' to module labels.
00035        The sequence will be called "btaggingAOD" + 'label', and will already be added to the process (but not to any Path)
00036        The sequence will include a JetTracksAssociatorAtVertex with name "jetTracksAssociatorAtVertex" + 'label'
00037        The method will return a pair (sequence, labels) where 'sequence' is the cms.Sequence object, and 'labels' contains
00038          labels["jta"]      = the name of the JetTrackAssociator module
00039          labels["tagInfos"] = list of names of TagInfo modules
00040          labels["jetTags "] = list of names of JetTag modules
00041        these labels are meant to be used for PAT BTagging tools
00042        NOTE: 'label' MUST NOT BE EMPTY
00043      """
00044     if (label == ''):
00045         raise ValueError, "Label for re-running BTagging can't be empty, it will crash CRAB." 
00046     process.load("RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi")
00047     process.load("RecoBTag.Configuration.RecoBTag_cff")
00048     from RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi import ic5JetTracksAssociatorAtVertex
00049     import RecoBTag.Configuration.RecoBTag_cff as btag
00050     
00051     # quickly make VInputTag from strings
00052     def vit(*args) : return cms.VInputTag( *[ cms.InputTag(x) for x in args ] )
00053     
00054     # define labels
00055     jtaLabel =  'jetTracksAssociatorAtVertex' + label
00056     ipTILabel = 'impactParameterTagInfos'     + label
00057     svTILabel = 'secondaryVertexTagInfos'     + label
00058     seTILabel = 'softElectronTagInfos'        + label
00059     smTILabel = 'softMuonTagInfos'            + label
00060     
00061     # make JTA and TagInfos
00062     setattr( process, jtaLabel,  ic5JetTracksAssociatorAtVertex.clone(jets = jetCollection))
00063     setattr( process, ipTILabel, btag.impactParameterTagInfos.clone(jetTracks = cms.InputTag(jtaLabel)) )
00064     setattr( process, svTILabel, btag.secondaryVertexTagInfos.clone(trackIPTagInfos = cms.InputTag(ipTILabel)) )
00065     setattr( process, seTILabel, btag.softElectronTagInfos.clone(jets = jetCollection) )
00066     setattr( process, smTILabel, btag.softMuonTagInfos.clone(jets = jetCollection) )
00067     setattr( process, 'jetBProbabilityBJetTags'+label, btag.jetBProbabilityBJetTags.clone(tagInfos = vit(ipTILabel)) )
00068     setattr( process, 'jetProbabilityBJetTags' +label,  btag.jetProbabilityBJetTags.clone(tagInfos = vit(ipTILabel)) )
00069     setattr( process, 'trackCountingHighPurBJetTags'+label, btag.trackCountingHighPurBJetTags.clone(tagInfos = vit(ipTILabel)) )
00070     setattr( process, 'trackCountingHighEffBJetTags'+label, btag.trackCountingHighEffBJetTags.clone(tagInfos = vit(ipTILabel)) )
00071     setattr( process, 'impactParameterMVABJetTags'+label, btag.impactParameterMVABJetTags.clone(tagInfos = vit(ipTILabel)) )
00072     setattr( process, 'simpleSecondaryVertexBJetTags'+label, btag.simpleSecondaryVertexBJetTags.clone(tagInfos = vit(svTILabel)) )
00073     setattr( process, 'combinedSecondaryVertexBJetTags'+label, btag.combinedSecondaryVertexBJetTags.clone(tagInfos = vit(ipTILabel, svTILabel)) )
00074     setattr( process, 'combinedSecondaryVertexMVABJetTags'+label, btag.combinedSecondaryVertexMVABJetTags.clone(tagInfos = vit(ipTILabel, svTILabel)) )
00075     setattr( process, 'softElectronBJetTags'+label, btag.softElectronBJetTags.clone(tagInfos = vit(seTILabel)) )
00076     setattr( process, 'softMuonBJetTags'+label, btag.softMuonBJetTags.clone(tagInfos = vit(smTILabel)) )
00077     setattr( process, 'softMuonNoIPBJetTags'+label, btag.softMuonNoIPBJetTags.clone(tagInfos = vit(smTILabel)) )
00078     
00079     def mkseq(process, firstlabel, *otherlabels):
00080        seq = getattr(process, firstlabel)
00081        for x in otherlabels: seq += getattr(process, x)
00082        return cms.Sequence(seq)
00083     
00084     labels = { 'jta' : jtaLabel, 
00085                'tagInfos' : (ipTILabel,svTILabel,seTILabel,smTILabel), 
00086                'jetTags'  : [ (x + label) for x in ('jetBProbabilityBJetTags',
00087                                                 'jetProbabilityBJetTags',
00088                                                 'trackCountingHighPurBJetTags',
00089                                                 'trackCountingHighEffBJetTags',
00090                                                 'impactParameterMVABJetTags',
00091                                                 'simpleSecondaryVertexBJetTags',
00092                                                 'combinedSecondaryVertexBJetTags',
00093                                                 'combinedSecondaryVertexMVABJetTags',
00094                                                 'softElectronBJetTags',
00095                                                 'softMuonBJetTags',
00096                                                 'softMuonNoIPBJetTags') ]
00097     }
00098     
00099     setattr( process, 'btaggingTagInfos' + label, mkseq(process, *(labels['tagInfos']) ) )
00100     setattr( process, 'btaggingJetTags' + label,  mkseq(process, *(labels['jetTags'])  ) )
00101     seq = mkseq(process, jtaLabel, 'btaggingTagInfos' + label, 'btaggingJetTags' + label) 
00102     setattr( process, 'btagging' + label, seq )
00103     return (seq, labels)
00104 
00105 def switchJetCollection(process,jetCollection,doJTA=True,doBTagging=True,jetCorrLabel=None,doType1MET=True,
00106                                 genJetCollection=cms.InputTag("iterativeCone5GenJets")):
00107     """Switch the collection of jets in PAT from the default value.
00108           doBTagging  : True to run the BTagging sequence on top of this jets, and import it into PAT.
00109           doJTA       : Run Jet Tracks Association and Jet Charge (will be forced to True if doBTagging is true)
00110           jetCorrLabel: Name of the algorithm and jet type JEC to pick corrections from, or None for no JEC 
00111                         Examples are ('IC5','Calo'), ('SC7','Calo'), ('KT4','PF')
00112                         It tries to find a 'L2L3JetCorrector' + algo + type , or otherwise to create if as a 
00113                         JetCorrectionServiceChain of 'L2RelativeJetCorrector' and 'L3AbsoluteJetCorrector'
00114           doType1MET  : If jetCorrLabel is not 'None', set this to 'True' to remake Type1 MET from these jets
00115                         NOTE: at the moment it must be False for non-CaloJets otherwise the JetMET POG module crashes.
00116           genJetCollection : GenJet collection to match to."""
00117     oldLabel = process.allLayer1Jets.jetSource;
00118     process.jetPartonMatch.src        = jetCollection
00119     process.jetGenJetMatch.src        = jetCollection
00120     process.jetGenJetMatch.matched    = genJetCollection
00121     process.jetPartonAssociation.jets = jetCollection
00122     massSearchReplaceParam(process.patTrigMatch, 'src', oldLabel, jetCollection)
00123     process.allLayer1Jets.jetSource = jetCollection
00124     # quickly make VInputTag from strings
00125     def vit(*args) : return cms.VInputTag( *[ cms.InputTag(x) for x in args ] )
00126     if doBTagging :
00127         (btagSeq, btagLabels) = runBTagging(process, jetCollection, 'AOD')
00128         process.patAODCoreReco += btagSeq # must add to Core, as it's needed by ExtraReco
00129         process.patJetCharge.src                     = btagLabels['jta']
00130         process.allLayer1Jets.trackAssociationSource = btagLabels['jta']
00131         process.allLayer1Jets.tagInfoSources       = cms.VInputTag( *[ cms.InputTag(x) for x in btagLabels['tagInfos'] ] )
00132         process.allLayer1Jets.discriminatorSources = cms.VInputTag( *[ cms.InputTag(x) for x in btagLabels['jetTags']  ] )
00133     else:
00134         process.patAODReco.remove(process.patBTagging)
00135         process.allLayer1Jets.addBTagInfo = False
00136     if doJTA or doBTagging:
00137         if not doBTagging:
00138             process.load("RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi")
00139             from RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi import ic5JetTracksAssociatorAtVertex
00140             process.jetTracksAssociatorAtVertex = ic5JetTracksAssociatorAtVertex.clone(jets = jetCollection)
00141             process.patAODReco.replace(process.patJetTracksCharge, process.jetTracksAssociatorAtVertex + process.patJetTracksCharge)
00142             process.patJetCharge.src                     = 'jetTracksAssociatorAtVertex'
00143             process.allLayer1Jets.trackAssociationSource = 'jetTracksAssociatorAtVertex'
00144     else: ## no JTA
00145         process.patAODReco.remove(process.patJetTracksCharge)
00146         process.allLayer1Jets.addAssociatedTracks = False
00147         process.allLayer1Jets.addJetCharge = False
00148     if jetCorrLabel != None:
00149         if jetCorrLabel == False : raise ValueError, "In switchJetCollection 'jetCorrLabel' must be set to None, not False"
00150         if jetCorrLabel == "None": raise ValueError, "In switchJetCollection 'jetCorrLabel' must be set to None (without quotes), not 'None'"
00151         if type(jetCorrLabel) != type(('IC5','Calo')): 
00152             raise ValueError, "In switchJetCollection 'jetCorrLabel' must be None, or a tuple ('Algo', 'Type')"
00153         if not hasattr( process, 'L2L3JetCorrector%s%s' % jetCorrLabel ):
00154             setattr( process, 
00155                         'L2L3JetCorrector%s%s' % jetCorrLabel, 
00156                         cms.ESSource("JetCorrectionServiceChain",
00157                             correctors = cms.vstring('L2RelativeJetCorrector%s%s' % jetCorrLabel,
00158                                                      'L3AbsoluteJetCorrector%s%s' % jetCorrLabel),
00159                             label      = cms.string('L2L3JetCorrector%s%s' % jetCorrLabel)
00160                         )
00161                     )
00162         switchJECParameters(process.jetCorrFactors, jetCorrLabel[0], jetCorrLabel[1], oldalgo='IC5',oldtype='Calo')
00163         process.jetCorrFactors.jetSource = jetCollection
00164         if doType1MET:
00165             process.corMetType1Icone5.inputUncorJetsLabel = jetCollection.value() # FIXME it's corMetType1Icone5 that's broken
00166             process.corMetType1Icone5.corrector           = 'L2L3JetCorrector%s%s' % jetCorrLabel
00167     else:
00168         process.patJetMETCorrections.remove(process.jetCorrFactors)
00169         process.allLayer1Jets.addJetCorrFactors = False
00170     ## Add this to the summary tables (not strictly needed, but useful)
00171     if oldLabel in process.aodSummary.candidates: 
00172         process.aodSummary.candidates[process.aodSummary.candidates.index(oldLabel)] = jetCollection
00173     else:
00174         process.aodSummary.candidates += [jetCollection]
00175         
00176 
00177 def addJetCollection(process,jetCollection,postfixLabel,
00178                         doJTA=True,doBTagging=True,jetCorrLabel=None,doType1MET=True,doL1Counters=False,
00179                         genJetCollection=cms.InputTag("iterativeCone5GenJets"),doTrigMatch=False):
00180     """Add a new collection of jets in PAT from the default value.
00181           postfixLabel: Postpone this label to the name of all modules that work with these jet collection.
00182                         it can't be an empty string
00183           doBTagging  : True to run the BTagging sequence on top of this jets, and import it into PAT.
00184           doJTA       : Run Jet Tracks Association and Jet Charge (will be forced to True if doBTagging is true)
00185           jetCorrLabel: Name of the algorithm and jet type JEC to pick corrections from, or None for no JEC 
00186                         Examples are ('IC5','Calo'), ('SC7','Calo'), ('KT4','PF')
00187                         It tries to find a 'L2L3JetCorrector' + algo + type , or otherwise to create if as a 
00188                         JetCorrectionServiceChain of 'L2RelativeJetCorrector' and 'L3AbsoluteJetCorrector'
00189           doType1MET  : Make also a new MET (NOT IMPLEMENTED)
00190           doL1Counters: copy also the filter modules that accept/reject the event looking at the number of jets
00191           genJetCollection : GenJet collection to match to.
00192 
00193        Note: This takes the configuration from the already-configured jets, so if you do 
00194              replaces before calling addJetCollection then they will affect also the new jets
00195     """
00196     def addAlso (label,value):
00197         existing = getattr(process, label)
00198         setattr( process, label + postfixLabel, value)
00199         process.patDefaultSequence.replace( existing, existing * value )
00200     def addClone(label,**replaceStatements):
00201         new      = getattr(process, label).clone(**replaceStatements)
00202         addAlso(label, new)
00203     addClone('allLayer1Jets', jetSource = jetCollection, addTrigMatch = doTrigMatch)
00204     l1Jets = getattr(process, 'allLayer1Jets'+postfixLabel)
00205     addClone('selectedLayer1Jets', src=cms.InputTag('allLayer1Jets'+postfixLabel))
00206     addClone('cleanLayer1Jets', src=cms.InputTag('selectedLayer1Jets'+postfixLabel))
00207     if doL1Counters:
00208         addClone('countLayer1Jets', src=cms.InputTag('cleanLayer1Jets'+postfixLabel))
00209     addClone('jetPartonMatch',       src = jetCollection)
00210     addClone('jetGenJetMatch',       src = jetCollection, matched = genJetCollection)
00211     addClone('jetPartonAssociation', jets = jetCollection)
00212     addClone('jetFlavourAssociation',srcByReference = cms.InputTag('jetPartonAssociation' + postfixLabel))
00213     def fixInputTag(x): x.setModuleLabel(x.moduleLabel+postfixLabel)
00214     def fixVInputTag(x): x[0].setModuleLabel(x[0].moduleLabel+postfixLabel)
00215     fixInputTag(l1Jets.JetPartonMapSource)
00216     fixInputTag(l1Jets.genJetMatch)
00217     fixInputTag(l1Jets.genPartonMatch)
00218     triggers = MassSearchParamVisitor('src', process.allLayer1Jets.jetSource)
00219     process.patTrigMatch.visit(triggers)
00220     for mod in triggers.modules():
00221         if doTrigMatch:
00222             newmod = mod.clone(src = jetCollection)
00223             setattr( process, mod.label() + postfixLabel, newmod )
00224             process.patTrigMatch.replace( mod, mod * newmod )
00225     for it in l1Jets.trigPrimMatch.value(): fixInputTag(it)
00226     def vit(*args) : return cms.VInputTag( *[ cms.InputTag(x) for x in args ] )
00227     if doBTagging :
00228         (btagSeq, btagLabels) = runBTagging(process, jetCollection, postfixLabel)
00229         process.patAODCoreReco += btagSeq  # must add to Core, as it's needed by Extra
00230         addClone('patJetCharge', src=cms.InputTag(btagLabels['jta']))
00231         l1Jets.trackAssociationSource = cms.InputTag(btagLabels['jta'])
00232         l1Jets.tagInfoSources         = cms.VInputTag( *[ cms.InputTag(x) for x in btagLabels['tagInfos'] ] )
00233         l1Jets.discriminatorSources   = cms.VInputTag( *[ cms.InputTag(x) for x in btagLabels['jetTags']  ] )
00234         fixInputTag(l1Jets.jetChargeSource)
00235     else:
00236        l1Jets.addBTagInfo = False 
00237     if doJTA or doBTagging:
00238         if not doBTagging:
00239             process.load("RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi")
00240             from RecoJets.JetAssociationProducers.ic5JetTracksAssociatorAtVertex_cfi import ic5JetTracksAssociatorAtVertex
00241             jtaLabel = 'jetTracksAssociatorAtVertex' + postfixLabel
00242             setattr( process, jtaLabel, ic5JetTracksAssociatorAtVertex.clone(jets = jetCollection) )
00243             process.patAODReco.replace(process.patJetTracksCharge, getattr(process,jtaLabel) + process.patJetTracksCharge)
00244             l1Jets.trackAssociationSource = cms.InputTag(jtaLabel)
00245             addClone('patJetCharge', src=cms.InputTag(jtaLabel)),
00246             fixInputTag(l1Jets.jetChargeSource)
00247     else: ## no JTA
00248         l1Jets.addAssociatedTracks = False
00249         l1Jets.addJetCharge = False
00250     if jetCorrLabel != None:
00251         if jetCorrLabel == False : raise ValueError, "In addJetCollection 'jetCorrLabel' must be set to None, not False"
00252         if jetCorrLabel == "None": raise ValueError, "In addJetCollection 'jetCorrLabel' must be set to None (without quotes), not 'None'"
00253         if type(jetCorrLabel) != type(('IC5','Calo')): 
00254             raise ValueError, "In switchJetCollection 'jetCorrLabel' must be None, or a tuple ('Algo', 'Type')"
00255         if not hasattr( process, 'L2L3JetCorrector%s%s' % jetCorrLabel ):
00256             setattr( process, 
00257                         'L2L3JetCorrector%s%s' % jetCorrLabel, 
00258                         cms.ESSource("JetCorrectionServiceChain",
00259                             correctors = cms.vstring('L2RelativeJetCorrector%s%s' % jetCorrLabel,
00260                                                      'L3AbsoluteJetCorrector%s%s' % jetCorrLabel),
00261                             label      = cms.string('L2L3JetCorrector%s%s' % jetCorrLabel)
00262                         )
00263                     )
00264         addClone('jetCorrFactors',       jetSource           = jetCollection, 
00265                                          defaultJetCorrector = cms.string('L2L3JetCorrector%s%s' % jetCorrLabel))
00266         switchJECParameters( getattr(process,'jetCorrFactors'+postfixLabel), jetCorrLabel[0], jetCorrLabel[1], oldalgo='IC5',oldtype='Calo' )
00267         fixVInputTag(l1Jets.jetCorrFactorsSource)
00268         if doType1MET:
00269             addClone('corMetType1Icone5', inputUncorJetsLabel = jetCollection.value(),
00270                                           corrector = cms.string('L2L3JetCorrector%s%s' % jetCorrLabel))
00271             addClone('corMetType1Icone5Muons', uncorMETInputTag = cms.InputTag("corMetType1Icone5"+postfixLabel))
00272             addClone('layer1METs',              metSource = cms.InputTag("corMetType1Icone5Muons"+postfixLabel), addTrigMatch = doTrigMatch)
00273             l1MET = getattr(process, 'layer1METs'+postfixLabel)
00274             mettriggers = MassSearchParamVisitor('src', process.layer1METs.metSource)
00275             process.patTrigMatch.visit(mettriggers)
00276             for mod in mettriggers.modules():
00277                 if doTrigMatch:
00278                     newmod = mod.clone(src = l1MET.metSource)
00279                     setattr( process, mod.label() + postfixLabel, newmod )
00280                     process.patTrigMatch.replace( mod, mod * newmod )
00281             for it in l1MET.trigPrimMatch.value(): fixInputTag(it)
00282             process.allLayer1Summary.candidates += [ cms.InputTag('layer1METs'+postfixLabel) ]
00283     else:
00284         l1Jets.addJetCorrFactors = False
00285     ## Add this to the summary tables (not strictly needed, but useful)
00286     if jetCollection not in process.aodSummary.candidates: 
00287         process.aodSummary.candidates += [ jetCollection ]
00288     process.allLayer1Summary.candidates      += [ cms.InputTag('allLayer1Jets'+postfixLabel) ]
00289     process.selectedLayer1Summary.candidates += [ cms.InputTag('selectedLayer1Jets'+postfixLabel) ]

Generated on Tue Jun 9 17:41:44 2009 for CMSSW by  doxygen 1.5.4