Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-16 23:01:10

0001 from __future__ import print_function
0002 from PhysicsTools.PatAlgos.tools.ConfigToolBase import *
0003 from FWCore.ParameterSet.Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable,  _Unlabelable,  _ValidatingListBase
0004 from FWCore.ParameterSet.SequenceTypes import _ModuleSequenceType, _Sequenceable
0005 from FWCore.ParameterSet.SequenceTypes import *
0006 from PhysicsTools.PatAlgos.tools.helpers import *
0007 from PhysicsTools.PatAlgos.recoLayer0.bTagging_cff import *
0008 import sys
0009 from FWCore.ParameterSet.MassReplace import MassSearchReplaceAnyInputTagVisitor
0010 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiCentralTagInfos,pfParticleNetFromMiniAODAK4PuppiCentralJetTags,pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags,pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags
0011 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiForwardTagInfos,pfParticleNetFromMiniAODAK4PuppiForwardJetTags,pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags
0012 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSCentralTagInfos,pfParticleNetFromMiniAODAK4CHSCentralJetTags,pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags,pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags
0013 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSForwardTagInfos,pfParticleNetFromMiniAODAK4CHSForwardJetTags,pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags
0014 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import pfParticleNetFromMiniAODAK8TagInfos,pfParticleNetFromMiniAODAK8JetTags,pfParticleNetFromMiniAODAK8DiscriminatorsJetTags
0015 
0016 ## dictionary with supported jet clustering algorithms
0017 supportedJetAlgos = {
0018    'ak' : 'AntiKt'
0019  , 'ca' : 'CambridgeAachen'
0020  , 'kt' : 'Kt'
0021 }
0022 
0023 def checkJetCorrectionsFormat(jetCorrections):
0024     ## check for the correct format
0025     if not isinstance(jetCorrections, type(('PAYLOAD-LABEL',['CORRECTION-LEVEL-A','CORRECTION-LEVEL-B'], 'MET-LABEL'))):
0026         raise ValueError("In addJetCollection: 'jetCorrections' must be 'None' (as a python value w/o quotation marks), or of type ('PAYLOAD-LABEL', ['CORRECTION-LEVEL-A', \
0027         'CORRECTION-LEVEL-B', ...], 'MET-LABEL'). Note that 'MET-LABEL' can be set to 'None' (as a string in quotation marks) in case you do not want to apply MET(Type1) \
0028         corrections.")
0029 
0030 
0031 def setupJetCorrections(process, knownModules, jetCorrections, jetSource, pvSource, patJets, labelName, postfix):
0032 
0033     task = getPatAlgosToolsTask(process)
0034 
0035     ## determine type of jet constituents from jetSource; supported
0036     ## jet constituent types are calo, pf, jpt, for pf also particleflow
0037     ## is aloowed as part of the jetSource label, which might be used
0038     ## in CommonTools.ParticleFlow
0039     _type="NONE"
0040     if jetCorrections[0].count('PF')>0:
0041         _type='PF'
0042     elif jetCorrections[0].count('Calo')>0:
0043         _type='Calo'
0044     elif jetCorrections[0].count('JPT')>0:
0045         _type='JPT'
0046     else:
0047         raise TypeError("In addJetCollection: Jet energy corrections are only supported for PF, JPT and Calo jets.")
0048     from PhysicsTools.PatAlgos.recoLayer0.jetCorrFactors_cfi import patJetCorrFactors
0049     if 'patJetCorrFactors'+labelName+postfix in knownModules :
0050         _newPatJetCorrFactors=getattr(process, 'patJetCorrFactors'+labelName+postfix)
0051         _newPatJetCorrFactors.src=jetSource
0052         _newPatJetCorrFactors.primaryVertices=pvSource
0053     else:
0054         addToProcessAndTask('patJetCorrFactors'+labelName+postfix,
0055                             patJetCorrFactors.clone(src=jetSource, primaryVertices=pvSource),
0056                             process, task)
0057         _newPatJetCorrFactors=getattr(process, "patJetCorrFactors"+labelName+postfix)
0058     _newPatJetCorrFactors.payload=jetCorrections[0]
0059     _newPatJetCorrFactors.levels=jetCorrections[1]
0060     ## check whether L1Offset or L1FastJet is part of levels
0061     error=False
0062     for x in jetCorrections[1]:
0063         if x == 'L1Offset' :
0064             if not error :
0065                 _newPatJetCorrFactors.useNPV=True
0066                 _newPatJetCorrFactors.primaryVertices='offlinePrimaryVertices'
0067                 _newPatJetCorrFactors.useRho=False
0068                 ## we set this to True now as a L1 correction type should appear only once
0069                 ## otherwise levels is miss configured
0070                 error=True
0071             else:
0072                 raise ValueError("In addJetCollection: Correction levels for jet energy corrections are miss configured. An L1 correction type should appear not more than \
0073                 once. Check the list of correction levels you requested to be applied: "+ jetCorrections[1])
0074         if x == 'L1FastJet' :
0075             if not error :
0076                 if _type == "JPT" :
0077                     raise TypeError("In addJetCollection: L1FastJet corrections are only supported for PF and Calo jets.")
0078                 ## configure module
0079                 _newPatJetCorrFactors.useRho=True
0080                 if "PF" in _type :
0081                     _newPatJetCorrFactors.rho=cms.InputTag('fixedGridRhoFastjetAll')
0082                 else :
0083                     _newPatJetCorrFactors.rho=cms.InputTag('fixedGridRhoFastjetAllCalo')
0084                 ## we set this to True now as a L1 correction type should appear only once
0085                 ## otherwise levels is miss configured
0086                 error=True
0087             else:
0088                 raise ValueError("In addJetCollection: Correction levels for jet energy corrections are miss configured. An L1 correction type should appear not more than \
0089                 once. Check the list of correction levels you requested to be applied: "+ jetCorrections[1])
0090     patJets.jetCorrFactorsSource=cms.VInputTag(cms.InputTag('patJetCorrFactors'+labelName+postfix))
0091     ## configure MET(Type1) corrections
0092     if jetCorrections[2].lower() != 'none' and jetCorrections[2] != '':
0093         if not jetCorrections[2].lower() == 'type-1' and not jetCorrections[2].lower() == 'type-2':
0094             raise ValueError("In addJetCollection: Wrong choice of MET corrections for new jet collection. Possible choices are None (or empty string), Type-1, Type-2 (i.e.\
0095             Type-1 and Type-2 corrections applied). This choice is not case sensitive. Your choice was: "+ jetCorrections[2])
0096         if _type == "JPT":
0097             raise ValueError("In addJecCollection: MET(type1) corrections are not supported for JPTJets. Please set the MET-LABEL to \"None\" (as string in quatiation \
0098             marks) and use raw tcMET together with JPTJets.")
0099         ## set up jet correctors for MET corrections
0100         process.load( "JetMETCorrections.Configuration.JetCorrectorsAllAlgos_cff") # FIXME: This adds a lot of garbage
0101         # I second the FIXME comment on the last line. When I counted it, this brought in 344 EDProducers
0102         # to be available to run unscheduled. All jet correctors, probably some small fraction of which
0103         # are actually used.
0104         task.add(process.jetCorrectorsAllAlgosTask)
0105         _payloadType = jetCorrections[0].split(_type)[0].lower()+_type
0106         if "PF" in _type :
0107             addToProcessAndTask(jetCorrections[0]+'L1FastJet',
0108                                 getattr(process, _payloadType+'L1FastjetCorrector').clone(srcRho=cms.InputTag('fixedGridRhoFastjetAll')),
0109                                 process, task)
0110         else :
0111             addToProcessAndTask(jetCorrections[0]+'L1FastJet',
0112                                 getattr(process, _payloadType+'L1FastjetCorrector').clone(srcRho=cms.InputTag('fixedGridRhoFastjetAllCalo')),
0113                                 process, task)
0114         addToProcessAndTask(jetCorrections[0]+'L1Offset', getattr(process, _payloadType+'L1OffsetCorrector').clone(), process, task)
0115         addToProcessAndTask(jetCorrections[0]+'L2Relative', getattr(process, _payloadType+'L2RelativeCorrector').clone(), process, task)
0116         addToProcessAndTask(jetCorrections[0]+'L3Absolute', getattr(process, _payloadType+'L3AbsoluteCorrector').clone(), process, task)
0117         addToProcessAndTask(jetCorrections[0]+'L2L3Residual', getattr(process, _payloadType+'ResidualCorrector').clone(), process, task)
0118         addToProcessAndTask(jetCorrections[0]+'CombinedCorrector',
0119                             cms.EDProducer( 'ChainedJetCorrectorProducer', correctors = cms.VInputTag()),
0120                             process, task)
0121         for x in jetCorrections[1]:
0122             if x != 'L1FastJet' and x != 'L1Offset' and x != 'L2Relative' and x != 'L3Absolute' and x != 'L2L3Residual':
0123                 raise ValueError('In addJetCollection: Unsupported JEC for MET(Type1). Currently supported jet correction levels are L1FastJet, L1Offset, L2Relative, L3Asolute, L2L3Residual. Requested was: %s'%(x))
0124             else:
0125                 _corrector = _payloadType
0126                 if x == 'L1FastJet':
0127                   _corrector += 'L1Fastjet'
0128                 elif x  == 'L2L3Residual':
0129                   _corrector += 'Residual'
0130                 else:
0131                   _corrector += x
0132                 _corrector += 'Corrector'
0133                 getattr(process, jetCorrections[0]+'CombinedCorrector').correctors.append(cms.InputTag(_corrector))
0134 
0135         ## set up MET(Type1) correction modules
0136         _labelCorrName = labelName
0137         if labelName != '':
0138             _labelCorrName = 'For' + labelName
0139         if _type == 'Calo':
0140             from JetMETCorrections.Type1MET.correctionTermsCaloMet_cff import corrCaloMetType1
0141             from JetMETCorrections.Type1MET.correctionTermsCaloMet_cff import corrCaloMetType2
0142             from JetMETCorrections.Type1MET.correctedMet_cff import caloMetT1
0143             from JetMETCorrections.Type1MET.correctedMet_cff import caloMetT1T2
0144             addToProcessAndTask(
0145                 jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix,
0146                 corrCaloMetType1.clone(src=jetSource,srcMET = "caloMetM",jetCorrLabel = cms.InputTag(jetCorrections[0]+'CombinedCorrector')),
0147                 process, task)
0148             addToProcessAndTask(
0149                 jetCorrections[0]+_labelCorrName+'JetMETcorr2'+postfix,
0150                 corrCaloMetType2.clone(srcUnclEnergySums = cms.VInputTag(
0151                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type2'),
0152                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'offset'),
0153                     cms.InputTag('muCaloMetCorr'))),
0154                 process, task)
0155             addToProcessAndTask(
0156                 jetCorrections[0]+_labelCorrName+'Type1CorMet'+postfix,
0157                 caloMetT1.clone(src = "caloMetM", srcCorrections = cms.VInputTag(
0158                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type1'))),
0159                 process, task)
0160             addToProcessAndTask(jetCorrections[0]+_labelCorrName+'Type1p2CorMet'+postfix,
0161                                 caloMetT1T2.clone(src = "caloMetM", srcCorrections = cms.VInputTag(
0162                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type1'),
0163                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr2'+postfix))),
0164                                 process, task)
0165         elif _type == 'PF':
0166             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import pfJetsPtrForMetCorr
0167             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import pfCandsNotInJetsPtrForMetCorr
0168             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import pfCandsNotInJetsForMetCorr
0169             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import pfCandMETcorr
0170             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import corrPfMetType1
0171             from JetMETCorrections.Type1MET.correctionTermsPfMetType1Type2_cff import corrPfMetType2
0172             from JetMETCorrections.Type1MET.correctedMet_cff import pfMetT1
0173             from JetMETCorrections.Type1MET.correctedMet_cff import pfMetT1T2
0174             addToProcessAndTask(jetCorrections[0]+_labelCorrName+'pfJetsPtrForMetCorr'+postfix,
0175                                 pfJetsPtrForMetCorr.clone(src = jetSource), process, task)
0176             addToProcessAndTask(
0177                 jetCorrections[0]+_labelCorrName+'pfCandsNotInJetsPtrForMetCorr'+postfix,
0178                 pfCandsNotInJetsPtrForMetCorr.clone(topCollection = jetCorrections[0]+_labelCorrName+'pfJetsPtrForMetCorr'+postfix),
0179                 process, task)
0180             addToProcessAndTask(
0181                 jetCorrections[0]+_labelCorrName+'pfCandsNotInJetsForMetCorr'+postfix,
0182                 pfCandsNotInJetsForMetCorr.clone(src = jetCorrections[0]+_labelCorrName+'pfCandsNotInJetsPtrForMetCorr'+postfix),
0183                 process, task)
0184             addToProcessAndTask(
0185                 jetCorrections[0]+_labelCorrName+'CandMETcorr'+postfix,
0186                 pfCandMETcorr.clone(src = cms.InputTag(jetCorrections[0]+_labelCorrName+'pfCandsNotInJetsForMetCorr'+postfix)),
0187                 process, task)
0188             addToProcessAndTask(
0189                 jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix,
0190                 corrPfMetType1.clone(src = jetSource, jetCorrLabel = cms.InputTag(jetCorrections[0]+'CombinedCorrector')),
0191                 process, task) # FIXME: Originally w/o jet corrections?
0192             addToProcessAndTask(jetCorrections[0]+_labelCorrName+'corrPfMetType2'+postfix,
0193                                 corrPfMetType2.clone(srcUnclEnergySums = cms.VInputTag(
0194                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type2'),
0195                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'offset'),
0196                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'CandMETcorr'+postfix))),
0197                                 process, task)
0198             addToProcessAndTask(jetCorrections[0]+_labelCorrName+'Type1CorMet'+postfix,
0199                                 pfMetT1.clone(srcCorrections = cms.VInputTag(
0200                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type1'))),
0201                                 process, task)
0202             addToProcessAndTask(jetCorrections[0]+_labelCorrName+'Type1p2CorMet'+postfix,
0203                                 pfMetT1T2.clone(srcCorrections = cms.VInputTag(
0204                                     cms.InputTag(jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix, 'type1'),
0205                                     jetCorrections[0]+_labelCorrName+'corrPfMetType2'+postfix)),
0206                                 process, task)
0207             if 'Puppi' in jetSource.value() and pfCandidates.value() == 'particleFlow':
0208                 getattr(process,jetCorrections[0]+_labelCorrName+'CandMETcorr'+postfix).srcWeights = "puppiNoLep"
0209 
0210         ## common configuration for Calo and PF
0211         if ('L1FastJet' in jetCorrections[1] or 'L1Fastjet' in jetCorrections[1]):
0212             getattr(process,jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix).offsetCorrLabel = cms.InputTag(jetCorrections[0]+'L1FastJet')
0213         #FIXME: What is wrong here?
0214         #elif ('L1Offset' in jetCorrections[1]):
0215             #getattr(process,jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix).offsetCorrLabel = cms.InputTag(jetCorrections[0]+'L1Offset')
0216         else:
0217             getattr(process,jetCorrections[0]+_labelCorrName+'JetMETcorr'+postfix).offsetCorrLabel = cms.InputTag('')
0218 
0219         from PhysicsTools.PatAlgos.producersLayer1.metProducer_cfi import patMETs
0220         if jetCorrections[2].lower() == 'type-1':
0221             addToProcessAndTask('patMETs'+labelName+postfix,
0222                                 patMETs.clone(metSource = cms.InputTag(jetCorrections[0]+_labelCorrName+'Type1CorMet'+postfix),
0223                                               addMuonCorrections = False),
0224                                 process, task)
0225         elif jetCorrections[2].lower() == 'type-2':
0226             addToProcessAndTask('patMETs'+labelName+postfix,
0227                                 patMETs.clone(metSource = cms.InputTag(jetCorrections[0]+_labelCorrName+'Type1p2CorMet'+postfix),
0228                                               addMuonCorrections = False),
0229                                 process, task)
0230 
0231 
0232 def setupSVClustering(btagInfo, svClustering, algo, rParam, fatJets=cms.InputTag(''), groomedFatJets=cms.InputTag('')):
0233     btagInfo.useSVClustering = cms.bool(svClustering)
0234     btagInfo.jetAlgorithm = cms.string(algo)
0235     btagInfo.rParam = cms.double(rParam)
0236     ## if the jet is actually a subjet
0237     if fatJets != cms.InputTag(''):
0238         btagInfo.fatJets = fatJets
0239         if groomedFatJets != cms.InputTag(''):
0240             btagInfo.groomedFatJets = groomedFatJets
0241 
0242 def setupPuppiForPackedPF(process, useExistingWeights=True, postfix=''):
0243     """
0244     Setup puppi weights
0245     Two instances of PuppiProducer:
0246     - packedpuppi (for jet reclustering)
0247     - packedpuppiNoLep (for MET reclustering)
0248     """
0249     from CommonTools.PileupAlgos.Puppi_cff import puppi
0250     task = getPatAlgosToolsTask(process)
0251 
0252     puppiLabel = 'packedpuppi'+postfix
0253 
0254     ## Instantiate PuppiProducer with "puppiLabel"
0255     ## if it does not exist.
0256     if not hasattr(process, puppiLabel):
0257         addToProcessAndTask(puppiLabel, puppi.clone(
0258             useExistingWeights = useExistingWeights,
0259             candName = 'packedPFCandidates',
0260             vertexName = 'offlineSlimmedPrimaryVertices'), process, task)
0261 
0262     puppiNoLepLabel = puppiLabel+'NoLep'
0263 
0264     if hasattr(process, puppiLabel) and not hasattr(process, puppiNoLepLabel):
0265         addToProcessAndTask(puppiNoLepLabel, getattr(process, puppiLabel).clone(
0266             puppiNoLep = True), process, task)
0267 
0268     return puppiLabel, puppiNoLepLabel
0269 
0270 def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
0271                   algo, rParam, btagDiscriminators, btagInfos, patJets, labelName, btagPrefix, postfix):
0272 
0273     task = getPatAlgosToolsTask(process)
0274 
0275     ## expand the btagDiscriminators to remove the meta taggers and substitute the equivalent sources
0276     discriminators = set(btagDiscriminators)
0277     present_metaSet = discriminators.intersection(set(supportedMetaDiscr.keys()))
0278     discriminators -= present_metaSet
0279     for meta_tagger in present_metaSet:
0280         for src in supportedMetaDiscr[meta_tagger]:
0281             discriminators.add(src)
0282     present_meta = sorted(present_metaSet)
0283     btagDiscriminators = sorted(discriminators)
0284 
0285     ## expand tagInfos to what is explicitly required by user + implicit
0286     ## requirements that come in from one or the other discriminator
0287     requiredTagInfos = list(btagInfos)
0288     for btagDiscr in btagDiscriminators :
0289         for tagInfoList in supportedBtagDiscr[btagDiscr] :
0290             for requiredTagInfo in tagInfoList :
0291                 tagInfoCovered = False
0292                 for tagInfo in requiredTagInfos :
0293                     if requiredTagInfo == tagInfo :
0294                         tagInfoCovered = True
0295                         break
0296                 if not tagInfoCovered :
0297                     requiredTagInfos.append(requiredTagInfo)
0298     ## load sequences and setups needed for btagging
0299     if hasattr( process, 'candidateJetProbabilityComputer' ) == False :
0300         if loadStdRecoBTag: # also loading modules already run in the standard reconstruction
0301             process.load("RecoBTag.ImpactParameter.impactParameter_cff")
0302             task.add(process.impactParameterTask)
0303             process.load("RecoBTag.SecondaryVertex.secondaryVertex_cff")
0304             task.add(process.secondaryVertexTask)
0305             process.load("RecoBTag.SoftLepton.softLepton_cff")
0306             task.add(process.softLeptonTask)
0307             process.load("RecoBTag.Combined.combinedMVA_cff")
0308             task.add(process.combinedMVATask)
0309             process.load("RecoBTag.CTagging.cTagging_cff")
0310             task.add(process.cTaggingTask)
0311         else: # to prevent loading of modules already run in the standard reconstruction
0312             process.load("RecoBTag.ImpactParameter.impactParameter_EventSetup_cff")
0313             process.load("RecoBTag.SecondaryVertex.secondaryVertex_EventSetup_cff")
0314             process.load("RecoBTag.SoftLepton.softLepton_EventSetup_cff")
0315             process.load("RecoBTag.Combined.combinedMVA_EventSetup_cff")
0316             process.load("RecoBTag.CTagging.cTagging_EventSetup_cff")
0317     import RecoBTag.Configuration.RecoBTag_cff as btag
0318     import RecoJets.JetProducers.caTopTaggers_cff as toptag
0319 
0320     if tightBTagNTkHits:
0321         if not runIVF:
0322             sys.stderr.write("-------------------------------------------------------------------\n")
0323             sys.stderr.write(" Warning: For a complete switch to the legacy tight b-tag track\n")
0324             sys.stderr.write("          selection, please also enable the \'runIVF\' switch.\n")
0325             sys.stderr.write("-------------------------------------------------------------------\n")
0326         if btagPrefix == '':
0327             sys.stderr.write("-------------------------------------------------------------------\n")
0328             sys.stderr.write(" Warning: With the tight b-tag track selection enabled, it is\n")
0329             sys.stderr.write("          advisable to set \'btagPrefix\' to a non-empty string to\n")
0330             sys.stderr.write("          avoid unintentional modifications to the default\n")
0331             sys.stderr.write("          b tagging setup that might be loaded in the same job.\n")
0332             sys.stderr.write("-------------------------------------------------------------------\n")
0333 
0334     ## define c tagging CvsL SV source (for now tied to the default SV source
0335     ## in the first part of the module label, product instance label and process name)
0336     svSourceCvsL = copy.deepcopy(svSource)
0337     svSourceCvsL.setModuleLabel(svSource.getModuleLabel()+'CvsL')
0338 
0339     ## check if and under what conditions to re-run IVF
0340     runIVFforCTagOnly = False
0341     ivfcTagInfos = ['pfInclusiveSecondaryVertexFinderCvsLTagInfos', 'pfInclusiveSecondaryVertexFinderNegativeCvsLTagInfos']
0342     ## if MiniAOD and running c tagging
0343     if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices' and any(i in requiredTagInfos for i in ivfcTagInfos) and not runIVF:
0344         runIVFforCTagOnly = True
0345         runIVF = True
0346         sys.stderr.write("-------------------------------------------------------------------\n")
0347         sys.stderr.write(" Info: To run c tagging on MiniAOD, c-tag-specific IVF secondary\n")
0348         sys.stderr.write("       vertices will be remade.\n")
0349         sys.stderr.write("-------------------------------------------------------------------\n")
0350     ## adjust svSources
0351     if runIVF and btagPrefix != '':
0352         if runIVFforCTagOnly:
0353             svSourceCvsL.setModuleLabel(btagPrefix+svSourceCvsL.getModuleLabel())
0354         else:
0355             svSource.setModuleLabel(btagPrefix+svSource.getModuleLabel())
0356             svSourceCvsL.setModuleLabel(btagPrefix+svSourceCvsL.getModuleLabel())
0357 
0358     ## setup all required btagInfos : we give a dedicated treatment for different
0359     ## types of tagInfos here. A common treatment is possible but might require a more
0360     ## general approach anyway in coordination with the btagging POG.
0361 
0362     runNegativeVertexing = False
0363     runNegativeCvsLVertexing = False
0364     for btagInfo in requiredTagInfos:
0365         if btagInfo in (
0366             'pfInclusiveSecondaryVertexFinderNegativeTagInfos',
0367             'pfNegativeDeepFlavourTagInfos',
0368             'pfNegativeParticleNetAK4TagInfos',
0369             ):
0370             runNegativeVertexing = True
0371         if btagInfo == 'pfInclusiveSecondaryVertexFinderNegativeCvsLTagInfos':
0372             runNegativeCvsLVertexing = True
0373             
0374     if runNegativeVertexing or runNegativeCvsLVertexing:
0375         import RecoVertex.AdaptiveVertexFinder.inclusiveNegativeVertexing_cff as NegVertex
0376 
0377     if runNegativeVertexing:                
0378         addToProcessAndTask(btagPrefix+'inclusiveCandidateNegativeVertexFinder'+labelName+postfix,
0379                             NegVertex.inclusiveCandidateNegativeVertexFinder.clone(primaryVertices = pvSource,tracks=pfCandidates),
0380                             process, task)
0381         addToProcessAndTask(btagPrefix+'candidateNegativeVertexMerger'+labelName+postfix,
0382                             NegVertex.candidateNegativeVertexMerger.clone(secondaryVertices = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeVertexFinder'+labelName+postfix)),
0383                             process, task)
0384         addToProcessAndTask(btagPrefix+'candidateNegativeVertexArbitrator'+labelName+postfix,
0385                             NegVertex.candidateNegativeVertexArbitrator.clone( secondaryVertices = cms.InputTag(btagPrefix+'candidateNegativeVertexMerger'+labelName+postfix)
0386                                                                                ,primaryVertices = pvSource
0387                                                                                ,tracks=pfCandidates),
0388                             process, task)
0389         addToProcessAndTask(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix,
0390                             NegVertex.inclusiveCandidateNegativeSecondaryVertices.clone(secondaryVertices = cms.InputTag(btagPrefix+'candidateNegativeVertexArbitrator'+labelName+postfix)),
0391                             process, task)
0392 
0393     if runNegativeCvsLVertexing:
0394         addToProcessAndTask(btagPrefix+'inclusiveCandidateNegativeVertexFinderCvsL'+labelName+postfix,
0395                             NegVertex.inclusiveCandidateNegativeVertexFinderCvsL.clone(primaryVertices = pvSource,tracks=pfCandidates),
0396                             process, task)
0397         addToProcessAndTask(btagPrefix+'candidateNegativeVertexMergerCvsL'+labelName+postfix,
0398                             NegVertex.candidateNegativeVertexMergerCvsL.clone(secondaryVertices = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeVertexFinderCvsL'+labelName+postfix)),
0399                             process, task)
0400         addToProcessAndTask(btagPrefix+'candidateNegativeVertexArbitratorCvsL'+labelName+postfix,
0401                             NegVertex.candidateNegativeVertexArbitratorCvsL.clone( secondaryVertices = cms.InputTag(btagPrefix+'candidateNegativeVertexMergerCvsL'+labelName+postfix)
0402                                                                                ,primaryVertices = pvSource
0403                                                                                ,tracks=pfCandidates),
0404                             process, task)
0405         addToProcessAndTask(btagPrefix+'inclusiveCandidateNegativeSecondaryVerticesCvsL'+labelName+postfix,
0406                             NegVertex.inclusiveCandidateNegativeSecondaryVerticesCvsL.clone(secondaryVertices = cms.InputTag(btagPrefix+'candidateNegativeVertexArbitratorCvsL'+labelName+postfix)),
0407                             process, task)
0408 
0409 
0410     acceptedTagInfos = list()
0411     for btagInfo in requiredTagInfos:
0412         if hasattr(btag,btagInfo):
0413             if btagInfo == 'pfImpactParameterTagInfos':
0414                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0415                                     btag.pfImpactParameterTagInfos.clone(jets = jetSource,primaryVertex=pvSource,candidates=pfCandidates),
0416                                     process, task)
0417                 if explicitJTA:
0418                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0419                     _btagInfo.explicitJTA = cms.bool(explicitJTA)
0420                 if tightBTagNTkHits:
0421                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0422                     _btagInfo.minimumNumberOfPixelHits = cms.int32(2)
0423                     _btagInfo.minimumNumberOfHits = cms.int32(8)
0424             if btagInfo == 'pfImpactParameterAK8TagInfos':
0425                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0426                                     btag.pfImpactParameterAK8TagInfos.clone(jets = jetSource,primaryVertex=pvSource,candidates=pfCandidates),
0427                                     process, task)
0428                 if explicitJTA:
0429                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0430                     _btagInfo.explicitJTA = cms.bool(explicitJTA)
0431                 if tightBTagNTkHits:
0432                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0433                     _btagInfo.minimumNumberOfPixelHits = cms.int32(2)
0434                     _btagInfo.minimumNumberOfHits = cms.int32(8)
0435             if btagInfo == 'pfImpactParameterCA15TagInfos':
0436                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0437                                     btag.pfImpactParameterCA15TagInfos.clone(jets = jetSource,primaryVertex=pvSource,candidates=pfCandidates),
0438                                     process, task)
0439                 if explicitJTA:
0440                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0441                     _btagInfo.explicitJTA = cms.bool(explicitJTA)
0442                 if tightBTagNTkHits:
0443                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0444                     _btagInfo.minimumNumberOfPixelHits = cms.int32(2)
0445                     _btagInfo.minimumNumberOfHits = cms.int32(8)
0446             if btagInfo == 'pfSecondaryVertexTagInfos':
0447                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0448                                     btag.pfSecondaryVertexTagInfos.clone(
0449                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix)),
0450                                     process, task)
0451                 if tightBTagNTkHits:
0452                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0453                     _btagInfo.trackSelection.pixelHitsMin = cms.uint32(2)
0454                     _btagInfo.trackSelection.totalHitsMin = cms.uint32(8)
0455             if btagInfo == 'pfDeepCSVTagInfos':
0456                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0457                                     btag.pfDeepCSVTagInfos.clone(
0458                                         svTagInfos = cms.InputTag(btagPrefix+'pfInclusiveSecondaryVertexFinderTagInfos'+labelName+postfix)),
0459                                     process, task)
0460                 if svClustering or fatJets != cms.InputTag(''):
0461                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0462             if btagInfo == 'pfDeepCSVNegativeTagInfos':
0463                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0464                                     btag.pfDeepCSVNegativeTagInfos.clone(
0465                                         svTagInfos = cms.InputTag(btagPrefix+'pfInclusiveSecondaryVertexFinderNegativeTagInfos'+labelName+postfix)),
0466                                     process, task)
0467                 if svClustering or fatJets != cms.InputTag(''):
0468                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0469             if btagInfo == 'pfDeepCSVPositiveTagInfos':
0470                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0471                                     btag.pfDeepCSVPositiveTagInfos.clone(
0472                                         svTagInfos = cms.InputTag(btagPrefix+'pfInclusiveSecondaryVertexFinderTagInfos'+labelName+postfix)),
0473                                     process, task)
0474                 if svClustering or fatJets != cms.InputTag(''):
0475                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0476             if btagInfo == 'pfDeepCMVATagInfos':
0477                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0478                                     btag.pfDeepCMVATagInfos.clone(
0479                                         deepNNTagInfos = cms.InputTag(btagPrefix+'pfDeepCSVTagInfos'+labelName+postfix),
0480                                         ipInfoSrc = cms.InputTag(btagPrefix+"pfImpactParameterTagInfos"+labelName+postfix),
0481                                         muInfoSrc = cms.InputTag(btagPrefix+"softPFMuonsTagInfos"+labelName+postfix),
0482                                         elInfoSrc = cms.InputTag(btagPrefix+"softPFElectronsTagInfos"+labelName+postfix)),
0483                                     process, task)
0484                 if svClustering or fatJets != cms.InputTag(''):
0485                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0486             if btagInfo == 'pfDeepCMVANegativeTagInfos':
0487                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0488                                     btag.pfDeepCMVATagInfos.clone(
0489                                         deepNNTagInfos = cms.InputTag(btagPrefix+'pfDeepCSVTagInfos'+labelName+postfix),
0490                                         ipInfoSrc = cms.InputTag(btagPrefix+"pfImpactParameterTagInfos"+labelName+postfix),
0491                                         muInfoSrc = cms.InputTag(btagPrefix+"softPFMuonsTagInfos"+labelName+postfix),
0492                                         elInfoSrc = cms.InputTag(btagPrefix+"softPFElectronsTagInfos"+labelName+postfix)),
0493                                     process, task)
0494                 if svClustering or fatJets != cms.InputTag(''):
0495                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0496             if btagInfo == 'pfDeepCMVAPositiveTagInfos':
0497                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0498                                     btag.pfDeepCMVATagInfos.clone(
0499                                         deepNNTagInfos = cms.InputTag(btagPrefix+'pfDeepCSVTagInfos'+labelName+postfix),
0500                                         ipInfoSrc = cms.InputTag(btagPrefix+"pfImpactParameterTagInfos"+labelName+postfix),
0501                                         muInfoSrc = cms.InputTag(btagPrefix+"softPFMuonsTagInfos"+labelName+postfix),
0502                                         elInfoSrc = cms.InputTag(btagPrefix+"softPFElectronsTagInfos"+labelName+postfix)),
0503                                     process, task)
0504                 if svClustering or fatJets != cms.InputTag(''):
0505                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)     
0506             if btagInfo == 'pfInclusiveSecondaryVertexFinderTagInfos':
0507                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0508                                     btag.pfInclusiveSecondaryVertexFinderTagInfos.clone(
0509                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix),
0510                                         extSVCollection=svSource),
0511                                     process, task)
0512                 if svClustering or fatJets != cms.InputTag(''):
0513                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0514             if btagInfo == 'pfInclusiveSecondaryVertexFinderAK8TagInfos':
0515                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0516                                     btag.pfInclusiveSecondaryVertexFinderAK8TagInfos.clone(
0517                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterAK8TagInfos'+labelName+postfix),
0518                                         extSVCollection=svSource),
0519                                     process, task)
0520                 if svClustering or fatJets != cms.InputTag(''):
0521                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0522             if btagInfo == 'pfBoostedDoubleSVAK8TagInfos':
0523                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0524                                     btag.pfBoostedDoubleSVAK8TagInfos.clone(
0525                                         svTagInfos = cms.InputTag(btagPrefix+'pfInclusiveSecondaryVertexFinderAK8TagInfos'+labelName+postfix)),
0526                                     process, task)
0527             if btagInfo == 'pfInclusiveSecondaryVertexFinderCA15TagInfos':
0528                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0529                                     btag.pfInclusiveSecondaryVertexFinderCA15TagInfos.clone(
0530                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterCA15TagInfos'+labelName+postfix),
0531                                         extSVCollection=svSource),
0532                                     process, task)
0533                 if svClustering or fatJets != cms.InputTag(''):
0534                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0535             if btagInfo == 'pfBoostedDoubleSVCA15TagInfos':
0536                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0537                                     btag.pfBoostedDoubleSVCA15TagInfos.clone(
0538                                         svTagInfos = cms.InputTag(btagPrefix+'pfInclusiveSecondaryVertexFinderCA15TagInfos'+labelName+postfix)),
0539                                     process, task)
0540             if btagInfo == 'pfInclusiveSecondaryVertexFinderCvsLTagInfos':
0541                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0542                                     btag.pfInclusiveSecondaryVertexFinderCvsLTagInfos.clone(
0543                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix),
0544                                         extSVCollection=svSourceCvsL),
0545                                     process, task)
0546                 if svClustering or fatJets != cms.InputTag(''):
0547                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0548             if btagInfo == 'pfInclusiveSecondaryVertexFinderNegativeCvsLTagInfos':
0549                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0550                                     btag.pfInclusiveSecondaryVertexFinderNegativeCvsLTagInfos.clone(
0551                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix),
0552                                         extSVCollection = btagPrefix+'inclusiveCandidateNegativeSecondaryVerticesCvsL'+labelName+postfix),
0553                                     process, task)
0554                 if svClustering or fatJets != cms.InputTag(''):
0555                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0556             if btagInfo == 'pfGhostTrackVertexTagInfos':
0557                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0558                                     btag.pfGhostTrackVertexTagInfos.clone(
0559                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix)),
0560                                     process, task)
0561             if btagInfo == 'pfSecondaryVertexNegativeTagInfos':
0562                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0563                                     btag.pfSecondaryVertexNegativeTagInfos.clone(
0564                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix)),
0565                                     process, task)
0566                 if tightBTagNTkHits:
0567                     _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0568                     _btagInfo.trackSelection.pixelHitsMin = cms.uint32(2)
0569                     _btagInfo.trackSelection.totalHitsMin = cms.uint32(8)
0570             if btagInfo == 'pfInclusiveSecondaryVertexFinderNegativeTagInfos':
0571                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0572                                     btag.pfInclusiveSecondaryVertexFinderNegativeTagInfos.clone(
0573                                         trackIPTagInfos = cms.InputTag(btagPrefix+'pfImpactParameterTagInfos'+labelName+postfix),
0574                                         extSVCollection=cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix)),
0575                                     process, task)
0576                 if svClustering or fatJets != cms.InputTag(''):
0577                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0578             if btagInfo == 'impactParameterTagInfos':
0579                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix, 
0580                                     btag.impactParameterTagInfos.clone(
0581                                         jetTracks = cms.InputTag('jetTracksAssociatorAtVertex'+labelName+postfix),
0582                                         primaryVertex=pvSource),
0583                                     process, task)
0584             if btagInfo == 'secondaryVertexTagInfos':
0585                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0586                                     btag.secondaryVertexTagInfos.clone(
0587                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0588                                     process, task)
0589             if btagInfo == 'inclusiveSecondaryVertexFinderTagInfos':
0590                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0591                                     btag.inclusiveSecondaryVertexFinderTagInfos.clone(
0592                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0593                                     process, task)
0594                 if svClustering or fatJets != cms.InputTag(''):
0595                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0596             if btagInfo == 'inclusiveSecondaryVertexFinderFilteredTagInfos':
0597                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0598                                     btag.inclusiveSecondaryVertexFinderFilteredTagInfos.clone(
0599                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0600                                     process, task)
0601                 if svClustering or fatJets != cms.InputTag(''):
0602                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0603             if btagInfo == 'secondaryVertexNegativeTagInfos':
0604                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0605                                     btag.secondaryVertexNegativeTagInfos.clone(
0606                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0607                                     process, task)
0608             if btagInfo == 'inclusiveSecondaryVertexFinderNegativeTagInfos':
0609                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0610                                     btag.inclusiveSecondaryVertexFinderNegativeTagInfos.clone(
0611                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0612                                     process, task)
0613                 if svClustering or fatJets != cms.InputTag(''):
0614                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0615             if btagInfo == 'inclusiveSecondaryVertexFinderFilteredNegativeTagInfos':
0616                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0617                                     btag.inclusiveSecondaryVertexFinderFilteredNegativeTagInfos.clone(
0618                                         trackIPTagInfos = cms.InputTag(btagPrefix+'impactParameterTagInfos'+labelName+postfix)),
0619                                     process, task)
0620                 if svClustering or fatJets != cms.InputTag(''):
0621                     setupSVClustering(getattr(process, btagPrefix+btagInfo+labelName+postfix), svClustering, algo, rParam, fatJets, groomedFatJets)
0622             if btagInfo == 'softMuonTagInfos':
0623                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0624                                     btag.softMuonTagInfos.clone(jets = jetSource, primaryVertex=pvSource),
0625                                     process, task)
0626             if btagInfo == 'softPFMuonsTagInfos':
0627                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0628                                     btag.softPFMuonsTagInfos.clone(jets = jetSource, primaryVertex=pvSource, muons=muSource),
0629                                     process, task)
0630             if btagInfo == 'softPFElectronsTagInfos':
0631                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0632                                     btag.softPFElectronsTagInfos.clone(jets = jetSource, primaryVertex=pvSource, electrons=elSource),
0633                                     process, task)
0634             if btagInfo == 'pixelClusterTagInfos':
0635                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0636                                     btag.pixelClusterTagInfos.clone(jets = jetSource, vertices=pvSource),
0637                                     process, task)
0638 
0639 
0640 
0641             if 'pfBoostedDouble' in btagInfo or 'SecondaryVertex' in btagInfo:
0642               _btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
0643               if pfCandidates.value() == 'packedPFCandidates':
0644                 packedPFPuppiLabel = setupPuppiForPackedPF(process)[0]
0645                 _btagInfo.weights = cms.InputTag(packedPFPuppiLabel)
0646               else:
0647                 _btagInfo.weights = cms.InputTag("puppi")
0648 
0649             if 'DeepFlavourTagInfos' in btagInfo:
0650                 svUsed = svSource
0651                 if btagInfo == 'pfNegativeDeepFlavourTagInfos':
0652                     deep_csv_tag_infos = 'pfDeepCSVNegativeTagInfos'
0653                     svUsed = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix)
0654                     flip = True 
0655                 else:
0656                     deep_csv_tag_infos = 'pfDeepCSVTagInfos'
0657                     flip = False
0658 
0659                 # use right input tags when running with RECO PF candidates, which actually
0660                 # depends of whether jets use "particleFlow"
0661                 if pfCandidates.value() == 'packedPFCandidates':
0662                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0663                     vertex_associator = cms.InputTag("")
0664                 else:
0665                     puppi_value_map = cms.InputTag("puppi")
0666                     vertex_associator = cms.InputTag("primaryVertexAssociation","original")
0667 
0668                 # If this jet is a puppi jet, then set is_weighted_jet to true.
0669                 is_weighted_jet = False
0670                 if ('puppi' in jetSource.value().lower()):
0671                     is_weighted_jet = True
0672                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0673                                     btag.pfDeepFlavourTagInfos.clone(
0674                                       jets = jetSource,
0675                                       vertices=pvSource,
0676                                       secondary_vertices=svUsed,
0677                                       shallow_tag_infos = cms.InputTag(btagPrefix+deep_csv_tag_infos+labelName+postfix),
0678                                       puppi_value_map = puppi_value_map,
0679                                       vertex_associator = vertex_associator,
0680                                       is_weighted_jet = is_weighted_jet,
0681                                       flip = flip),
0682                                     process, task)
0683             
0684             if ('ParticleTransformerAK4TagInfos' in btagInfo) and ('UnifiedParticleTransformerAK4TagInfos' not in btagInfo): #We also have to veto UParT is we select ParT
0685                 svUsed = svSource
0686                 if btagInfo == 'pfNegativeParticleTransformerAK4TagInfos':
0687                     svUsed, flip, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10.
0688                 else:
0689                     svUsed, flip, max_sip3dsig_for_flip = svSource, False, -1.
0690                 # use right input tags when running with RECO PF candidates, which actually
0691                 # depends of whether jets use "particleFlow"
0692                 if pfCandidates.value() == 'packedPFCandidates':
0693                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0694                     vertex_associator = cms.InputTag("")
0695                 else:
0696                     puppi_value_map = cms.InputTag("puppi")
0697                     vertex_associator = cms.InputTag("primaryVertexAssociation","original")
0698 
0699                 # If this jet is a puppi jet, then set is_weighted_jet to true.
0700                 is_weighted_jet = False
0701                 if ('puppi' in jetSource.value().lower()):
0702                     is_weighted_jet = True
0703                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0704                                     btag.pfParticleTransformerAK4TagInfos.clone(
0705                                       jets = jetSource,
0706                                       vertices=pvSource,
0707                                       secondary_vertices=svUsed,
0708                                       puppi_value_map = puppi_value_map,
0709                                       vertex_associator = vertex_associator,
0710                                       is_weighted_jet = is_weighted_jet,
0711                                       flip = flip,
0712                                       max_sip3dsig_for_flip=max_sip3dsig_for_flip),
0713                                     process, task)
0714                 
0715             if 'UnifiedParticleTransformerAK4TagInfos' in btagInfo:
0716                 svUsed = svSource
0717                 if btagInfo == 'pfNegativeUnifiedParticleTransformerAK4TagInfos':
0718                     svUsed = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix)
0719                     flip = True 
0720                 else:
0721                     flip = False
0722                 # use right input tags when running with RECO PF candidates, which actually
0723                 # depends of whether jets use "particleFlow"
0724                 if pfCandidates.value() == 'packedPFCandidates':
0725                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0726                     vertex_associator = cms.InputTag("")
0727                 else:
0728                     puppi_value_map = cms.InputTag("puppi")
0729                     vertex_associator = cms.InputTag("primaryVertexAssociation","original")
0730 
0731                 # If this jet is a puppi jet, then set is_weighted_jet to true.
0732                 is_weighted_jet = False
0733                 if ('puppi' in jetSource.value().lower()):
0734                     is_weighted_jet = True
0735                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0736                                     btag.pfUnifiedParticleTransformerAK4TagInfos.clone(
0737                                       jets = jetSource,
0738                                       vertices=pvSource,
0739                                       secondary_vertices=svUsed,
0740                                       puppi_value_map = puppi_value_map,
0741                                       vertex_associator = vertex_associator,
0742                                       is_weighted_jet = is_weighted_jet,
0743                                       flip = flip),
0744                                     process, task)
0745 
0746             if btagInfo == 'pfDeepDoubleXTagInfos':
0747                 # can only run on PAT jets, so the updater needs to be used
0748                 if 'updated' not in jetSource.value().lower():
0749                     raise ValueError("Invalid jet collection: %s. pfDeepDoubleXTagInfos only supports running via updateJetCollection." % jetSource.value())
0750                 packedPFPuppiLabel = setupPuppiForPackedPF(process)[0]
0751                 puppi_value_map = cms.InputTag(packedPFPuppiLabel)
0752                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0753                                     btag.pfDeepDoubleXTagInfos.clone(
0754                                       jets = jetSource,
0755                                       vertices=pvSource,
0756                                       secondary_vertices=svSource,
0757                                       shallow_tag_infos = cms.InputTag(btagPrefix+'pfBoostedDoubleSVAK8TagInfos'+labelName+postfix),
0758                                       puppi_value_map = puppi_value_map,
0759                                       ),
0760                                     process, task)
0761             if btagInfo == 'pfHiggsInteractionNetTagInfos':
0762                 packedPFPuppiLabel = setupPuppiForPackedPF(process)[0]
0763                 puppi_value_map = cms.InputTag(packedPFPuppiLabel)
0764                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0765                                     btag.pfHiggsInteractionNetTagInfos.clone(
0766                                       jets = jetSource,
0767                                       vertices = pvSource,
0768                                       secondary_vertices = svSource,
0769                                       pf_candidates = pfCandidates,
0770                                       puppi_value_map = puppi_value_map
0771                                       ),
0772                                     process, task)
0773 
0774             if btagInfo == 'pfDeepBoostedJetTagInfos':
0775                 if pfCandidates.value() == 'packedPFCandidates':
0776                     # case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
0777                     if 'updated' not in jetSource.value().lower():
0778                         raise ValueError("Invalid jet collection: %s. pfDeepBoostedJetTagInfos only supports running via updateJetCollection." % jetSource.value())
0779                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0780                     vertex_associator = ""
0781                 elif pfCandidates.value() == 'particleFlow':
0782                     raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
0783                     # case 2: running on new jet collection whose daughters are PFCandidates (e.g., cluster jets in RECO/AOD)
0784                     # daughters are the particles used in jet clustering, so already scaled by their puppi weights
0785                     # Uncomment the lines below after running pfDeepBoostedJetTagInfos with reco::PFCandidates becomes supported
0786 #                     puppi_value_map = "puppi"
0787 #                     vertex_associator = "primaryVertexAssociation:original"
0788                 else:
0789                     raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0790                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0791                                     btag.pfDeepBoostedJetTagInfos.clone(
0792                                       jets = jetSource,
0793                                       vertices = pvSource,
0794                                       secondary_vertices = svSource,
0795                                       pf_candidates = pfCandidates,
0796                                       puppi_value_map = puppi_value_map,
0797                                       vertex_associator = vertex_associator,
0798                                       ),
0799                                     process, task)
0800 
0801             if btagInfo == 'pfParticleNetTagInfos':
0802                 if pfCandidates.value() == 'packedPFCandidates':
0803                     # case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
0804                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0805                     vertex_associator = ""
0806                 elif pfCandidates.value() == 'particleFlow':
0807                     raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
0808                     # case 2: running on new jet collection whose daughters are PFCandidates (e.g., cluster jets in RECO/AOD)
0809                     puppi_value_map = "puppi"
0810                     vertex_associator = "primaryVertexAssociation:original"
0811                 else:
0812                     raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0813                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0814                                     btag.pfParticleNetTagInfos.clone(
0815                                       jets = jetSource,
0816                                       vertices = pvSource,
0817                                       secondary_vertices = svSource,
0818                                       pf_candidates = pfCandidates,
0819                                       puppi_value_map = puppi_value_map,
0820                                       vertex_associator = vertex_associator,
0821                                       ),
0822                                     process, task)
0823 
0824             if 'ParticleNetAK4TagInfos' in btagInfo:
0825                 if btagInfo == 'pfNegativeParticleNetAK4TagInfos':
0826                     secondary_vertices = btagPrefix + \
0827                         'inclusiveCandidateNegativeSecondaryVertices' + labelName + postfix
0828                     flip_ip_sign = True
0829                     sip3dSigMax = 10
0830                 else:
0831                     secondary_vertices = svSource
0832                     flip_ip_sign = False
0833                     sip3dSigMax = -1
0834                 if pfCandidates.value() == 'packedPFCandidates':
0835                     # case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
0836                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0837                     vertex_associator = ""
0838                 elif pfCandidates.value() == 'particleFlow':
0839                     raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
0840                     # case 2: running on new jet collection whose daughters are PFCandidates (e.g., cluster jets in RECO/AOD)
0841                     puppi_value_map = "puppi"
0842                     vertex_associator = "primaryVertexAssociation:original"
0843                 else:
0844                     raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0845                 # If this jet is a Puppi jet, use puppi-weighted p4.
0846                 use_puppiP4 = False
0847                 if "puppi" in jetSource.value().lower():
0848                     use_puppiP4 = True
0849                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0850                                     btag.pfParticleNetAK4TagInfos.clone(
0851                                       jets = jetSource,
0852                                       vertices = pvSource,
0853                                       secondary_vertices = secondary_vertices,
0854                                       pf_candidates = pfCandidates,
0855                                       puppi_value_map = puppi_value_map,
0856                                       vertex_associator = vertex_associator,
0857                                       flip_ip_sign = flip_ip_sign,
0858                                       sip3dSigMax = sip3dSigMax,
0859                                       use_puppiP4 = use_puppiP4
0860                                       ),
0861                                     process, task)
0862 
0863             acceptedTagInfos.append(btagInfo)
0864         elif hasattr(toptag, btagInfo) :
0865             acceptedTagInfos.append(btagInfo)
0866         elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiCentralTagInfos' or btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos':
0867             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0868             if btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos':
0869                 svUsed, flip_ip_sign, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10.
0870             else:
0871                 svUsed, flip_ip_sign, max_sip3dsig_for_flip = svSource, False, -1.
0872             if pfCandidates.value() != 'packedPFCandidates':
0873                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0874             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0875                                 pfParticleNetFromMiniAODAK4PuppiCentralTagInfos.clone(
0876                                   jets = jetSource,
0877                                   vertices = pvSource,
0878                                   secondary_vertices = svUsed,
0879                                   pf_candidates = pfCandidates,
0880                                   flip_ip_sign = flip_ip_sign,
0881                                   max_sip3dsig_for_flip = max_sip3dsig_for_flip,
0882                                   ),
0883                                 process, task)
0884             acceptedTagInfos.append(btagInfo)
0885         elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiForwardTagInfos':
0886             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0887             if pfCandidates.value() != 'packedPFCandidates':
0888                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0889             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0890                                 pfParticleNetFromMiniAODAK4PuppiForwardTagInfos.clone(
0891                                   jets = jetSource,
0892                                   vertices = pvSource,
0893                                   secondary_vertices = svSource,
0894                                   pf_candidates = pfCandidates,
0895                                   ),
0896                                 process, task)
0897             acceptedTagInfos.append(btagInfo)
0898         elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSCentralTagInfos' or btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiForwardTagInfos':
0899             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0900             if btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiForwardTagInfos':
0901                 svUsed, flip_ip_sign, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10.
0902             else:
0903                 svUsed, flip_ip_sign, max_sip3dsig_for_flip = svSource, False, -1.
0904             if pfCandidates.value() != 'packedPFCandidates':
0905                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0906             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0907                                 pfParticleNetFromMiniAODAK4CHSCentralTagInfos.clone(
0908                                   jets = jetSource,
0909                                   vertices = pvSource,
0910                                   secondary_vertices = svUsed,
0911                                   pf_candidates = pfCandidates,
0912                                   flip_ip_sign = flip_ip_sign,
0913                                   max_sip3dsig_for_flip = max_sip3dsig_for_flip,
0914                                   ),
0915                                 process, task)
0916             acceptedTagInfos.append(btagInfo)
0917         elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSForwardTagInfos':
0918             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0919             if pfCandidates.value() != 'packedPFCandidates':
0920                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0921             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0922                                 pfParticleNetFromMiniAODAK4CHSForwardTagInfos.clone(
0923                                   jets = jetSource,
0924                                   vertices = pvSource,
0925                                   secondary_vertices = svSource,
0926                                   pf_candidates = pfCandidates,
0927                                   ),
0928                                 process, task)
0929             acceptedTagInfos.append(btagInfo)
0930         elif btagInfo == 'pfParticleNetFromMiniAODAK8TagInfos':
0931             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0932             if pfCandidates.value() != 'packedPFCandidates':
0933                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0934             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0935                                 pfParticleNetFromMiniAODAK8TagInfos.clone(
0936                                   jets = jetSource,
0937                                   vertices = pvSource,
0938                                   secondary_vertices = svSource,
0939                                   pf_candidates = pfCandidates,
0940                                   ),
0941                                 process, task)
0942             acceptedTagInfos.append(btagInfo)
0943         else:
0944             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagInfo))
0945     # setup all required btagDiscriminators
0946     acceptedBtagDiscriminators = list()
0947     for discriminator_name in btagDiscriminators :          
0948         btagDiscr = discriminator_name.split(':')[0] #split input tag to get the producer label
0949         #print discriminator_name, '-->', btagDiscr
0950         newDiscr = btagPrefix+btagDiscr+labelName+postfix #new discriminator name
0951         if hasattr(btag,btagDiscr): 
0952             if hasattr(process, newDiscr):
0953                 pass 
0954             elif hasattr(getattr(btag, btagDiscr), 'tagInfos'):
0955                 addToProcessAndTask(
0956                     newDiscr,
0957                     getattr(btag, btagDiscr).clone(
0958                         tagInfos = cms.VInputTag(
0959                             *[ cms.InputTag(btagPrefix+x+labelName+postfix) \
0960                             for x in supportedBtagDiscr[discriminator_name][0] ]
0961                         )
0962                     ),
0963                     process,
0964                     task
0965                 )
0966             elif hasattr(getattr(btag, btagDiscr), 'src'):
0967                 addToProcessAndTask(
0968                     newDiscr,
0969                     getattr(btag, btagDiscr).clone(
0970                         src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0971                     ),
0972                     process,
0973                     task
0974                 )
0975             else:
0976                 raise ValueError('I do not know how to update %s it does not have neither "tagInfos" nor "src" attributes' % btagDiscr)
0977             acceptedBtagDiscriminators.append(discriminator_name)
0978         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiCentralJetTags':
0979             if hasattr(process, newDiscr):
0980                 pass
0981             addToProcessAndTask(
0982                 newDiscr,
0983                 pfParticleNetFromMiniAODAK4PuppiCentralJetTags.clone(
0984                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0985                 ),
0986                 process,
0987                 task
0988             )
0989             acceptedBtagDiscriminators.append(discriminator_name)
0990         elif btagDiscr=='pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags':
0991             if hasattr(process, newDiscr):
0992                 pass
0993             addToProcessAndTask(
0994                 newDiscr,
0995                 pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags.clone(
0996                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0997                 ),
0998                 process,
0999                 task
1000             )
1001             acceptedBtagDiscriminators.append(discriminator_name)
1002         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiForwardJetTags':
1003             if hasattr(process, newDiscr):
1004                 pass
1005             addToProcessAndTask(
1006                 newDiscr,
1007                 pfParticleNetFromMiniAODAK4PuppiForwardJetTags.clone(
1008                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
1009                 ),
1010                 process,
1011                 task
1012             )
1013             acceptedBtagDiscriminators.append(discriminator_name)
1014         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSCentralJetTags':
1015             if hasattr(process, newDiscr):
1016                 pass
1017             addToProcessAndTask(
1018                 newDiscr,
1019                 pfParticleNetFromMiniAODAK4CHSCentralJetTags.clone(
1020                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
1021                 ),
1022                 process,
1023                 task
1024             )
1025             acceptedBtagDiscriminators.append(discriminator_name)
1026         elif btagDiscr=='pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags':
1027             if hasattr(process, newDiscr):
1028                 pass
1029             addToProcessAndTask(
1030                 newDiscr,
1031                 pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags.clone(
1032                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
1033                 ),
1034                 process,
1035                 task
1036             )
1037             acceptedBtagDiscriminators.append(discriminator_name)
1038         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSForwardJetTags':
1039             if hasattr(process, newDiscr):
1040                 pass
1041             addToProcessAndTask(
1042                 newDiscr,
1043                 pfParticleNetFromMiniAODAK4CHSForwardJetTags.clone(
1044                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
1045                 ),
1046                 process,
1047                 task
1048             )
1049             acceptedBtagDiscriminators.append(discriminator_name)
1050         elif btagDiscr=='pfParticleNetFromMiniAODAK8JetTags':
1051             if hasattr(process, newDiscr):
1052                 pass
1053             addToProcessAndTask(
1054                 newDiscr,
1055                 pfParticleNetFromMiniAODAK8JetTags.clone(
1056                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
1057                 ),
1058                 process,
1059                 task
1060             )
1061             acceptedBtagDiscriminators.append(discriminator_name)
1062         else:
1063             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagDiscr))
1064             
1065     #update meta-taggers, if any
1066     for meta_tagger in present_meta:
1067         btagDiscr = meta_tagger.split(':')[0] #split input tag to get the producer label
1068         #print discriminator_name, '-->', btagDiscr
1069         newDiscr = btagPrefix+btagDiscr+labelName+postfix #new discriminator name
1070         if hasattr(btag,btagDiscr): 
1071             if hasattr(process, newDiscr):
1072                 pass 
1073             else:
1074                 addToProcessAndTask(
1075                     newDiscr,
1076                     getattr(btag, btagDiscr).clone(),
1077                     process,
1078                     task
1079                 )
1080                 for dependency in supportedMetaDiscr[meta_tagger]:
1081                     if ':' in dependency:
1082                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1083                     else:
1084                         new_dep = btagPrefix+dependency+labelName+postfix
1085                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1086                     replace.doIt(getattr(process, newDiscr), newDiscr)
1087             acceptedBtagDiscriminators.append(meta_tagger)
1088         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags':
1089             if hasattr(process, newDiscr):
1090                 pass 
1091             else:
1092                 addToProcessAndTask(
1093                     newDiscr,
1094                     pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags.clone(),
1095                     process,
1096                     task
1097                 )
1098                 for dependency in supportedMetaDiscr[meta_tagger]:
1099                     if ':' in dependency:
1100                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1101                     else:
1102                         new_dep = btagPrefix+dependency+labelName+postfix
1103                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1104                     replace.doIt(getattr(process, newDiscr), newDiscr)
1105             acceptedBtagDiscriminators.append(meta_tagger)
1106         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags':
1107             if hasattr(process, newDiscr):
1108                 pass 
1109             else:
1110                 addToProcessAndTask(
1111                     newDiscr,
1112                     pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags.clone(),
1113                     process,
1114                     task
1115                 )
1116                 for dependency in supportedMetaDiscr[meta_tagger]:
1117                     if ':' in dependency:
1118                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1119                     else:
1120                         new_dep = btagPrefix+dependency+labelName+postfix
1121                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1122                     replace.doIt(getattr(process, newDiscr), newDiscr)
1123             acceptedBtagDiscriminators.append(meta_tagger)
1124         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags':
1125             if hasattr(process, newDiscr):
1126                 pass 
1127             else:
1128                 addToProcessAndTask(
1129                     newDiscr,
1130                     pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags.clone(),
1131                     process,
1132                     task
1133                 )
1134                 for dependency in supportedMetaDiscr[meta_tagger]:
1135                     if ':' in dependency:
1136                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1137                     else:
1138                         new_dep = btagPrefix+dependency+labelName+postfix
1139                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1140                     replace.doIt(getattr(process, newDiscr), newDiscr)
1141             acceptedBtagDiscriminators.append(meta_tagger)
1142         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags':
1143             if hasattr(process, newDiscr):
1144                 pass 
1145             else:
1146                 addToProcessAndTask(
1147                     newDiscr,
1148                     pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags.clone(),
1149                     process,
1150                     task
1151                 )
1152                 for dependency in supportedMetaDiscr[meta_tagger]:
1153                     if ':' in dependency:
1154                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1155                     else:
1156                         new_dep = btagPrefix+dependency+labelName+postfix
1157                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1158                     replace.doIt(getattr(process, newDiscr), newDiscr)
1159             acceptedBtagDiscriminators.append(meta_tagger)
1160         elif btagDiscr=='pfParticleNetFromMiniAODAK8DiscriminatorsJetTags':
1161             if hasattr(process, newDiscr):
1162                 pass 
1163             else:
1164                 addToProcessAndTask(
1165                     newDiscr,
1166                     pfParticleNetFromMiniAODAK8DiscriminatorsJetTags.clone(),
1167                     process,
1168                     task
1169                 )
1170                 for dependency in supportedMetaDiscr[meta_tagger]:
1171                     if ':' in dependency:
1172                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1173                     else:
1174                         new_dep = btagPrefix+dependency+labelName+postfix
1175                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1176                     replace.doIt(getattr(process, newDiscr), newDiscr)
1177             acceptedBtagDiscriminators.append(meta_tagger)
1178                         
1179         else:
1180             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagDiscr))
1181         
1182     ## replace corresponding tags for pat jet production
1183     patJets.tagInfoSources = cms.VInputTag( *[ cms.InputTag(btagPrefix+x+labelName+postfix) for x in acceptedTagInfos ] )
1184     patJets.discriminatorSources = cms.VInputTag(*[ 
1185         cms.InputTag(btagPrefix+x+labelName+postfix) \
1186           if ':' not in x else \
1187           cms.InputTag(btagPrefix+x.split(':')[0]+labelName+postfix+':'+x.split(':')[1]) \
1188           for x in acceptedBtagDiscriminators 
1189         ])
1190     if len(acceptedBtagDiscriminators) > 0 :
1191         patJets.addBTagInfo = True
1192     ## if re-running IVF
1193     if runIVF:
1194         if not tightBTagNTkHits:
1195             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices': ## MiniAOD case
1196                 if not runIVFforCTagOnly: rerunningIVFMiniAOD()
1197             else:
1198                 rerunningIVF()
1199         from PhysicsTools.PatAlgos.tools.helpers import loadWithPrefix
1200         ivfbTagInfos = ['pfInclusiveSecondaryVertexFinderTagInfos', 'pfInclusiveSecondaryVertexFinderAK8TagInfos', 'pfInclusiveSecondaryVertexFinderCA15TagInfos']
1201         if any(i in acceptedTagInfos for i in ivfbTagInfos) and not runIVFforCTagOnly:
1202             if not hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1203                 loadWithPrefix(process, 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff', btagPrefix, task.label())
1204             if tightBTagNTkHits:
1205                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1206                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinder')
1207                     _temp.minHits = cms.uint32(8)
1208             ## MiniAOD case
1209             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices':
1210                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1211                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinder')
1212                     _temp.primaryVertices = pvSource
1213                     _temp.tracks = pfCandidates
1214                 if hasattr( process, btagPrefix+'candidateVertexArbitrator' ):
1215                     _temp = getattr(process, btagPrefix+'candidateVertexArbitrator')
1216                     _temp.primaryVertices = pvSource
1217                     _temp.tracks = pfCandidates
1218                 if hasattr( process, btagPrefix+'inclusiveCandidateSecondaryVertices' ) and not hasattr( process, svSource.getModuleLabel() ):
1219                     addToProcessAndTask(svSource.getModuleLabel(),
1220                                         getattr(process, btagPrefix+'inclusiveCandidateSecondaryVertices').clone(),
1221                                         process, task)
1222         if any(i in acceptedTagInfos for i in ivfcTagInfos):
1223             if not hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1224                 loadWithPrefix(process, 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff', btagPrefix, task.label())
1225             if tightBTagNTkHits:
1226                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1227                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinderCvsL')
1228                     _temp.minHits = cms.uint32(8)
1229             ## MiniAOD case
1230             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices':
1231                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1232                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinderCvsL')
1233                     _temp.primaryVertices = pvSource
1234                     _temp.tracks = pfCandidates
1235                 if hasattr( process, btagPrefix+'candidateVertexArbitratorCvsL' ):
1236                     _temp = getattr(process, btagPrefix+'candidateVertexArbitratorCvsL')
1237                     _temp.primaryVertices = pvSource
1238                     _temp.tracks = pfCandidates
1239                 if hasattr( process, btagPrefix+'inclusiveCandidateSecondaryVerticesCvsL' ) and not hasattr( process, svSourceCvsL.getModuleLabel() ):
1240                     addToProcessAndTask(svSourceCvsL.getModuleLabel(),
1241                                         getattr(process, btagPrefix+'inclusiveCandidateSecondaryVerticesCvsL').clone(),
1242                                         process, task)
1243         if 'inclusiveSecondaryVertexFinderTagInfos' in acceptedTagInfos:
1244             if not hasattr( process, 'inclusiveVertexing' ):
1245                 process.load( 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff' )
1246                 task.add(process.inclusiveVertexingTask)
1247                 task.add(process.inclusiveCandidateVertexingTask)
1248                 task.add(process.inclusiveCandidateVertexingCvsLTask)
1249         if 'inclusiveSecondaryVertexFinderFilteredTagInfos' in acceptedTagInfos:
1250             if not hasattr( process, 'inclusiveVertexing' ):
1251                 process.load( 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff' )
1252                 task.add(process.inclusiveVertexingTask)
1253                 task.add(process.inclusiveCandidateVertexingTask)
1254                 task.add(process.inclusiveCandidateVertexingCvsLTask)
1255     if 'inclusiveSecondaryVertexFinderFilteredTagInfos' in acceptedTagInfos:
1256         if not hasattr( process, 'inclusiveSecondaryVerticesFiltered' ):
1257             process.load( 'RecoBTag.SecondaryVertex.inclusiveSecondaryVerticesFiltered_cfi' )
1258             task.add(process.inclusiveSecondaryVerticesFiltered)
1259             task.add(process.bVertexFilter)
1260         if not hasattr( process, 'bToCharmDecayVertexMerged' ):
1261             process.load( 'RecoBTag.SecondaryVertex.bToCharmDecayVertexMerger_cfi' )
1262             task.add(process.bToCharmDecayVertexMerged)
1263     if 'caTopTagInfos' in acceptedTagInfos :
1264         patJets.addTagInfos = True
1265         if not hasattr( process, 'caTopTagInfos' ) and not hasattr( process, 'caTopTagInfosAK8' ):
1266             process.load( 'RecoJets.JetProducers.caTopTaggers_cff' )
1267             task.add(process.caTopTaggersTask)
1268 
1269 class AddJetCollection(ConfigToolBase):
1270     """
1271     Tool to add a new jet collection to your PAT Tuple or to modify an existing one.
1272     """
1273     _label='addJetCollection'
1274     _defaultParameters=dicttypes.SortedKeysDict()
1275 
1276     def __init__(self):
1277         """
1278         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1279         """
1280         ## initialization of the base class
1281         ConfigToolBase.__init__(self)
1282         ## add all parameters that should be known to the class
1283         self.addParameter(self._defaultParameters,'labelName', 'UNDEFINED', "Label name of the new patJet collection.", str)
1284         self.addParameter(self._defaultParameters,'postfix','', "Postfix from usePF2PAT.", str)
1285         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1286         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1287         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('particleFlow'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1288         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1289         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlinePrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1290         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('inclusiveCandidateSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1291         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('gedGsfElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1292         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('muons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1293         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1294         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1295         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1296         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1297         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1298         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1299         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1300         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1301         self.addParameter(self._defaultParameters,'getJetMCFlavour', True, "Get jet MC truth flavour")
1302         self.addParameter(self._defaultParameters,'genJetCollection', cms.InputTag("ak4GenJets"), "GenJet collection to match to", cms.InputTag)
1303         self.addParameter(self._defaultParameters,'genParticles', cms.InputTag("genParticles"), "GenParticle collection to be used", cms.InputTag)
1304         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1305         collection. The format has to be given in a python tuple of type: (\'AK4Calo\',[\'L2Relative\', \'L3Absolute\'], patMet). Here the first argument corresponds to the payload \
1306         in the CMS Conditions database for the given jet collection; the second argument corresponds to the jet energy correction levels that you want to be embedded into your \
1307         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1308         third argument indicates whether MET(Type1/2) corrections should be applied corresponding to the new patJetCollection. If so a new patMet collection will be added to your PAT \
1309         Tuple in addition to the raw patMet. This new patMet collection will have the MET(Type1/2) corrections applied. The argument can have the following types: \'type-1\' for \
1310         type-1 corrected MET; \'type-2\' for type-1 plus type-2 corrected MET; \'\' or \'none\' if no further MET corrections should be applied to your MET. The arguments \'type-1\' \
1311         and \'type-2\' are not case sensitive.", tuple, acceptNoneValue=True)
1312         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging, in most cases just the labels of the btag discriminators that \
1313         you are interested in is all relevant information that you need for a high level analysis. Add here all btag discriminators, that you are interested in as a list of strings. \
1314         If this list is empty no btag discriminator information will be added to your new patJet collection.", allowedValues=(list(set().union(supportedBtagDiscr.keys(),supportedMetaDiscr.keys()))),Type=list)
1315         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects contain all relevant information from which all discriminators of a certain \
1316         type have been calculated. You might be interested in keeping this information for low level tests or to re-calculate some discriminators from hand. Note that this information \
1317         on the one hand can be very space consuming and that it is not necessary to access the pre-calculated btag discriminator information that has been derived from it. Only in very \
1318         special cases the btagInfos might really be needed in your analysis. Add here all btagInfos, that you are interested in as a list of strings. If this list is empty no btagInfos \
1319         will be added to your new patJet collection.", allowedValues=supportedBtagInfos,Type=list)
1320         self.addParameter(self._defaultParameters,'jetTrackAssociation',False, "Add JetTrackAssociation and JetCharge from reconstructed tracks to your new patJet collection. This \
1321         switch is only of relevance if you don\'t add any btag information to your new patJet collection (btagDiscriminators or btagInfos) and still want this information added to \
1322         your new patJetCollection. If btag information of any form is added to the new patJet collection this information will be added automatically.")
1323         self.addParameter(self._defaultParameters,'outputModules',['out'],"Add a list of all output modules to which you would like the new jet collection to be added. Usually this is \
1324         just one single output module with name \'out\', which corresponds also the default configuration of the tool. There is cases though where you might want to add this collection \
1325         to more than one output module.")
1326         ## set defaults
1327         self._parameters=copy.deepcopy(self._defaultParameters)
1328         ## add comments
1329         self._comment = "This is a tool to add more patJet collectinos to your PAT Tuple or to re-configure the default collection. You can add and embed additional information like jet\
1330         energy correction factors, btag information and generator match information to the new patJet collection depending on the parameters that you pass on to this function. Consult \
1331         the descriptions of each parameter for more information."
1332 
1333     def getDefaultParameters(self):
1334         """
1335         Return default parameters of the class
1336         """
1337         return self._defaultParameters
1338 
1339     def __call__(self,process,labelName=None,postfix=None,btagPrefix=None,jetSource=None,pfCandidates=None,explicitJTA=None,pvSource=None,svSource=None,elSource=None,muSource=None,runIVF=None,tightBTagNTkHits=None,loadStdRecoBTag=None,svClustering=None,fatJets=None,groomedFatJets=None,algo=None,rParam=None,getJetMCFlavour=None,genJetCollection=None,genParticles=None,jetCorrections=None,btagDiscriminators=None,btagInfos=None,jetTrackAssociation=None,outputModules=None):
1340         """
1341         Function call wrapper. This will check the parameters and call the actual implementation that
1342         can be found in toolCode via the base class function apply.
1343         """
1344         if labelName is None:
1345             labelName=self._defaultParameters['labelName'].value
1346         self.setParameter('labelName', labelName)
1347         if postfix is None:
1348             postfix=self._defaultParameters['postfix'].value
1349         self.setParameter('postfix', postfix)
1350         if btagPrefix is None:
1351             btagPrefix=self._defaultParameters['btagPrefix'].value
1352         self.setParameter('btagPrefix', btagPrefix)
1353         if jetSource is None:
1354             jetSource=self._defaultParameters['jetSource'].value
1355         self.setParameter('jetSource', jetSource)
1356         if pfCandidates is None:
1357             pfCandidates=self._defaultParameters['pfCandidates'].value
1358         self.setParameter('pfCandidates', pfCandidates)
1359         if explicitJTA is None:
1360             explicitJTA=self._defaultParameters['explicitJTA'].value
1361         self.setParameter('explicitJTA', explicitJTA)
1362         if pvSource is None:
1363             pvSource=self._defaultParameters['pvSource'].value
1364         self.setParameter('pvSource', pvSource)
1365         if svSource is None:
1366             svSource=self._defaultParameters['svSource'].value
1367         self.setParameter('svSource', svSource)
1368         if elSource is None:
1369             elSource=self._defaultParameters['elSource'].value
1370         self.setParameter('elSource', elSource)
1371         if muSource is None:
1372             muSource=self._defaultParameters['muSource'].value
1373         self.setParameter('muSource', muSource)
1374         if runIVF is None:
1375             runIVF=self._defaultParameters['runIVF'].value
1376         self.setParameter('runIVF', runIVF)
1377         if tightBTagNTkHits is None:
1378             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
1379         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
1380         if loadStdRecoBTag is None:
1381             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
1382         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
1383         if svClustering is None:
1384             svClustering=self._defaultParameters['svClustering'].value
1385         self.setParameter('svClustering', svClustering)
1386         if fatJets is None:
1387             fatJets=self._defaultParameters['fatJets'].value
1388         self.setParameter('fatJets', fatJets)
1389         if groomedFatJets is None:
1390             groomedFatJets=self._defaultParameters['groomedFatJets'].value
1391         self.setParameter('groomedFatJets', groomedFatJets)
1392         if algo is None:
1393             algo=self._defaultParameters['algo'].value
1394         self.setParameter('algo', algo)
1395         if rParam is None:
1396             rParam=self._defaultParameters['rParam'].value
1397         self.setParameter('rParam', rParam)
1398         if getJetMCFlavour is None:
1399             getJetMCFlavour=self._defaultParameters['getJetMCFlavour'].value
1400         self.setParameter('getJetMCFlavour', getJetMCFlavour)
1401         if genJetCollection is None:
1402             genJetCollection=self._defaultParameters['genJetCollection'].value
1403         self.setParameter('genJetCollection', genJetCollection)
1404         if genParticles is None:
1405             genParticles=self._defaultParameters['genParticles'].value
1406         self.setParameter('genParticles', genParticles)
1407         if jetCorrections is None:
1408             jetCorrections=self._defaultParameters['jetCorrections'].value
1409         self.setParameter('jetCorrections', jetCorrections)
1410         if btagDiscriminators is None:
1411             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
1412         self.setParameter('btagDiscriminators', btagDiscriminators)
1413         if btagInfos is None:
1414             btagInfos=self._defaultParameters['btagInfos'].value
1415         self.setParameter('btagInfos', btagInfos)
1416         if jetTrackAssociation is None:
1417             jetTrackAssociation=self._defaultParameters['jetTrackAssociation'].value
1418         self.setParameter('jetTrackAssociation', jetTrackAssociation)
1419         if outputModules is None:
1420             outputModules=self._defaultParameters['outputModules'].value
1421         self.setParameter('outputModules', outputModules)
1422         self.apply(process)
1423 
1424     def toolCode(self, process):
1425         """
1426         Tool code implementation
1427         """
1428         task = getPatAlgosToolsTask(process)
1429 
1430         ## initialize parameters
1431         labelName=self._parameters['labelName'].value
1432         postfix=self._parameters['postfix'].value
1433         btagPrefix=self._parameters['btagPrefix'].value
1434         jetSource=self._parameters['jetSource'].value
1435         pfCandidates=self._parameters['pfCandidates'].value
1436         explicitJTA=self._parameters['explicitJTA'].value
1437         pvSource=self._parameters['pvSource'].value
1438         svSource=self._parameters['svSource'].value
1439         elSource=self._parameters['elSource'].value
1440         muSource=self._parameters['muSource'].value
1441         runIVF=self._parameters['runIVF'].value
1442         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
1443         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
1444         svClustering=self._parameters['svClustering'].value
1445         fatJets=self._parameters['fatJets'].value
1446         groomedFatJets=self._parameters['groomedFatJets'].value
1447         algo=self._parameters['algo'].value
1448         rParam=self._parameters['rParam'].value
1449         getJetMCFlavour=self._parameters['getJetMCFlavour'].value
1450         genJetCollection=self._parameters['genJetCollection'].value
1451         genParticles=self._parameters['genParticles'].value
1452         jetCorrections=self._parameters['jetCorrections'].value
1453         btagDiscriminators=list(self._parameters['btagDiscriminators'].value)
1454         btagInfos=list(self._parameters['btagInfos'].value)
1455         jetTrackAssociation=self._parameters['jetTrackAssociation'].value
1456         outputModules=list(self._parameters['outputModules'].value)
1457 
1458         ## added jets must have a defined 'labelName'
1459         if labelName=='UNDEFINED':
1460             undefinedLabelName(self)
1461 
1462         ## a list of all producer modules, which are already known to process
1463         knownModules = process.producerNames().split()
1464         ## determine whether btagging information is required or not
1465         if btagDiscriminators.count('None')>0:
1466             btagDiscriminators.remove('None')
1467         if btagInfos.count('None')>0:
1468             btagInfos.remove('None')
1469         bTagging=(len(btagDiscriminators)>0 or len(btagInfos)>0)
1470         ## check if any legacy btag discriminators are being used
1471         infos = 0
1472         for info in btagInfos:
1473             if info.startswith('pf'): infos = infos + 1
1474             if 'softpf' in info.lower(): infos = infos + 1
1475         tags = 0
1476         for tag in btagDiscriminators:
1477             if tag.startswith('pf'): tags = tags + 1
1478             if 'softpf' in tag.lower(): tags = tags + 1
1479         bTaggingLegacy=(len(btagDiscriminators)>tags or len(btagInfos)>infos)
1480         ## construct postfix label for auxiliary modules; this postfix
1481         ## label will start with a capitalized first letter following
1482         ## the CMS naming conventions and for improved readablility
1483         _labelName=labelName[:1].upper()+labelName[1:]
1484 
1485         ## supported algo types are ak, ca, and kt
1486         _algo=''
1487         for x in ["ak", "ca", "kt"]:
1488             if x in algo.lower():
1489                 _algo=supportedJetAlgos[x]
1490                 break
1491         if _algo=='':
1492             unsupportedJetAlgorithm(self)
1493         ## add new patJets to process (keep instance for later further modifications)
1494         from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJets
1495         if 'patJets'+_labelName+postfix in knownModules :
1496             _newPatJets=getattr(process, 'patJets'+_labelName+postfix)
1497             _newPatJets.jetSource=jetSource
1498         else :
1499             addToProcessAndTask('patJets'+_labelName+postfix, patJets.clone(jetSource=jetSource), process, task)
1500             _newPatJets=getattr(process, 'patJets'+_labelName+postfix)
1501             knownModules.append('patJets'+_labelName+postfix)
1502         ## add new selectedPatJets to process
1503         from PhysicsTools.PatAlgos.selectionLayer1.jetSelector_cfi import selectedPatJets
1504         if 'selectedPatJets'+_labelName+postfix in knownModules :
1505             _newSelectedPatJets=getattr(process, 'selectedPatJets'+_labelName+postfix)
1506             _newSelectedPatJets.src='patJets'+_labelName+postfix
1507         else :
1508             addToProcessAndTask('selectedPatJets'+_labelName+postfix,
1509                                 selectedPatJets.clone(src='patJets'+_labelName+postfix),
1510                                 process, task)
1511             knownModules.append('selectedPatJets'+_labelName+postfix)
1512 
1513         ## add new patJetPartonMatch to process
1514         from PhysicsTools.PatAlgos.mcMatchLayer0.jetMatch_cfi import patJetPartonMatch
1515         if 'patJetPartonMatch'+_labelName+postfix in knownModules :
1516             _newPatJetPartonMatch=getattr(process, 'patJetPartonMatch'+_labelName+postfix)
1517             _newPatJetPartonMatch.src=jetSource
1518             _newPatJetPartonMatch.matched=genParticles
1519         else :
1520             addToProcessAndTask('patJetPartonMatch'+_labelName+postfix,
1521                                 patJetPartonMatch.clone(src=jetSource, matched=genParticles),
1522                                 process, task)
1523             knownModules.append('patJetPartonMatch'+_labelName+postfix)
1524         ## add new patJetGenJetMatch to process
1525         from PhysicsTools.PatAlgos.mcMatchLayer0.jetMatch_cfi import patJetGenJetMatch
1526         if 'patJetGenJetMatch'+_labelName+postfix in knownModules :
1527             _newPatJetGenJetMatch=getattr(process, 'patJetGenJetMatch'+_labelName+postfix)
1528             _newPatJetGenJetMatch.src=jetSource
1529             _newPatJetGenJetMatch.maxDeltaR=rParam
1530             _newPatJetGenJetMatch.matched=genJetCollection
1531         else :
1532             addToProcessAndTask('patJetGenJetMatch'+_labelName+postfix,
1533                                 patJetGenJetMatch.clone(src=jetSource, maxDeltaR=rParam, matched=genJetCollection),
1534                                 process, task)
1535             knownModules.append('patJetGenJetMatch'+_labelName+postfix)
1536         ## modify new patJets collection accordingly
1537         _newPatJets.genJetMatch.setModuleLabel('patJetGenJetMatch'+_labelName+postfix)
1538         _newPatJets.genPartonMatch.setModuleLabel('patJetPartonMatch'+_labelName+postfix)
1539         ## get jet MC truth flavour if required by user
1540         if (getJetMCFlavour):
1541             ## legacy jet flavour (see https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagMCTools)
1542             ## add new patJetPartonsLegacy to process
1543             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartonsLegacy
1544             if 'patJetPartonsLegacy'+postfix not in knownModules :
1545                 addToProcessAndTask('patJetPartonsLegacy'+postfix, patJetPartonsLegacy.clone(src=genParticles),
1546                                     process, task)
1547                 knownModules.append('patJetPartonsLegacy'+postfix)
1548             else:
1549                 getattr(process, 'patJetPartonsLegacy'+postfix).src=genParticles
1550             ## add new patJetPartonAssociationLegacy to process
1551             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartonAssociationLegacy
1552             if 'patJetPartonAssociationLegacy'+_labelName+postfix in knownModules :
1553                 _newPatJetPartonAssociation=getattr(process, 'patJetPartonAssociationLegacy'+_labelName+postfix)
1554                 _newPatJetPartonAssociation.jets=jetSource
1555             else :
1556                 addToProcessAndTask('patJetPartonAssociationLegacy'+_labelName+postfix,
1557                                     patJetPartonAssociationLegacy.clone(jets=jetSource), process, task)
1558                 knownModules.append('patJetPartonAssociationLegacy'+_labelName+postfix)
1559             ## add new patJetPartonAssociationLegacy to process
1560             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociationLegacy
1561             if 'patJetFlavourAssociationLegacy'+_labelName+postfix in knownModules :
1562                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociationLegacy'+_labelName+postfix)
1563                 _newPatJetFlavourAssociation.srcByReference='patJetPartonAssociationLegacy'+_labelName+postfix
1564             else:
1565                 addToProcessAndTask('patJetFlavourAssociationLegacy'+_labelName+postfix,
1566                                     patJetFlavourAssociationLegacy.clone(
1567                                         srcByReference='patJetPartonAssociationLegacy'+_labelName+postfix),
1568                                     process, task)
1569                 knownModules.append('patJetFlavourAssociationLegacy'+_labelName+postfix)
1570             ## modify new patJets collection accordingly
1571             _newPatJets.JetPartonMapSource.setModuleLabel('patJetFlavourAssociationLegacy'+_labelName+postfix)
1572             ## new jet flavour (see https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagMCTools)
1573             ## add new patJetPartons to process
1574             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartons
1575             if 'patJetPartons'+postfix not in knownModules :
1576                 addToProcessAndTask('patJetPartons'+postfix, patJetPartons.clone(particles=genParticles), process, task)
1577                 knownModules.append('patJetPartons'+postfix)
1578             else:
1579                 getattr(process, 'patJetPartons'+postfix).particles=genParticles
1580             ## add new patJetFlavourAssociation to process
1581             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociation
1582             if 'patJetFlavourAssociation'+_labelName+postfix in knownModules :
1583                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1584                 _newPatJetFlavourAssociation.jets=jetSource
1585                 _newPatJetFlavourAssociation.jetAlgorithm=_algo
1586                 _newPatJetFlavourAssociation.rParam=rParam
1587                 _newPatJetFlavourAssociation.bHadrons=cms.InputTag("patJetPartons"+postfix,"bHadrons")
1588                 _newPatJetFlavourAssociation.cHadrons=cms.InputTag("patJetPartons"+postfix,"cHadrons")
1589                 _newPatJetFlavourAssociation.partons=cms.InputTag("patJetPartons"+postfix,"physicsPartons")
1590                 _newPatJetFlavourAssociation.leptons=cms.InputTag("patJetPartons"+postfix,"leptons")
1591             else :
1592                 addToProcessAndTask('patJetFlavourAssociation'+_labelName+postfix,
1593                                     patJetFlavourAssociation.clone(
1594                                         jets=jetSource,
1595                                         jetAlgorithm=_algo,
1596                                         rParam=rParam,
1597                                         bHadrons = cms.InputTag("patJetPartons"+postfix,"bHadrons"),
1598                                         cHadrons = cms.InputTag("patJetPartons"+postfix,"cHadrons"),
1599                                         partons = cms.InputTag("patJetPartons"+postfix,"physicsPartons"),
1600                                         leptons = cms.InputTag("patJetPartons"+postfix,"leptons")),
1601                                     process, task)
1602 
1603                 knownModules.append('patJetFlavourAssociation'+_labelName+postfix)
1604             if 'Puppi' in jetSource.value() and pfCandidates.value() == 'particleFlow':
1605                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1606                 _newPatJetFlavourAssociation.weights = cms.InputTag("puppi")
1607             ## modify new patJets collection accordingly
1608             _newPatJets.JetFlavourInfoSource.setModuleLabel('patJetFlavourAssociation'+_labelName+postfix)
1609             ## if the jets is actually a subjet
1610             if fatJets != cms.InputTag('') and groomedFatJets != cms.InputTag(''):
1611                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1612                 _newPatJetFlavourAssociation.jets=fatJets
1613                 _newPatJetFlavourAssociation.groomedJets=groomedFatJets
1614                 _newPatJetFlavourAssociation.subjets=jetSource
1615                 _newPatJets.JetFlavourInfoSource=cms.InputTag('patJetFlavourAssociation'+_labelName+postfix,'SubJets')
1616         else:
1617             _newPatJets.getJetMCFlavour = False
1618             _newPatJets.addJetFlavourInfo = False
1619 
1620         ## add jetTrackAssociation for legacy btagging (or jetTracksAssociation only) if required by user
1621         if (jetTrackAssociation or bTaggingLegacy):
1622             ## add new jetTracksAssociationAtVertex to process
1623             from RecoJets.JetAssociationProducers.ak4JTA_cff import ak4JetTracksAssociatorAtVertex, ak4JetTracksAssociatorExplicit
1624             if 'jetTracksAssociationAtVertex'+_labelName+postfix in knownModules :
1625                 _newJetTracksAssociationAtVertex=getattr(process, 'jetTracksAssociatorAtVertex'+_labelName+postfix)
1626                 _newJetTracksAssociationAtVertex.jets=jetSource
1627                 _newJetTracksAssociationAtVertex.pvSrc=pvSource
1628             else:
1629                 jetTracksAssociator=ak4JetTracksAssociatorAtVertex
1630                 if explicitJTA:
1631                     jetTracksAssociator=ak4JetTracksAssociatorExplicit
1632                 addToProcessAndTask('jetTracksAssociatorAtVertex'+_labelName+postfix,
1633                                     jetTracksAssociator.clone(jets=jetSource,pvSrc=pvSource),
1634                                     process, task)
1635                 knownModules.append('jetTracksAssociationAtVertex'+_labelName+postfix)
1636             ## add new patJetCharge to process
1637             from PhysicsTools.PatAlgos.recoLayer0.jetTracksCharge_cff import patJetCharge
1638             if 'patJetCharge'+_labelName+postfix in knownModules :
1639                 _newPatJetCharge=getattr(process, 'patJetCharge'+_labelName+postfix)
1640                 _newPatJetCharge.src='jetTracksAssociatorAtVertex'+_labelName+postfix
1641             else:
1642                 addToProcessAndTask('patJetCharge'+_labelName+postfix,
1643                                     patJetCharge.clone(src = 'jetTracksAssociatorAtVertex'+_labelName+postfix),
1644                                     process, task)
1645                 knownModules.append('patJetCharge'+_labelName+postfix)
1646             ## modify new patJets collection accordingly
1647             _newPatJets.addAssociatedTracks=True
1648             _newPatJets.trackAssociationSource=cms.InputTag('jetTracksAssociatorAtVertex'+_labelName+postfix)
1649             _newPatJets.addJetCharge=True
1650             _newPatJets.jetChargeSource=cms.InputTag('patJetCharge'+_labelName+postfix)
1651         else:
1652             ## modify new patJets collection accordingly
1653             _newPatJets.addAssociatedTracks=False
1654             _newPatJets.trackAssociationSource=''
1655             _newPatJets.addJetCharge=False
1656             _newPatJets.jetChargeSource=''
1657         ## run btagging if required by user
1658         if (bTagging):
1659             setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
1660                           _algo, rParam, btagDiscriminators, btagInfos, _newPatJets, _labelName, btagPrefix, postfix)
1661         else:
1662             _newPatJets.addBTagInfo = False
1663             _newPatJets.addTagInfos = False
1664             ## adjust output module; these collections will be empty anyhow, but we do it to stay clean
1665             for outputModule in outputModules:
1666                     if hasattr(process,outputModule):
1667                         getattr(process,outputModule).outputCommands.append("drop *_"+'selected'+_labelName+postfix+"_tagInfos_*")
1668 
1669         ## add jet correction factors if required by user
1670         if (jetCorrections != None):
1671             ## check the jet corrections format
1672             checkJetCorrectionsFormat(jetCorrections)
1673             ## setup jet energy corrections and MET corrections
1674             setupJetCorrections(process, knownModules, jetCorrections, jetSource, pvSource, _newPatJets, _labelName, postfix)
1675         else:
1676             ## switch jetCorrFactors off
1677             _newPatJets.addJetCorrFactors=False
1678 
1679 addJetCollection=AddJetCollection()
1680 
1681 class SwitchJetCollection(ConfigToolBase):
1682     """
1683     Tool to switch parameters of the PAT jet collection to your PAT Tuple.
1684     """
1685     _label='switchJetCollection'
1686     _defaultParameters=dicttypes.SortedKeysDict()
1687 
1688     def __init__(self):
1689         """
1690         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1691         """
1692         ## initialization of the base class
1693         ConfigToolBase.__init__(self)
1694         ## add all parameters that should be known to the class
1695         self.addParameter(self._defaultParameters,'postfix','', "postfix from usePF2PAT")
1696         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1697         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1698         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('particleFlow'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1699         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1700         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlinePrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1701         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('inclusiveCandidateSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1702         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('gedGsfElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1703         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('muons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1704         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1705         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1706         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1707         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1708         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1709         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1710         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1711         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1712         self.addParameter(self._defaultParameters,'getJetMCFlavour', True, "Get jet MC truth flavour")
1713         self.addParameter(self._defaultParameters,'genJetCollection', cms.InputTag("ak4GenJets"), "GenJet collection to match to")
1714         self.addParameter(self._defaultParameters,'genParticles', cms.InputTag("genParticles"), "GenParticle collection to be used", cms.InputTag)
1715         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1716         collection. The format is to be passed on in a python tuple: e.g. (\'AK4Calo\',[\'L2Relative\', \'L3Absolute\'], patMet). The first argument corresponds to the payload \
1717         in the CMS Conditions database for the given jet collection; the second argument corresponds to the jet energy correction level that you want to be embedded into your \
1718         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1719         third argument indicates whether MET(Type1) corrections should be applied corresponding to the new patJetCollection. If so a new patMet collection will be added to your PAT \
1720         Tuple in addition to the raw patMet with the MET(Type1) corrections applied. The argument corresponds to the patMet collection to which the MET(Type1) corrections should be \
1721         applied. If you are not interested in MET(Type1) corrections to this new patJet collection pass None as third argument of the python tuple.", tuple, acceptNoneValue=True)
1722         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging in general the btag discriminators is all relevant \
1723         information that you need for a high level analysis. Add here all btag discriminators, that you are interested in as a list of strings. If this list is empty no btag \
1724         discriminator information will be added to your new patJet collection.", allowedValues=(list(set().union(supportedBtagDiscr.keys(),supportedMetaDiscr.keys()))),Type=list)
1725         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects conatin all relevant information from which all discriminators of a certain \
1726         type have been calculated. Note that this information on the one hand can be very space consuming and on the other hand is not necessary to access the btag discriminator \
1727         information that has been derived from it. Only in very special cases the btagInfos might really be needed in your analysis. Add here all btagInfos, that you are interested \
1728         in as a list of strings. If this list is empty no btagInfos will be added to your new patJet collection.", allowedValues=supportedBtagInfos,Type=list)
1729         self.addParameter(self._defaultParameters,'jetTrackAssociation',False, "Add JetTrackAssociation and JetCharge from reconstructed tracks to your new patJet collection. This \
1730         switch is only of relevance if you don\'t add any btag information to your new patJet collection (btagDiscriminators or btagInfos) and still want this information added to \
1731         your new patJetCollection. If btag information is added to the new patJet collection this information will be added automatically.")
1732         self.addParameter(self._defaultParameters,'outputModules',['out'],"Output module labels. Add a list of all output modules to which you would like the new jet collection to \
1733         be added, in case you use more than one output module.")
1734         ## set defaults
1735         self._parameters=copy.deepcopy(self._defaultParameters)
1736         ## add comments
1737         self._comment = "This is a tool to add more patJet collectinos to your PAT Tuple. You can add and embed additional information like jet energy correction factors, btag \
1738         information and generator match information to the new patJet collection depending on the parameters that you pass on to this function. Consult the descriptions of each \
1739         parameter for more information."
1740 
1741     def getDefaultParameters(self):
1742         """
1743         Return default parameters of the class
1744         """
1745         return self._defaultParameters
1746 
1747     def __call__(self,process,postfix=None,btagPrefix=None,jetSource=None,pfCandidates=None,explicitJTA=None,pvSource=None,svSource=None,elSource=None,muSource=None,runIVF=None,tightBTagNTkHits=None,loadStdRecoBTag=None,svClustering=None,fatJets=None,groomedFatJets=None,algo=None,rParam=None,getJetMCFlavour=None,genJetCollection=None,genParticles=None,jetCorrections=None,btagDiscriminators=None,btagInfos=None,jetTrackAssociation=None,outputModules=None):
1748         """
1749         Function call wrapper. This will check the parameters and call the actual implementation that
1750         can be found in toolCode via the base class function apply.
1751         """
1752         if postfix is None:
1753             postfix=self._defaultParameters['postfix'].value
1754         self.setParameter('postfix', postfix)
1755         if btagPrefix is None:
1756             btagPrefix=self._defaultParameters['btagPrefix'].value
1757         self.setParameter('btagPrefix', btagPrefix)
1758         if jetSource is None:
1759             jetSource=self._defaultParameters['jetSource'].value
1760         self.setParameter('jetSource', jetSource)
1761         if pfCandidates is None:
1762             pfCandidates=self._defaultParameters['pfCandidates'].value
1763         self.setParameter('pfCandidates', pfCandidates)
1764         if explicitJTA is None:
1765             explicitJTA=self._defaultParameters['explicitJTA'].value
1766         self.setParameter('explicitJTA', explicitJTA)
1767         if pvSource is None:
1768             pvSource=self._defaultParameters['pvSource'].value
1769         self.setParameter('pvSource', pvSource)
1770         if svSource is None:
1771             svSource=self._defaultParameters['svSource'].value
1772         self.setParameter('svSource', svSource)
1773         if elSource is None:
1774             elSource=self._defaultParameters['elSource'].value
1775         self.setParameter('elSource', elSource)
1776         if muSource is None:
1777             muSource=self._defaultParameters['muSource'].value
1778         self.setParameter('muSource', muSource)
1779         if runIVF is None:
1780             runIVF=self._defaultParameters['runIVF'].value
1781         self.setParameter('runIVF', runIVF)
1782         if tightBTagNTkHits is None:
1783             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
1784         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
1785         if loadStdRecoBTag is None:
1786             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
1787         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
1788         if svClustering is None:
1789             svClustering=self._defaultParameters['svClustering'].value
1790         self.setParameter('svClustering', svClustering)
1791         if fatJets is None:
1792             fatJets=self._defaultParameters['fatJets'].value
1793         self.setParameter('fatJets', fatJets)
1794         if groomedFatJets is None:
1795             groomedFatJets=self._defaultParameters['groomedFatJets'].value
1796         self.setParameter('groomedFatJets', groomedFatJets)
1797         if algo is None:
1798             algo=self._defaultParameters['algo'].value
1799         self.setParameter('algo', algo)
1800         if rParam is None:
1801             rParam=self._defaultParameters['rParam'].value
1802         self.setParameter('rParam', rParam)
1803         if getJetMCFlavour is None:
1804             getJetMCFlavour=self._defaultParameters['getJetMCFlavour'].value
1805         self.setParameter('getJetMCFlavour', getJetMCFlavour)
1806         if genJetCollection is None:
1807             genJetCollection=self._defaultParameters['genJetCollection'].value
1808         self.setParameter('genJetCollection', genJetCollection)
1809         if genParticles is None:
1810             genParticles=self._defaultParameters['genParticles'].value
1811         self.setParameter('genParticles', genParticles)
1812         if jetCorrections is None:
1813             jetCorrections=self._defaultParameters['jetCorrections'].value
1814         self.setParameter('jetCorrections', jetCorrections)
1815         if btagDiscriminators is None:
1816             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
1817         self.setParameter('btagDiscriminators', btagDiscriminators)
1818         if btagInfos is None:
1819             btagInfos=self._defaultParameters['btagInfos'].value
1820         self.setParameter('btagInfos', btagInfos)
1821         if jetTrackAssociation is None:
1822             jetTrackAssociation=self._defaultParameters['jetTrackAssociation'].value
1823         self.setParameter('jetTrackAssociation', jetTrackAssociation)
1824         if outputModules is None:
1825             outputModules=self._defaultParameters['outputModules'].value
1826         self.setParameter('outputModules', outputModules)
1827         self.apply(process)
1828 
1829     def toolCode(self, process):
1830         """
1831         Tool code implementation
1832         """
1833         ## initialize parameters
1834         postfix=self._parameters['postfix'].value
1835         btagPrefix=self._parameters['btagPrefix'].value
1836         jetSource=self._parameters['jetSource'].value
1837         pfCandidates=self._parameters['pfCandidates'].value
1838         explicitJTA=self._parameters['explicitJTA'].value
1839         pvSource=self._parameters['pvSource'].value
1840         svSource=self._parameters['svSource'].value
1841         elSource=self._parameters['elSource'].value
1842         muSource=self._parameters['muSource'].value
1843         runIVF=self._parameters['runIVF'].value
1844         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
1845         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
1846         svClustering=self._parameters['svClustering'].value
1847         fatJets=self._parameters['fatJets'].value
1848         groomedFatJets=self._parameters['groomedFatJets'].value
1849         algo=self._parameters['algo'].value
1850         rParam=self._parameters['rParam'].value
1851         getJetMCFlavour=self._parameters['getJetMCFlavour'].value
1852         genJetCollection=self._parameters['genJetCollection'].value
1853         genParticles=self._parameters['genParticles'].value
1854         jetCorrections=self._parameters['jetCorrections'].value
1855         btagDiscriminators=self._parameters['btagDiscriminators'].value
1856         btagInfos=self._parameters['btagInfos'].value
1857         jetTrackAssociation=self._parameters['jetTrackAssociation'].value
1858         outputModules=self._parameters['outputModules'].value
1859 
1860         ## call addJetCollections w/o labelName; this will act on the default patJets collection
1861         addJetCollection(
1862             process,
1863             labelName='',
1864             postfix=postfix,
1865             btagPrefix=btagPrefix,
1866             jetSource=jetSource,
1867             pfCandidates=pfCandidates,
1868             explicitJTA=explicitJTA,
1869             pvSource=pvSource,
1870             svSource=svSource,
1871             elSource=elSource,
1872             muSource=muSource,
1873             runIVF=runIVF,
1874             tightBTagNTkHits=tightBTagNTkHits,
1875             loadStdRecoBTag=loadStdRecoBTag,
1876             svClustering=svClustering,
1877             fatJets=fatJets,
1878             groomedFatJets=groomedFatJets,
1879             algo=algo,
1880             rParam=rParam,
1881             getJetMCFlavour=getJetMCFlavour,
1882             genJetCollection=genJetCollection,
1883             genParticles=genParticles,
1884             jetCorrections=jetCorrections,
1885             btagDiscriminators=btagDiscriminators,
1886             btagInfos=btagInfos,
1887             jetTrackAssociation=jetTrackAssociation,
1888             outputModules=outputModules,
1889             )
1890 
1891 switchJetCollection=SwitchJetCollection()
1892 
1893 
1894 class UpdateJetCollection(ConfigToolBase):
1895     """
1896     Tool to update a jet collection in your PAT Tuple (primarily intended for MiniAOD for which the default input argument values have been set).
1897     """
1898     _label='updateJetCollection'
1899     _defaultParameters=dicttypes.SortedKeysDict()
1900 
1901     def __init__(self):
1902         """
1903         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1904         """
1905         ## initialization of the base class
1906         ConfigToolBase.__init__(self)
1907         ## add all parameters that should be known to the class
1908         self.addParameter(self._defaultParameters,'labelName', '', "Label name of the new patJet collection.", str)
1909         self.addParameter(self._defaultParameters,'postfix','', "Postfix from usePF2PAT.", str)
1910         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1911         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1912         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('packedPFCandidates'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1913         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1914         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlineSlimmedPrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1915         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('slimmedSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1916         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('slimmedElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1917         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('slimmedMuons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1918         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1919         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1920         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1921         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1922         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1923         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1924         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1925         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1926         self.addParameter(self._defaultParameters,'sortByPt', True, "Set to False to not modify incoming jet order")
1927         self.addParameter(self._defaultParameters,'printWarning', True, "To be use as False in production to reduce log size")
1928         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1929         collection. The format has to be given in a python tuple of type: (\'AK4Calo\',[\'L2Relative\', \'L3Absolute\'], patMet). Here the first argument corresponds to the payload \
1930         in the CMS Conditions database for the given jet collection; the second argument corresponds to the jet energy correction levels that you want to be embedded into your \
1931         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1932         third argument indicates whether MET(Type1/2) corrections should be applied corresponding to the new patJetCollection. If so a new patMet collection will be added to your PAT \
1933         Tuple in addition to the raw patMet. This new patMet collection will have the MET(Type1/2) corrections applied. The argument can have the following types: \'type-1\' for \
1934         type-1 corrected MET; \'type-2\' for type-1 plus type-2 corrected MET; \'\' or \'none\' if no further MET corrections should be applied to your MET. The arguments \'type-1\' \
1935         and \'type-2\' are not case sensitive.", tuple, acceptNoneValue=True)
1936         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging, in most cases just the labels of the btag discriminators that \
1937         you are interested in is all relevant information that you need for a high level analysis. Add here all btag discriminators, that you are interested in as a list of strings. \
1938         If this list is empty no btag discriminator information will be added to your new patJet collection.", allowedValues=(list(set().union(supportedBtagDiscr.keys(),supportedMetaDiscr.keys()))),Type=list)
1939         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects contain all relevant information from which all discriminators of a certain \
1940         type have been calculated. You might be interested in keeping this information for low level tests or to re-calculate some discriminators from hand. Note that this information \
1941         on the one hand can be very space consuming and that it is not necessary to access the pre-calculated btag discriminator information that has been derived from it. Only in very \
1942         special cases the btagInfos might really be needed in your analysis. Add here all btagInfos, that you are interested in as a list of strings. If this list is empty no btagInfos \
1943         will be added to your new patJet collection.", allowedValues=supportedBtagInfos,Type=list)
1944         self.addParameter(self._defaultParameters,'outputModules',['out'],"Add a list of all output modules to which you would like the new jet collection to be added. Usually this is \
1945         just one single output module with name \'out\', which corresponds also the default configuration of the tool. There is cases though where you might want to add this collection \
1946         to more than one output module.")
1947         ## set defaults
1948         self._parameters=copy.deepcopy(self._defaultParameters)
1949         ## add comments
1950         self._comment = "This is a tool to add more patJet collectinos to your PAT Tuple or to re-configure the default collection. You can add and embed additional information like jet\
1951         energy correction factors, btag information and generator match information to the new patJet collection depending on the parameters that you pass on to this function. Consult \
1952         the descriptions of each parameter for more information."
1953 
1954     def getDefaultParameters(self):
1955         """
1956         Return default parameters of the class
1957         """
1958         return self._defaultParameters
1959 
1960     def __call__(self,process,labelName=None,postfix=None,btagPrefix=None,jetSource=None,pfCandidates=None,explicitJTA=None,pvSource=None,svSource=None,elSource=None,muSource=None,runIVF=None,tightBTagNTkHits=None,loadStdRecoBTag=None,svClustering=None,fatJets=None,groomedFatJets=None,algo=None,rParam=None,sortByPt=None,printWarning=None,jetCorrections=None,btagDiscriminators=None,btagInfos=None):
1961         """
1962         Function call wrapper. This will check the parameters and call the actual implementation that
1963         can be found in toolCode via the base class function apply.
1964         """
1965         if labelName is None:
1966             labelName=self._defaultParameters['labelName'].value
1967         self.setParameter('labelName', labelName)
1968         if postfix is None:
1969             postfix=self._defaultParameters['postfix'].value
1970         self.setParameter('postfix', postfix)
1971         if btagPrefix is None:
1972             btagPrefix=self._defaultParameters['btagPrefix'].value
1973         self.setParameter('btagPrefix', btagPrefix)
1974         if jetSource is None:
1975             jetSource=self._defaultParameters['jetSource'].value
1976         self.setParameter('jetSource', jetSource)
1977         if pfCandidates is None:
1978             pfCandidates=self._defaultParameters['pfCandidates'].value
1979         self.setParameter('pfCandidates', pfCandidates)
1980         if explicitJTA is None:
1981             explicitJTA=self._defaultParameters['explicitJTA'].value
1982         self.setParameter('explicitJTA', explicitJTA)
1983         if pvSource is None:
1984             pvSource=self._defaultParameters['pvSource'].value
1985         self.setParameter('pvSource', pvSource)
1986         if svSource is None:
1987             svSource=self._defaultParameters['svSource'].value
1988         self.setParameter('svSource', svSource)
1989         if elSource is None:
1990             elSource=self._defaultParameters['elSource'].value
1991         self.setParameter('elSource', elSource)
1992         if muSource is None:
1993             muSource=self._defaultParameters['muSource'].value
1994         self.setParameter('muSource', muSource)
1995         if runIVF is None:
1996             runIVF=self._defaultParameters['runIVF'].value
1997         self.setParameter('runIVF', runIVF)
1998         if tightBTagNTkHits is None:
1999             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
2000         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
2001         if loadStdRecoBTag is None:
2002             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
2003         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
2004         if svClustering is None:
2005             svClustering=self._defaultParameters['svClustering'].value
2006         self.setParameter('svClustering', svClustering)
2007         if fatJets is None:
2008             fatJets=self._defaultParameters['fatJets'].value
2009         self.setParameter('fatJets', fatJets)
2010         if groomedFatJets is None:
2011             groomedFatJets=self._defaultParameters['groomedFatJets'].value
2012         self.setParameter('groomedFatJets', groomedFatJets)
2013         if algo is None:
2014             algo=self._defaultParameters['algo'].value
2015         self.setParameter('algo', algo)
2016         if rParam is None:
2017             rParam=self._defaultParameters['rParam'].value
2018         self.setParameter('rParam', rParam)
2019         if sortByPt is None:
2020             sortByPt=self._defaultParameters['sortByPt'].value
2021         self.setParameter('sortByPt', sortByPt)
2022         if printWarning is None:
2023             printWarning=self._defaultParameters['printWarning'].value
2024         self.setParameter('printWarning', printWarning)
2025         if jetCorrections is None:
2026             jetCorrections=self._defaultParameters['jetCorrections'].value
2027         self.setParameter('jetCorrections', jetCorrections)
2028         if btagDiscriminators is None:
2029             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
2030         self.setParameter('btagDiscriminators', btagDiscriminators)
2031         if btagInfos is None:
2032             btagInfos=self._defaultParameters['btagInfos'].value
2033         self.setParameter('btagInfos', btagInfos)
2034         self.apply(process)
2035 
2036     def toolCode(self, process):
2037         """
2038         Tool code implementation
2039         """
2040         ## initialize parameters
2041         labelName=self._parameters['labelName'].value
2042         postfix=self._parameters['postfix'].value
2043         btagPrefix=self._parameters['btagPrefix'].value
2044         jetSource=self._parameters['jetSource'].value
2045         pfCandidates=self._parameters['pfCandidates'].value
2046         explicitJTA=self._parameters['explicitJTA'].value
2047         pvSource=self._parameters['pvSource'].value
2048         svSource=self._parameters['svSource'].value
2049         elSource=self._parameters['elSource'].value
2050         muSource=self._parameters['muSource'].value
2051         runIVF=self._parameters['runIVF'].value
2052         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
2053         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
2054         svClustering=self._parameters['svClustering'].value
2055         fatJets=self._parameters['fatJets'].value
2056         groomedFatJets=self._parameters['groomedFatJets'].value
2057         algo=self._parameters['algo'].value
2058         rParam=self._parameters['rParam'].value
2059         sortByPt=self._parameters['sortByPt'].value
2060         printWarning=self._parameters['printWarning'].value
2061         jetCorrections=self._parameters['jetCorrections'].value
2062         btagDiscriminators=list(self._parameters['btagDiscriminators'].value)
2063         btagInfos=list(self._parameters['btagInfos'].value)
2064 
2065         ## a list of all producer modules, which are already known to process
2066         knownModules = process.producerNames().split()
2067         ## determine whether btagging information is required or not
2068         if btagDiscriminators.count('None')>0:
2069             btagDiscriminators.remove('None')
2070         if btagInfos.count('None')>0:
2071             btagInfos.remove('None')
2072         bTagging=(len(btagDiscriminators)>0 or len(btagInfos)>0)
2073 
2074         ## construct postfix label for auxiliary modules; this postfix
2075         ## label will start with a capitalized first letter following
2076         ## the CMS naming conventions and for improved readablility
2077         _labelName=labelName[:1].upper()+labelName[1:]
2078 
2079         ## supported algo types are ak, ca, and kt
2080         _algo=''
2081         for x in ["ak", "ca", "kt"]:
2082             if x in algo.lower():
2083                 _algo=supportedJetAlgos[x]
2084                 break
2085         if _algo=='':
2086             unsupportedJetAlgorithm(self)
2087 
2088         task = getPatAlgosToolsTask(process)
2089 
2090         ## add new updatedPatJets to process (keep instance for later further modifications)
2091         from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cfi import updatedPatJets
2092         if not sortByPt: # default is True
2093             updatedPatJets.sort = cms.bool(False)
2094         if 'updatedPatJets'+_labelName+postfix in knownModules :
2095             _newPatJets=getattr(process, 'updatedPatJets'+_labelName+postfix)
2096             _newPatJets.jetSource=jetSource
2097         else :
2098             addToProcessAndTask('updatedPatJets'+_labelName+postfix,
2099                                 updatedPatJets.clone(jetSource=jetSource,
2100                                 printWarning=printWarning), process, task)
2101             _newPatJets=getattr(process, 'updatedPatJets'+_labelName+postfix)
2102             knownModules.append('updatedPatJets'+_labelName+postfix)
2103         ## add new selectedUpdatedPatJets to process
2104         from PhysicsTools.PatAlgos.selectionLayer1.jetSelector_cfi import selectedPatJets
2105         if 'selectedUpdatedPatJets'+_labelName+postfix in knownModules :
2106             _newSelectedPatJets=getattr(process, 'selectedUpdatedPatJets'+_labelName+postfix)
2107             _newSelectedPatJets.src='updatedPatJets'+_labelName+postfix
2108         else :
2109             addToProcessAndTask('selectedUpdatedPatJets'+_labelName+postfix,
2110                                 selectedPatJets.clone(src='updatedPatJets'+_labelName+postfix),
2111                                 process, task)
2112             knownModules.append('selectedUpdatedPatJets'+_labelName+postfix)
2113 
2114         ## run btagging if required by user
2115         if (bTagging):
2116             if printWarning:
2117                sys.stderr.write("**************************************************************\n")
2118                sys.stderr.write("b tagging needs to be run on uncorrected jets. Hence, the JECs\n")
2119                sys.stderr.write("will first be undone for 'updatedPatJets%s' and then applied to\n" % (_labelName+postfix) )
2120                sys.stderr.write("'updatedPatJetsTransientCorrected%s'.\n" % (_labelName+postfix) )
2121                sys.stderr.write("**************************************************************\n")
2122             _jetSource = cms.InputTag('updatedPatJets'+_labelName+postfix)
2123             ## insert new jet collection with jet corrections applied and btag info added
2124             self(
2125                 process,
2126                 labelName = ('TransientCorrected'+_labelName),
2127                 jetSource = _jetSource,
2128                 pfCandidates=pfCandidates,
2129                 explicitJTA=explicitJTA,
2130                 pvSource=pvSource,
2131                 svSource=svSource,
2132                 elSource=elSource,
2133                 muSource=muSource,
2134                 runIVF=runIVF,
2135                 tightBTagNTkHits=tightBTagNTkHits,
2136                 loadStdRecoBTag=loadStdRecoBTag,
2137                 svClustering=svClustering,
2138                 fatJets=fatJets,
2139                 groomedFatJets=groomedFatJets,
2140                 algo=algo,
2141                 rParam=rParam,
2142                 jetCorrections = jetCorrections,
2143                 btagPrefix = btagPrefix,
2144                 postfix = postfix
2145             )
2146             ## setup btagging
2147             _patJets=getattr(process, 'updatedPatJetsTransientCorrected'+_labelName+postfix)
2148             setupBTagging(process, _jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
2149                           _algo, rParam, btagDiscriminators, btagInfos, _patJets, _labelName, btagPrefix, postfix)
2150             ## update final selected jets
2151             _newSelectedPatJets=getattr(process, 'selectedUpdatedPatJets'+_labelName+postfix)
2152             _newSelectedPatJets.src='updatedPatJetsTransientCorrected'+_labelName+postfix
2153             ## remove automatically added but redundant 'TransientCorrected' selected jets
2154             delattr(process, 'selectedUpdatedPatJetsTransientCorrected'+_labelName+postfix)
2155         else:
2156             _newPatJets.addBTagInfo = False
2157             _newPatJets.addTagInfos = False
2158 
2159         ## add jet correction factors if required by user
2160         if (jetCorrections is not None or bTagging):
2161             ## check the jet corrections format
2162             if jetCorrections is None and bTagging:
2163                 raise ValueError("Passing jetCorrections = None while running bTagging is likely not intended.")
2164             else:
2165                 checkJetCorrectionsFormat(jetCorrections)
2166             ## reset MET corrrection
2167             if jetCorrections[2].lower() != 'none' and jetCorrections[2] != '':
2168                 sys.stderr.write("-------------------------------------------------------------------\n")
2169                 sys.stderr.write(" Warning: MET correction was set to " + jetCorrections[2] + " but\n")
2170                 sys.stderr.write("          will be ignored. Please set it to \"None\" to avoid\n")
2171                 sys.stderr.write("          getting this warning.\n")
2172                 sys.stderr.write("-------------------------------------------------------------------\n")
2173                 jetCorrectionsList = list(jetCorrections)
2174                 jetCorrectionsList[2] = 'None'
2175                 jetCorrections = tuple(jetCorrectionsList)
2176             ## if running b tagging, need to use uncorrected jets
2177             if (bTagging):
2178                 jetCorrections = ('AK4PFchs', cms.vstring([]), 'None')
2179             ## setup jet energy corrections
2180             setupJetCorrections(process, knownModules, jetCorrections, jetSource, pvSource, _newPatJets, _labelName, postfix)
2181         else:
2182             ## switch jetCorrFactors off
2183             _newPatJets.addJetCorrFactors=False
2184 
2185 updateJetCollection=UpdateJetCollection()
2186 
2187 
2188 class AddJetID(ConfigToolBase):
2189     """
2190     Compute jet id for process
2191     """
2192     _label='addJetID'
2193     _defaultParameters=dicttypes.SortedKeysDict()
2194     def __init__(self):
2195         ConfigToolBase.__init__(self)
2196         self.addParameter(self._defaultParameters,'jetSrc','', "", Type=cms.InputTag)
2197         self.addParameter(self._defaultParameters,'jetIdTag','', "Tag to append to jet id map", Type=str)
2198         self._parameters=copy.deepcopy(self._defaultParameters)
2199         self._comment = ""
2200 
2201     def getDefaultParameters(self):
2202         return self._defaultParameters
2203 
2204     def __call__(self,process,
2205                  jetSrc     = None,
2206                  jetIdTag    = None) :
2207         if  jetSrc is None:
2208             jetSrc=self._defaultParameters['jetSrc'].value
2209         if  jetIdTag is None:
2210             jetIdTag=self._defaultParameters['jetIdTag'].value
2211         self.setParameter('jetSrc',jetSrc)
2212         self.setParameter('jetIdTag',jetIdTag)
2213         self.apply(process)
2214 
2215     def toolCode(self, process):
2216         jetSrc=self._parameters['jetSrc'].value
2217         jetIdTag=self._parameters['jetIdTag'].value
2218 
2219         jetIdLabel = jetIdTag + 'JetID'
2220         sys.stderr.write("Making new jet ID label with label " + jetIdTag + "\n")
2221 
2222         ## replace jet id sequence
2223         task = getPatAlgosToolsTask(process)
2224         process.load("RecoJets.JetProducers.ak4JetID_cfi")
2225         task.add(process.ak4JetID)
2226         addToProcessAndTask(jetIdLabel, process.ak4JetID.clone(src = jetSrc),
2227                             process, task)
2228 
2229 
2230 addJetID=AddJetID()
2231 
2232 
2233 class SetTagInfos(ConfigToolBase):
2234     """
2235     Replace tag infos for collection jetSrc
2236     """
2237     _label='setTagInfos'
2238     _defaultParameters=dicttypes.SortedKeysDict()
2239     def __init__(self):
2240         ConfigToolBase.__init__(self)
2241         self.addParameter(self._defaultParameters,'coll',"patJets","jet collection to set tag infos for")
2242         self.addParameter(self._defaultParameters,'tagInfos',cms.vstring( ), "tag infos to set")
2243         self._parameters=copy.deepcopy(self._defaultParameters)
2244         self._comment = ""
2245 
2246     def getDefaultParameters(self):
2247         return self._defaultParameters
2248 
2249     def __call__(self,process,
2250                  coll         = None,
2251                  tagInfos     = None) :
2252         if  coll is None:
2253             coll=self._defaultParameters['coll'].value
2254         if  tagInfos is None:
2255             tagInfos=self._defaultParameters['tagInfos'].value
2256         self.setParameter('coll',coll)
2257         self.setParameter('tagInfos',tagInfos)
2258         self.apply(process)
2259 
2260     def toolCode(self, process):
2261         coll=self._parameters['coll'].value
2262         tagInfos=self._parameters['tagInfos'].value
2263 
2264         found = False
2265         newTags = cms.VInputTag()
2266         iNewTags = 0
2267         for k in tagInfos :
2268             for j in getattr( process, coll ).tagInfoSources :
2269                 vv = j.value();
2270                 if ( vv.find(k) != -1 ):
2271                     found = True
2272                     newTags.append( j )
2273 
2274         if not found:
2275             raise RuntimeError("""
2276             Cannot replace tag infos in jet collection""" % (coll))
2277         else :
2278             getattr(process,coll).tagInfoSources = newTags
2279 
2280 setTagInfos=SetTagInfos()
2281 
2282 def deprecatedOptionOutputModule(obj):
2283     sys.stderr.write("-------------------------------------------------------\n")
2284     sys.stderr.write(" Error: the option 'outputModule' is not supported\n")
2285     sys.stderr.write("        anymore by:\n")
2286     sys.stderr.write("                     " + obj._label + "\n")
2287     sys.stderr.write("        please use 'outputModules' now and specify the\n")
2288     sys.stderr.write("        names of all needed OutModules in there\n")
2289     sys.stderr.write("        (default: ['out'])\n")
2290     sys.stderr.write("-------------------------------------------------------\n")
2291     raise KeyError("Unsupported option 'outputModule' used in '"+obj._label+"'")
2292 
2293 def undefinedLabelName(obj):
2294     sys.stderr.write("-------------------------------------------------------\n")
2295     sys.stderr.write(" Error: the jet 'labelName' is not defined.\n")
2296     sys.stderr.write("        All added jets must have 'labelName' defined.\n")
2297     sys.stderr.write("-------------------------------------------------------\n")
2298     raise KeyError("Undefined jet 'labelName' used in '"+obj._label+"'")
2299 
2300 def unsupportedJetAlgorithm(obj):
2301     sys.stderr.write("-------------------------------------------------------\n")
2302     sys.stderr.write(" Error: Unsupported jet algorithm detected.\n")
2303     sys.stderr.write("        The supported algorithms are:\n")
2304     for key in supportedJetAlgos.keys():
2305         sys.stderr.write("        " + key.upper() + ", " + key.lower() + ": " + supportedJetAlgos[key] + "\n")
2306     sys.stderr.write("-------------------------------------------------------\n")
2307     raise KeyError("Unsupported jet algorithm used in '"+obj._label+"'")
2308 
2309 def rerunningIVF():
2310     sys.stderr.write("-------------------------------------------------------------------\n")
2311     sys.stderr.write(" Warning: You are attempting to remake the IVF secondary vertices\n")
2312     sys.stderr.write("          already produced by the standard reconstruction. This\n")
2313     sys.stderr.write("          option is not enabled by default so please use it only if\n")
2314     sys.stderr.write("          you know what you are doing.\n")
2315     sys.stderr.write("-------------------------------------------------------------------\n")
2316 
2317 def rerunningIVFMiniAOD():
2318     sys.stderr.write("-------------------------------------------------------------------\n")
2319     sys.stderr.write(" Warning: You are attempting to remake IVF secondary vertices from\n")
2320     sys.stderr.write("          MiniAOD. If that was your intention, note that secondary\n")
2321     sys.stderr.write("          vertices remade from MiniAOD will have somewhat degraded\n")
2322     sys.stderr.write("          performance compared to those remade from RECO/AOD.\n")
2323     sys.stderr.write("-------------------------------------------------------------------\n")