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
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
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
00052 def vit(*args) : return cms.VInputTag( *[ cms.InputTag(x) for x in args ] )
00053
00054
00055 jtaLabel = 'jetTracksAssociatorAtVertex' + label
00056 ipTILabel = 'impactParameterTagInfos' + label
00057 svTILabel = 'secondaryVertexTagInfos' + label
00058 seTILabel = 'softElectronTagInfos' + label
00059 smTILabel = 'softMuonTagInfos' + label
00060
00061
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
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
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:
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()
00166 process.corMetType1Icone5.corrector = 'L2L3JetCorrector%s%s' % jetCorrLabel
00167 else:
00168 process.patJetMETCorrections.remove(process.jetCorrFactors)
00169 process.allLayer1Jets.addJetCorrFactors = False
00170
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
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:
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
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) ]