Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-06 03:13:06

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