Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:58:19

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
0011 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiForwardTagInfos,pfParticleNetFromMiniAODAK4PuppiForwardJetTags,pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags
0012 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSCentralTagInfos,pfParticleNetFromMiniAODAK4CHSCentralJetTags,pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags
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:
0685                 svUsed = svSource
0686                 if btagInfo == 'pfNegativeParticleTransformerAK4TagInfos':
0687                     svUsed = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix)
0688                     flip = True 
0689                 else:
0690                     flip = False
0691                 # use right input tags when running with RECO PF candidates, which actually
0692                 # depends of whether jets use "particleFlow"
0693                 if pfCandidates.value() == 'packedPFCandidates':
0694                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0695                     vertex_associator = cms.InputTag("")
0696                 else:
0697                     puppi_value_map = cms.InputTag("puppi")
0698                     vertex_associator = cms.InputTag("primaryVertexAssociation","original")
0699 
0700                 # If this jet is a puppi jet, then set is_weighted_jet to true.
0701                 is_weighted_jet = False
0702                 if ('puppi' in jetSource.value().lower()):
0703                     is_weighted_jet = True
0704                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0705                                     btag.pfParticleTransformerAK4TagInfos.clone(
0706                                       jets = jetSource,
0707                                       vertices=pvSource,
0708                                       secondary_vertices=svUsed,
0709                                       puppi_value_map = puppi_value_map,
0710                                       vertex_associator = vertex_associator,
0711                                       is_weighted_jet = is_weighted_jet,
0712                                       flip = flip),
0713                                     process, task)
0714             if btagInfo == 'pfDeepDoubleXTagInfos':
0715                 # can only run on PAT jets, so the updater needs to be used
0716                 if 'updated' not in jetSource.value().lower():
0717                     raise ValueError("Invalid jet collection: %s. pfDeepDoubleXTagInfos only supports running via updateJetCollection." % jetSource.value())
0718                 packedPFPuppiLabel = setupPuppiForPackedPF(process)[0]
0719                 puppi_value_map = cms.InputTag(packedPFPuppiLabel)
0720                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0721                                     btag.pfDeepDoubleXTagInfos.clone(
0722                                       jets = jetSource,
0723                                       vertices=pvSource,
0724                                       secondary_vertices=svSource,
0725                                       shallow_tag_infos = cms.InputTag(btagPrefix+'pfBoostedDoubleSVAK8TagInfos'+labelName+postfix),
0726                                       puppi_value_map = puppi_value_map,
0727                                       ),
0728                                     process, task)
0729             if btagInfo == 'pfHiggsInteractionNetTagInfos':
0730                 packedPFPuppiLabel = setupPuppiForPackedPF(process)[0]
0731                 puppi_value_map = cms.InputTag(packedPFPuppiLabel)
0732                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0733                                     btag.pfHiggsInteractionNetTagInfos.clone(
0734                                       jets = jetSource,
0735                                       vertices = pvSource,
0736                                       secondary_vertices = svSource,
0737                                       pf_candidates = pfCandidates,
0738                                       puppi_value_map = puppi_value_map
0739                                       ),
0740                                     process, task)
0741 
0742             if btagInfo == 'pfDeepBoostedJetTagInfos':
0743                 if pfCandidates.value() == 'packedPFCandidates':
0744                     # case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
0745                     if 'updated' not in jetSource.value().lower():
0746                         raise ValueError("Invalid jet collection: %s. pfDeepBoostedJetTagInfos only supports running via updateJetCollection." % jetSource.value())
0747                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0748                     vertex_associator = ""
0749                 elif pfCandidates.value() == 'particleFlow':
0750                     raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
0751                     # case 2: running on new jet collection whose daughters are PFCandidates (e.g., cluster jets in RECO/AOD)
0752                     # daughters are the particles used in jet clustering, so already scaled by their puppi weights
0753                     # Uncomment the lines below after running pfDeepBoostedJetTagInfos with reco::PFCandidates becomes supported
0754 #                     puppi_value_map = "puppi"
0755 #                     vertex_associator = "primaryVertexAssociation:original"
0756                 else:
0757                     raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0758                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0759                                     btag.pfDeepBoostedJetTagInfos.clone(
0760                                       jets = jetSource,
0761                                       vertices = pvSource,
0762                                       secondary_vertices = svSource,
0763                                       pf_candidates = pfCandidates,
0764                                       puppi_value_map = puppi_value_map,
0765                                       vertex_associator = vertex_associator,
0766                                       ),
0767                                     process, task)
0768 
0769             if btagInfo == 'pfParticleNetTagInfos':
0770                 if pfCandidates.value() == 'packedPFCandidates':
0771                     # case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
0772                     puppi_value_map = setupPuppiForPackedPF(process)[0]
0773                     vertex_associator = ""
0774                 elif pfCandidates.value() == 'particleFlow':
0775                     raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
0776                     # case 2: running on new jet collection whose daughters are PFCandidates (e.g., cluster jets in RECO/AOD)
0777                     puppi_value_map = "puppi"
0778                     vertex_associator = "primaryVertexAssociation:original"
0779                 else:
0780                     raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0781                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0782                                     btag.pfParticleNetTagInfos.clone(
0783                                       jets = jetSource,
0784                                       vertices = pvSource,
0785                                       secondary_vertices = svSource,
0786                                       pf_candidates = pfCandidates,
0787                                       puppi_value_map = puppi_value_map,
0788                                       vertex_associator = vertex_associator,
0789                                       ),
0790                                     process, task)
0791 
0792             if 'ParticleNetAK4TagInfos' in btagInfo:
0793                 if btagInfo == 'pfNegativeParticleNetAK4TagInfos':
0794                     secondary_vertices = btagPrefix + \
0795                         'inclusiveCandidateNegativeSecondaryVertices' + labelName + postfix
0796                     flip_ip_sign = True
0797                     sip3dSigMax = 10
0798                 else:
0799                     secondary_vertices = svSource
0800                     flip_ip_sign = False
0801                     sip3dSigMax = -1
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                 # If this jet is a Puppi jet, use puppi-weighted p4.
0814                 use_puppiP4 = False
0815                 if "puppi" in jetSource.value().lower():
0816                     use_puppiP4 = True
0817                 addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0818                                     btag.pfParticleNetAK4TagInfos.clone(
0819                                       jets = jetSource,
0820                                       vertices = pvSource,
0821                                       secondary_vertices = secondary_vertices,
0822                                       pf_candidates = pfCandidates,
0823                                       puppi_value_map = puppi_value_map,
0824                                       vertex_associator = vertex_associator,
0825                                       flip_ip_sign = flip_ip_sign,
0826                                       sip3dSigMax = sip3dSigMax,
0827                                       use_puppiP4 = use_puppiP4
0828                                       ),
0829                                     process, task)
0830 
0831             acceptedTagInfos.append(btagInfo)
0832         elif hasattr(toptag, btagInfo) :
0833             acceptedTagInfos.append(btagInfo)
0834         elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiCentralTagInfos':
0835             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0836             if pfCandidates.value() != 'packedPFCandidates':
0837                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0838             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0839                                 pfParticleNetFromMiniAODAK4PuppiCentralTagInfos.clone(
0840                                   jets = jetSource,
0841                                   vertices = pvSource,
0842                                   secondary_vertices = svSource,
0843                                   pf_candidates = pfCandidates,
0844                                   ),
0845                                 process, task)
0846             acceptedTagInfos.append(btagInfo)
0847         elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiForwardTagInfos':
0848             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0849             if pfCandidates.value() != 'packedPFCandidates':
0850                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0851             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0852                                 pfParticleNetFromMiniAODAK4PuppiForwardTagInfos.clone(
0853                                   jets = jetSource,
0854                                   vertices = pvSource,
0855                                   secondary_vertices = svSource,
0856                                   pf_candidates = pfCandidates,
0857                                   ),
0858                                 process, task)
0859             acceptedTagInfos.append(btagInfo)
0860         elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSCentralTagInfos':
0861             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0862             if pfCandidates.value() != 'packedPFCandidates':
0863                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0864             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0865                                 pfParticleNetFromMiniAODAK4CHSCentralTagInfos.clone(
0866                                   jets = jetSource,
0867                                   vertices = pvSource,
0868                                   secondary_vertices = svSource,
0869                                   pf_candidates = pfCandidates,
0870                                   ),
0871                                 process, task)
0872             acceptedTagInfos.append(btagInfo)
0873         elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSForwardTagInfos':
0874             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0875             if pfCandidates.value() != 'packedPFCandidates':
0876                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0877             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0878                                 pfParticleNetFromMiniAODAK4CHSForwardTagInfos.clone(
0879                                   jets = jetSource,
0880                                   vertices = pvSource,
0881                                   secondary_vertices = svSource,
0882                                   pf_candidates = pfCandidates,
0883                                   ),
0884                                 process, task)
0885             acceptedTagInfos.append(btagInfo)
0886         elif btagInfo == 'pfParticleNetFromMiniAODAK8TagInfos':
0887             # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround
0888             if pfCandidates.value() != 'packedPFCandidates':
0889                 raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
0890             addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
0891                                 pfParticleNetFromMiniAODAK8TagInfos.clone(
0892                                   jets = jetSource,
0893                                   vertices = pvSource,
0894                                   secondary_vertices = svSource,
0895                                   pf_candidates = pfCandidates,
0896                                   ),
0897                                 process, task)
0898             acceptedTagInfos.append(btagInfo)
0899         else:
0900             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagInfo))
0901     # setup all required btagDiscriminators
0902     acceptedBtagDiscriminators = list()
0903     for discriminator_name in btagDiscriminators :          
0904         btagDiscr = discriminator_name.split(':')[0] #split input tag to get the producer label
0905         #print discriminator_name, '-->', btagDiscr
0906         newDiscr = btagPrefix+btagDiscr+labelName+postfix #new discriminator name
0907         if hasattr(btag,btagDiscr): 
0908             if hasattr(process, newDiscr):
0909                 pass 
0910             elif hasattr(getattr(btag, btagDiscr), 'tagInfos'):
0911                 addToProcessAndTask(
0912                     newDiscr,
0913                     getattr(btag, btagDiscr).clone(
0914                         tagInfos = cms.VInputTag(
0915                             *[ cms.InputTag(btagPrefix+x+labelName+postfix) \
0916                             for x in supportedBtagDiscr[discriminator_name][0] ]
0917                         )
0918                     ),
0919                     process,
0920                     task
0921                 )
0922             elif hasattr(getattr(btag, btagDiscr), 'src'):
0923                 addToProcessAndTask(
0924                     newDiscr,
0925                     getattr(btag, btagDiscr).clone(
0926                         src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0927                     ),
0928                     process,
0929                     task
0930                 )
0931             else:
0932                 raise ValueError('I do not know how to update %s it does not have neither "tagInfos" nor "src" attributes' % btagDiscr)
0933             acceptedBtagDiscriminators.append(discriminator_name)
0934         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiCentralJetTags':
0935             if hasattr(process, newDiscr):
0936                 pass
0937             addToProcessAndTask(
0938                 newDiscr,
0939                 pfParticleNetFromMiniAODAK4PuppiCentralJetTags.clone(
0940                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0941                 ),
0942                 process,
0943                 task
0944             )
0945             acceptedBtagDiscriminators.append(discriminator_name)
0946         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiForwardJetTags':
0947             if hasattr(process, newDiscr):
0948                 pass
0949             addToProcessAndTask(
0950                 newDiscr,
0951                 pfParticleNetFromMiniAODAK4PuppiForwardJetTags.clone(
0952                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0953                 ),
0954                 process,
0955                 task
0956             )
0957             acceptedBtagDiscriminators.append(discriminator_name)
0958         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSCentralJetTags':
0959             if hasattr(process, newDiscr):
0960                 pass
0961             addToProcessAndTask(
0962                 newDiscr,
0963                 pfParticleNetFromMiniAODAK4CHSCentralJetTags.clone(
0964                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0965                 ),
0966                 process,
0967                 task
0968             )
0969             acceptedBtagDiscriminators.append(discriminator_name)
0970         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSForwardJetTags':
0971             if hasattr(process, newDiscr):
0972                 pass
0973             addToProcessAndTask(
0974                 newDiscr,
0975                 pfParticleNetFromMiniAODAK4CHSForwardJetTags.clone(
0976                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0977                 ),
0978                 process,
0979                 task
0980             )
0981             acceptedBtagDiscriminators.append(discriminator_name)
0982         elif btagDiscr=='pfParticleNetFromMiniAODAK8JetTags':
0983             if hasattr(process, newDiscr):
0984                 pass
0985             addToProcessAndTask(
0986                 newDiscr,
0987                 pfParticleNetFromMiniAODAK8JetTags.clone(
0988                     src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix)
0989                 ),
0990                 process,
0991                 task
0992             )
0993             acceptedBtagDiscriminators.append(discriminator_name)
0994         else:
0995             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagDiscr))
0996             
0997     #update meta-taggers, if any
0998     for meta_tagger in present_meta:
0999         btagDiscr = meta_tagger.split(':')[0] #split input tag to get the producer label
1000         #print discriminator_name, '-->', btagDiscr
1001         newDiscr = btagPrefix+btagDiscr+labelName+postfix #new discriminator name
1002         if hasattr(btag,btagDiscr): 
1003             if hasattr(process, newDiscr):
1004                 pass 
1005             else:
1006                 addToProcessAndTask(
1007                     newDiscr,
1008                     getattr(btag, btagDiscr).clone(),
1009                     process,
1010                     task
1011                 )
1012                 for dependency in supportedMetaDiscr[meta_tagger]:
1013                     if ':' in dependency:
1014                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1015                     else:
1016                         new_dep = btagPrefix+dependency+labelName+postfix
1017                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1018                     replace.doIt(getattr(process, newDiscr), newDiscr)
1019             acceptedBtagDiscriminators.append(meta_tagger)
1020         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags':
1021             if hasattr(process, newDiscr):
1022                 pass 
1023             else:
1024                 addToProcessAndTask(
1025                     newDiscr,
1026                     pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags.clone(),
1027                     process,
1028                     task
1029                 )
1030                 for dependency in supportedMetaDiscr[meta_tagger]:
1031                     if ':' in dependency:
1032                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1033                     else:
1034                         new_dep = btagPrefix+dependency+labelName+postfix
1035                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1036                     replace.doIt(getattr(process, newDiscr), newDiscr)
1037             acceptedBtagDiscriminators.append(meta_tagger)
1038         elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags':
1039             if hasattr(process, newDiscr):
1040                 pass 
1041             else:
1042                 addToProcessAndTask(
1043                     newDiscr,
1044                     pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags.clone(),
1045                     process,
1046                     task
1047                 )
1048                 for dependency in supportedMetaDiscr[meta_tagger]:
1049                     if ':' in dependency:
1050                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1051                     else:
1052                         new_dep = btagPrefix+dependency+labelName+postfix
1053                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1054                     replace.doIt(getattr(process, newDiscr), newDiscr)
1055             acceptedBtagDiscriminators.append(meta_tagger)
1056         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags':
1057             if hasattr(process, newDiscr):
1058                 pass 
1059             else:
1060                 addToProcessAndTask(
1061                     newDiscr,
1062                     pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags.clone(),
1063                     process,
1064                     task
1065                 )
1066                 for dependency in supportedMetaDiscr[meta_tagger]:
1067                     if ':' in dependency:
1068                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1069                     else:
1070                         new_dep = btagPrefix+dependency+labelName+postfix
1071                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1072                     replace.doIt(getattr(process, newDiscr), newDiscr)
1073             acceptedBtagDiscriminators.append(meta_tagger)
1074         elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags':
1075             if hasattr(process, newDiscr):
1076                 pass 
1077             else:
1078                 addToProcessAndTask(
1079                     newDiscr,
1080                     pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags.clone(),
1081                     process,
1082                     task
1083                 )
1084                 for dependency in supportedMetaDiscr[meta_tagger]:
1085                     if ':' in dependency:
1086                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1087                     else:
1088                         new_dep = btagPrefix+dependency+labelName+postfix
1089                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1090                     replace.doIt(getattr(process, newDiscr), newDiscr)
1091             acceptedBtagDiscriminators.append(meta_tagger)
1092         elif btagDiscr=='pfParticleNetFromMiniAODAK8DiscriminatorsJetTags':
1093             if hasattr(process, newDiscr):
1094                 pass 
1095             else:
1096                 addToProcessAndTask(
1097                     newDiscr,
1098                     pfParticleNetFromMiniAODAK8DiscriminatorsJetTags.clone(),
1099                     process,
1100                     task
1101                 )
1102                 for dependency in supportedMetaDiscr[meta_tagger]:
1103                     if ':' in dependency:
1104                         new_dep = btagPrefix+dependency.split(':')[0]+labelName+postfix+':'+dependency.split(':')[1]
1105                     else:
1106                         new_dep = btagPrefix+dependency+labelName+postfix
1107                     replace = MassSearchReplaceAnyInputTagVisitor(dependency, new_dep)
1108                     replace.doIt(getattr(process, newDiscr), newDiscr)
1109             acceptedBtagDiscriminators.append(meta_tagger)
1110                         
1111         else:
1112             print('  --> %s ignored, since not available via RecoBTag.Configuration.RecoBTag_cff!'%(btagDiscr))
1113         
1114     ## replace corresponding tags for pat jet production
1115     patJets.tagInfoSources = cms.VInputTag( *[ cms.InputTag(btagPrefix+x+labelName+postfix) for x in acceptedTagInfos ] )
1116     patJets.discriminatorSources = cms.VInputTag(*[ 
1117         cms.InputTag(btagPrefix+x+labelName+postfix) \
1118           if ':' not in x else \
1119           cms.InputTag(btagPrefix+x.split(':')[0]+labelName+postfix+':'+x.split(':')[1]) \
1120           for x in acceptedBtagDiscriminators 
1121         ])
1122     if len(acceptedBtagDiscriminators) > 0 :
1123         patJets.addBTagInfo = True
1124     ## if re-running IVF
1125     if runIVF:
1126         if not tightBTagNTkHits:
1127             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices': ## MiniAOD case
1128                 if not runIVFforCTagOnly: rerunningIVFMiniAOD()
1129             else:
1130                 rerunningIVF()
1131         from PhysicsTools.PatAlgos.tools.helpers import loadWithPrefix
1132         ivfbTagInfos = ['pfInclusiveSecondaryVertexFinderTagInfos', 'pfInclusiveSecondaryVertexFinderAK8TagInfos', 'pfInclusiveSecondaryVertexFinderCA15TagInfos']
1133         if any(i in acceptedTagInfos for i in ivfbTagInfos) and not runIVFforCTagOnly:
1134             if not hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1135                 loadWithPrefix(process, 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff', btagPrefix, task.label())
1136             if tightBTagNTkHits:
1137                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1138                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinder')
1139                     _temp.minHits = cms.uint32(8)
1140             ## MiniAOD case
1141             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices':
1142                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinder' ):
1143                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinder')
1144                     _temp.primaryVertices = pvSource
1145                     _temp.tracks = pfCandidates
1146                 if hasattr( process, btagPrefix+'candidateVertexArbitrator' ):
1147                     _temp = getattr(process, btagPrefix+'candidateVertexArbitrator')
1148                     _temp.primaryVertices = pvSource
1149                     _temp.tracks = pfCandidates
1150                 if hasattr( process, btagPrefix+'inclusiveCandidateSecondaryVertices' ) and not hasattr( process, svSource.getModuleLabel() ):
1151                     addToProcessAndTask(svSource.getModuleLabel(),
1152                                         getattr(process, btagPrefix+'inclusiveCandidateSecondaryVertices').clone(),
1153                                         process, task)
1154         if any(i in acceptedTagInfos for i in ivfcTagInfos):
1155             if not hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1156                 loadWithPrefix(process, 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff', btagPrefix, task.label())
1157             if tightBTagNTkHits:
1158                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1159                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinderCvsL')
1160                     _temp.minHits = cms.uint32(8)
1161             ## MiniAOD case
1162             if pvSource.getModuleLabel() == 'offlineSlimmedPrimaryVertices':
1163                 if hasattr( process, btagPrefix+'inclusiveCandidateVertexFinderCvsL' ):
1164                     _temp = getattr(process, btagPrefix+'inclusiveCandidateVertexFinderCvsL')
1165                     _temp.primaryVertices = pvSource
1166                     _temp.tracks = pfCandidates
1167                 if hasattr( process, btagPrefix+'candidateVertexArbitratorCvsL' ):
1168                     _temp = getattr(process, btagPrefix+'candidateVertexArbitratorCvsL')
1169                     _temp.primaryVertices = pvSource
1170                     _temp.tracks = pfCandidates
1171                 if hasattr( process, btagPrefix+'inclusiveCandidateSecondaryVerticesCvsL' ) and not hasattr( process, svSourceCvsL.getModuleLabel() ):
1172                     addToProcessAndTask(svSourceCvsL.getModuleLabel(),
1173                                         getattr(process, btagPrefix+'inclusiveCandidateSecondaryVerticesCvsL').clone(),
1174                                         process, task)
1175         if 'inclusiveSecondaryVertexFinderTagInfos' in acceptedTagInfos:
1176             if not hasattr( process, 'inclusiveVertexing' ):
1177                 process.load( 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff' )
1178                 task.add(process.inclusiveVertexingTask)
1179                 task.add(process.inclusiveCandidateVertexingTask)
1180                 task.add(process.inclusiveCandidateVertexingCvsLTask)
1181         if 'inclusiveSecondaryVertexFinderFilteredTagInfos' in acceptedTagInfos:
1182             if not hasattr( process, 'inclusiveVertexing' ):
1183                 process.load( 'RecoVertex.AdaptiveVertexFinder.inclusiveVertexing_cff' )
1184                 task.add(process.inclusiveVertexingTask)
1185                 task.add(process.inclusiveCandidateVertexingTask)
1186                 task.add(process.inclusiveCandidateVertexingCvsLTask)
1187     if 'inclusiveSecondaryVertexFinderFilteredTagInfos' in acceptedTagInfos:
1188         if not hasattr( process, 'inclusiveSecondaryVerticesFiltered' ):
1189             process.load( 'RecoBTag.SecondaryVertex.inclusiveSecondaryVerticesFiltered_cfi' )
1190             task.add(process.inclusiveSecondaryVerticesFiltered)
1191             task.add(process.bVertexFilter)
1192         if not hasattr( process, 'bToCharmDecayVertexMerged' ):
1193             process.load( 'RecoBTag.SecondaryVertex.bToCharmDecayVertexMerger_cfi' )
1194             task.add(process.bToCharmDecayVertexMerged)
1195     if 'caTopTagInfos' in acceptedTagInfos :
1196         patJets.addTagInfos = True
1197         if not hasattr( process, 'caTopTagInfos' ) and not hasattr( process, 'caTopTagInfosAK8' ):
1198             process.load( 'RecoJets.JetProducers.caTopTaggers_cff' )
1199             task.add(process.caTopTaggersTask)
1200 
1201 class AddJetCollection(ConfigToolBase):
1202     """
1203     Tool to add a new jet collection to your PAT Tuple or to modify an existing one.
1204     """
1205     _label='addJetCollection'
1206     _defaultParameters=dicttypes.SortedKeysDict()
1207 
1208     def __init__(self):
1209         """
1210         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1211         """
1212         ## initialization of the base class
1213         ConfigToolBase.__init__(self)
1214         ## add all parameters that should be known to the class
1215         self.addParameter(self._defaultParameters,'labelName', 'UNDEFINED', "Label name of the new patJet collection.", str)
1216         self.addParameter(self._defaultParameters,'postfix','', "Postfix from usePF2PAT.", str)
1217         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1218         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1219         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('particleFlow'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1220         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1221         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlinePrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1222         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('inclusiveCandidateSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1223         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('gedGsfElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1224         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('muons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1225         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1226         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1227         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1228         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1229         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1230         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1231         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1232         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1233         self.addParameter(self._defaultParameters,'getJetMCFlavour', True, "Get jet MC truth flavour")
1234         self.addParameter(self._defaultParameters,'genJetCollection', cms.InputTag("ak4GenJets"), "GenJet collection to match to", cms.InputTag)
1235         self.addParameter(self._defaultParameters,'genParticles', cms.InputTag("genParticles"), "GenParticle collection to be used", cms.InputTag)
1236         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1237         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 \
1238         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 \
1239         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1240         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 \
1241         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 \
1242         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\' \
1243         and \'type-2\' are not case sensitive.", tuple, acceptNoneValue=True)
1244         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging, in most cases just the labels of the btag discriminators that \
1245         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. \
1246         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)
1247         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects contain all relevant information from which all discriminators of a certain \
1248         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 \
1249         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 \
1250         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 \
1251         will be added to your new patJet collection.", allowedValues=supportedBtagInfos,Type=list)
1252         self.addParameter(self._defaultParameters,'jetTrackAssociation',False, "Add JetTrackAssociation and JetCharge from reconstructed tracks to your new patJet collection. This \
1253         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 \
1254         your new patJetCollection. If btag information of any form is added to the new patJet collection this information will be added automatically.")
1255         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 \
1256         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 \
1257         to more than one output module.")
1258         ## set defaults
1259         self._parameters=copy.deepcopy(self._defaultParameters)
1260         ## add comments
1261         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\
1262         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 \
1263         the descriptions of each parameter for more information."
1264 
1265     def getDefaultParameters(self):
1266         """
1267         Return default parameters of the class
1268         """
1269         return self._defaultParameters
1270 
1271     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):
1272         """
1273         Function call wrapper. This will check the parameters and call the actual implementation that
1274         can be found in toolCode via the base class function apply.
1275         """
1276         if labelName is None:
1277             labelName=self._defaultParameters['labelName'].value
1278         self.setParameter('labelName', labelName)
1279         if postfix is None:
1280             postfix=self._defaultParameters['postfix'].value
1281         self.setParameter('postfix', postfix)
1282         if btagPrefix is None:
1283             btagPrefix=self._defaultParameters['btagPrefix'].value
1284         self.setParameter('btagPrefix', btagPrefix)
1285         if jetSource is None:
1286             jetSource=self._defaultParameters['jetSource'].value
1287         self.setParameter('jetSource', jetSource)
1288         if pfCandidates is None:
1289             pfCandidates=self._defaultParameters['pfCandidates'].value
1290         self.setParameter('pfCandidates', pfCandidates)
1291         if explicitJTA is None:
1292             explicitJTA=self._defaultParameters['explicitJTA'].value
1293         self.setParameter('explicitJTA', explicitJTA)
1294         if pvSource is None:
1295             pvSource=self._defaultParameters['pvSource'].value
1296         self.setParameter('pvSource', pvSource)
1297         if svSource is None:
1298             svSource=self._defaultParameters['svSource'].value
1299         self.setParameter('svSource', svSource)
1300         if elSource is None:
1301             elSource=self._defaultParameters['elSource'].value
1302         self.setParameter('elSource', elSource)
1303         if muSource is None:
1304             muSource=self._defaultParameters['muSource'].value
1305         self.setParameter('muSource', muSource)
1306         if runIVF is None:
1307             runIVF=self._defaultParameters['runIVF'].value
1308         self.setParameter('runIVF', runIVF)
1309         if tightBTagNTkHits is None:
1310             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
1311         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
1312         if loadStdRecoBTag is None:
1313             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
1314         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
1315         if svClustering is None:
1316             svClustering=self._defaultParameters['svClustering'].value
1317         self.setParameter('svClustering', svClustering)
1318         if fatJets is None:
1319             fatJets=self._defaultParameters['fatJets'].value
1320         self.setParameter('fatJets', fatJets)
1321         if groomedFatJets is None:
1322             groomedFatJets=self._defaultParameters['groomedFatJets'].value
1323         self.setParameter('groomedFatJets', groomedFatJets)
1324         if algo is None:
1325             algo=self._defaultParameters['algo'].value
1326         self.setParameter('algo', algo)
1327         if rParam is None:
1328             rParam=self._defaultParameters['rParam'].value
1329         self.setParameter('rParam', rParam)
1330         if getJetMCFlavour is None:
1331             getJetMCFlavour=self._defaultParameters['getJetMCFlavour'].value
1332         self.setParameter('getJetMCFlavour', getJetMCFlavour)
1333         if genJetCollection is None:
1334             genJetCollection=self._defaultParameters['genJetCollection'].value
1335         self.setParameter('genJetCollection', genJetCollection)
1336         if genParticles is None:
1337             genParticles=self._defaultParameters['genParticles'].value
1338         self.setParameter('genParticles', genParticles)
1339         if jetCorrections is None:
1340             jetCorrections=self._defaultParameters['jetCorrections'].value
1341         self.setParameter('jetCorrections', jetCorrections)
1342         if btagDiscriminators is None:
1343             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
1344         self.setParameter('btagDiscriminators', btagDiscriminators)
1345         if btagInfos is None:
1346             btagInfos=self._defaultParameters['btagInfos'].value
1347         self.setParameter('btagInfos', btagInfos)
1348         if jetTrackAssociation is None:
1349             jetTrackAssociation=self._defaultParameters['jetTrackAssociation'].value
1350         self.setParameter('jetTrackAssociation', jetTrackAssociation)
1351         if outputModules is None:
1352             outputModules=self._defaultParameters['outputModules'].value
1353         self.setParameter('outputModules', outputModules)
1354         self.apply(process)
1355 
1356     def toolCode(self, process):
1357         """
1358         Tool code implementation
1359         """
1360         task = getPatAlgosToolsTask(process)
1361 
1362         ## initialize parameters
1363         labelName=self._parameters['labelName'].value
1364         postfix=self._parameters['postfix'].value
1365         btagPrefix=self._parameters['btagPrefix'].value
1366         jetSource=self._parameters['jetSource'].value
1367         pfCandidates=self._parameters['pfCandidates'].value
1368         explicitJTA=self._parameters['explicitJTA'].value
1369         pvSource=self._parameters['pvSource'].value
1370         svSource=self._parameters['svSource'].value
1371         elSource=self._parameters['elSource'].value
1372         muSource=self._parameters['muSource'].value
1373         runIVF=self._parameters['runIVF'].value
1374         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
1375         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
1376         svClustering=self._parameters['svClustering'].value
1377         fatJets=self._parameters['fatJets'].value
1378         groomedFatJets=self._parameters['groomedFatJets'].value
1379         algo=self._parameters['algo'].value
1380         rParam=self._parameters['rParam'].value
1381         getJetMCFlavour=self._parameters['getJetMCFlavour'].value
1382         genJetCollection=self._parameters['genJetCollection'].value
1383         genParticles=self._parameters['genParticles'].value
1384         jetCorrections=self._parameters['jetCorrections'].value
1385         btagDiscriminators=list(self._parameters['btagDiscriminators'].value)
1386         btagInfos=list(self._parameters['btagInfos'].value)
1387         jetTrackAssociation=self._parameters['jetTrackAssociation'].value
1388         outputModules=list(self._parameters['outputModules'].value)
1389 
1390         ## added jets must have a defined 'labelName'
1391         if labelName=='UNDEFINED':
1392             undefinedLabelName(self)
1393 
1394         ## a list of all producer modules, which are already known to process
1395         knownModules = process.producerNames().split()
1396         ## determine whether btagging information is required or not
1397         if btagDiscriminators.count('None')>0:
1398             btagDiscriminators.remove('None')
1399         if btagInfos.count('None')>0:
1400             btagInfos.remove('None')
1401         bTagging=(len(btagDiscriminators)>0 or len(btagInfos)>0)
1402         ## check if any legacy btag discriminators are being used
1403         infos = 0
1404         for info in btagInfos:
1405             if info.startswith('pf'): infos = infos + 1
1406             if 'softpf' in info.lower(): infos = infos + 1
1407         tags = 0
1408         for tag in btagDiscriminators:
1409             if tag.startswith('pf'): tags = tags + 1
1410             if 'softpf' in tag.lower(): tags = tags + 1
1411         bTaggingLegacy=(len(btagDiscriminators)>tags or len(btagInfos)>infos)
1412         ## construct postfix label for auxiliary modules; this postfix
1413         ## label will start with a capitalized first letter following
1414         ## the CMS naming conventions and for improved readablility
1415         _labelName=labelName[:1].upper()+labelName[1:]
1416 
1417         ## supported algo types are ak, ca, and kt
1418         _algo=''
1419         for x in ["ak", "ca", "kt"]:
1420             if x in algo.lower():
1421                 _algo=supportedJetAlgos[x]
1422                 break
1423         if _algo=='':
1424             unsupportedJetAlgorithm(self)
1425         ## add new patJets to process (keep instance for later further modifications)
1426         from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJets
1427         if 'patJets'+_labelName+postfix in knownModules :
1428             _newPatJets=getattr(process, 'patJets'+_labelName+postfix)
1429             _newPatJets.jetSource=jetSource
1430         else :
1431             addToProcessAndTask('patJets'+_labelName+postfix, patJets.clone(jetSource=jetSource), process, task)
1432             _newPatJets=getattr(process, 'patJets'+_labelName+postfix)
1433             knownModules.append('patJets'+_labelName+postfix)
1434         ## add new selectedPatJets to process
1435         from PhysicsTools.PatAlgos.selectionLayer1.jetSelector_cfi import selectedPatJets
1436         if 'selectedPatJets'+_labelName+postfix in knownModules :
1437             _newSelectedPatJets=getattr(process, 'selectedPatJets'+_labelName+postfix)
1438             _newSelectedPatJets.src='patJets'+_labelName+postfix
1439         else :
1440             addToProcessAndTask('selectedPatJets'+_labelName+postfix,
1441                                 selectedPatJets.clone(src='patJets'+_labelName+postfix),
1442                                 process, task)
1443             knownModules.append('selectedPatJets'+_labelName+postfix)
1444 
1445         ## add new patJetPartonMatch to process
1446         from PhysicsTools.PatAlgos.mcMatchLayer0.jetMatch_cfi import patJetPartonMatch
1447         if 'patJetPartonMatch'+_labelName+postfix in knownModules :
1448             _newPatJetPartonMatch=getattr(process, 'patJetPartonMatch'+_labelName+postfix)
1449             _newPatJetPartonMatch.src=jetSource
1450             _newPatJetPartonMatch.matched=genParticles
1451         else :
1452             addToProcessAndTask('patJetPartonMatch'+_labelName+postfix,
1453                                 patJetPartonMatch.clone(src=jetSource, matched=genParticles),
1454                                 process, task)
1455             knownModules.append('patJetPartonMatch'+_labelName+postfix)
1456         ## add new patJetGenJetMatch to process
1457         from PhysicsTools.PatAlgos.mcMatchLayer0.jetMatch_cfi import patJetGenJetMatch
1458         if 'patJetGenJetMatch'+_labelName+postfix in knownModules :
1459             _newPatJetGenJetMatch=getattr(process, 'patJetGenJetMatch'+_labelName+postfix)
1460             _newPatJetGenJetMatch.src=jetSource
1461             _newPatJetGenJetMatch.maxDeltaR=rParam
1462             _newPatJetGenJetMatch.matched=genJetCollection
1463         else :
1464             addToProcessAndTask('patJetGenJetMatch'+_labelName+postfix,
1465                                 patJetGenJetMatch.clone(src=jetSource, maxDeltaR=rParam, matched=genJetCollection),
1466                                 process, task)
1467             knownModules.append('patJetGenJetMatch'+_labelName+postfix)
1468         ## modify new patJets collection accordingly
1469         _newPatJets.genJetMatch.setModuleLabel('patJetGenJetMatch'+_labelName+postfix)
1470         _newPatJets.genPartonMatch.setModuleLabel('patJetPartonMatch'+_labelName+postfix)
1471         ## get jet MC truth flavour if required by user
1472         if (getJetMCFlavour):
1473             ## legacy jet flavour (see https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagMCTools)
1474             ## add new patJetPartonsLegacy to process
1475             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartonsLegacy
1476             if 'patJetPartonsLegacy'+postfix not in knownModules :
1477                 addToProcessAndTask('patJetPartonsLegacy'+postfix, patJetPartonsLegacy.clone(src=genParticles),
1478                                     process, task)
1479                 knownModules.append('patJetPartonsLegacy'+postfix)
1480             else:
1481                 getattr(process, 'patJetPartonsLegacy'+postfix).src=genParticles
1482             ## add new patJetPartonAssociationLegacy to process
1483             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartonAssociationLegacy
1484             if 'patJetPartonAssociationLegacy'+_labelName+postfix in knownModules :
1485                 _newPatJetPartonAssociation=getattr(process, 'patJetPartonAssociationLegacy'+_labelName+postfix)
1486                 _newPatJetPartonAssociation.jets=jetSource
1487             else :
1488                 addToProcessAndTask('patJetPartonAssociationLegacy'+_labelName+postfix,
1489                                     patJetPartonAssociationLegacy.clone(jets=jetSource), process, task)
1490                 knownModules.append('patJetPartonAssociationLegacy'+_labelName+postfix)
1491             ## add new patJetPartonAssociationLegacy to process
1492             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociationLegacy
1493             if 'patJetFlavourAssociationLegacy'+_labelName+postfix in knownModules :
1494                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociationLegacy'+_labelName+postfix)
1495                 _newPatJetFlavourAssociation.srcByReference='patJetPartonAssociationLegacy'+_labelName+postfix
1496             else:
1497                 addToProcessAndTask('patJetFlavourAssociationLegacy'+_labelName+postfix,
1498                                     patJetFlavourAssociationLegacy.clone(
1499                                         srcByReference='patJetPartonAssociationLegacy'+_labelName+postfix),
1500                                     process, task)
1501                 knownModules.append('patJetFlavourAssociationLegacy'+_labelName+postfix)
1502             ## modify new patJets collection accordingly
1503             _newPatJets.JetPartonMapSource.setModuleLabel('patJetFlavourAssociationLegacy'+_labelName+postfix)
1504             ## new jet flavour (see https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagMCTools)
1505             ## add new patJetPartons to process
1506             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetPartons
1507             if 'patJetPartons'+postfix not in knownModules :
1508                 addToProcessAndTask('patJetPartons'+postfix, patJetPartons.clone(particles=genParticles), process, task)
1509                 knownModules.append('patJetPartons'+postfix)
1510             else:
1511                 getattr(process, 'patJetPartons'+postfix).particles=genParticles
1512             ## add new patJetFlavourAssociation to process
1513             from PhysicsTools.PatAlgos.mcMatchLayer0.jetFlavourId_cff import patJetFlavourAssociation
1514             if 'patJetFlavourAssociation'+_labelName+postfix in knownModules :
1515                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1516                 _newPatJetFlavourAssociation.jets=jetSource
1517                 _newPatJetFlavourAssociation.jetAlgorithm=_algo
1518                 _newPatJetFlavourAssociation.rParam=rParam
1519                 _newPatJetFlavourAssociation.bHadrons=cms.InputTag("patJetPartons"+postfix,"bHadrons")
1520                 _newPatJetFlavourAssociation.cHadrons=cms.InputTag("patJetPartons"+postfix,"cHadrons")
1521                 _newPatJetFlavourAssociation.partons=cms.InputTag("patJetPartons"+postfix,"physicsPartons")
1522                 _newPatJetFlavourAssociation.leptons=cms.InputTag("patJetPartons"+postfix,"leptons")
1523             else :
1524                 addToProcessAndTask('patJetFlavourAssociation'+_labelName+postfix,
1525                                     patJetFlavourAssociation.clone(
1526                                         jets=jetSource,
1527                                         jetAlgorithm=_algo,
1528                                         rParam=rParam,
1529                                         bHadrons = cms.InputTag("patJetPartons"+postfix,"bHadrons"),
1530                                         cHadrons = cms.InputTag("patJetPartons"+postfix,"cHadrons"),
1531                                         partons = cms.InputTag("patJetPartons"+postfix,"physicsPartons"),
1532                                         leptons = cms.InputTag("patJetPartons"+postfix,"leptons")),
1533                                     process, task)
1534 
1535                 knownModules.append('patJetFlavourAssociation'+_labelName+postfix)
1536             if 'Puppi' in jetSource.value() and pfCandidates.value() == 'particleFlow':
1537                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1538                 _newPatJetFlavourAssociation.weights = cms.InputTag("puppi")
1539             ## modify new patJets collection accordingly
1540             _newPatJets.JetFlavourInfoSource.setModuleLabel('patJetFlavourAssociation'+_labelName+postfix)
1541             ## if the jets is actually a subjet
1542             if fatJets != cms.InputTag('') and groomedFatJets != cms.InputTag(''):
1543                 _newPatJetFlavourAssociation=getattr(process, 'patJetFlavourAssociation'+_labelName+postfix)
1544                 _newPatJetFlavourAssociation.jets=fatJets
1545                 _newPatJetFlavourAssociation.groomedJets=groomedFatJets
1546                 _newPatJetFlavourAssociation.subjets=jetSource
1547                 _newPatJets.JetFlavourInfoSource=cms.InputTag('patJetFlavourAssociation'+_labelName+postfix,'SubJets')
1548         else:
1549             _newPatJets.getJetMCFlavour = False
1550             _newPatJets.addJetFlavourInfo = False
1551 
1552         ## add jetTrackAssociation for legacy btagging (or jetTracksAssociation only) if required by user
1553         if (jetTrackAssociation or bTaggingLegacy):
1554             ## add new jetTracksAssociationAtVertex to process
1555             from RecoJets.JetAssociationProducers.ak4JTA_cff import ak4JetTracksAssociatorAtVertex, ak4JetTracksAssociatorExplicit
1556             if 'jetTracksAssociationAtVertex'+_labelName+postfix in knownModules :
1557                 _newJetTracksAssociationAtVertex=getattr(process, 'jetTracksAssociatorAtVertex'+_labelName+postfix)
1558                 _newJetTracksAssociationAtVertex.jets=jetSource
1559                 _newJetTracksAssociationAtVertex.pvSrc=pvSource
1560             else:
1561                 jetTracksAssociator=ak4JetTracksAssociatorAtVertex
1562                 if explicitJTA:
1563                     jetTracksAssociator=ak4JetTracksAssociatorExplicit
1564                 addToProcessAndTask('jetTracksAssociatorAtVertex'+_labelName+postfix,
1565                                     jetTracksAssociator.clone(jets=jetSource,pvSrc=pvSource),
1566                                     process, task)
1567                 knownModules.append('jetTracksAssociationAtVertex'+_labelName+postfix)
1568             ## add new patJetCharge to process
1569             from PhysicsTools.PatAlgos.recoLayer0.jetTracksCharge_cff import patJetCharge
1570             if 'patJetCharge'+_labelName+postfix in knownModules :
1571                 _newPatJetCharge=getattr(process, 'patJetCharge'+_labelName+postfix)
1572                 _newPatJetCharge.src='jetTracksAssociatorAtVertex'+_labelName+postfix
1573             else:
1574                 addToProcessAndTask('patJetCharge'+_labelName+postfix,
1575                                     patJetCharge.clone(src = 'jetTracksAssociatorAtVertex'+_labelName+postfix),
1576                                     process, task)
1577                 knownModules.append('patJetCharge'+_labelName+postfix)
1578             ## modify new patJets collection accordingly
1579             _newPatJets.addAssociatedTracks=True
1580             _newPatJets.trackAssociationSource=cms.InputTag('jetTracksAssociatorAtVertex'+_labelName+postfix)
1581             _newPatJets.addJetCharge=True
1582             _newPatJets.jetChargeSource=cms.InputTag('patJetCharge'+_labelName+postfix)
1583         else:
1584             ## modify new patJets collection accordingly
1585             _newPatJets.addAssociatedTracks=False
1586             _newPatJets.trackAssociationSource=''
1587             _newPatJets.addJetCharge=False
1588             _newPatJets.jetChargeSource=''
1589         ## run btagging if required by user
1590         if (bTagging):
1591             setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
1592                           _algo, rParam, btagDiscriminators, btagInfos, _newPatJets, _labelName, btagPrefix, postfix)
1593         else:
1594             _newPatJets.addBTagInfo = False
1595             _newPatJets.addTagInfos = False
1596             ## adjust output module; these collections will be empty anyhow, but we do it to stay clean
1597             for outputModule in outputModules:
1598                     if hasattr(process,outputModule):
1599                         getattr(process,outputModule).outputCommands.append("drop *_"+'selected'+_labelName+postfix+"_tagInfos_*")
1600 
1601         ## add jet correction factors if required by user
1602         if (jetCorrections != None):
1603             ## check the jet corrections format
1604             checkJetCorrectionsFormat(jetCorrections)
1605             ## setup jet energy corrections and MET corrections
1606             setupJetCorrections(process, knownModules, jetCorrections, jetSource, pvSource, _newPatJets, _labelName, postfix)
1607         else:
1608             ## switch jetCorrFactors off
1609             _newPatJets.addJetCorrFactors=False
1610 
1611 addJetCollection=AddJetCollection()
1612 
1613 class SwitchJetCollection(ConfigToolBase):
1614     """
1615     Tool to switch parameters of the PAT jet collection to your PAT Tuple.
1616     """
1617     _label='switchJetCollection'
1618     _defaultParameters=dicttypes.SortedKeysDict()
1619 
1620     def __init__(self):
1621         """
1622         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1623         """
1624         ## initialization of the base class
1625         ConfigToolBase.__init__(self)
1626         ## add all parameters that should be known to the class
1627         self.addParameter(self._defaultParameters,'postfix','', "postfix from usePF2PAT")
1628         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1629         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1630         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('particleFlow'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1631         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1632         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlinePrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1633         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('inclusiveCandidateSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1634         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('gedGsfElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1635         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('muons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1636         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1637         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1638         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1639         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1640         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1641         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1642         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1643         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1644         self.addParameter(self._defaultParameters,'getJetMCFlavour', True, "Get jet MC truth flavour")
1645         self.addParameter(self._defaultParameters,'genJetCollection', cms.InputTag("ak4GenJets"), "GenJet collection to match to")
1646         self.addParameter(self._defaultParameters,'genParticles', cms.InputTag("genParticles"), "GenParticle collection to be used", cms.InputTag)
1647         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1648         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 \
1649         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 \
1650         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1651         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 \
1652         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 \
1653         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)
1654         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging in general the btag discriminators is all relevant \
1655         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 \
1656         discriminator information will be added to your new patJet collection.", allowedValues=(list(set().union(supportedBtagDiscr.keys(),supportedMetaDiscr.keys()))),Type=list)
1657         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects conatin all relevant information from which all discriminators of a certain \
1658         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 \
1659         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 \
1660         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)
1661         self.addParameter(self._defaultParameters,'jetTrackAssociation',False, "Add JetTrackAssociation and JetCharge from reconstructed tracks to your new patJet collection. This \
1662         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 \
1663         your new patJetCollection. If btag information is added to the new patJet collection this information will be added automatically.")
1664         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 \
1665         be added, in case you use more than one output module.")
1666         ## set defaults
1667         self._parameters=copy.deepcopy(self._defaultParameters)
1668         ## add comments
1669         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 \
1670         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 \
1671         parameter for more information."
1672 
1673     def getDefaultParameters(self):
1674         """
1675         Return default parameters of the class
1676         """
1677         return self._defaultParameters
1678 
1679     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):
1680         """
1681         Function call wrapper. This will check the parameters and call the actual implementation that
1682         can be found in toolCode via the base class function apply.
1683         """
1684         if postfix is None:
1685             postfix=self._defaultParameters['postfix'].value
1686         self.setParameter('postfix', postfix)
1687         if btagPrefix is None:
1688             btagPrefix=self._defaultParameters['btagPrefix'].value
1689         self.setParameter('btagPrefix', btagPrefix)
1690         if jetSource is None:
1691             jetSource=self._defaultParameters['jetSource'].value
1692         self.setParameter('jetSource', jetSource)
1693         if pfCandidates is None:
1694             pfCandidates=self._defaultParameters['pfCandidates'].value
1695         self.setParameter('pfCandidates', pfCandidates)
1696         if explicitJTA is None:
1697             explicitJTA=self._defaultParameters['explicitJTA'].value
1698         self.setParameter('explicitJTA', explicitJTA)
1699         if pvSource is None:
1700             pvSource=self._defaultParameters['pvSource'].value
1701         self.setParameter('pvSource', pvSource)
1702         if svSource is None:
1703             svSource=self._defaultParameters['svSource'].value
1704         self.setParameter('svSource', svSource)
1705         if elSource is None:
1706             elSource=self._defaultParameters['elSource'].value
1707         self.setParameter('elSource', elSource)
1708         if muSource is None:
1709             muSource=self._defaultParameters['muSource'].value
1710         self.setParameter('muSource', muSource)
1711         if runIVF is None:
1712             runIVF=self._defaultParameters['runIVF'].value
1713         self.setParameter('runIVF', runIVF)
1714         if tightBTagNTkHits is None:
1715             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
1716         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
1717         if loadStdRecoBTag is None:
1718             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
1719         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
1720         if svClustering is None:
1721             svClustering=self._defaultParameters['svClustering'].value
1722         self.setParameter('svClustering', svClustering)
1723         if fatJets is None:
1724             fatJets=self._defaultParameters['fatJets'].value
1725         self.setParameter('fatJets', fatJets)
1726         if groomedFatJets is None:
1727             groomedFatJets=self._defaultParameters['groomedFatJets'].value
1728         self.setParameter('groomedFatJets', groomedFatJets)
1729         if algo is None:
1730             algo=self._defaultParameters['algo'].value
1731         self.setParameter('algo', algo)
1732         if rParam is None:
1733             rParam=self._defaultParameters['rParam'].value
1734         self.setParameter('rParam', rParam)
1735         if getJetMCFlavour is None:
1736             getJetMCFlavour=self._defaultParameters['getJetMCFlavour'].value
1737         self.setParameter('getJetMCFlavour', getJetMCFlavour)
1738         if genJetCollection is None:
1739             genJetCollection=self._defaultParameters['genJetCollection'].value
1740         self.setParameter('genJetCollection', genJetCollection)
1741         if genParticles is None:
1742             genParticles=self._defaultParameters['genParticles'].value
1743         self.setParameter('genParticles', genParticles)
1744         if jetCorrections is None:
1745             jetCorrections=self._defaultParameters['jetCorrections'].value
1746         self.setParameter('jetCorrections', jetCorrections)
1747         if btagDiscriminators is None:
1748             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
1749         self.setParameter('btagDiscriminators', btagDiscriminators)
1750         if btagInfos is None:
1751             btagInfos=self._defaultParameters['btagInfos'].value
1752         self.setParameter('btagInfos', btagInfos)
1753         if jetTrackAssociation is None:
1754             jetTrackAssociation=self._defaultParameters['jetTrackAssociation'].value
1755         self.setParameter('jetTrackAssociation', jetTrackAssociation)
1756         if outputModules is None:
1757             outputModules=self._defaultParameters['outputModules'].value
1758         self.setParameter('outputModules', outputModules)
1759         self.apply(process)
1760 
1761     def toolCode(self, process):
1762         """
1763         Tool code implementation
1764         """
1765         ## initialize parameters
1766         postfix=self._parameters['postfix'].value
1767         btagPrefix=self._parameters['btagPrefix'].value
1768         jetSource=self._parameters['jetSource'].value
1769         pfCandidates=self._parameters['pfCandidates'].value
1770         explicitJTA=self._parameters['explicitJTA'].value
1771         pvSource=self._parameters['pvSource'].value
1772         svSource=self._parameters['svSource'].value
1773         elSource=self._parameters['elSource'].value
1774         muSource=self._parameters['muSource'].value
1775         runIVF=self._parameters['runIVF'].value
1776         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
1777         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
1778         svClustering=self._parameters['svClustering'].value
1779         fatJets=self._parameters['fatJets'].value
1780         groomedFatJets=self._parameters['groomedFatJets'].value
1781         algo=self._parameters['algo'].value
1782         rParam=self._parameters['rParam'].value
1783         getJetMCFlavour=self._parameters['getJetMCFlavour'].value
1784         genJetCollection=self._parameters['genJetCollection'].value
1785         genParticles=self._parameters['genParticles'].value
1786         jetCorrections=self._parameters['jetCorrections'].value
1787         btagDiscriminators=self._parameters['btagDiscriminators'].value
1788         btagInfos=self._parameters['btagInfos'].value
1789         jetTrackAssociation=self._parameters['jetTrackAssociation'].value
1790         outputModules=self._parameters['outputModules'].value
1791 
1792         ## call addJetCollections w/o labelName; this will act on the default patJets collection
1793         addJetCollection(
1794             process,
1795             labelName='',
1796             postfix=postfix,
1797             btagPrefix=btagPrefix,
1798             jetSource=jetSource,
1799             pfCandidates=pfCandidates,
1800             explicitJTA=explicitJTA,
1801             pvSource=pvSource,
1802             svSource=svSource,
1803             elSource=elSource,
1804             muSource=muSource,
1805             runIVF=runIVF,
1806             tightBTagNTkHits=tightBTagNTkHits,
1807             loadStdRecoBTag=loadStdRecoBTag,
1808             svClustering=svClustering,
1809             fatJets=fatJets,
1810             groomedFatJets=groomedFatJets,
1811             algo=algo,
1812             rParam=rParam,
1813             getJetMCFlavour=getJetMCFlavour,
1814             genJetCollection=genJetCollection,
1815             genParticles=genParticles,
1816             jetCorrections=jetCorrections,
1817             btagDiscriminators=btagDiscriminators,
1818             btagInfos=btagInfos,
1819             jetTrackAssociation=jetTrackAssociation,
1820             outputModules=outputModules,
1821             )
1822 
1823 switchJetCollection=SwitchJetCollection()
1824 
1825 
1826 class UpdateJetCollection(ConfigToolBase):
1827     """
1828     Tool to update a jet collection in your PAT Tuple (primarily intended for MiniAOD for which the default input argument values have been set).
1829     """
1830     _label='updateJetCollection'
1831     _defaultParameters=dicttypes.SortedKeysDict()
1832 
1833     def __init__(self):
1834         """
1835         Initialize elements of the class. Note that the tool needs to be derived from ConfigToolBase to be usable in the configEditor.
1836         """
1837         ## initialization of the base class
1838         ConfigToolBase.__init__(self)
1839         ## add all parameters that should be known to the class
1840         self.addParameter(self._defaultParameters,'labelName', '', "Label name of the new patJet collection.", str)
1841         self.addParameter(self._defaultParameters,'postfix','', "Postfix from usePF2PAT.", str)
1842         self.addParameter(self._defaultParameters,'btagPrefix','', "Prefix to be added to b-tag discriminator and TagInfo names", str)
1843         self.addParameter(self._defaultParameters,'jetSource','', "Label of the input collection from which the new patJet collection should be created", cms.InputTag)
1844         self.addParameter(self._defaultParameters,'pfCandidates',cms.InputTag('packedPFCandidates'), "Label of the input collection for candidatecandidatese used in b-tagging", cms.InputTag)
1845         self.addParameter(self._defaultParameters,'explicitJTA', False, "Use explicit jet-track association")
1846         self.addParameter(self._defaultParameters,'pvSource',cms.InputTag('offlineSlimmedPrimaryVertices'), "Label of the input collection for primary vertices used in b-tagging", cms.InputTag)
1847         self.addParameter(self._defaultParameters,'svSource',cms.InputTag('slimmedSecondaryVertices'), "Label of the input collection for IVF vertices used in b-tagging", cms.InputTag)
1848         self.addParameter(self._defaultParameters,'elSource',cms.InputTag('slimmedElectrons'), "Label of the input collection for electrons used in b-tagging", cms.InputTag)
1849         self.addParameter(self._defaultParameters,'muSource',cms.InputTag('slimmedMuons'), "Label of the input collection for muons used in b-tagging", cms.InputTag)
1850         self.addParameter(self._defaultParameters,'runIVF', False, "Re-run IVF secondary vertex reconstruction")
1851         self.addParameter(self._defaultParameters,'tightBTagNTkHits', False, "Enable legacy tight b-tag track selection")
1852         self.addParameter(self._defaultParameters,'loadStdRecoBTag', False, "Load the standard reconstruction b-tagging modules")
1853         self.addParameter(self._defaultParameters,'svClustering', False, "Secondary vertices ghost-associated to jets using jet clustering (mostly intended for subjets)")
1854         self.addParameter(self._defaultParameters,'fatJets', cms.InputTag(''), "Fat jet collection used for secondary vertex clustering", cms.InputTag)
1855         self.addParameter(self._defaultParameters,'groomedFatJets', cms.InputTag(''), "Groomed fat jet collection used for secondary vertex clustering", cms.InputTag)
1856         self.addParameter(self._defaultParameters,'algo', 'AK', "Jet algorithm of the input collection from which the new patJet collection should be created")
1857         self.addParameter(self._defaultParameters,'rParam', 0.4, "Jet size (distance parameter R used in jet clustering)")
1858         self.addParameter(self._defaultParameters,'sortByPt', True, "Set to False to not modify incoming jet order")
1859         self.addParameter(self._defaultParameters,'printWarning', True, "To be use as False in production to reduce log size")
1860         self.addParameter(self._defaultParameters,'jetCorrections',None, "Add all relevant information about jet energy corrections that you want to be added to your new patJet \
1861         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 \
1862         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 \
1863         new patJet collection. This should be given as a list of strings. Available values are L1Offset, L1FastJet, L1JPTOffset, L2Relative, L3Absolute, L5Falvour, L7Parton; the \
1864         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 \
1865         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 \
1866         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\' \
1867         and \'type-2\' are not case sensitive.", tuple, acceptNoneValue=True)
1868         self.addParameter(self._defaultParameters,'btagDiscriminators',['None'], "If you are interested in btagging, in most cases just the labels of the btag discriminators that \
1869         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. \
1870         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)
1871         self.addParameter(self._defaultParameters,'btagInfos',['None'], "The btagInfos objects contain all relevant information from which all discriminators of a certain \
1872         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 \
1873         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 \
1874         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 \
1875         will be added to your new patJet collection.", allowedValues=supportedBtagInfos,Type=list)
1876         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 \
1877         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 \
1878         to more than one output module.")
1879         ## set defaults
1880         self._parameters=copy.deepcopy(self._defaultParameters)
1881         ## add comments
1882         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\
1883         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 \
1884         the descriptions of each parameter for more information."
1885 
1886     def getDefaultParameters(self):
1887         """
1888         Return default parameters of the class
1889         """
1890         return self._defaultParameters
1891 
1892     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):
1893         """
1894         Function call wrapper. This will check the parameters and call the actual implementation that
1895         can be found in toolCode via the base class function apply.
1896         """
1897         if labelName is None:
1898             labelName=self._defaultParameters['labelName'].value
1899         self.setParameter('labelName', labelName)
1900         if postfix is None:
1901             postfix=self._defaultParameters['postfix'].value
1902         self.setParameter('postfix', postfix)
1903         if btagPrefix is None:
1904             btagPrefix=self._defaultParameters['btagPrefix'].value
1905         self.setParameter('btagPrefix', btagPrefix)
1906         if jetSource is None:
1907             jetSource=self._defaultParameters['jetSource'].value
1908         self.setParameter('jetSource', jetSource)
1909         if pfCandidates is None:
1910             pfCandidates=self._defaultParameters['pfCandidates'].value
1911         self.setParameter('pfCandidates', pfCandidates)
1912         if explicitJTA is None:
1913             explicitJTA=self._defaultParameters['explicitJTA'].value
1914         self.setParameter('explicitJTA', explicitJTA)
1915         if pvSource is None:
1916             pvSource=self._defaultParameters['pvSource'].value
1917         self.setParameter('pvSource', pvSource)
1918         if svSource is None:
1919             svSource=self._defaultParameters['svSource'].value
1920         self.setParameter('svSource', svSource)
1921         if elSource is None:
1922             elSource=self._defaultParameters['elSource'].value
1923         self.setParameter('elSource', elSource)
1924         if muSource is None:
1925             muSource=self._defaultParameters['muSource'].value
1926         self.setParameter('muSource', muSource)
1927         if runIVF is None:
1928             runIVF=self._defaultParameters['runIVF'].value
1929         self.setParameter('runIVF', runIVF)
1930         if tightBTagNTkHits is None:
1931             tightBTagNTkHits=self._defaultParameters['tightBTagNTkHits'].value
1932         self.setParameter('tightBTagNTkHits', tightBTagNTkHits)
1933         if loadStdRecoBTag is None:
1934             loadStdRecoBTag=self._defaultParameters['loadStdRecoBTag'].value
1935         self.setParameter('loadStdRecoBTag', loadStdRecoBTag)
1936         if svClustering is None:
1937             svClustering=self._defaultParameters['svClustering'].value
1938         self.setParameter('svClustering', svClustering)
1939         if fatJets is None:
1940             fatJets=self._defaultParameters['fatJets'].value
1941         self.setParameter('fatJets', fatJets)
1942         if groomedFatJets is None:
1943             groomedFatJets=self._defaultParameters['groomedFatJets'].value
1944         self.setParameter('groomedFatJets', groomedFatJets)
1945         if algo is None:
1946             algo=self._defaultParameters['algo'].value
1947         self.setParameter('algo', algo)
1948         if rParam is None:
1949             rParam=self._defaultParameters['rParam'].value
1950         self.setParameter('rParam', rParam)
1951         if sortByPt is None:
1952             sortByPt=self._defaultParameters['sortByPt'].value
1953         self.setParameter('sortByPt', sortByPt)
1954         if printWarning is None:
1955             printWarning=self._defaultParameters['printWarning'].value
1956         self.setParameter('printWarning', printWarning)
1957         if jetCorrections is None:
1958             jetCorrections=self._defaultParameters['jetCorrections'].value
1959         self.setParameter('jetCorrections', jetCorrections)
1960         if btagDiscriminators is None:
1961             btagDiscriminators=self._defaultParameters['btagDiscriminators'].value
1962         self.setParameter('btagDiscriminators', btagDiscriminators)
1963         if btagInfos is None:
1964             btagInfos=self._defaultParameters['btagInfos'].value
1965         self.setParameter('btagInfos', btagInfos)
1966         self.apply(process)
1967 
1968     def toolCode(self, process):
1969         """
1970         Tool code implementation
1971         """
1972         ## initialize parameters
1973         labelName=self._parameters['labelName'].value
1974         postfix=self._parameters['postfix'].value
1975         btagPrefix=self._parameters['btagPrefix'].value
1976         jetSource=self._parameters['jetSource'].value
1977         pfCandidates=self._parameters['pfCandidates'].value
1978         explicitJTA=self._parameters['explicitJTA'].value
1979         pvSource=self._parameters['pvSource'].value
1980         svSource=self._parameters['svSource'].value
1981         elSource=self._parameters['elSource'].value
1982         muSource=self._parameters['muSource'].value
1983         runIVF=self._parameters['runIVF'].value
1984         tightBTagNTkHits=self._parameters['tightBTagNTkHits'].value
1985         loadStdRecoBTag=self._parameters['loadStdRecoBTag'].value
1986         svClustering=self._parameters['svClustering'].value
1987         fatJets=self._parameters['fatJets'].value
1988         groomedFatJets=self._parameters['groomedFatJets'].value
1989         algo=self._parameters['algo'].value
1990         rParam=self._parameters['rParam'].value
1991         sortByPt=self._parameters['sortByPt'].value
1992         printWarning=self._parameters['printWarning'].value
1993         jetCorrections=self._parameters['jetCorrections'].value
1994         btagDiscriminators=list(self._parameters['btagDiscriminators'].value)
1995         btagInfos=list(self._parameters['btagInfos'].value)
1996 
1997         ## a list of all producer modules, which are already known to process
1998         knownModules = process.producerNames().split()
1999         ## determine whether btagging information is required or not
2000         if btagDiscriminators.count('None')>0:
2001             btagDiscriminators.remove('None')
2002         if btagInfos.count('None')>0:
2003             btagInfos.remove('None')
2004         bTagging=(len(btagDiscriminators)>0 or len(btagInfos)>0)
2005 
2006         ## construct postfix label for auxiliary modules; this postfix
2007         ## label will start with a capitalized first letter following
2008         ## the CMS naming conventions and for improved readablility
2009         _labelName=labelName[:1].upper()+labelName[1:]
2010 
2011         ## supported algo types are ak, ca, and kt
2012         _algo=''
2013         for x in ["ak", "ca", "kt"]:
2014             if x in algo.lower():
2015                 _algo=supportedJetAlgos[x]
2016                 break
2017         if _algo=='':
2018             unsupportedJetAlgorithm(self)
2019 
2020         task = getPatAlgosToolsTask(process)
2021 
2022         ## add new updatedPatJets to process (keep instance for later further modifications)
2023         from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cfi import updatedPatJets
2024         if not sortByPt: # default is True
2025             updatedPatJets.sort = cms.bool(False)
2026         if 'updatedPatJets'+_labelName+postfix in knownModules :
2027             _newPatJets=getattr(process, 'updatedPatJets'+_labelName+postfix)
2028             _newPatJets.jetSource=jetSource
2029         else :
2030             addToProcessAndTask('updatedPatJets'+_labelName+postfix,
2031                                 updatedPatJets.clone(jetSource=jetSource,
2032                                 printWarning=printWarning), process, task)
2033             _newPatJets=getattr(process, 'updatedPatJets'+_labelName+postfix)
2034             knownModules.append('updatedPatJets'+_labelName+postfix)
2035         ## add new selectedUpdatedPatJets to process
2036         from PhysicsTools.PatAlgos.selectionLayer1.jetSelector_cfi import selectedPatJets
2037         if 'selectedUpdatedPatJets'+_labelName+postfix in knownModules :
2038             _newSelectedPatJets=getattr(process, 'selectedUpdatedPatJets'+_labelName+postfix)
2039             _newSelectedPatJets.src='updatedPatJets'+_labelName+postfix
2040         else :
2041             addToProcessAndTask('selectedUpdatedPatJets'+_labelName+postfix,
2042                                 selectedPatJets.clone(src='updatedPatJets'+_labelName+postfix),
2043                                 process, task)
2044             knownModules.append('selectedUpdatedPatJets'+_labelName+postfix)
2045 
2046         ## run btagging if required by user
2047         if (bTagging):
2048             if printWarning:
2049                sys.stderr.write("**************************************************************\n")
2050                sys.stderr.write("b tagging needs to be run on uncorrected jets. Hence, the JECs\n")
2051                sys.stderr.write("will first be undone for 'updatedPatJets%s' and then applied to\n" % (_labelName+postfix) )
2052                sys.stderr.write("'updatedPatJetsTransientCorrected%s'.\n" % (_labelName+postfix) )
2053                sys.stderr.write("**************************************************************\n")
2054             _jetSource = cms.InputTag('updatedPatJets'+_labelName+postfix)
2055             ## insert new jet collection with jet corrections applied and btag info added
2056             self(
2057                 process,
2058                 labelName = ('TransientCorrected'+_labelName),
2059                 jetSource = _jetSource,
2060                 pfCandidates=pfCandidates,
2061                 explicitJTA=explicitJTA,
2062                 pvSource=pvSource,
2063                 svSource=svSource,
2064                 elSource=elSource,
2065                 muSource=muSource,
2066                 runIVF=runIVF,
2067                 tightBTagNTkHits=tightBTagNTkHits,
2068                 loadStdRecoBTag=loadStdRecoBTag,
2069                 svClustering=svClustering,
2070                 fatJets=fatJets,
2071                 groomedFatJets=groomedFatJets,
2072                 algo=algo,
2073                 rParam=rParam,
2074                 jetCorrections = jetCorrections,
2075                 btagPrefix = btagPrefix,
2076                 postfix = postfix
2077             )
2078             ## setup btagging
2079             _patJets=getattr(process, 'updatedPatJetsTransientCorrected'+_labelName+postfix)
2080             setupBTagging(process, _jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
2081                           _algo, rParam, btagDiscriminators, btagInfos, _patJets, _labelName, btagPrefix, postfix)
2082             ## update final selected jets
2083             _newSelectedPatJets=getattr(process, 'selectedUpdatedPatJets'+_labelName+postfix)
2084             _newSelectedPatJets.src='updatedPatJetsTransientCorrected'+_labelName+postfix
2085             ## remove automatically added but redundant 'TransientCorrected' selected jets
2086             delattr(process, 'selectedUpdatedPatJetsTransientCorrected'+_labelName+postfix)
2087         else:
2088             _newPatJets.addBTagInfo = False
2089             _newPatJets.addTagInfos = False
2090 
2091         ## add jet correction factors if required by user
2092         if (jetCorrections is not None or bTagging):
2093             ## check the jet corrections format
2094             if jetCorrections is None and bTagging:
2095                 raise ValueError("Passing jetCorrections = None while running bTagging is likely not intended.")
2096             else:
2097                 checkJetCorrectionsFormat(jetCorrections)
2098             ## reset MET corrrection
2099             if jetCorrections[2].lower() != 'none' and jetCorrections[2] != '':
2100                 sys.stderr.write("-------------------------------------------------------------------\n")
2101                 sys.stderr.write(" Warning: MET correction was set to " + jetCorrections[2] + " but\n")
2102                 sys.stderr.write("          will be ignored. Please set it to \"None\" to avoid\n")
2103                 sys.stderr.write("          getting this warning.\n")
2104                 sys.stderr.write("-------------------------------------------------------------------\n")
2105                 jetCorrectionsList = list(jetCorrections)
2106                 jetCorrectionsList[2] = 'None'
2107                 jetCorrections = tuple(jetCorrectionsList)
2108             ## if running b tagging, need to use uncorrected jets
2109             if (bTagging):
2110                 jetCorrections = ('AK4PFchs', cms.vstring([]), 'None')
2111             ## setup jet energy corrections
2112             setupJetCorrections(process, knownModules, jetCorrections, jetSource, pvSource, _newPatJets, _labelName, postfix)
2113         else:
2114             ## switch jetCorrFactors off
2115             _newPatJets.addJetCorrFactors=False
2116 
2117 updateJetCollection=UpdateJetCollection()
2118 
2119 
2120 class AddJetID(ConfigToolBase):
2121     """
2122     Compute jet id for process
2123     """
2124     _label='addJetID'
2125     _defaultParameters=dicttypes.SortedKeysDict()
2126     def __init__(self):
2127         ConfigToolBase.__init__(self)
2128         self.addParameter(self._defaultParameters,'jetSrc','', "", Type=cms.InputTag)
2129         self.addParameter(self._defaultParameters,'jetIdTag','', "Tag to append to jet id map", Type=str)
2130         self._parameters=copy.deepcopy(self._defaultParameters)
2131         self._comment = ""
2132 
2133     def getDefaultParameters(self):
2134         return self._defaultParameters
2135 
2136     def __call__(self,process,
2137                  jetSrc     = None,
2138                  jetIdTag    = None) :
2139         if  jetSrc is None:
2140             jetSrc=self._defaultParameters['jetSrc'].value
2141         if  jetIdTag is None:
2142             jetIdTag=self._defaultParameters['jetIdTag'].value
2143         self.setParameter('jetSrc',jetSrc)
2144         self.setParameter('jetIdTag',jetIdTag)
2145         self.apply(process)
2146 
2147     def toolCode(self, process):
2148         jetSrc=self._parameters['jetSrc'].value
2149         jetIdTag=self._parameters['jetIdTag'].value
2150 
2151         jetIdLabel = jetIdTag + 'JetID'
2152         sys.stderr.write("Making new jet ID label with label " + jetIdTag + "\n")
2153 
2154         ## replace jet id sequence
2155         task = getPatAlgosToolsTask(process)
2156         process.load("RecoJets.JetProducers.ak4JetID_cfi")
2157         task.add(process.ak4JetID)
2158         addToProcessAndTask(jetIdLabel, process.ak4JetID.clone(src = jetSrc),
2159                             process, task)
2160 
2161 
2162 addJetID=AddJetID()
2163 
2164 
2165 class SetTagInfos(ConfigToolBase):
2166     """
2167     Replace tag infos for collection jetSrc
2168     """
2169     _label='setTagInfos'
2170     _defaultParameters=dicttypes.SortedKeysDict()
2171     def __init__(self):
2172         ConfigToolBase.__init__(self)
2173         self.addParameter(self._defaultParameters,'coll',"patJets","jet collection to set tag infos for")
2174         self.addParameter(self._defaultParameters,'tagInfos',cms.vstring( ), "tag infos to set")
2175         self._parameters=copy.deepcopy(self._defaultParameters)
2176         self._comment = ""
2177 
2178     def getDefaultParameters(self):
2179         return self._defaultParameters
2180 
2181     def __call__(self,process,
2182                  coll         = None,
2183                  tagInfos     = None) :
2184         if  coll is None:
2185             coll=self._defaultParameters['coll'].value
2186         if  tagInfos is None:
2187             tagInfos=self._defaultParameters['tagInfos'].value
2188         self.setParameter('coll',coll)
2189         self.setParameter('tagInfos',tagInfos)
2190         self.apply(process)
2191 
2192     def toolCode(self, process):
2193         coll=self._parameters['coll'].value
2194         tagInfos=self._parameters['tagInfos'].value
2195 
2196         found = False
2197         newTags = cms.VInputTag()
2198         iNewTags = 0
2199         for k in tagInfos :
2200             for j in getattr( process, coll ).tagInfoSources :
2201                 vv = j.value();
2202                 if ( vv.find(k) != -1 ):
2203                     found = True
2204                     newTags.append( j )
2205 
2206         if not found:
2207             raise RuntimeError("""
2208             Cannot replace tag infos in jet collection""" % (coll))
2209         else :
2210             getattr(process,coll).tagInfoSources = newTags
2211 
2212 setTagInfos=SetTagInfos()
2213 
2214 def deprecatedOptionOutputModule(obj):
2215     sys.stderr.write("-------------------------------------------------------\n")
2216     sys.stderr.write(" Error: the option 'outputModule' is not supported\n")
2217     sys.stderr.write("        anymore by:\n")
2218     sys.stderr.write("                     " + obj._label + "\n")
2219     sys.stderr.write("        please use 'outputModules' now and specify the\n")
2220     sys.stderr.write("        names of all needed OutModules in there\n")
2221     sys.stderr.write("        (default: ['out'])\n")
2222     sys.stderr.write("-------------------------------------------------------\n")
2223     raise KeyError("Unsupported option 'outputModule' used in '"+obj._label+"'")
2224 
2225 def undefinedLabelName(obj):
2226     sys.stderr.write("-------------------------------------------------------\n")
2227     sys.stderr.write(" Error: the jet 'labelName' is not defined.\n")
2228     sys.stderr.write("        All added jets must have 'labelName' defined.\n")
2229     sys.stderr.write("-------------------------------------------------------\n")
2230     raise KeyError("Undefined jet 'labelName' used in '"+obj._label+"'")
2231 
2232 def unsupportedJetAlgorithm(obj):
2233     sys.stderr.write("-------------------------------------------------------\n")
2234     sys.stderr.write(" Error: Unsupported jet algorithm detected.\n")
2235     sys.stderr.write("        The supported algorithms are:\n")
2236     for key in supportedJetAlgos.keys():
2237         sys.stderr.write("        " + key.upper() + ", " + key.lower() + ": " + supportedJetAlgos[key] + "\n")
2238     sys.stderr.write("-------------------------------------------------------\n")
2239     raise KeyError("Unsupported jet algorithm used in '"+obj._label+"'")
2240 
2241 def rerunningIVF():
2242     sys.stderr.write("-------------------------------------------------------------------\n")
2243     sys.stderr.write(" Warning: You are attempting to remake the IVF secondary vertices\n")
2244     sys.stderr.write("          already produced by the standard reconstruction. This\n")
2245     sys.stderr.write("          option is not enabled by default so please use it only if\n")
2246     sys.stderr.write("          you know what you are doing.\n")
2247     sys.stderr.write("-------------------------------------------------------------------\n")
2248 
2249 def rerunningIVFMiniAOD():
2250     sys.stderr.write("-------------------------------------------------------------------\n")
2251     sys.stderr.write(" Warning: You are attempting to remake IVF secondary vertices from\n")
2252     sys.stderr.write("          MiniAOD. If that was your intention, note that secondary\n")
2253     sys.stderr.write("          vertices remade from MiniAOD will have somewhat degraded\n")
2254     sys.stderr.write("          performance compared to those remade from RECO/AOD.\n")
2255     sys.stderr.write("-------------------------------------------------------------------\n")