patAlgosToolsTask = getPatAlgosToolsTask(process)
process.outpath = cms.EndPath(process.out, patAlgosToolsTask)

## and add them to the event content
from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection,addJetCollection

## Puppi
jetSeq = cms.Sequence()
process.load("CommonTools.PileupAlgos.Puppi_cff")
#process.puppi.candName = cms.InputTag( 'particleFlow' ) 
jetSeq += process.puppi

from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
process.ak8PFJetsPuppi = ak4PFJetsPuppi.clone( src = cms.InputTag( 'puppi' ),
                                               doAreaFastjet = True, 
                                               rParam = 0.8, 
                                               jetAlgorithm = 'AntiKt' )
jetSeq += process.ak8PFJetsPuppi

process.jetSequence = jetSeq

addJetCollection(
   process,
   #labelName = 'AK8PFCHS',
   labelName = 'AK8PFPuppi',
   #jetSource = cms.InputTag('ak8PFJetsCHS'),
   jetSource = cms.InputTag('ak8PFJetsPuppi'),
   #pvSource = cms.InputTag('offlinePrimaryVertices'),
   #svSource = cms.InputTag('inclusiveCandidateSecondaryVertices'),
   algo = 'AK',
   rParam = 0.8,
def applySubstructure( process, postfix="" ) :

    task = getPatAlgosToolsTask(process)

    from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection


    from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJetsDefault


    # Configure the RECO jets
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents
    from RecoJets.JetProducers.ak8GenJets_cfi import ak8GenJets, ak8GenJetsSoftDrop, ak8GenJetsConstituents
    addToProcessAndTask('ak4PFJetsPuppi'+postfix,ak4PFJetsPuppi.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppi'+postfix,ak8PFJetsPuppi.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppiConstituents', ak8PFJetsPuppiConstituents.clone(cut = cms.string('pt > 170.0 && abs(rapidity()) < 2.4') ), process, task )
    addToProcessAndTask('ak8PFJetsCHSConstituents', ak8PFJetsCHSConstituents.clone(), process, task )
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop'+postfix, ak8PFJetsPuppiSoftDrop.clone( src = cms.InputTag('ak8PFJetsPuppiConstituents', 'constituents') ), process, task)
    addToProcessAndTask('ak8GenJetsNoNuConstituents'+postfix, ak8GenJetsConstituents.clone(src='ak8GenJetsNoNu'), process, task )
    addToProcessAndTask('ak8GenJetsNoNuSoftDrop'+postfix,ak8GenJetsSoftDrop.clone(src=cms.InputTag('ak8GenJetsNoNuConstituents'+postfix, 'constituents')),process,task)
    addToProcessAndTask('slimmedGenJetsAK8SoftDropSubJets'+postfix,
                            cms.EDProducer("PATGenJetSlimmer",
                                               src = cms.InputTag("ak8GenJetsNoNuSoftDrop"+postfix, "SubJets"),
                                               packedGenParticles = cms.InputTag("packedGenParticles"),
                                               cut = cms.string(""),
                                               cutLoose = cms.string(""),
                                               nLoose = cms.uint32(0),
                                               clearDaughters = cms.bool(False), #False means rekeying
                                               dropSpecific = cms.bool(True),  # Save space
                                               ), process, task )
    
    
    #add AK8 CHS
    addJetCollection(process, postfix=postfix, labelName = 'AK8',
                     jetSource = cms.InputTag('ak8PFJetsCHS'+postfix),
                     algo= 'AK', rParam = 0.8,
                     btagDiscriminators = ['None'],
                     jetCorrections = ('AK8PFchs', cms.vstring(['L1FastJet', 'L2Relative', 'L3Absolute']), 'None'),
                     genJetCollection = cms.InputTag('slimmedGenJetsAK8')
                     )
    getattr(process,"patJetsAK8"+postfix).userData.userFloats.src = [] # start with empty list of user floats
    getattr(process,"selectedPatJetsAK8").cut = cms.string("pt > 170")


    ## add AK8 groomed masses with CHS
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsCHSPruned, ak8PFJetsCHSSoftDrop
    addToProcessAndTask('ak8PFJetsCHSPruned'+postfix, ak8PFJetsCHSPruned.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDrop'+postfix, ak8PFJetsCHSSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsCHS_groomingValueMaps_cfi import ak8PFJetsCHSPrunedMass, ak8PFJetsCHSTrimmedMass, ak8PFJetsCHSFilteredMass, ak8PFJetsCHSSoftDropMass
    addToProcessAndTask('ak8PFJetsCHSPrunedMass'+postfix, ak8PFJetsCHSPrunedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSTrimmedMass'+postfix, ak8PFJetsCHSTrimmedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSFilteredMass'+postfix, ak8PFJetsCHSFilteredMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDropMass'+postfix, ak8PFJetsCHSSoftDropMass.clone(), process, task)

    getattr(process,"patJetsAK8").userData.userFloats.src += ['ak8PFJetsCHSPrunedMass'+postfix,'ak8PFJetsCHSSoftDropMass'+postfix]  
    getattr(process,"patJetsAK8").addTagInfos = cms.bool(False)

    # add Njetiness for CHS
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8'+postfix, process.Njettiness.clone(), process, task)
    getattr(process,"NjettinessAK8").src = cms.InputTag("ak8PFJetsCHS"+postfix)
    getattr(process,"NjettinessAK8").cone = cms.double(0.8)
    getattr(process,"patJetsAK8").userData.userFloats.src += ['NjettinessAK8'+postfix+':tau1','NjettinessAK8'+postfix+':tau2','NjettinessAK8'+postfix+':tau3','NjettinessAK8'+postfix+':tau4']

    # add Njetiness from CHS
    addToProcessAndTask('NjettinessAK8Subjets'+postfix, process.Njettiness.clone(), process, task)
    getattr(process,"NjettinessAK8Subjets"+postfix).src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix, "SubJets")
    getattr(process,"NjettinessAK8Subjets").cone = cms.double(0.8)
        
    ## PATify CHS soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFCHSSoftDrop',
        jetSource = cms.InputTag('ak8PFJetsCHSSoftDrop'+postfix),
        btagDiscriminators = ['None'],
        jetCorrections = ('AK8PFchs', ['L1FastJet', 'L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour = False # jet flavor disabled
    )





    #add RECO AK8 from PUPPI and RECO AK8 PUPPI with soft drop... will be needed by ungroomed AK8 jets later
    ## PATify puppi soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFPuppiSoftDrop' + postfix,
        jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix),
        btagDiscriminators = ['None'],
        genJetCollection = cms.InputTag('slimmedGenJetsAK8'), 
        jetCorrections = ('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour = False # jet flavor disabled
    )
    ## PATify soft drop subjets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFPuppiSoftDropSubjets',
        jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix,'SubJets'),
        algo = 'ak',  # needed for subjet flavor clustering
        rParam = 0.8, # needed for subjet flavor clustering
        btagDiscriminators = ['pfDeepCSVJetTags:probb', 'pfDeepCSVJetTags:probbb', 'pfCombinedInclusiveSecondaryVertexV2BJetTags','pfCombinedMVAV2BJetTags'],
        jetCorrections = ('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        explicitJTA = True,  # needed for subjet b tagging
        svClustering = True, # needed for subjet b tagging
        genJetCollection = cms.InputTag('slimmedGenJetsAK8SoftDropSubJets'), 
        fatJets=cms.InputTag('ak8PFJetsPuppi'),             # needed for subjet flavor clustering
        groomedFatJets=cms.InputTag('ak8PFJetsPuppiSoftDrop') # needed for subjet flavor clustering
    )


    # add groomed ECFs and N-subjettiness to soft dropped pat::Jets for fat jets and subjets
    process.load('RecoJets.JetProducers.ECF_cff')
    addToProcessAndTask('nb1AK8PuppiSoftDrop'+postfix, process.ecfNbeta1.clone(src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix), cuts = cms.vstring('', '', 'pt > 250')), process, task)
    addToProcessAndTask('nb2AK8PuppiSoftDrop'+postfix, process.ecfNbeta2.clone(src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix), cuts = cms.vstring('', '', 'pt > 250')), process, task)

    #too slow now ==> disable
    from Configuration.Eras.Modifier_pp_on_AA_2018_cff import pp_on_AA_2018
    from Configuration.Eras.Modifier_pp_on_XeXe_2017_cff import pp_on_XeXe_2017
    from Configuration.Eras.Modifier_phase2_common_cff import phase2_common
    for e in [pp_on_XeXe_2017, pp_on_AA_2018, phase2_common]:
        e.toModify(getattr(process,'nb1AK8PuppiSoftDrop'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] )
        e.toModify(getattr(process,'nb2AK8PuppiSoftDrop'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] )


    getattr(process,"patJetsAK8PFPuppiSoftDrop").userData.userFloats.src += ['nb1AK8PuppiSoftDrop'+postfix+':ecfN2','nb1AK8PuppiSoftDrop'+postfix+':ecfN3']
    getattr(process,"patJetsAK8PFPuppiSoftDrop").userData.userFloats.src += ['nb2AK8PuppiSoftDrop'+postfix+':ecfN2','nb2AK8PuppiSoftDrop'+postfix+':ecfN3']
    addToProcessAndTask('nb1AK8PuppiSoftDropSubjets'+postfix, process.ecfNbeta1.clone(src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix, "SubJets")), process, task)
    addToProcessAndTask('nb2AK8PuppiSoftDropSubjets'+postfix, process.ecfNbeta2.clone(src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix, "SubJets")), process, task)
    getattr(process,"patJetsAK8PFPuppiSoftDropSubjets"+postfix).userData.userFloats.src += ['nb1AK8PuppiSoftDropSubjets'+postfix+':ecfN2','nb1AK8PuppiSoftDropSubjets'+postfix+':ecfN3']
    getattr(process,"patJetsAK8PFPuppiSoftDropSubjets"+postfix).userData.userFloats.src += ['nb2AK8PuppiSoftDropSubjets'+postfix+':ecfN2','nb2AK8PuppiSoftDropSubjets'+postfix+':ecfN3']
    getattr(process,"patJetsAK8PFPuppiSoftDropSubjets"+postfix).userData.userFloats.src += ['NjettinessAK8Subjets'+postfix+':tau1','NjettinessAK8Subjets'+postfix+':tau2','NjettinessAK8Subjets'+postfix+':tau3','NjettinessAK8Subjets'+postfix+':tau4']

    for e in [pp_on_XeXe_2017, pp_on_AA_2018, phase2_common]:
        e.toModify(getattr(process,'nb1AK8PuppiSoftDropSubjets'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] )
        e.toModify(getattr(process,'nb2AK8PuppiSoftDropSubjets'+postfix), cuts = ['pt > 999999', 'pt > 999999', 'pt > 999999'] )

    # rekey the groomed ECF value maps to the ungroomed reco jets, which will then be picked
    # up by PAT in the user floats. 
    addToProcessAndTask("ak8PFJetsPuppiSoftDropValueMap"+postfix, 
                        cms.EDProducer("RecoJetToPatJetDeltaRValueMapProducer",
                                       src = cms.InputTag("ak8PFJetsPuppi"+postfix),
                                       matched = cms.InputTag("patJetsAK8PFPuppiSoftDrop"+postfix),
                                       distMax = cms.double(0.8),
                                       values = cms.vstring([
                    'userFloat("nb1AK8PuppiSoftDrop'+postfix+':ecfN2")',
                    'userFloat("nb1AK8PuppiSoftDrop'+postfix+':ecfN3")',
                    'userFloat("nb2AK8PuppiSoftDrop'+postfix+':ecfN2")',
                    'userFloat("nb2AK8PuppiSoftDrop'+postfix+':ecfN3")',
                    ]),
                                       valueLabels = cms.vstring( [
                    'nb1AK8PuppiSoftDropN2',
                    'nb1AK8PuppiSoftDropN3',
                    'nb2AK8PuppiSoftDropN2',
                    'nb2AK8PuppiSoftDropN3',
                    ]) ),
                    process, task)

        
    # Patify AK8 PF PUPPI
    addJetCollection(process, postfix=postfix, labelName = 'AK8Puppi',
                     jetSource = cms.InputTag('ak8PFJetsPuppi'+postfix),
                     algo= 'AK', rParam = 0.8,
                     jetCorrections = ('AK8PFPuppi', cms.vstring(['L2Relative', 'L3Absolute']), 'None'),
                     btagDiscriminators = ([
                         'pfCombinedSecondaryVertexV2BJetTags',
                         'pfCombinedInclusiveSecondaryVertexV2BJetTags',
                         'pfCombinedMVAV2BJetTags',
                         'pfDeepCSVJetTags:probb',
                         'pfDeepCSVJetTags:probc',
                         'pfDeepCSVJetTags:probudsg',
                         'pfDeepCSVJetTags:probbb',
                         'pfBoostedDoubleSecondaryVertexAK8BJetTags']),
                     genJetCollection = cms.InputTag('slimmedGenJetsAK8')
                     )
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src = [] # start with empty list of user floats
    getattr(process,"selectedPatJetsAK8Puppi"+postfix).cut = cms.string("pt > 100")
    getattr(process,"selectedPatJetsAK8Puppi"+postfix).cutLoose = cms.string("pt > 30")
    getattr(process,"selectedPatJetsAK8Puppi"+postfix).nLoose = cms.uint32(3)

    from RecoJets.JetAssociationProducers.j2tParametersVX_cfi import j2tParametersVX
    addToProcessAndTask('ak8PFJetsPuppiTracksAssociatorAtVertex'+postfix, cms.EDProducer("JetTracksAssociatorAtVertex",
                                      j2tParametersVX.clone( coneSize = cms.double(0.8) ),
                                      jets = cms.InputTag("ak8PFJetsPuppi") ),
                        process, task)
    addToProcessAndTask('patJetAK8PuppiCharge'+postfix, cms.EDProducer("JetChargeProducer",
                                     src = cms.InputTag("ak8PFJetsPuppiTracksAssociatorAtVertex"),
                                     var = cms.string('Pt'),
                                     exp = cms.double(1.0) ), 
                        process, task)

    ## now add AK8 groomed masses and ECF
    from RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi import ak8PFJetsPuppiSoftDropMass
    addToProcessAndTask('ak8PFJetsPuppiSoftDropMass'+postfix, ak8PFJetsPuppiSoftDropMass.clone(), process, task)
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src += ['ak8PFJetsPuppiSoftDropMass'+postfix]
    getattr(process,"patJetsAK8Puppi"+postfix).addTagInfos = cms.bool(False)
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src += [
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap'+postfix,'nb1AK8PuppiSoftDropN2'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap'+postfix,'nb1AK8PuppiSoftDropN3'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap'+postfix,'nb2AK8PuppiSoftDropN2'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap'+postfix,'nb2AK8PuppiSoftDropN3'),
        ]


    # add PUPPI Njetiness
    addToProcessAndTask('NjettinessAK8Puppi'+postfix, process.Njettiness.clone(), process, task)
    getattr(process,"NjettinessAK8Puppi"+postfix).src = cms.InputTag("ak8PFJetsPuppi"+postfix)
    getattr(process,"NjettinessAK8Puppi").cone = cms.double(0.8)
    getattr(process,"patJetsAK8Puppi").userData.userFloats.src += ['NjettinessAK8Puppi'+postfix+':tau1','NjettinessAK8Puppi'+postfix+':tau2','NjettinessAK8Puppi'+postfix+':tau3','NjettinessAK8Puppi'+postfix+':tau4']

    # Now combine the CHS and PUPPI information into the PUPPI jets via delta R value maps
    addToProcessAndTask("ak8PFJetsCHSValueMap"+postfix, cms.EDProducer("RecoJetToPatJetDeltaRValueMapProducer",
                                            src = cms.InputTag("ak8PFJetsPuppi"+postfix),
                                            matched = cms.InputTag("patJetsAK8"+postfix),
                                            distMax = cms.double(0.8),
                                            values = cms.vstring([
                                                'userFloat("ak8PFJetsCHSPrunedMass"'+postfix+')',
                                                'userFloat("ak8PFJetsCHSSoftDropMass"'+postfix+')',
                                                'userFloat("NjettinessAK8'+postfix+':tau1")',
                                                'userFloat("NjettinessAK8'+postfix+':tau2")',
                                                'userFloat("NjettinessAK8'+postfix+':tau3")',
                                                'userFloat("NjettinessAK8'+postfix+':tau4")',
                                                'pt','eta','phi','mass', 'jetArea', 'jecFactor(0)'
                                            ]),
                                            valueLabels = cms.vstring( [
                                                'ak8PFJetsCHSPrunedMass',
                                                'ak8PFJetsCHSSoftDropMass',
                                                'NjettinessAK8CHSTau1',
                                                'NjettinessAK8CHSTau2',
                                                'NjettinessAK8CHSTau3',
                                                'NjettinessAK8CHSTau4',
                                                'pt','eta','phi','mass', 'jetArea', 'rawFactor'
                                            ]) ),
                        process, task)


    # Now set up the user floats
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src += [
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'ak8PFJetsCHSPrunedMass'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'ak8PFJetsCHSSoftDropMass'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau1'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau2'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau3'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau4'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'pt'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'eta'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'phi'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'mass'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'jetArea'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'rawFactor'),
                                                   ]

    

    
    addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropSubjets"+postfix,
                        cms.EDProducer("PATJetSlimmer",
                             src = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"),
                             packedPFCandidates = cms.InputTag("packedPFCandidates"),
                             dropJetVars = cms.string("1"),
                             dropDaughters = cms.string("0"),
                             rekeyDaughters = cms.string("1"),
                             dropTrackRefs = cms.string("1"),
                             dropSpecific = cms.string("1"),
                             dropTagInfos = cms.string("1"),
                             modifyJets = cms.bool(True),
                             mixedDaughters = cms.bool(False),
                             modifierConfig = cms.PSet( modifications = cms.VPSet() )
                                       ),
                        process, task)

    
    ## Establish references between PATified fat jets and subjets using the BoostedJetMerger
    addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix,
                        cms.EDProducer("BoostedJetMerger",
                               jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"),
                               subjetSrc=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjets")
                                       ),
                        process, task )

    
    addToProcessAndTask("packedPatJetsAK8"+postfix, cms.EDProducer("JetSubstructurePacker",
                                           jetSrc = cms.InputTag("selectedPatJetsAK8Puppi"+postfix),
                                           distMax = cms.double(0.8),
                                           algoTags = cms.VInputTag(
                                               cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix)
                                           ),
                                           algoLabels = cms.vstring(
                                               'SoftDropPuppi'
                                           ),
                                          fixDaughters = cms.bool(True),
                                          packedPFCandidates = cms.InputTag("packedPFCandidates"+postfix),
                                                                   ),
                        process, task)

    # switch off daughter re-keying since it's done in the JetSubstructurePacker (and can't be done afterwards)
    process.slimmedJetsAK8.rekeyDaughters = "0"
    # Reconfigure the slimmedAK8 jet information to keep 
    process.slimmedJetsAK8.dropDaughters = cms.string("pt < 170")
    process.slimmedJetsAK8.dropSpecific = cms.string("pt < 170")
    process.slimmedJetsAK8.dropTagInfos = cms.string("pt < 170")
Exemple #3
0
  def addRecoJetCollection(self,
    proc,
    jet,
    inputCollection    = "",
    minPtFastjet       = None,
    genJetsCollection  = "",
    bTagDiscriminators = ["None"],
    JETCorrLevels      = ["L1FastJet", "L2Relative", "L3Absolute", "L2L3Residual"],
    ):
    print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: Adding Reco Jet Collection: {}".format(jet))

    currentTasks = []

    if inputCollection and inputCollection not in self.patJetsInMiniAOD:
      raise RuntimeError("Invalid input collection: %s" % inputCollection)
    
    #=======================================================
    #
    # Figure out which jet collection we're dealing with
    #
    #=======================================================
    recoJetInfo = RecoJetInfo(jet, inputCollection)
    jetLower = recoJetInfo.jetLower
    jetUpper = recoJetInfo.jetUpper
    tagName  = recoJetInfo.jetTagName

    if inputCollection == "slimmedJets":
      assert(jetLower == "ak4pfchs")
    elif inputCollection == "slimmedJetsAK8":
      assert(jetLower == "ak8pfpuppi")
    elif inputCollection == "slimmedJetsPuppi":
      assert(jetLower == "ak4pfpuppi")
    elif inputCollection == "slimmedCaloJets":
      assert(jetLower == "ak4calo")
    
    #=======================================================
    #
    # If the patJet collection in MiniAOD is not specified, 
    # we have to build the patJet collection from scratch.
    #
    #========================================================
    if not inputCollection or recoJetInfo.doCalo:
      print("jetCollectionTools::RecoJetAdder::addRecoJetCollection: inputCollection not specified. Building recojet collection now")

      #=======================================================
      #
      # Prepare the inputs to jet clustering
      #
      #========================================================
      #
      # Specify PF candidates
      #
      pfCand = self.pfLabel
      #
      # Setup PU method for PF candidates
      # 
      if recoJetInfo.jetPUMethod not in [ "", "cs" ]:
        pfCand += recoJetInfo.jetPUMethod

      
      #
      # Setup modules to perform PU mitigation for 
      # PF candidates
      #
      if pfCand not in self.prerequisites:
        #
        # Skip if no PU Method or CS specified
        #
        if recoJetInfo.jetPUMethod in [ "", "cs" ]:
          pass
        #
        # CHS
        #
        elif recoJetInfo.jetPUMethod == "chs":
          from CommonTools.ParticleFlow.pfCHS_cff import pfCHS, packedPrimaryVertexAssociationJME
          self.addProcessAndTask(proc, "packedPrimaryVertexAssociationJME", packedPrimaryVertexAssociationJME.clone())
          self.prerequisites.append("packedPrimaryVertexAssociationJME")
          self.addProcessAndTask(proc, pfCand, pfCHS.clone())
          self.prerequisites.append(pfCand)
        #
        # PUPPI
        #
        elif recoJetInfo.jetPUMethod == "puppi":
          self.addProcessAndTask(proc, pfCand, puppi.clone(
              candName = self.pfLabel,
              vertexName = self.pvLabel,
            )
          )
          self.prerequisites.append(pfCand)
        #
        # Softkiller
        #
        elif recoJetInfo.jetPUMethod == "sk":
          self.addProcessAndTask(proc, pfCand, softKiller.clone(
              PFCandidates = self.pfLabel,
              rParam = recoJetInfo.jetSizeNr,
            )
          )
          self.prerequisites.append(pfCand)
        else:
          raise RuntimeError("Currently unsupported PU method: '%s'" % recoJetInfo.jetPUMethod)
      
      #============================================
      #
      # Create the recojet collection
      #
      #============================================
      if not recoJetInfo.doCalo:
        jetCollection = '{}Collection'.format(jetUpper)

        if jetCollection in self.main:
          raise ValueError("Step '%s' already implemented" % jetCollection)
        #
        # Cluster new jet
        #
        if recoJetInfo.jetPUMethod == "chs":
          self.addProcessAndTask(proc, jetCollection, ak4PFJetsCHS.clone(
              src = pfCand,
            )
          )
        elif recoJetInfo.jetPUMethod == "puppi":
          self.addProcessAndTask(proc, jetCollection, ak4PFJetsPuppi.clone(
              src = self.pfLabel,
              srcWeights = pfCand
            )
          )
        elif recoJetInfo.jetPUMethod == "sk":
          self.addProcessAndTask(proc, pfCand, ak4PFJetsSK.clone(
              src = pfCand,
            )
          )
        elif recoJetInfo.jetPUMethod == "cs":
          self.addProcessAndTask(proc, jetCollection, ak4PFJetsCS.clone(
            src = pfCand,
          )
        )
        else:
          self.addProcessAndTask(proc, jetCollection, ak4PFJets.clone(
            src = pfCand,
          )
        )
        getattr(proc, jetCollection).jetAlgorithm = supportedJetAlgos[recoJetInfo.jetAlgo]
        getattr(proc, jetCollection).rParam = recoJetInfo.jetSizeNr
        #
        # Set minimum pt threshold of reco jets to be saved after fastjet clustering
        #
        if minPtFastjet != None:
          getattr(proc, jetCollection).jetPtMin = minPtFastjet
        currentTasks.append(jetCollection)
      else:
        jetCollection = inputCollection
      

      #=============================================
      #
      # Make patJet collection
      #
      #=============================================
      #
      # Jet correction 
      #
      if recoJetInfo.jetPUMethod == "puppi":
        jetCorrLabel = "Puppi"
      elif recoJetInfo.jetPUMethod in [ "cs", "sk" ]:
        jetCorrLabel = "chs"
      else:
        jetCorrLabel = recoJetInfo.jetPUMethod

      jetCorrections = (
        "{}{}{}{}".format(
          recoJetInfo.jetAlgo.upper(),
          recoJetInfo.jetSize,
          "Calo" if recoJetInfo.doCalo else recoJetInfo.jetReco.upper(),
          jetCorrLabel
        ),
        JETCorrLevels,
        "None",
      )

      postfix = "Recluster" if inputCollection == "" else ""
      addJetCollection(
        proc,
        labelName          = jetUpper,
        postfix            = postfix,
        jetSource          = cms.InputTag(jetCollection),
        algo               = recoJetInfo.jetAlgo,
        rParam             = recoJetInfo.jetSizeNr,
        pvSource           = cms.InputTag(self.pvLabel),
        pfCandidates       = cms.InputTag(self.pfLabel),
        svSource           = cms.InputTag(self.svLabel),
        muSource           = cms.InputTag(self.muLabel),
        elSource           = cms.InputTag(self.elLabel),
        genJetCollection   = cms.InputTag(genJetsCollection),
        genParticles       = cms.InputTag(self.gpLabel),
        jetCorrections     = jetCorrections,
      )

      #
      # Need to set this explicitly for PUPPI jets
      #
      if recoJetInfo.jetPUMethod == "puppi":
        getattr(proc, "patJetFlavourAssociation{}{}".format(jetUpper,postfix)).weights = cms.InputTag(pfCand)

      getJetMCFlavour = not recoJetInfo.doCalo and recoJetInfo.jetPUMethod != "cs"
      if not self.runOnMC: #Remove modules for Gen-level object matching
        delattr(proc, 'patJetGenJetMatch{}{}'.format(jetUpper,postfix))
        delattr(proc, 'patJetPartonMatch{}{}'.format(jetUpper,postfix))
        getJetMCFlavour = False 
      setattr(getattr(proc, "patJets{}{}".format(jetUpper,postfix)), "getJetMCFlavour", cms.bool(getJetMCFlavour))

      selectedPatJets = "selectedPatJets{}{}".format(jetUpper,postfix)
      #=============================================
      #
      # Update the patJet collection. 
      # This is where we setup 
      # -  JEC
      # -  b-tagging discriminators  
      # 
      #=============================================
      updateJetCollection(
        proc,
        labelName          = jetUpper,
        postfix            = "Final",
        jetSource          = cms.InputTag(selectedPatJets),
        jetCorrections     = jetCorrections,
        btagDiscriminators = bTagDiscriminators,
      )

      recoJetInfo.patJetFinalCollection = "selectedUpdatedPatJets{}{}".format(jetUpper,"Final")
    else:
      recoJetInfo.patJetFinalCollection = inputCollection

    self.main.extend(currentTasks)

    return recoJetInfo
Exemple #4
0
def hltMETsSeq(proc, particleFlow, primaryVertices):

    ### Puppi MET

    # Puppi candidates for MET
    proc.pfNoLepPUPPI = cms.EDFilter('PdgIdCandViewSelector',
                                     src=cms.InputTag(particleFlow),
                                     pdgId=cms.vint32(1, 2, 22, 111, 130, 310,
                                                      2112, 211, -211, 321,
                                                      -321, 999211, 2212,
                                                      -2212))
    proc.pfLeptonsPUPPET = cms.EDFilter(
        'PdgIdCandViewSelector',
        src=cms.InputTag(particleFlow),
        pdgId=cms.vint32(-11, 11, -13, 13),
    )
    proc.puppiNoLep = puppi.clone(
        candName='pfNoLepPUPPI',
        vertexName=primaryVertices,
    )
    proc.puppiMerged = cms.EDProducer(
        'CandViewMerger',
        src=cms.VInputTag('puppiNoLep', 'pfLeptonsPUPPET'),
    )
    proc.hltPuppiForMET = puppiPhoton.clone(
        candName=particleFlow,
        # Line below points puppi-MET to puppi-no-lepton, which increases the response
        puppiCandName='puppiMerged',
        # Line below replaces reference linking with delta-R matching
        # because the puppi references after merging are not consistent with those of the original PF collection
        useRefs=False,
    )
    proc.hltPuppiMET = cms.EDProducer(
        'PFMETProducer',
        src=cms.InputTag('hltPuppiForMET'),
        globalThreshold=cms.double(0.0),
        calculateSignificance=cms.bool(False),
    )
    proc.hltPuppiMETsRawSeq = cms.Sequence(
        (proc.pfNoLepPUPPI * proc.puppiNoLep + proc.pfLeptonsPUPPET) *
        proc.puppiMerged * proc.hltPuppiForMET * proc.hltPuppiMET)

    ### Puppi MET Type-1

    # Puppi candidates for Jets
    proc.hltPuppi = puppi.clone(
        candName=particleFlow,
        vertexName=primaryVertices,
    )
    proc.ak4PuppiJetsForPuppiMETTypeOne = ak4PFJetsPuppi.clone(
        src='hltPuppi', )
    proc.hltAK4PuppiFastJetCorrector = cms.EDProducer(
        'L1FastjetCorrectorProducer',
        srcRho=cms.InputTag('fixedGridRhoFastjetAll' + '::' + proc.name_()),
        algorithm=cms.string('AK4PFPuppi'),
        level=cms.string('L1FastJet'))
    proc.hltAK4PuppiRelativeCorrector = cms.EDProducer(
        'LXXXCorrectorProducer',
        algorithm=cms.string('AK4PFPuppi'),
        level=cms.string('L2Relative'))
    proc.hltAK4PuppiAbsoluteCorrector = cms.EDProducer(
        'LXXXCorrectorProducer',
        algorithm=cms.string('AK4PFPuppi'),
        level=cms.string('L3Absolute'))
    proc.hltAK4PuppiResidualCorrector = cms.EDProducer(
        'LXXXCorrectorProducer',
        algorithm=cms.string('AK4PFPuppi'),
        level=cms.string('L2L3Residual'))
    proc.hltAK4PuppiCorrector = cms.EDProducer(
        'ChainedJetCorrectorProducer',
        correctors=cms.VInputTag('hltAK4PuppiFastJetCorrector',
                                 'hltAK4PuppiRelativeCorrector',
                                 'hltAK4PuppiAbsoluteCorrector',
                                 'hltAK4PuppiResidualCorrector'))
    proc.hltcorrPuppiMETTypeOne = cms.EDProducer(
        'PFJetMETcorrInputProducer',
        src=cms.InputTag('ak4PuppiJetsForPuppiMETTypeOne'),
        type1JetPtThreshold=cms.double(35.0),
        skipEMfractionThreshold=cms.double(0.9),
        skipEM=cms.bool(True),
        jetCorrLabelRes=cms.InputTag('hltAK4PuppiCorrector'),
        offsetCorrLabel=cms.InputTag('hltAK4PuppiFastJetCorrector'),
        skipMuons=cms.bool(True),
        skipMuonSelection=cms.string('isGlobalMuon | isStandAloneMuon'),
        jetCorrEtaMax=cms.double(9.9),
        jetCorrLabel=cms.InputTag('hltAK4PuppiCorrector'))
    proc.hltPuppiMETTypeOne = cms.EDProducer(
        'CorrectedPFMETProducer',
        src=cms.InputTag('hltPuppiMET'),
        srcCorrections=cms.VInputTag('hltcorrPuppiMETTypeOne:type1'))
    proc.hltPuppiMETsTypeOneSeq = cms.Sequence(
        proc.hltPuppi * proc.ak4PuppiJetsForPuppiMETTypeOne *
        proc.hltAK4PuppiFastJetCorrector * proc.hltAK4PuppiRelativeCorrector *
        proc.hltAK4PuppiAbsoluteCorrector * proc.hltAK4PuppiResidualCorrector *
        proc.hltAK4PuppiCorrector * proc.hltcorrPuppiMETTypeOne *
        proc.hltPuppiMETTypeOne)

    # [testing] Puppi MET with Puppi-For-Jets inputs
    proc.hltPuppiMETWithPuppiForJets = cms.EDProducer(
        'PFMETProducer',
        src=cms.InputTag('hltPuppi'),
        globalThreshold=cms.double(0.0),
        calculateSignificance=cms.bool(False),
    )
    proc.hltPuppiMETsRawSeq += cms.Sequence(proc.hltPuppi *
                                            proc.hltPuppiMETWithPuppiForJets)

    ### SoftKiller MET

    proc.hltSoftKiller = cms.EDProducer(
        'SoftKillerProducer',
        PFCandidates=cms.InputTag(particleFlow),
        Rho_EtaMax=cms.double(5.0),
        rParam=cms.double(0.4))
    proc.hltSoftKillerMET = cms.EDProducer(
        'PFMETProducer',
        src=cms.InputTag('hltSoftKiller'),
        globalThreshold=cms.double(0.0),
        calculateSignificance=cms.bool(False),
    )
    proc.hltSoftKillerMETsSeq = cms.Sequence(proc.hltSoftKiller *
                                             proc.hltSoftKillerMET)

    ### METs Sequence

    proc.hltMETsSeq = cms.Sequence(
        proc.hltPuppiMETsRawSeq
        #      * proc.hltPuppiMETsTypeOneSeq --> HLT JECs for PuppiJets not available
        + proc.hltSoftKillerMETsSeq)
def applySubstructure( process, postfix="" ) :

    task = getPatAlgosToolsTask(process)

    from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection


    from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJetsDefault

    #add AK8
    addJetCollection(process, postfix=postfix, labelName = 'AK8',
                     jetSource = cms.InputTag('ak8PFJetsCHS'+postfix),
                     algo= 'AK', rParam = 0.8,
                     jetCorrections = ('AK8PFchs', cms.vstring(['L1FastJet', 'L2Relative', 'L3Absolute']), 'None'),
                     genJetCollection = cms.InputTag('slimmedGenJetsAK8')
                     )
    getattr(process,"patJetsAK8"+postfix).userData.userFloats.src = [] # start with empty list of user floats
    getattr(process,"selectedPatJetsAK8").cut = cms.string("pt > 170")


    ## AK8 groomed masses
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsCHSPruned, ak8PFJetsCHSSoftDrop
    addToProcessAndTask('ak8PFJetsCHSPruned'+postfix, ak8PFJetsCHSPruned.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDrop'+postfix, ak8PFJetsCHSSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsCHS_groomingValueMaps_cfi import ak8PFJetsCHSPrunedMass, ak8PFJetsCHSTrimmedMass, ak8PFJetsCHSFilteredMass, ak8PFJetsCHSSoftDropMass
    addToProcessAndTask('ak8PFJetsCHSPrunedMass'+postfix, ak8PFJetsCHSPrunedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSTrimmedMass'+postfix, ak8PFJetsCHSTrimmedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSFilteredMass'+postfix, ak8PFJetsCHSFilteredMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDropMass'+postfix, ak8PFJetsCHSSoftDropMass.clone(), process, task)

    getattr(process,"patJetsAK8").userData.userFloats.src += ['ak8PFJetsCHSPrunedMass'+postfix,'ak8PFJetsCHSSoftDropMass'+postfix]  
    getattr(process,"patJetsAK8").addTagInfos = cms.bool(False)



    # add Njetiness
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8'+postfix, process.Njettiness.clone(), process, task)


    getattr(process,"NjettinessAK8").src = cms.InputTag("ak8PFJetsCHS"+postfix)
    getattr(process,"NjettinessAK8").cone = cms.double(0.8)
    getattr(process,"patJetsAK8").userData.userFloats.src += ['NjettinessAK8'+postfix+':tau1','NjettinessAK8'+postfix+':tau2','NjettinessAK8'+postfix+':tau3']




    #add AK8 from PUPPI                                                                                                                                 
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi
    addToProcessAndTask('ak4PFJetsPuppi'+postfix,ak4PFJetsPuppi.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppi'+postfix,ak8PFJetsPuppi.clone(), process, task)
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppiSoftDrop
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop'+postfix, ak8PFJetsPuppiSoftDrop.clone(), process, task)
    getattr(process,"ak8PFJetsPuppi").doAreaFastjet = True # even for standard ak8PFJets this is overwritten in RecoJets/Configuration/python/RecoPFJets_cff


    #add AK8 from PUPPI
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents
    
    #from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents
    addToProcessAndTask('ak4PFJetsPuppi'+postfix,ak4PFJetsPuppi.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppiConstituents', ak8PFJetsPuppiConstituents.clone(), process, task )
    addToProcessAndTask('ak8PFJetsCHSConstituents', ak8PFJetsCHSConstituents.clone(), process, task )
    addToProcessAndTask('ak8PFJetsPuppi'+postfix,ak8PFJetsPuppi.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop'+postfix, ak8PFJetsPuppiSoftDrop.clone(), process, task)
    getattr(process,"ak8PFJetsPuppi").doAreaFastjet = True # even for standard ak8PFJets this is overwritten in RecoJets/Configuration/python/RecoPFJets_cff

        
    addJetCollection(process, postfix=postfix, labelName = 'AK8Puppi',
                     jetSource = cms.InputTag('ak8PFJetsPuppi'+postfix),
                     algo= 'AK', rParam = 0.8,
                     jetCorrections = ('AK8PFPuppi', cms.vstring(['L2Relative', 'L3Absolute']), 'None'),
                     btagDiscriminators = ([x.value() for x in patJetsDefault.discriminatorSources] + ['pfBoostedDoubleSecondaryVertexAK8BJetTags']),
                     genJetCollection = cms.InputTag('slimmedGenJetsAK8')
                     )
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src = [] # start with empty list of user floats
    getattr(process,"selectedPatJetsAK8Puppi"+postfix).cut = cms.string("pt > 170")


    from RecoJets.JetAssociationProducers.j2tParametersVX_cfi import j2tParametersVX
    addToProcessAndTask('ak8PFJetsPuppiTracksAssociatorAtVertex'+postfix, cms.EDProducer("JetTracksAssociatorAtVertex",
                                      j2tParametersVX.clone( coneSize = cms.double(0.8) ),
                                      jets = cms.InputTag("ak8PFJetsPuppi") ),
                        process, task)
    addToProcessAndTask('patJetAK8PuppiCharge'+postfix, cms.EDProducer("JetChargeProducer",
                                     src = cms.InputTag("ak8PFJetsPuppiTracksAssociatorAtVertex"),
                                     var = cms.string('Pt'),
                                     exp = cms.double(1.0) ), 
                        process, task)

    ## AK8 groomed masses
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppiSoftDrop
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop'+postfix, ak8PFJetsPuppiSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi import ak8PFJetsPuppiSoftDropMass
    addToProcessAndTask('ak8PFJetsPuppiSoftDropMass'+postfix, ak8PFJetsPuppiSoftDropMass.clone(), process, task)
    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src += ['ak8PFJetsPuppiSoftDropMass'+postfix]
    getattr(process,"patJetsAK8Puppi"+postfix).addTagInfos = cms.bool(False)



    # add Njetiness
    addToProcessAndTask('NjettinessAK8Puppi'+postfix, process.Njettiness.clone(), process, task)
    getattr(process,"NjettinessAK8Puppi"+postfix).src = cms.InputTag("ak8PFJetsPuppi"+postfix)
    getattr(process,"NjettinessAK8Puppi").cone = cms.double(0.8)
    getattr(process,"patJetsAK8Puppi").userData.userFloats.src += ['NjettinessAK8Puppi'+postfix+':tau1','NjettinessAK8Puppi'+postfix+':tau2','NjettinessAK8Puppi'+postfix+':tau3']




    addToProcessAndTask("ak8PFJetsCHSValueMap"+postfix, cms.EDProducer("RecoJetToPatJetDeltaRValueMapProducer",
                                            src = cms.InputTag("ak8PFJetsPuppi"+postfix),
                                            matched = cms.InputTag("patJetsAK8"+postfix),
                                            distMax = cms.double(0.8),
                                            values = cms.vstring([
                                                'userFloat("ak8PFJetsCHSPrunedMass"'+postfix+')',
                                                'userFloat("ak8PFJetsCHSSoftDropMass"'+postfix+')',
                                                'userFloat("NjettinessAK8'+postfix+':tau1")',
                                                'userFloat("NjettinessAK8'+postfix+':tau2")',
                                                'userFloat("NjettinessAK8'+postfix+':tau3")',
                                                'pt','eta','phi','mass'
                                            ]),
                                            valueLabels = cms.vstring( [
                                                'ak8PFJetsCHSPrunedMass',
                                                'ak8PFJetsCHSSoftDropMass',
                                                'NjettinessAK8CHSTau1',
                                                'NjettinessAK8CHSTau2',
                                                'NjettinessAK8CHSTau3',
                                                'pt','eta','phi','mass'
                                            ]) ),
                        process, task)

    getattr(process,"patJetsAK8Puppi"+postfix).userData.userFloats.src += [
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'ak8PFJetsCHSPrunedMass'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'ak8PFJetsCHSSoftDropMass'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau1'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau2'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'NjettinessAK8CHSTau3'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'pt'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'eta'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'phi'),
                                                   cms.InputTag('ak8PFJetsCHSValueMap'+postfix,'mass'),
                                                   ]

    # add Njetiness
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8Subjets'+postfix, process.Njettiness.clone(), process, task)
    getattr(process,"NjettinessAK8Subjets"+postfix).src = cms.InputTag("ak8PFJetsPuppiSoftDrop"+postfix, "SubJets")
    getattr(process,"NjettinessAK8Subjets").cone = cms.double(0.8)
    

    
    ## PATify CHS soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFCHSSoftDrop',
        jetSource = cms.InputTag('ak8PFJetsCHSSoftDrop'+postfix),
        btagDiscriminators = ['None'],
        jetCorrections = ('AK8PFchs', ['L1FastJet', 'L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour = False # jet flavor disabled
    )


    ## PATify puppi soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFPuppiSoftDrop',
        jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix),
        btagDiscriminators = ['None'],
        jetCorrections = ('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour = False # jet flavor disabled
    )
    
    ## PATify soft drop subjets
    addJetCollection(
        process,
        postfix=postfix,
        labelName = 'AK8PFPuppiSoftDropSubjets',
        jetSource = cms.InputTag('ak8PFJetsPuppiSoftDrop'+postfix,'SubJets'),
        algo = 'ak',  # needed for subjet flavor clustering
        rParam = 0.8, # needed for subjet flavor clustering
        btagDiscriminators = ['pfDeepCSVJetTags:probb', 'pfDeepCSVJetTags:probbb', 'pfCombinedInclusiveSecondaryVertexV2BJetTags','pfCombinedMVAV2BJetTags'],
        jetCorrections = ('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        explicitJTA = True,  # needed for subjet b tagging
        svClustering = True, # needed for subjet b tagging
        genJetCollection = cms.InputTag('slimmedGenJets'), 
        fatJets=cms.InputTag('ak8PFJetsPuppi'),             # needed for subjet flavor clustering
        groomedFatJets=cms.InputTag('ak8PFJetsPuppiSoftDrop') # needed for subjet flavor clustering
    )
    getattr(process,"selectedPatJetsAK8PFPuppiSoftDrop"+postfix).cut = cms.string("pt > 170")
    getattr(process,"patJetsAK8PFPuppiSoftDropSubjets"+postfix).userData.userFloats.src += ['NjettinessAK8Subjets'+postfix+':tau1','NjettinessAK8Subjets'+postfix+':tau2','NjettinessAK8Subjets'+postfix+':tau3']
    
    addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropSubjets"+postfix,
                        cms.EDProducer("PATJetSlimmer",
                             src = cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"),
                             packedPFCandidates = cms.InputTag("packedPFCandidates"),
                             dropJetVars = cms.string("1"),
                             dropDaughters = cms.string("0"),
                             rekeyDaughters = cms.string("1"),
                             dropTrackRefs = cms.string("1"),
                             dropSpecific = cms.string("1"),
                             dropTagInfos = cms.string("1"),
                             modifyJets = cms.bool(True),
                             mixedDaughters = cms.bool(False),
                             modifierConfig = cms.PSet( modifications = cms.VPSet() )
                                       ),
                        process, task)

    
    ## Establish references between PATified fat jets and subjets using the BoostedJetMerger
    addToProcessAndTask("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix,
                        cms.EDProducer("BoostedJetMerger",
                               jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"),
                               subjetSrc=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjets")
                                       ),
                        process, task )

    
    addToProcessAndTask("packedPatJetsAK8"+postfix, cms.EDProducer("JetSubstructurePacker",
                                           jetSrc = cms.InputTag("selectedPatJetsAK8Puppi"+postfix),
                                           distMax = cms.double(0.8),
                                           algoTags = cms.VInputTag(
                                               cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked"+postfix)
                                           ),
                                           algoLabels = cms.vstring(
                                               'SoftDropPuppi'
                                           ),
                                          fixDaughters = cms.bool(True),
                                          packedPFCandidates = cms.InputTag("packedPFCandidates"+postfix),
                                                                   ),
                        process, task)

    # switch off daughter re-keying since it's done in the JetSubstructurePacker (and can't be done afterwards)
    process.slimmedJetsAK8.rekeyDaughters = "0"
Exemple #6
0
def applySubstructure(process, postfix=""):

    task = getPatAlgosToolsTask(process)

    from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection

    from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJetsDefault

    # Configure the RECO jets
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents
    from RecoJets.JetProducers.ak8GenJets_cfi import ak8GenJets, ak8GenJetsSoftDrop, ak8GenJetsConstituents
    addToProcessAndTask('ak4PFJetsPuppi' + postfix, ak4PFJetsPuppi.clone(),
                        process, task)
    addToProcessAndTask('ak8PFJetsPuppi' + postfix, ak8PFJetsPuppi.clone(),
                        process, task)
    addToProcessAndTask(
        'ak8PFJetsPuppiConstituents',
        ak8PFJetsPuppiConstituents.clone(
            cut=cms.string('pt > 170.0 && abs(rapidity()) < 2.4')), process,
        task)
    addToProcessAndTask('ak8PFJetsCHSConstituents',
                        ak8PFJetsCHSConstituents.clone(), process, task)
    addToProcessAndTask(
        'ak8PFJetsPuppiSoftDrop' + postfix,
        ak8PFJetsPuppiSoftDrop.clone(
            src=cms.InputTag('ak8PFJetsPuppiConstituents', 'constituents')),
        process, task)
    addToProcessAndTask('ak8GenJetsNoNuConstituents' + postfix,
                        ak8GenJetsConstituents.clone(src='ak8GenJetsNoNu'),
                        process, task)
    addToProcessAndTask(
        'ak8GenJetsNoNuSoftDrop' + postfix,
        ak8GenJetsSoftDrop.clone(
            src=cms.InputTag('ak8GenJetsNoNuConstituents' +
                             postfix, 'constituents')), process, task)
    addToProcessAndTask(
        'slimmedGenJetsAK8SoftDropSubJets' + postfix,
        cms.EDProducer(
            "PATGenJetSlimmer",
            src=cms.InputTag("ak8GenJetsNoNuSoftDrop" + postfix, "SubJets"),
            packedGenParticles=cms.InputTag("packedGenParticles"),
            cut=cms.string(""),
            cutLoose=cms.string(""),
            nLoose=cms.uint32(0),
            clearDaughters=cms.bool(False),  #False means rekeying
            dropSpecific=cms.bool(True),  # Save space
        ),
        process,
        task)

    #add AK8 CHS
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8',
        jetSource=cms.InputTag('ak8PFJetsCHS' + postfix),
        algo='AK',
        rParam=0.8,
        btagDiscriminators=['None'],
        jetCorrections=('AK8PFchs',
                        cms.vstring(['L1FastJet', 'L2Relative',
                                     'L3Absolute']), 'None'),
        genJetCollection=cms.InputTag('slimmedGenJetsAK8'))
    getattr(process, "patJetsAK8" + postfix).userData.userFloats.src = [
    ]  # start with empty list of user floats
    getattr(process, "selectedPatJetsAK8").cut = cms.string("pt > 170")

    ## add AK8 groomed masses with CHS
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsCHSPruned, ak8PFJetsCHSSoftDrop
    addToProcessAndTask('ak8PFJetsCHSPruned' + postfix,
                        ak8PFJetsCHSPruned.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDrop' + postfix,
                        ak8PFJetsCHSSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsCHS_groomingValueMaps_cfi import ak8PFJetsCHSPrunedMass, ak8PFJetsCHSTrimmedMass, ak8PFJetsCHSFilteredMass, ak8PFJetsCHSSoftDropMass
    addToProcessAndTask('ak8PFJetsCHSPrunedMass' + postfix,
                        ak8PFJetsCHSPrunedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSTrimmedMass' + postfix,
                        ak8PFJetsCHSTrimmedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSFilteredMass' + postfix,
                        ak8PFJetsCHSFilteredMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDropMass' + postfix,
                        ak8PFJetsCHSSoftDropMass.clone(), process, task)

    getattr(process, "patJetsAK8").userData.userFloats.src += [
        'ak8PFJetsCHSPrunedMass' + postfix,
        'ak8PFJetsCHSSoftDropMass' + postfix
    ]
    getattr(process, "patJetsAK8").addTagInfos = cms.bool(False)

    # add Njetiness for CHS
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8' + postfix, process.Njettiness.clone(),
                        process, task)
    getattr(process,
            "NjettinessAK8").src = cms.InputTag("ak8PFJetsCHS" + postfix)
    getattr(process, "NjettinessAK8").cone = cms.double(0.8)
    getattr(process, "patJetsAK8").userData.userFloats.src += [
        'NjettinessAK8' + postfix + ':tau1',
        'NjettinessAK8' + postfix + ':tau2',
        'NjettinessAK8' + postfix + ':tau3',
        'NjettinessAK8' + postfix + ':tau4'
    ]

    # add Njetiness from CHS
    addToProcessAndTask('NjettinessAK8Subjets' + postfix,
                        process.Njettiness.clone(), process, task)
    getattr(process, "NjettinessAK8Subjets" + postfix).src = cms.InputTag(
        "ak8PFJetsPuppiSoftDrop" + postfix, "SubJets")
    getattr(process, "NjettinessAK8Subjets").cone = cms.double(0.8)

    ## PATify CHS soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFCHSSoftDrop',
        jetSource=cms.InputTag('ak8PFJetsCHSSoftDrop' + postfix),
        btagDiscriminators=['None'],
        jetCorrections=('AK8PFchs', ['L1FastJet', 'L2Relative',
                                     'L3Absolute'], 'None'),
        getJetMCFlavour=False  # jet flavor disabled
    )

    #add RECO AK8 from PUPPI and RECO AK8 PUPPI with soft drop... will be needed by ungroomed AK8 jets later
    ## PATify puppi soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFPuppiSoftDrop' + postfix,
        jetSource=cms.InputTag('ak8PFJetsPuppiSoftDrop' + postfix),
        btagDiscriminators=['None'],
        genJetCollection=cms.InputTag('slimmedGenJetsAK8'),
        jetCorrections=('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour=False  # jet flavor disabled
    )
    ## PATify soft drop subjets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFPuppiSoftDropSubjets',
        jetSource=cms.InputTag('ak8PFJetsPuppiSoftDrop' + postfix, 'SubJets'),
        algo='ak',  # needed for subjet flavor clustering
        rParam=0.8,  # needed for subjet flavor clustering
        btagDiscriminators=[
            'pfDeepCSVJetTags:probb', 'pfDeepCSVJetTags:probbb',
            'pfCombinedInclusiveSecondaryVertexV2BJetTags',
            'pfCombinedMVAV2BJetTags'
        ],
        jetCorrections=('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        explicitJTA=True,  # needed for subjet b tagging
        svClustering=True,  # needed for subjet b tagging
        genJetCollection=cms.InputTag('slimmedGenJetsAK8SoftDropSubJets'),
        fatJets=cms.InputTag(
            'ak8PFJetsPuppi'),  # needed for subjet flavor clustering
        groomedFatJets=cms.InputTag(
            'ak8PFJetsPuppiSoftDrop')  # needed for subjet flavor clustering
    )

    # add groomed ECFs and N-subjettiness to soft dropped pat::Jets for fat jets and subjets
    process.load('RecoJets.JetProducers.ECF_cff')
    addToProcessAndTask(
        'nb1AK8PuppiSoftDrop' + postfix,
        process.ecfNbeta1.clone(
            src=cms.InputTag("ak8PFJetsPuppiSoftDrop" + postfix),
            cuts=cms.vstring('', '', 'pt > 250')), process, task)
    addToProcessAndTask(
        'nb2AK8PuppiSoftDrop' + postfix,
        process.ecfNbeta2.clone(
            src=cms.InputTag("ak8PFJetsPuppiSoftDrop" + postfix),
            cuts=cms.vstring('', '', 'pt > 250')), process, task)

    #too slow now ==> disable
    from Configuration.Eras.Modifier_pp_on_AA_2018_cff import pp_on_AA_2018
    from Configuration.Eras.Modifier_pp_on_XeXe_2017_cff import pp_on_XeXe_2017
    from Configuration.Eras.Modifier_phase2_common_cff import phase2_common
    for e in [pp_on_XeXe_2017, pp_on_AA_2018, phase2_common]:
        e.toModify(getattr(process, 'nb1AK8PuppiSoftDrop' + postfix),
                   cuts=['pt > 999999', 'pt > 999999', 'pt > 999999'])
        e.toModify(getattr(process, 'nb2AK8PuppiSoftDrop' + postfix),
                   cuts=['pt > 999999', 'pt > 999999', 'pt > 999999'])

    getattr(process, "patJetsAK8PFPuppiSoftDrop").userData.userFloats.src += [
        'nb1AK8PuppiSoftDrop' + postfix + ':ecfN2',
        'nb1AK8PuppiSoftDrop' + postfix + ':ecfN3'
    ]
    getattr(process, "patJetsAK8PFPuppiSoftDrop").userData.userFloats.src += [
        'nb2AK8PuppiSoftDrop' + postfix + ':ecfN2',
        'nb2AK8PuppiSoftDrop' + postfix + ':ecfN3'
    ]
    addToProcessAndTask(
        'nb1AK8PuppiSoftDropSubjets' + postfix,
        process.ecfNbeta1.clone(
            src=cms.InputTag("ak8PFJetsPuppiSoftDrop" + postfix, "SubJets")),
        process, task)
    addToProcessAndTask(
        'nb2AK8PuppiSoftDropSubjets' + postfix,
        process.ecfNbeta2.clone(
            src=cms.InputTag("ak8PFJetsPuppiSoftDrop" + postfix, "SubJets")),
        process, task)
    getattr(process, "patJetsAK8PFPuppiSoftDropSubjets" +
            postfix).userData.userFloats.src += [
                'nb1AK8PuppiSoftDropSubjets' + postfix + ':ecfN2',
                'nb1AK8PuppiSoftDropSubjets' + postfix + ':ecfN3'
            ]
    getattr(process, "patJetsAK8PFPuppiSoftDropSubjets" +
            postfix).userData.userFloats.src += [
                'nb2AK8PuppiSoftDropSubjets' + postfix + ':ecfN2',
                'nb2AK8PuppiSoftDropSubjets' + postfix + ':ecfN3'
            ]
    getattr(process, "patJetsAK8PFPuppiSoftDropSubjets" +
            postfix).userData.userFloats.src += [
                'NjettinessAK8Subjets' + postfix + ':tau1',
                'NjettinessAK8Subjets' + postfix + ':tau2',
                'NjettinessAK8Subjets' + postfix + ':tau3',
                'NjettinessAK8Subjets' + postfix + ':tau4'
            ]

    for e in [pp_on_XeXe_2017, pp_on_AA_2018, phase2_common]:
        e.toModify(getattr(process, 'nb1AK8PuppiSoftDropSubjets' + postfix),
                   cuts=['pt > 999999', 'pt > 999999', 'pt > 999999'])
        e.toModify(getattr(process, 'nb2AK8PuppiSoftDropSubjets' + postfix),
                   cuts=['pt > 999999', 'pt > 999999', 'pt > 999999'])

    # rekey the groomed ECF value maps to the ungroomed reco jets, which will then be picked
    # up by PAT in the user floats.
    addToProcessAndTask(
        "ak8PFJetsPuppiSoftDropValueMap" + postfix,
        cms.EDProducer(
            "RecoJetToPatJetDeltaRValueMapProducer",
            src=cms.InputTag("ak8PFJetsPuppi" + postfix),
            matched=cms.InputTag("patJetsAK8PFPuppiSoftDrop" + postfix),
            distMax=cms.double(0.8),
            values=cms.vstring([
                'userFloat("nb1AK8PuppiSoftDrop' + postfix + ':ecfN2")',
                'userFloat("nb1AK8PuppiSoftDrop' + postfix + ':ecfN3")',
                'userFloat("nb2AK8PuppiSoftDrop' + postfix + ':ecfN2")',
                'userFloat("nb2AK8PuppiSoftDrop' + postfix + ':ecfN3")',
            ]),
            valueLabels=cms.vstring([
                'nb1AK8PuppiSoftDropN2',
                'nb1AK8PuppiSoftDropN3',
                'nb2AK8PuppiSoftDropN2',
                'nb2AK8PuppiSoftDropN3',
            ])), process, task)

    # Patify AK8 PF PUPPI
    addJetCollection(process,
                     postfix=postfix,
                     labelName='AK8Puppi',
                     jetSource=cms.InputTag('ak8PFJetsPuppi' + postfix),
                     algo='AK',
                     rParam=0.8,
                     jetCorrections=('AK8PFPuppi',
                                     cms.vstring(['L2Relative',
                                                  'L3Absolute']), 'None'),
                     btagDiscriminators=([
                         'pfCombinedSecondaryVertexV2BJetTags',
                         'pfCombinedInclusiveSecondaryVertexV2BJetTags',
                         'pfCombinedMVAV2BJetTags', 'pfDeepCSVJetTags:probb',
                         'pfDeepCSVJetTags:probc', 'pfDeepCSVJetTags:probudsg',
                         'pfDeepCSVJetTags:probbb',
                         'pfBoostedDoubleSecondaryVertexAK8BJetTags'
                     ]),
                     genJetCollection=cms.InputTag('slimmedGenJetsAK8'))
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src = [
    ]  # start with empty list of user floats
    getattr(process,
            "selectedPatJetsAK8Puppi" + postfix).cut = cms.string("pt > 100")
    getattr(process, "selectedPatJetsAK8Puppi" +
            postfix).cutLoose = cms.string("pt > 30")
    getattr(process,
            "selectedPatJetsAK8Puppi" + postfix).nLoose = cms.uint32(3)

    from RecoJets.JetAssociationProducers.j2tParametersVX_cfi import j2tParametersVX
    addToProcessAndTask(
        'ak8PFJetsPuppiTracksAssociatorAtVertex' + postfix,
        cms.EDProducer("JetTracksAssociatorAtVertex",
                       j2tParametersVX.clone(coneSize=cms.double(0.8)),
                       jets=cms.InputTag("ak8PFJetsPuppi")), process, task)
    addToProcessAndTask(
        'patJetAK8PuppiCharge' + postfix,
        cms.EDProducer(
            "JetChargeProducer",
            src=cms.InputTag("ak8PFJetsPuppiTracksAssociatorAtVertex"),
            var=cms.string('Pt'),
            exp=cms.double(1.0)), process, task)

    ## now add AK8 groomed masses and ECF
    from RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi import ak8PFJetsPuppiSoftDropMass
    addToProcessAndTask('ak8PFJetsPuppiSoftDropMass' + postfix,
                        ak8PFJetsPuppiSoftDropMass.clone(), process, task)
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src += [
        'ak8PFJetsPuppiSoftDropMass' + postfix
    ]
    getattr(process, "patJetsAK8Puppi" + postfix).addTagInfos = cms.bool(False)
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src += [
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap' + postfix,
                     'nb1AK8PuppiSoftDropN2'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap' + postfix,
                     'nb1AK8PuppiSoftDropN3'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap' + postfix,
                     'nb2AK8PuppiSoftDropN2'),
        cms.InputTag('ak8PFJetsPuppiSoftDropValueMap' + postfix,
                     'nb2AK8PuppiSoftDropN3'),
    ]

    # add PUPPI Njetiness
    addToProcessAndTask('NjettinessAK8Puppi' + postfix,
                        process.Njettiness.clone(), process, task)
    getattr(process, "NjettinessAK8Puppi" +
            postfix).src = cms.InputTag("ak8PFJetsPuppi" + postfix)
    getattr(process, "NjettinessAK8Puppi").cone = cms.double(0.8)
    getattr(process, "patJetsAK8Puppi").userData.userFloats.src += [
        'NjettinessAK8Puppi' + postfix + ':tau1',
        'NjettinessAK8Puppi' + postfix + ':tau2',
        'NjettinessAK8Puppi' + postfix + ':tau3',
        'NjettinessAK8Puppi' + postfix + ':tau4'
    ]

    # Now combine the CHS and PUPPI information into the PUPPI jets via delta R value maps
    addToProcessAndTask(
        "ak8PFJetsCHSValueMap" + postfix,
        cms.EDProducer(
            "RecoJetToPatJetDeltaRValueMapProducer",
            src=cms.InputTag("ak8PFJetsPuppi" + postfix),
            matched=cms.InputTag("patJetsAK8" + postfix),
            distMax=cms.double(0.8),
            values=cms.vstring([
                'userFloat("ak8PFJetsCHSPrunedMass"' + postfix + ')',
                'userFloat("ak8PFJetsCHSSoftDropMass"' + postfix + ')',
                'userFloat("NjettinessAK8' + postfix + ':tau1")',
                'userFloat("NjettinessAK8' + postfix + ':tau2")',
                'userFloat("NjettinessAK8' + postfix + ':tau3")',
                'userFloat("NjettinessAK8' + postfix + ':tau4")', 'pt', 'eta',
                'phi', 'mass', 'jetArea', 'jecFactor(0)'
            ]),
            valueLabels=cms.vstring([
                'ak8PFJetsCHSPrunedMass', 'ak8PFJetsCHSSoftDropMass',
                'NjettinessAK8CHSTau1', 'NjettinessAK8CHSTau2',
                'NjettinessAK8CHSTau3', 'NjettinessAK8CHSTau4', 'pt', 'eta',
                'phi', 'mass', 'jetArea', 'rawFactor'
            ])), process, task)

    # Now set up the user floats
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src += [
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix,
                     'ak8PFJetsCHSPrunedMass'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix,
                     'ak8PFJetsCHSSoftDropMass'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau1'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau2'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau3'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau4'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'pt'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'eta'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'phi'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'mass'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'jetArea'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'rawFactor'),
    ]

    addToProcessAndTask(
        "slimmedJetsAK8PFPuppiSoftDropSubjets" + postfix,
        cms.EDProducer(
            "PATJetSlimmer",
            src=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"),
            packedPFCandidates=cms.InputTag("packedPFCandidates"),
            dropJetVars=cms.string("1"),
            dropDaughters=cms.string("0"),
            rekeyDaughters=cms.string("1"),
            dropTrackRefs=cms.string("1"),
            dropSpecific=cms.string("1"),
            dropTagInfos=cms.string("1"),
            modifyJets=cms.bool(True),
            mixedDaughters=cms.bool(False),
            modifierConfig=cms.PSet(modifications=cms.VPSet())), process, task)

    ## Establish references between PATified fat jets and subjets using the BoostedJetMerger
    addToProcessAndTask(
        "slimmedJetsAK8PFPuppiSoftDropPacked" + postfix,
        cms.EDProducer(
            "BoostedJetMerger",
            jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"),
            subjetSrc=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjets")),
        process, task)

    addToProcessAndTask(
        "packedPatJetsAK8" + postfix,
        cms.EDProducer(
            "JetSubstructurePacker",
            jetSrc=cms.InputTag("selectedPatJetsAK8Puppi" + postfix),
            distMax=cms.double(0.8),
            algoTags=cms.VInputTag(
                cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked" + postfix)),
            algoLabels=cms.vstring('SoftDropPuppi'),
            fixDaughters=cms.bool(True),
            packedPFCandidates=cms.InputTag("packedPFCandidates" + postfix),
        ), process, task)

    # switch off daughter re-keying since it's done in the JetSubstructurePacker (and can't be done afterwards)
    process.slimmedJetsAK8.rekeyDaughters = "0"
    # Reconfigure the slimmedAK8 jet information to keep
    process.slimmedJetsAK8.dropDaughters = cms.string("pt < 170")
    process.slimmedJetsAK8.dropSpecific = cms.string("pt < 170")
    process.slimmedJetsAK8.dropTagInfos = cms.string("pt < 170")
patAlgosToolsTask = getPatAlgosToolsTask(process)
process.outpath = cms.EndPath(process.out, patAlgosToolsTask)

## and add them to the event content
from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection, addJetCollection

## Puppi
jetSeq = cms.Sequence()
process.load("CommonTools.PileupAlgos.Puppi_cff")
#process.puppi.candName = cms.InputTag( 'particleFlow' )
jetSeq += process.puppi

from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi

process.ak8PFJetsPuppi = ak4PFJetsPuppi.clone(src=cms.InputTag('puppi'),
                                              doAreaFastjet=True,
                                              rParam=0.8,
                                              jetAlgorithm='AntiKt')
jetSeq += process.ak8PFJetsPuppi

process.jetSequence = jetSeq

addJetCollection(
    process,
    #labelName = 'AK8PFCHS',
    labelName='AK8PFPuppi',
    #jetSource = cms.InputTag('ak8PFJetsCHS'),
    jetSource=cms.InputTag('ak8PFJetsPuppi'),
    #pvSource = cms.InputTag('offlinePrimaryVertices'),
    #svSource = cms.InputTag('inclusiveCandidateSecondaryVertices'),
    algo='AK',
    rParam=0.8,
Exemple #8
0
def jetToolbox( proc, jetType, jetSequence, outputFile,
		updateCollection='', updateCollectionSubjets='',
		newPFCollection=False, nameNewPFCollection = '',	
		PUMethod='CHS', 
		miniAOD=True,
		runOnMC=True,
		JETCorrPayload='', JETCorrLevels = [ 'None' ], GetJetMCFlavour=True,
		Cut = '', 
		postFix='',
		# blank means default list of discriminators, None means none
		bTagDiscriminators = '',
		bTagInfos = None, 
		subjetBTagDiscriminators = '',
		subjetBTagInfos = None, 
		subJETCorrPayload='', subJETCorrLevels = [ 'None' ], GetSubjetMCFlavour=True,
		CutSubjet = '', 
		addPruning=False, zCut=0.1, rCut=0.5, addPrunedSubjets=False,
		addSoftDrop=False, betaCut=0.0,  zCutSD=0.1, addSoftDropSubjets=False,
		addTrimming=False, rFiltTrim=0.2, ptFrac=0.03,
		addFiltering=False, rfilt=0.3, nfilt=3,
		addCMSTopTagger=False,
		addMassDrop=False,
		addHEPTopTagger=False,
		addNsub=False, maxTau=4,
		addNsubSubjets=False, subjetMaxTau=4,
		addPUJetID=False,
		addQGTagger=False, QGjetsLabel='chs',
		addEnergyCorrFunc=False, 
		addEnergyCorrFuncSubjets=False,
		# set this to false to disable creation of jettoolbox.root
		# then you need to associate the jetTask to a Path or EndPath manually in your config
		associateTask=True,
		# 0 = no printouts, 1 = warnings only, 2 = warnings & info, 3 = warnings, info, debug
		verbosity=2,
		):

	runOnData = not runOnMC
	if runOnData:
		GetJetMCFlavour = False
		GetSubjetMCFlavour = False
	
	###############################################################################
	#######  Verifying some inputs and defining variables
	###############################################################################
	if verbosity>=1: print('|---- jetToolbox: Initializing collection... (with postfix '+postFix+')')
	if newPFCollection and verbosity>=2: print('|---- jetToolBox: Using '+ nameNewPFCollection +' as PFCandidates collection')
	supportedJetAlgos = { 'ak': 'AntiKt', 'ca' : 'CambridgeAachen', 'kt' : 'Kt' }
	recommendedJetAlgos = [ 'ak4', 'ak8', 'ca4', 'ca8', 'ca10', 'ca15' ]
	payloadList = [ 'None',
			'AK1PFchs', 'AK2PFchs', 'AK3PFchs', 'AK4PFchs', 'AK5PFchs', 'AK6PFchs', 'AK7PFchs', 'AK8PFchs', 'AK9PFchs', 'AK10PFchs',
			'AK1PFPuppi', 'AK2PFPuppi', 'AK3PFPuppi', 'AK4PFPuppi', 'AK5PFPuppi', 'AK6PFPuppi', 'AK7PFPuppi', 'AK8PFPuppi', 'AK9PFPuppi', 'AK10PFPuppi',  
			'AK1PFSK', 'AK2PFSK', 'AK3PFSK', 'AK4PFSK', 'AK5PFSK', 'AK6PFSK', 'AK7PFSK', 'AK8PFSK', 'AK9PFSK', 'AK10PFSK',  
			'AK1PF', 'AK2PF', 'AK3PF', 'AK4PF', 'AK5PF', 'AK6PF', 'AK7PF', 'AK8PF', 'AK9PF', 'AK10PF' ]
	JECLevels = [ 'L1Offset', 'L1FastJet', 'L1JPTOffset', 'L2Relative', 'L3Absolute', 'L5Falvour', 'L7Parton' ]
	if runOnData:
		JECLevels += ['L2L3Residual']
	jetAlgo = ''
	algorithm = ''
	size = ''
	for TYPE, tmpAlgo in supportedJetAlgos.iteritems(): 
		if TYPE in jetType.lower():
			jetAlgo = TYPE
			algorithm = tmpAlgo
			size = jetType.replace( TYPE, '' )

	jetSize = 0.
	if int(size) in range(0, 20): jetSize = int(size)/10.
	else: raise ValueError('|---- jetToolBox: jetSize has not a valid value. Insert a number between 1 and 20 after algorithm, like: AK8')
	### Trick for uppercase/lowercase algo name
	jetALGO = jetAlgo.upper()+size
	jetalgo = jetAlgo.lower()+size
	if jetalgo not in recommendedJetAlgos and verbosity>=1: print('|---- jetToolBox: CMS recommends the following jet algorithms: '+' '.join(recommendedJetAlgos)+'. You are using '+jetalgo+' .')


	#################################################################################
	####### Toolbox start 
	#################################################################################

	elemToKeep = []
	jetSeq = cms.Sequence()
	genParticlesLabel = ''
	pvLabel = ''
	tvLabel = ''
	toolsUsed = []
	mod = OrderedDict()

	### List of Jet Corrections
	if not set(JETCorrLevels).issubset(set(JECLevels)): 
		if ( 'CHS' in PUMethod ) or  ( 'Plain' in PUMethod ): JETCorrLevels = ['L1FastJet','L2Relative', 'L3Absolute']
		else: JETCorrLevels = [ 'L2Relative', 'L3Absolute']
		if runOnData: JETCorrLevels.append('L2L3Residual')
	if not set(subJETCorrLevels).issubset(set(JECLevels)): 
		if ( 'CHS' in PUMethod ) or  ( 'Plain' in PUMethod ): subJETCorrLevels = ['L1FastJet','L2Relative', 'L3Absolute']
		else: subJETCorrLevels = [ 'L2Relative', 'L3Absolute']
		if runOnData: subJETCorrLevels.append('L2L3Residual')


	## b-tag discriminators
	defaultBTagDiscriminators = [
			'pfTrackCountingHighEffBJetTags',
			'pfTrackCountingHighPurBJetTags',
			'pfJetProbabilityBJetTags',
			'pfJetBProbabilityBJetTags',
			'pfSimpleSecondaryVertexHighEffBJetTags',
			'pfSimpleSecondaryVertexHighPurBJetTags',
			'pfCombinedSecondaryVertexV2BJetTags',
			'pfCombinedInclusiveSecondaryVertexV2BJetTags',
			'pfCombinedMVAV2BJetTags'
	]
	if bTagDiscriminators is '': bTagDiscriminators = defaultBTagDiscriminators
	if subjetBTagDiscriminators is '': subjetBTagDiscriminators = defaultBTagDiscriminators

	if updateCollection and 'Puppi' in updateCollection: PUMethod='Puppi'
	mod["PATJetsLabel"] = jetALGO+'PF'+PUMethod
	mod["PATJetsLabelPost"] = mod["PATJetsLabel"]+postFix
	# some substructure quantities don't include the 'PF' in the name
	mod["SubstructureLabel"] = jetALGO+PUMethod+postFix
	if not updateCollection: 

		mod["GenJetsNoNu"] = jetalgo+'GenJetsNoNu'
		#### For MiniAOD
		if miniAOD:

			if verbosity>=2: print('|---- jetToolBox: JETTOOLBOX RUNNING ON MiniAOD FOR '+jetALGO+' JETS USING '+PUMethod)

			genParticlesLabel = 'prunedGenParticles'
			pvLabel = 'offlineSlimmedPrimaryVertices'
			svLabel = 'slimmedSecondaryVertices'
			tvLabel = 'unpackedTracksAndVertices'
			muLabel = 'slimmedMuons'
			elLabel = 'slimmedElectrons'
			pfCand = nameNewPFCollection if newPFCollection else 'packedPFCandidates'

			if runOnMC:
				## Filter out neutrinos from packed GenParticles
				mod["GenParticlesNoNu"] = 'packedGenParticlesForJetsNoNu'
				_addProcessAndTask(proc, mod["GenParticlesNoNu"],
						cms.EDFilter("CandPtrSelector", 
							src = cms.InputTag("packedGenParticles"), 
							cut = cms.string("abs(pdgId) != 12 && abs(pdgId) != 14 && abs(pdgId) != 16")
							))
				jetSeq += getattr(proc, mod["GenParticlesNoNu"])

				_addProcessAndTask(proc, mod["GenJetsNoNu"],
						ak4GenJets.clone( src = mod["GenParticlesNoNu"],
							rParam = jetSize, 
							jetAlgorithm = algorithm ) ) 
				jetSeq += getattr(proc, mod["GenJetsNoNu"])

			#for Inclusive Vertex Finder
			proc.load('PhysicsTools.PatAlgos.slimming.unpackedTracksAndVertices_cfi')

		#### For AOD
		else:
			if verbosity>=2: print('|---- jetToolBox: JETTOOLBOX RUNNING ON AOD FOR '+jetALGO+' JETS USING '+PUMethod)

			genParticlesLabel = 'genParticles'
			pvLabel = 'offlinePrimaryVertices'
			tvLabel = 'generalTracks'
			muLabel = 'muons'
			elLabel = 'gedGsfElectrons'
			pfCand =  nameNewPFCollection if newPFCollection else 'particleFlow'
			svLabel = 'inclusiveCandidateSecondaryVertices'

			if runOnMC:
				proc.load('RecoJets.Configuration.GenJetParticles_cff')
				_addProcessAndTask(proc, mod["GenJetsNoNu"], ak4GenJets.clone(src='genParticlesForJetsNoNu', rParam=jetSize, jetAlgorithm=algorithm))
				jetSeq += getattr(proc, mod["GenJetsNoNu"])
			

		####  Creating PATjets
		tmpPfCandName = pfCand.lower()
		mod["PFJets"] = ""
		if 'Puppi' in PUMethod:
			if ('puppi' in tmpPfCandName): 
				srcForPFJets = pfCand
				if verbosity>=1: print('|---- jetToolBox: Not running puppi algorithm because keyword puppi was specified in nameNewPFCollection, but applying puppi corrections.')
			else: 
				proc.load('CommonTools.PileupAlgos.Puppi_cff')
				puppi.candName = cms.InputTag( pfCand ) 
				if miniAOD:
				  puppi.vertexName = cms.InputTag('offlineSlimmedPrimaryVertices')
				  puppi.clonePackedCands = cms.bool(True)
				  puppi.useExistingWeights = cms.bool(True)
				_addProcessAndTask(proc, 'puppi', getattr(proc, 'puppi'))
				jetSeq += getattr(proc, 'puppi' )
				srcForPFJets = 'puppi'

			from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
			mod["PFJets"] = jetalgo+'PFJetsPuppi'+postFix
			_addProcessAndTask(proc, mod["PFJets"],
					ak4PFJetsPuppi.clone( src = cms.InputTag( srcForPFJets ),
						doAreaFastjet = True, 
						rParam = jetSize, 
						jetAlgorithm = algorithm ) )  
			jetSeq += getattr(proc, mod["PFJets"])

			if JETCorrPayload not in payloadList: JETCorrPayload = 'AK'+size+'PFPuppi'
			if subJETCorrPayload not in payloadList: subJETCorrPayload = 'AK4PFPuppi'

		elif 'SK' in PUMethod:

			if ('sk' in tmpPfCandName): 
				srcForPFJets = pfCand
				if verbosity>=1: print('|---- jetToolBox: Not running softkiller algorithm because keyword SK was specified in nameNewPFCollection, but applying SK corrections.')
			else:
				proc.load('CommonTools.PileupAlgos.softKiller_cfi')
				getattr( proc, 'softKiller' ).PFCandidates = cms.InputTag( pfCand )
				_addProcessAndTask(proc, 'softKiller', getattr(proc, 'softKiller'))
				jetSeq += getattr(proc, 'softKiller' )
				srcForPFJets = 'softKiller'

			from RecoJets.JetProducers.ak4PFJetsSK_cfi import ak4PFJetsSK
			mod["PFJets"] = jetalgo+'PFJetsSK'+postFix
			_addProcessAndTask(proc, mod["PFJets"],
					ak4PFJetsSK.clone(  src = cms.InputTag( srcForPFJets ),
						rParam = jetSize, 
						jetAlgorithm = algorithm ) ) 
			jetSeq += getattr(proc, mod["PFJets"])

			if JETCorrPayload not in payloadList: JETCorrPayload = 'AK'+size+'PFSK'
			if subJETCorrPayload not in payloadList: subJETCorrPayload = 'AK4PFSK'
		
		elif 'CS' in PUMethod: 

			from RecoJets.JetProducers.ak4PFJetsCHSCS_cfi import ak4PFJetsCHSCS
			mod["PFJets"] = jetalgo+'PFJetsCS'+postFix
			_addProcessAndTask(proc, mod["PFJets"],
					ak4PFJetsCHSCS.clone( doAreaFastjet = True, 
						src = cms.InputTag( pfCand ), #srcForPFJets ),
						csRParam = cms.double(jetSize),
						jetAlgorithm = algorithm ) ) 
			if miniAOD: getattr( proc, mod["PFJets"]).src = pfCand
			jetSeq += getattr(proc, mod["PFJets"])

			if JETCorrPayload not in payloadList: JETCorrPayload = 'AK'+size+'PFCS'
			if subJETCorrPayload not in payloadList: subJETCorrPayload = 'AK4PFCS'

		elif 'CHS' in PUMethod: 
			
			if miniAOD:
				if ('chs' in tmpPfCandName): 
					srcForPFJets = pfCand
					if verbosity>=1: print('|---- jetToolBox: Not running CHS algorithm because keyword CHS was specified in nameNewPFCollection, but applying CHS corrections.')
				else: 
					_addProcessAndTask(proc, 'chs', cms.EDFilter('CandPtrSelector', src=cms.InputTag(pfCand), cut=cms.string('fromPV')))
					jetSeq += getattr(proc, 'chs')
					srcForPFJets = 'chs'
			else:
				if ( pfCand == 'particleFlow' ):
					from RecoParticleFlow.PFProducer.particleFlowTmpPtrs_cfi import particleFlowTmpPtrs
					_addProcessAndTask(proc, 'newParticleFlowTmpPtrs', particleFlowTmpPtrs.clone(src=pfCand))
					jetSeq += getattr(proc, 'newParticleFlowTmpPtrs')
					from CommonTools.ParticleFlow.pfNoPileUpJME_cff import pfPileUpJME, pfNoPileUpJME
					proc.load('CommonTools.ParticleFlow.goodOfflinePrimaryVertices_cfi')
					_addProcessAndTask(proc, 'newPfPileUpJME', pfPileUpJME.clone(PFCandidates='newParticleFlowTmpPtrs'))
					jetSeq += getattr(proc, 'newPfPileUpJME')
					_addProcessAndTask(proc, 'newPfNoPileUpJME', pfNoPileUpJME.clone(topCollection='newPfPileUpJME', bottomCollection='newParticleFlowTmpPtrs'))
					jetSeq += getattr(proc, 'newPfNoPileUpJME')
					srcForPFJets = 'newPfNoPileUpJME'
				else: 
					proc.load('CommonTools.ParticleFlow.pfNoPileUpJME_cff')
					srcForPFJets = 'pfNoPileUpJME'
				
			mod["PFJets"] = jetalgo+'PFJetsCHS'+postFix
			_addProcessAndTask(proc, mod["PFJets"],
					ak4PFJetsCHS.clone( src = cms.InputTag( srcForPFJets ), 
						doAreaFastjet = True, 
						rParam = jetSize, 
						jetAlgorithm = algorithm ) ) 
			jetSeq += getattr(proc, mod["PFJets"])

			if JETCorrPayload not in payloadList: JETCorrPayload = 'AK'+size+'PFchs'
			if subJETCorrPayload not in payloadList: subJETCorrPayload = 'AK4PFchs'

		else: 
			PUMethod = ''
			mod["PFJets"] = jetalgo+'PFJets'+postFix
			_addProcessAndTask(proc, mod["PFJets"],
					ak4PFJets.clone( 
						doAreaFastjet = True, 
						rParam = jetSize, 
						jetAlgorithm = algorithm ) ) 
			if miniAOD: getattr( proc, mod["PFJets"]).src = pfCand
			jetSeq += getattr(proc, mod["PFJets"])
			if JETCorrPayload not in payloadList: JETCorrPayload = 'AK'+size+'PF'
			if subJETCorrPayload not in payloadList: subJETCorrPayload = 'AK4PF'


		if 'None' in JETCorrPayload: JEC = None
		else: JEC = ( JETCorrPayload.replace('CS','chs').replace('SK','chs') , JETCorrLevels, 'None' )   ### temporary
		#else: JEC = ( JETCorrPayload., JETCorrLevels, 'None' ) 
		if verbosity>=2: print('|---- jetToolBox: Applying these corrections: '+str(JEC))

		if addPrunedSubjets or addSoftDropSubjets or addCMSTopTagger:
			if 'None' in subJETCorrPayload: subJEC = None
			else: subJEC = ( subJETCorrPayload.replace('CS','chs').replace('SK','chs') , subJETCorrLevels, 'None' )   ### temporary


		mod["PFJetsConstituents"] = mod["PFJets"]+'Constituents'
		mod["PFJetsConstituentsColon"] = mod["PFJets"]+'Constituents:constituents'
		mod["PFJetsConstituentsColonOrUpdate"] = mod["PFJetsConstituentsColon"] if not updateCollection else updateCollection
		if (PUMethod in [ 'CHS', 'CS', 'Puppi' ]) and miniAOD: _addProcessAndTask(proc, mod["PFJetsConstituents"], cms.EDProducer("MiniAODJetConstituentSelector", src=cms.InputTag(mod["PFJets"]), cut=cms.string(Cut)))
		else: _addProcessAndTask(proc, mod["PFJetsConstituents"], cms.EDProducer("PFJetConstituentSelector", src=cms.InputTag(mod["PFJets"]), cut=cms.string(Cut)))
		jetSeq += getattr(proc, mod["PFJetsConstituents"])

		addJetCollection(
				proc,
				labelName = mod["PATJetsLabel"],
				jetSource = cms.InputTag(mod["PFJets"]),
				postfix = postFix, 
				algo = jetalgo,
				rParam = jetSize,
				jetCorrections = JEC if JEC is not None else None, 
				pfCandidates = cms.InputTag( pfCand ),  
				svSource = cms.InputTag( svLabel ),  
				genJetCollection = cms.InputTag(mod["GenJetsNoNu"]),
				pvSource = cms.InputTag( pvLabel ), 
				muSource = cms.InputTag( muLabel ),
				elSource = cms.InputTag( elLabel ),
				btagDiscriminators = bTagDiscriminators,
				btagInfos = bTagInfos,
				getJetMCFlavour = GetJetMCFlavour,
				genParticles = cms.InputTag(genParticlesLabel),
				outputModules = ['outputFile']
				)
		patJets = 'patJets'
		patSubJets = ''
		selPatJets = 'selectedPatJets'
		mod["PATJets"] = patJets+mod["PATJetsLabelPost"]
		mod["selPATJets"] = selPatJets+mod["PATJetsLabelPost"]
		getattr(proc, mod["PATJets"]).addTagInfos = cms.bool(True)

		if 'CS' in PUMethod: getattr( proc, mod["PATJets"] ).getJetMCFlavour = False  # CS jets cannot be re-clustered from their constituents
	else:
		if verbosity>=2: print('|---- jetToolBox: JETTOOLBOX IS UPDATING '+updateCollection+' collection')
		genParticlesLabel = 'prunedGenParticles'
		pvLabel = 'offlineSlimmedPrimaryVertices'
		svLabel = 'slimmedSecondaryVertices'
		tvLabel = 'unpackedTracksAndVertices'
		muLabel = 'slimmedMuons'
		elLabel = 'slimmedElectrons'

		if not JETCorrPayload: 
			raise ValueError('|---- jetToolBox: updateCollection option requires to add JETCorrPayload.')

		JEC = ( JETCorrPayload, JETCorrLevels, 'None' )   ### temporary
		if verbosity>=2: print('|---- jetToolBox: Applying these corrections: '+str(JEC))
		updateJetCollection(
				proc,
				postfix = postFix,
				jetSource = cms.InputTag( updateCollection ),
				labelName = mod["PATJetsLabel"],
				jetCorrections = JEC, 
				btagDiscriminators = bTagDiscriminators,
				)
		mod["PATJetsCorrFactors"] = 'patJetCorrFactors'+mod["PATJetsLabelPost"]
		getattr( proc, mod["PATJetsCorrFactors"] ).payload = JETCorrPayload
		getattr( proc, mod["PATJetsCorrFactors"] ).levels = JETCorrLevels
		patJets = 'updatedPatJets'
		patSubJets = ''
		selPatJets = 'selectedPatJets'
		mod["PATJets"] = patJets+mod["PATJetsLabelPost"]
		mod["selPATJets"] = selPatJets+mod["PATJetsLabelPost"]

		if updateCollectionSubjets:
			if verbosity>=2: print('|---- jetToolBox: JETTOOLBOX IS UPDATING '+updateCollectionSubjets+' collection for subjets/groomers.')
			if 'SoftDrop' in updateCollectionSubjets: updateSubjetLabel = 'SoftDrop'
			else: updateSubjetLabel = 'Pruned'
			mod["PATSubjetsLabel"] = jetALGO+'PF'+PUMethod+postFix+updateSubjetLabel+'Packed'
			updateJetCollection(
					proc,
					jetSource = cms.InputTag( updateCollectionSubjets ),
					labelName = mod["PATSubjetsLabel"],
					jetCorrections = JEC, 
					explicitJTA = True,
					fatJets = cms.InputTag( updateCollection ),
					rParam = jetSize, 
					algo = jetALGO,
					btagDiscriminators = subjetBTagDiscriminators,
					)
			mod["PATSubjetsCorrFactors"] = 'patJetCorrFactors'+mod["PATSubjetsLabel"]
			getattr( proc, mod["PATSubjetsCorrFactors"] ).payload = subJETCorrPayload
			getattr( proc, mod["PATSubjetsCorrFactors"] ).levels = subJETCorrLevels
			patSubJets = 'updatedPatJets'+mod["PATSubjetsLabel"]

		if addPrunedSubjets or addSoftDropSubjets or addCMSTopTagger or addMassDrop or addHEPTopTagger or addPruning or addSoftDrop: 
			if verbosity>=1: print('|---- jetToolBox: You are trying to add a groomer variable into a clustered jet collection. THIS IS NOT RECOMMENDED, it is recommended to recluster jets instead using a plain jetToolbox configuration. Please use this feature at your own risk.')

	mod["PFJetsOrUpdate"] = mod["PFJets"] if not updateCollection else updateCollection

	if bTagDiscriminators and verbosity>=2: print('|---- jetToolBox: Adding these btag discriminators: '+str(bTagDiscriminators)+' in the jet collection.')
	if ( (addPrunedSubjets or addSoftDropSubjets) or (updateCollection and updateCollectionSubjets) ) and subjetBTagDiscriminators and verbosity>=2:
		print('|---- jetToolBox: Adding these btag discriminators: '+str(subjetBTagDiscriminators)+' in the subjet collection.')

	#### Groomers
	if addSoftDrop or addSoftDropSubjets: 

		mod["PFJetsSoftDrop"] = mod["PFJets"]+'SoftDrop'
		mod["SoftDropMass"] = mod["PFJets"]+'SoftDropMass'
		_addProcessAndTask(proc, mod["PFJetsSoftDrop"],
			ak8PFJetsCHSSoftDrop.clone( 
				src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
				rParam = jetSize, 
				jetAlgorithm = algorithm, 
				useExplicitGhosts=True,
				R0= cms.double(jetSize),
				zcut=zCutSD, 
				beta=betaCut,
				doAreaFastjet = cms.bool(True),
				writeCompound = cms.bool(True),
				jetCollInstanceName=cms.string('SubJets') ) )
		_addProcessAndTask(proc, mod["SoftDropMass"],
			ak8PFJetsCHSSoftDropMass.clone( src = cms.InputTag( mod["PFJetsOrUpdate"] ), 
				matched = cms.InputTag( mod["PFJetsSoftDrop"] ),
				distMax = cms.double( jetSize ) ) )

		elemToKeep += [ 'keep *_'+mod["SoftDropMass"]+'_*_*'] 
		jetSeq += getattr(proc, mod["PFJetsSoftDrop"] )
		jetSeq += getattr(proc, mod["SoftDropMass"] )
		getattr( proc, mod["PATJets"]).userData.userFloats.src += [ mod["SoftDropMass"] ]
		toolsUsed.append( mod["SoftDropMass"] )

		if addSoftDropSubjets:

			mod["GenJetsNoNuSoftDrop"] = mod["GenJetsNoNu"]+'SoftDrop'
			if runOnMC:
				_addProcessAndTask(proc, mod["GenJetsNoNuSoftDrop"],
						ak4GenJets.clone(
							SubJetParameters,
							useSoftDrop = cms.bool(True),
							rParam = jetSize, 
							jetAlgorithm = algorithm, 
							useExplicitGhosts=cms.bool(True),
							#zcut=cms.double(zCutSD), 
							R0= cms.double(jetSize),
							beta=cms.double(betaCut),
							writeCompound = cms.bool(True),
							jetCollInstanceName=cms.string('SubJets')
							))
				if miniAOD: getattr( proc, mod["GenJetsNoNuSoftDrop"] ).src = mod["GenParticlesNoNu"]
				jetSeq += getattr(proc, mod["GenJetsNoNuSoftDrop"] )

			mod["PATJetsSoftDropLabel"] = mod["PATJetsLabelPost"]+'SoftDrop'
			addJetCollection(
					proc,
					labelName = mod["PATJetsSoftDropLabel"],
					jetSource = cms.InputTag( mod["PFJetsSoftDrop"]),
					algo = jetalgo,
					rParam = jetSize,
					jetCorrections = JEC if JEC is not None else None, 
					pvSource = cms.InputTag( pvLabel ),
					btagDiscriminators = ['None'],
					genJetCollection = cms.InputTag( mod["GenJetsNoNu"]),
					getJetMCFlavour = False, # jet flavor should always be disabled for groomed jets
					genParticles = cms.InputTag(genParticlesLabel),
					outputModules = ['outputFile']
					)
			mod["PATJetsSoftDrop"] = patJets+mod["PATJetsSoftDropLabel"]
			mod["selPATJetsSoftDrop"] = selPatJets+mod["PATJetsSoftDropLabel"]

			_addProcessAndTask(proc, mod["selPATJetsSoftDrop"], selectedPatJets.clone(src=mod["PATJetsSoftDrop"], cut=Cut))

			mod["PATSubjetsSoftDropLabel"] = mod["PATJetsSoftDropLabel"]+'Subjets'
			addJetCollection(
					proc,
					labelName = mod["PATSubjetsSoftDropLabel"],
					jetSource = cms.InputTag( mod["PFJetsSoftDrop"], 'SubJets'),
					algo = jetalgo,  # needed for subjet b tagging
					rParam = jetSize,  # needed for subjet b tagging
					jetCorrections = subJEC if subJEC is not None else None, 
					pfCandidates = cms.InputTag( pfCand ), 
					pvSource = cms.InputTag( pvLabel), 
					svSource = cms.InputTag( svLabel ),  
					muSource = cms.InputTag( muLabel ),
					elSource = cms.InputTag( elLabel ),
					btagDiscriminators = subjetBTagDiscriminators,
					btagInfos = bTagInfos,
					genJetCollection = cms.InputTag( mod["GenJetsNoNuSoftDrop"],'SubJets'),
					getJetMCFlavour = GetSubjetMCFlavour,
					genParticles = cms.InputTag(genParticlesLabel),
					explicitJTA = True,  # needed for subjet b tagging
					svClustering = True, # needed for subjet b tagging
					fatJets=cms.InputTag(mod["PFJets"]),             # needed for subjet flavor clustering
					groomedFatJets=cms.InputTag(mod["PFJetsSoftDrop"]), # needed for subjet flavor clustering
					outputModules = ['outputFile']
					) 
			mod["PATSubjetsSoftDrop"] = patJets+mod["PATSubjetsSoftDropLabel"]
			mod["selPATSubjetsSoftDrop"] = selPatJets+mod["PATSubjetsSoftDropLabel"]

			_addProcessAndTask(proc, mod["selPATSubjetsSoftDrop"], selectedPatJets.clone(src=mod["PATSubjetsSoftDrop"], cut=CutSubjet))

			# Establish references between PATified fat jets and subjets using the BoostedJetMerger
			mod["selPATJetsSoftDropPacked"] = mod["selPATJetsSoftDrop"]+'Packed'
			_addProcessAndTask(proc, mod["selPATJetsSoftDropPacked"],
					cms.EDProducer("BoostedJetMerger",
						jetSrc=cms.InputTag(mod["selPATJetsSoftDrop"]),
						subjetSrc=cms.InputTag(mod["selPATSubjetsSoftDrop"])
						))
			jetSeq += getattr(proc, mod["selPATJetsSoftDropPacked"] )
			elemToKeep += [ 'keep *_'+mod["selPATJetsSoftDropPacked"]+'_SubJets_*' ]
			toolsUsed.append( mod["selPATJetsSoftDropPacked"]+':SubJets' )

			## Pack fat jets with subjets
			mod["packedPATJetsSoftDrop"] = 'packedPatJets'+mod["PATJetsSoftDropLabel"]
			_addProcessAndTask(proc, mod["packedPATJetsSoftDrop"],
				 cms.EDProducer("JetSubstructurePacker",
						jetSrc=cms.InputTag(mod["selPATJets"]),
						distMax = cms.double( jetSize ),
						fixDaughters = cms.bool(False),
						algoTags = cms.VInputTag(
						cms.InputTag(mod["selPATJetsSoftDropPacked"])
						), 
						algoLabels =cms.vstring('SoftDrop')
						)
				 )
			jetSeq += getattr(proc, mod["packedPATJetsSoftDrop"])
			elemToKeep += [ 'keep *_'+mod["packedPATJetsSoftDrop"]+'_*_*' ]
			if verbosity>=2: print('|---- jetToolBox: Creating '+mod["packedPATJetsSoftDrop"]+' collection with SoftDrop subjets.')



	if addPruning or addPrunedSubjets: 

		mod["PFJetsPruned"] = mod["PFJets"]+'Pruned'
		mod["PrunedMass"] =  mod["PFJets"]+'PrunedMass'
		_addProcessAndTask(proc, mod["PFJetsPruned"],
			ak8PFJetsCHSPruned.clone( 
				src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
				rParam = jetSize, 
				jetAlgorithm = algorithm, 
				zcut=zCut, 
				rcut_factor=rCut,
				writeCompound = cms.bool(True),
				doAreaFastjet = cms.bool(True),
				jetCollInstanceName=cms.string('SubJets') ) )
		_addProcessAndTask(proc, mod["PrunedMass"],
			ak8PFJetsCHSPrunedMass.clone( 
				src = cms.InputTag( mod["PFJetsOrUpdate"] ), 
				matched = cms.InputTag( mod["PFJetsPruned"]), 
				distMax = cms.double( jetSize ) ) )

		jetSeq += getattr(proc, mod["PFJetsPruned"])
		jetSeq += getattr(proc, mod["PrunedMass"])
		getattr( proc, mod["PATJets"]).userData.userFloats.src += [ mod["PrunedMass"] ]
		elemToKeep += [ 'keep *_'+mod["PrunedMass"]+'_*_*'] 
		toolsUsed.append( mod["PrunedMass"] )

		if addPrunedSubjets:
			if runOnMC:
				mod["GenJetsNoNuPruned"] = mod["GenJetsNoNu"]+'Pruned'
				_addProcessAndTask(proc, mod["GenJetsNoNuPruned"],
						ak4GenJets.clone(
							SubJetParameters,
							rParam = jetSize,
							usePruning = cms.bool(True),
							writeCompound = cms.bool(True),
							jetCollInstanceName=cms.string('SubJets')
							))
				if miniAOD: getattr( proc, mod["GenJetsNoNuPruned"] ).src = mod["GenParticlesNoNu"]
				jetSeq += getattr(proc, mod["GenJetsNoNuPruned"])

			mod["PATJetsPrunedLabel"] = mod["PATJetsLabelPost"]+'Pruned'
			addJetCollection(
					proc,
					labelName = mod["PATJetsPrunedLabel"],
					jetSource = cms.InputTag( mod["PFJetsPruned"]),
					algo = jetalgo,
					rParam = jetSize,
					jetCorrections = JEC if JEC is not None else None, 
					pvSource = cms.InputTag( pvLabel ),
					btagDiscriminators = ['None'],
					genJetCollection = cms.InputTag( mod["GenJetsNoNu"]),
					getJetMCFlavour = False, # jet flavor should always be disabled for groomed jets
					genParticles = cms.InputTag(genParticlesLabel),
					outputModules = ['outputFile']
					)
			mod["PATJetsPruned"] = patJets+mod["PATJetsPrunedLabel"]
			mod["selPATJetsPruned"] = selPatJets+mod["PATJetsPrunedLabel"]

			_addProcessAndTask(proc, mod["selPATJetsPruned"], selectedPatJets.clone(src=mod["PATJetsPruned"], cut=Cut))

			mod["PATSubjetsPrunedLabel"] = mod["PATJetsPrunedLabel"]+'Subjets'
			addJetCollection(
					proc,
					labelName = mod["PATSubjetsPrunedLabel"],
					jetSource = cms.InputTag( mod["PFJetsPruned"], 'SubJets'),
					algo = jetalgo,  # needed for subjet b tagging
					rParam = jetSize,  # needed for subjet b tagging
					jetCorrections = subJEC if subJEC is not None else None, 
					pfCandidates = cms.InputTag( pfCand ),  
					pvSource = cms.InputTag( pvLabel), 
					svSource = cms.InputTag( svLabel ), 
					muSource = cms.InputTag( muLabel ),
					elSource = cms.InputTag( elLabel ),
					getJetMCFlavour = GetSubjetMCFlavour,
					genParticles = cms.InputTag(genParticlesLabel),
					btagDiscriminators = subjetBTagDiscriminators,
					btagInfos = bTagInfos,
					genJetCollection = cms.InputTag( mod["GenJetsNoNuPruned"],'SubJets'),
					explicitJTA = True,  # needed for subjet b tagging
					svClustering = True, # needed for subjet b tagging
					fatJets=cms.InputTag(mod["PFJets"]),             # needed for subjet flavor clustering
					groomedFatJets=cms.InputTag(mod["PFJetsPruned"]), # needed for subjet flavor clustering
					outputModules = ['outputFile']
					) 
			mod["PATSubjetsPruned"] = patJets+mod["PATSubjetsPrunedLabel"]
			mod["selPATSubjetsPruned"] = selPatJets+mod["PATSubjetsPrunedLabel"]

			_addProcessAndTask(proc, mod["selPATSubjetsPruned"], selectedPatJets.clone(src=mod["PATSubjetsPruned"], cut=CutSubjet))

			## Establish references between PATified fat jets and subjets using the BoostedJetMerger
			mod["selPATJetsPrunedPacked"] = mod["selPATJetsPruned"]+'Packed'
			_addProcessAndTask(proc, mod["selPATJetsPrunedPacked"],
					cms.EDProducer("BoostedJetMerger",
						jetSrc=cms.InputTag(mod["selPATJetsPruned"]),
						subjetSrc=cms.InputTag(mod["selPATSubjetsPruned"]),
						))
			jetSeq += getattr(proc, mod["selPATJetsPrunedPacked"])
			elemToKeep += [ 'keep *_'+mod["selPATJetsPrunedPacked"]+'_SubJets_*' ]
			toolsUsed.append( mod["selPATJetsPrunedPacked"]+':SubJets' )

			## Pack fat jets with subjets
			mod["packedPATJetsPruned"] = 'packedPatJets'+mod["PATSubjetsPrunedLabel"]
			_addProcessAndTask(proc, mod["packedPATJetsPruned"],
				 cms.EDProducer("JetSubstructurePacker",
						jetSrc=cms.InputTag(mod["selPATJets"]),
						distMax = cms.double( jetSize ),
						fixDaughters = cms.bool(False),
						algoTags = cms.VInputTag(
						cms.InputTag(mod["selPATJetsPrunedPacked"])
						), 
						algoLabels =cms.vstring('Pruned')
						)
				 )
			jetSeq += getattr(proc, mod["packedPATJetsPruned"])
			elemToKeep += [ 'keep *_'+mod["packedPATJetsPruned"]+'_*_*' ]
			if verbosity>=2: print('|---- jetToolBox: Creating '+mod["packedPATJetsPruned"]+' collection with Pruned subjets.')


	if addTrimming:

		mod["PFJetsTrimmed"] = mod["PFJets"]+'Trimmed'
		mod["TrimmedMass"] = mod["PFJets"]+'TrimmedMass'
		_addProcessAndTask(proc, mod["PFJetsTrimmed"],
				ak8PFJetsCHSTrimmed.clone( 
					rParam = jetSize, 
					src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
					jetAlgorithm = algorithm,
					rFilt= rFiltTrim,
					trimPtFracMin= ptFrac) ) 
		_addProcessAndTask(proc, mod["TrimmedMass"],
				ak8PFJetsCHSTrimmedMass.clone( 
					src = cms.InputTag( mod["PFJetsOrUpdate"] ), 
					matched = cms.InputTag( mod["PFJetsTrimmed"]), 
					distMax = cms.double( jetSize ) ) )

		elemToKeep += [ 'keep *_'+mod["TrimmedMass"]+'_*_*'] 
		jetSeq += getattr(proc, mod["PFJetsTrimmed"])
		jetSeq += getattr(proc, mod["TrimmedMass"])
		getattr( proc, mod["PATJets"]).userData.userFloats.src += [mod["TrimmedMass"]]
		toolsUsed.append( mod["TrimmedMass"] )

	if addFiltering:

		mod["PFJetsFiltered"] = mod["PFJets"]+'Filtered'
		mod["FilteredMass"] = mod["PFJets"]+'FilteredMass'
		_addProcessAndTask(proc, mod["PFJetsFiltered"],
				ak8PFJetsCHSFiltered.clone( 
					src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
					rParam = jetSize, 
					jetAlgorithm = algorithm,
					rFilt= rfilt,
					nFilt= nfilt ) ) 
		_addProcessAndTask(proc, mod["FilteredMass"],
				ak8PFJetsCHSFilteredMass.clone( 
					src = cms.InputTag( mod["PFJetsOrUpdate"] ), 
					matched = cms.InputTag( mod["PFJetsFiltered"]), 
					distMax = cms.double( jetSize ) ) )
		elemToKeep += [ 'keep *_'+mod["FilteredMass"]+'_*_*'] 
		jetSeq += getattr(proc, mod["PFJetsFiltered"])
		jetSeq += getattr(proc, mod["FilteredMass"])
		getattr( proc, patJets+jetALGO+'PF'+PUMethod+postFix).userData.userFloats.src += [mod["FilteredMass"]]
		toolsUsed.append( mod["FilteredMass"] )

	if addCMSTopTagger :

		if 'CA' in jetALGO : 

			mod["PFJetsCMSTopTag"] = mod["PFJets"].replace(jetalgo,"cmsTopTag")
			_addProcessAndTask(proc, mod["PFJetsCMSTopTag"],
					cms.EDProducer("CATopJetProducer",
						PFJetParameters.clone( 
							src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
							doAreaFastjet = cms.bool(True),
							doRhoFastjet = cms.bool(False),
							jetPtMin = cms.double(100.0)
							),
						AnomalousCellParameters,
						CATopJetParameters.clone( jetCollInstanceName = cms.string("SubJets"),
							verbose = cms.bool(False),
							algorithm = cms.int32(1), # 0 = KT, 1 = CA, 2 = anti-KT
							tagAlgo = cms.int32(0), #0=legacy top
							useAdjacency = cms.int32(2), # modified adjacency
							centralEtaCut = cms.double(2.5), # eta for defining "central" jets
							sumEtBins = cms.vdouble(0,1600,2600), # sumEt bins over which cuts vary. vector={bin 0 lower bound, bin 1 lower bound, ...}
							rBins = cms.vdouble(0.8,0.8,0.8), # Jet distance paramter R. R values depend on sumEt bins.
							ptFracBins = cms.vdouble(0.05,0.05,0.05), # minimum fraction of central jet pt for subjets (deltap)
							deltarBins = cms.vdouble(0.19,0.19,0.19), # Applicable only if useAdjacency=1. deltar adjacency values for each sumEtBin
							nCellBins = cms.vdouble(1.9,1.9,1.9),
							),
						jetAlgorithm = cms.string("CambridgeAachen"),
						rParam = cms.double(jetSize),
						writeCompound = cms.bool(True)
						)
					)
			
			mod["CATopTagInfos"] = "CATopTagInfos"+postFix
			_addProcessAndTask(proc, mod["CATopTagInfos"],
					cms.EDProducer("CATopJetTagger",
						src = cms.InputTag(mod["PFJetsCMSTopTag"]),
						TopMass = cms.double(171),
						TopMassMin = cms.double(0.),
						TopMassMax = cms.double(250.),
						WMass = cms.double(80.4),
						WMassMin = cms.double(0.0),
						WMassMax = cms.double(200.0),
						MinMassMin = cms.double(0.0),
						MinMassMax = cms.double(200.0),
						verbose = cms.bool(False)
						)
					)
			mod["PATJetsCMSTopTagLabel"] = 'CMSTopTag'+PUMethod+postFix
			addJetCollection(
					proc,
					labelName = mod["PATJetsCMSTopTagLabel"],
					jetSource = cms.InputTag(mod["PFJetsCMSTopTag"]),
					jetCorrections = JEC if JEC is not None else None, 
					pfCandidates = cms.InputTag( pfCand ),  
					pvSource = cms.InputTag( pvLabel), 
					svSource = cms.InputTag( svLabel ), 
					muSource = cms.InputTag( muLabel ),
					elSource = cms.InputTag( elLabel ),
					btagDiscriminators = bTagDiscriminators,
					btagInfos = bTagInfos,
					genJetCollection = cms.InputTag(mod["GenJetsNoNu"]),
					getJetMCFlavour = False, # jet flavor should always be disabled for groomed jets
					genParticles = cms.InputTag(genParticlesLabel)
					)
			mod["PATJetsCMSTopTag"] = patJets+mod["PATJetsCMSTopTagLabel"]
			mod["selPATJetsCMSTopTag"] = selPatJets+mod["PATJetsCMSTopTagLabel"]
			getattr(proc,mod["PATJetsCMSTopTag"]).addTagInfos = True
			getattr(proc,mod["PATJetsCMSTopTag"]).tagInfoSources = cms.VInputTag( cms.InputTag(mod["CATopTagInfos"]))
			_addProcessAndTask(proc, mod["selPATJetsCMSTopTag"], selectedPatJets.clone(src=mod["PATJetsCMSTopTag"], cut=Cut))

			mod["PATSubjetsCMSTopTagLabel"] = mod["PATJetsCMSTopTagLabel"]+'Subjets'
			addJetCollection(
					proc,
					labelName = mod["PATSubjetsCMSTopTagLabel"],
					jetSource = cms.InputTag(mod["PFJetsCMSTopTag"], 'SubJets'),
					algo = jetalgo,  # needed for subjet b tagging
					rParam = jetSize,  # needed for subjet b tagging
					jetCorrections = subJEC if subJEC is not None else None, 
					pfCandidates = cms.InputTag( pfCand ),  
					pvSource = cms.InputTag( pvLabel), 
					svSource = cms.InputTag( svLabel ), 
					muSource = cms.InputTag( muLabel ),
					elSource = cms.InputTag( elLabel ),
					btagDiscriminators = bTagDiscriminators,
					btagInfos = bTagInfos,
					genJetCollection = cms.InputTag( mod["GenJetsNoNu"]),
					getJetMCFlavour = GetSubjetMCFlavour,
					explicitJTA = True,  # needed for subjet b tagging
					svClustering = True, # needed for subjet b tagging
					fatJets=cms.InputTag(mod["PFJets"]),             # needed for subjet flavor clustering
					groomedFatJets=cms.InputTag(mod["PATJetsCMSTopTag"]), # needed for subjet flavor clustering
					genParticles = cms.InputTag(genParticlesLabel)
					)
			mod["PATSubjetsCMSTopTag"] = patJets+mod["PATSubjetsCMSTopTagLabel"]
			mod["selPATSubjetsCMSTopTag"] = selPatJets+mod["PATSubjetsCMSTopTagLabel"]

			_addProcessAndTask(proc, mod["selPATSubjetsCMSTopTag"], selectedPatJets.clone(src=mod["PATSubjetsCMSTopTag"], cut=Cut))

			mod["PATJetsCMSTopTagPacked"] = mod["PATJetsCMSTopTag"]+'Packed'
			_addProcessAndTask(proc, mod["PATJetsCMSTopTagPacked"],
					cms.EDProducer("BoostedJetMerger",
						jetSrc=cms.InputTag(mod["PATJetsCMSTopTag"]),
						subjetSrc=cms.InputTag(mod["PATSubjetsCMSTopTag"])
						))
			jetSeq += getattr(proc, mod["PATJetsCMSTopTagPacked"])
			elemToKeep += [ 'keep *_'+mod["PATJetsCMSTopTagPacked"]+'_*_*' ]
			toolsUsed.append( mod["PATJetsCMSTopTagPacked"] )

		else:
			raise ValueError('|---- jetToolBox: CMS recommends CambridgeAachen for CMS Top Tagger, you are using '+algorithm+'. JetToolbox will not run CMS Top Tagger.')

	if addMassDrop :

		if 'CA' in jetALGO :
			mod["PFJetsMassDrop"] = mod["PFJets"]+'MassDropFiltered'
			mod["MassDropFilteredMass"] = mod["PFJetsMassDrop"]+'Mass'
			_addProcessAndTask(proc, mod["PFJetsMassDrop"],
					ca15PFJetsCHSMassDropFiltered.clone( 
						rParam = jetSize,
						src = cms.InputTag( mod["PFJetsConstituentsColonOrUpdate"] ),
						) )
			_addProcessAndTask(proc, mod["MassDropFilteredMass"], ak8PFJetsCHSPrunedMass.clone(src=cms.InputTag(mod["PFJets"]),
				matched = cms.InputTag(mod["PFJetsMassDrop"]), distMax = cms.double( jetSize ) ) )
			elemToKeep += [ 'keep *_'+mod["MassDropFilteredMass"]+'_*_*' ]
			getattr( proc, mod["PATJets"]).userData.userFloats.src += [ mod["MassDropFilteredMass"] ]
			jetSeq += getattr(proc, mod["PFJetsMassDrop"])
			jetSeq += getattr(proc, mod["MassDropFilteredMass"])
			toolsUsed.append( mod["MassDropFilteredMass"] )
		else:
			raise ValueError('|---- jetToolBox: CMS recommends CambridgeAachen for Mass Drop, you are using '+algorithm+'. JetToolbox will not run Mass Drop.')

	if addHEPTopTagger: 
		if ( jetSize >= 1. ) and ( 'CA' in jetALGO ): 

			mod["PFJetsHEPTopTag"] = mod["PFJets"].replace(jetalgo,"hepTopTag")
			mod["PFJetsHEPTopTagMass"] = mod["PFJetsHEPTopTag"]+'Mass'+jetALGO
			_addProcessAndTask(proc, mod["PFJetsHEPTopTag"], hepTopTagPFJetsCHS.clone(src=cms.InputTag(mod["PFJetsConstituentsColonOrUpdate"])))
			_addProcessAndTask(proc, mod["PFJetsHEPTopTagMass"], ak8PFJetsCHSPrunedMass.clone(src=cms.InputTag(mod["PFJets"]),
				matched = cms.InputTag(mod["PFJetsHEPTopTag"]), distMax = cms.double( jetSize ) ) )
			elemToKeep += [ 'keep *_'+mod["PFJetsHEPTopTagMass"]+'_*_*' ]
			getattr( proc, mod["PATJets"]).userData.userFloats.src += [ mod["PFJetsHEPTopTagMass"] ]
			jetSeq += getattr(proc, mod["PFJetsHEPTopTag"])
			jetSeq += getattr(proc, mod["PFJetsHEPTopTagMass"])
			toolsUsed.append( mod["PFJetsHEPTopTagMass"] )
		else:
			raise ValueError('|---- jetToolBox: CMS recommends CambridgeAachen w/ jet cone size > 1.0 for HEPTopTagger, you are using '+algorithm+'. JetToolbox will not run HEP TopTagger.')

	####### Nsubjettiness
	if addNsub:
		from RecoJets.JetProducers.nJettinessAdder_cfi import Njettiness

		rangeTau = range(1,maxTau+1)
		mod["Njettiness"] = 'Njettiness'+mod["SubstructureLabel"]
		_addProcessAndTask(proc, mod["Njettiness"],
				Njettiness.clone( src = cms.InputTag( mod["PFJetsOrUpdate"] ),
					Njets=cms.vuint32(rangeTau),         # compute 1-, 2-, 3-, 4- subjettiness
					# variables for measure definition : 
					measureDefinition = cms.uint32( 0 ), # CMS default is normalized measure
					beta = cms.double(1.0),              # CMS default is 1
					R0 = cms.double( jetSize ),              # CMS default is jet cone size
					Rcutoff = cms.double( 999.0),       # not used by default
					# variables for axes definition :
					axesDefinition = cms.uint32( 6 ),    # CMS default is 1-pass KT axes
					nPass = cms.int32(999),             # not used by default
					akAxesR0 = cms.double(-999.0) ) )        # not used by default

		elemToKeep += [ 'keep *_'+mod["Njettiness"]+'_*_*' ]
		for tau in rangeTau: getattr( proc, mod["PATJets"]).userData.userFloats.src += [mod["Njettiness"]+':tau'+str(tau) ] 
		jetSeq += getattr(proc, mod["Njettiness"])
		toolsUsed.append( mod["Njettiness"] )

	####### Nsubjettiness
	if addNsubSubjets:

		from RecoJets.JetProducers.nJettinessAdder_cfi import Njettiness

		mod["NsubGroomer"] = ''
		mod["NsubSubjets"] = ''
		mod["NsubPATSubjets"] = ''
		if addSoftDropSubjets or updateCollectionSubjets:
			mod["NsubGroomer"] = mod["PFJetsSoftDrop"]
			mod["NsubSubjets"] = mod["PATSubjetsSoftDropLabel"]
			mod["NsubPATSubjets"] = mod["PATSubjetsSoftDrop"]
			if updateCollectionSubjets:
				if verbosity>=2: print('|---- jetToolBox: Using updateCollection option. ASSUMING MINIAOD collection '+ updateCollectionSubjets +' for Nsubjettiness of subjets.')
		elif addPrunedSubjets:
			mod["NsubGroomer"] = mod["PFJetsPruned"]
			mod["NsubSubjets"] = mod["PATSubjetsPrunedLabel"]
			mod["NsubPATSubjets"] = mod["PATSubjetsPruned"]
		else: 
			raise ValueError('|---- jetToolBox: Nsubjettiness of subjets needs a Subjet collection. Or create one using addSoftDropSubjets option, or updateCollection.')

		mod["Nsubjettiness"] = 'Nsubjettiness'+mod["NsubSubjets"]
		rangeTau = range(1,subjetMaxTau+1)
		_addProcessAndTask(proc, mod["Nsubjettiness"],
				Njettiness.clone( src = cms.InputTag( ( mod["NsubGroomer"] if not updateCollectionSubjets else updateCollectionSubjets ), 'SubJets' ), 
					Njets=cms.vuint32(rangeTau),         # compute 1-, 2-, 3-, 4- subjettiness
					# variables for measure definition : 
					measureDefinition = cms.uint32( 0 ), # CMS default is normalized measure
					beta = cms.double(1.0),              # CMS default is 1
					R0 = cms.double( jetSize ),              # CMS default is jet cone size
					Rcutoff = cms.double( 999.0),       # not used by default
					# variables for axes definition :
					axesDefinition = cms.uint32( 6 ),    # CMS default is 1-pass KT axes
					nPass = cms.int32(999),             # not used by default
					akAxesR0 = cms.double(-999.0) ) )        # not used by default

		elemToKeep += [ 'keep *_'+mod["Nsubjettiness"]+'_*_*' ]
		for tau in rangeTau: getattr( proc, ( mod["NsubPATSubjets"] if not updateCollectionSubjets else patSubJets ) ).userData.userFloats.src += [mod["Nsubjettiness"]+':tau'+str(tau) ] 
		jetSeq += getattr(proc, mod["Nsubjettiness"])
		toolsUsed.append( mod["Nsubjettiness"] )

	###### QGTagger
	if addQGTagger:
		if ( 'ak4' in jetalgo ) and ( PUMethod not in ['Puppi','CS','SK'] ) :
			from RecoJets.JetProducers.QGTagger_cfi import QGTagger
			proc.load('RecoJets.JetProducers.QGTagger_cfi') 	## In 74X you need to run some stuff before.
			mod["QGTagger"] = 'QGTagger'+mod["PATJetsLabelPost"]
			_addProcessAndTask(proc, mod["QGTagger"],
					QGTagger.clone(
						srcJets = cms.InputTag( mod["PFJetsOrUpdate"] ),    # Could be reco::PFJetCollection or pat::JetCollection (both AOD and miniAOD)
						jetsLabel = cms.string('QGL_AK4PF'+QGjetsLabel)        # Other options (might need to add an ESSource for it): see https://twiki.cern.ch/twiki/bin/viewauth/CMS/QGDataBaseVersion
						)
					)
			elemToKeep += [ 'keep *_'+mod["QGTagger"]+'_*_*' ]
			getattr( proc, mod["PATJets"]).userData.userFloats.src += [mod["QGTagger"]+':qgLikelihood']
			jetSeq += getattr(proc, mod["QGTagger"])

			toolsUsed.append( mod["QGTagger"] )
		else:
			raise ValueError('|---- jetToolBox: QGTagger is optimized for ak4 jets with CHS. NOT running QGTagger')

			
	####### Pileup JetID
	if addPUJetID:
		if ( 'ak4' in jetalgo ) and ( PUMethod not in ['CS','SK'] ):
			if PUMethod=="Puppi" and verbosity>=1: print('|---- jetToolBox: PUJetID is not yet optimized for ak4 PFjets with PUPPI. USE ONLY FOR TESTING.')
			from RecoJets.JetProducers.pileupjetidproducer_cfi import pileupJetIdCalculator,pileupJetIdEvaluator

			mod["PUJetIDCalc"] = mod["PATJetsLabelPost"]+'pileupJetIdCalculator'
			_addProcessAndTask(proc, mod["PUJetIDCalc"],
					pileupJetIdCalculator.clone(
						jets = cms.InputTag( mod["PFJetsOrUpdate"] ),
						rho = cms.InputTag("fixedGridRhoFastjetAll"),
						vertexes = cms.InputTag(pvLabel),
						applyJec = cms.bool(True),
						inputIsCorrected = cms.bool(False)
						))

			mod["PUJetIDEval"] = mod["PATJetsLabelPost"]+'pileupJetIdEvaluator'
			_addProcessAndTask(proc, mod["PUJetIDEval"],
					pileupJetIdEvaluator.clone(
						jetids = cms.InputTag(mod["PUJetIDCalc"]),
						jets = cms.InputTag( mod["PFJetsOrUpdate"] ),
						rho = cms.InputTag("fixedGridRhoFastjetAll"),
						vertexes = cms.InputTag(pvLabel)
						)
					)

			getattr( proc, mod["PATJets"]).userData.userFloats.src += [mod["PUJetIDEval"]+':fullDiscriminant']
			getattr( proc, mod["PATJets"]).userData.userInts.src += [mod["PUJetIDEval"]+':cutbasedId',mod["PUJetIDEval"]+':fullId']
			elemToKeep += ['keep *_'+mod["PUJetIDEval"]+'_*_*']
			toolsUsed.append( mod["PUJetIDEval"] )
		else:
			raise ValueError('|---- jetToolBox: PUJetID is optimized for ak4 PFjets with CHS. NOT running PUJetID.')

	###### Energy Correlation Functions
	if addEnergyCorrFunc:
		if PUMethod!="Puppi" or (addSoftDrop==False and addSoftDropSubjets==False):
			raise ValueError("|---- jetToolBox: addEnergyCorrFunc only supported for Puppi w/ addSoftDrop or addSoftDropSubjets")
		from RecoJets.JetProducers.ECF_cff import ecfNbeta1, ecfNbeta2
		mod["ECFnb1"] = 'nb1'+mod["SubstructureLabel"]+'SoftDrop'
# 		mod["ECFnb2"] = 'nb2'+mod["SubstructureLabel"]+'SoftDrop'
		_addProcessAndTask(proc, mod["ECFnb1"], ecfNbeta1.clone(src=cms.InputTag(mod["PFJetsSoftDrop"]), cuts=cms.vstring('', '', 'pt > 250')))
# 		_addProcessAndTask(proc, mod["ECFnb2"], ecfNbeta2.clone(src=cms.InputTag(mod["PFJetsSoftDrop"]), cuts=cms.vstring('', '', 'pt > 250')))
		elemToKeep += [ 'keep *_' + mod["ECFnb1"] + '_*_*',
					# 'keep *_'+mod["ECFnb2"]+'_*_*'
					]
		jetSeq += getattr(proc, mod["ECFnb1"])
# 		jetSeq += getattr(proc, mod["ECFnb2"])
# 		toolsUsed.extend([mod["ECFnb1"], mod["ECFnb2"]])
		toolsUsed.extend([mod["ECFnb1"]])

		# set up user floats
		getattr(proc, mod["PATJetsSoftDrop"]).userData.userFloats.src += [
			mod["ECFnb1"]+':ecfN2',
			mod["ECFnb1"]+':ecfN3',
# 			mod["ECFnb2"]+':ecfN2',
# 			mod["ECFnb2"]+':ecfN3',
		]
		# rekey the groomed ECF value maps to the ungroomed reco jets, which will then be picked
		# up by PAT in the user floats. 
		mod["PFJetsSoftDropValueMap"] = mod["PFJetsSoftDrop"]+'ValueMap'
		_addProcessAndTask(proc, mod["PFJetsSoftDropValueMap"],
			cms.EDProducer("RecoJetToPatJetDeltaRValueMapProducer",
				src = cms.InputTag(mod["PFJets"]),
				matched = cms.InputTag(mod["PATJetsSoftDrop"]),
				distMax = cms.double(jetSize),
				values = cms.vstring([
					'userFloat("'+mod["ECFnb1"]+':ecfN2'+'")',
					'userFloat("'+mod["ECFnb1"]+':ecfN3'+'")',
# 					'userFloat("'+mod["ECFnb2"]+':ecfN2'+'")',
# 					'userFloat("'+mod["ECFnb2"]+':ecfN3'+'")',
				]),
				valueLabels = cms.vstring( [
					mod["ECFnb1"]+'N2',
					mod["ECFnb1"]+'N3',
# 					mod["ECFnb2"]+'N2',
# 					mod["ECFnb2"]+'N3',
				]),
			)
		)
		getattr(proc, mod["PATJets"]).userData.userFloats.src += [
			mod["PFJetsSoftDropValueMap"]+':'+mod["ECFnb1"]+'N2',
			mod["PFJetsSoftDropValueMap"]+':'+mod["ECFnb1"]+'N3',
# 			mod["PFJetsSoftDropValueMap"]+':'+mod["ECFnb2"]+'N2',
# 			mod["PFJetsSoftDropValueMap"]+':'+mod["ECFnb2"]+'N3',
		]

	if addEnergyCorrFuncSubjets:
		if PUMethod!="Puppi" or addSoftDropSubjets==False:
			raise ValueError("|---- jetToolBox: addEnergyCorrFuncSubjets only supported for Puppi w/ addSoftDropSubjets")
		from RecoJets.JetProducers.ECF_cff import ecfNbeta1, ecfNbeta2
		mod["ECFnb1Subjets"] = 'nb1'+mod["SubstructureLabel"]+'SoftDropSubjets'
		mod["ECFnb2Subjets"] = 'nb2'+mod["SubstructureLabel"]+'SoftDropSubjets'
		_addProcessAndTask(proc, mod["ECFnb1Subjets"], ecfNbeta1.clone(src=cms.InputTag(mod["PFJetsSoftDrop"], 'SubJets')))
		_addProcessAndTask(proc, mod["ECFnb2Subjets"], ecfNbeta2.clone(src=cms.InputTag(mod["PFJetsSoftDrop"], 'SubJets')))
		elemToKeep += [ 'keep *_'+mod["ECFnb1Subjets"]+'_*_*', 'keep *_'+mod["ECFnb2Subjets"]+'_*_*']
		jetSeq += getattr(proc, mod["ECFnb1Subjets"])
		jetSeq += getattr(proc, mod["ECFnb2Subjets"])
		toolsUsed.extend([mod["ECFnb1Subjets"],mod["ECFnb2Subjets"]])

		# set up user floats
		getattr(proc, mod["PATSubjetsSoftDrop"]).userData.userFloats.src += [
			mod["ECFnb1Subjets"]+':ecfN2',
			mod["ECFnb1Subjets"]+':ecfN3',
			mod["ECFnb2Subjets"]+':ecfN2',
			mod["ECFnb2Subjets"]+':ecfN3',
		]

	if hasattr(proc, 'patJetPartons'): proc.patJetPartons.particles = genParticlesLabel

	_addProcessAndTask(proc, mod["selPATJets"], selectedPatJets.clone(src=mod["PATJets"], cut=Cut))
	elemToKeep += [ 'keep *_'+mod["selPATJets"]+'_*_*' ]
	elemToKeep += [ 'drop *_'+mod["selPATJets"]+'_calo*_*' ]
	elemToKeep += [ 'drop *_'+mod["selPATJets"]+'_tagInfos_*' ]

	if updateCollectionSubjets:
		mod["PATSubjets"] = patJets+mod["PATSubjetsLabel"]
		mod["selPATSubjets"] = selPatJets+mod["PATSubjetsLabel"]
		_addProcessAndTask(proc, mod["selPATSubjets"], selectedPatJets.clone(src=mod["PATSubjets"], cut=Cut))
		elemToKeep += [ 'keep *_'+mod["selPATSubjets"]+'__*' ]


	if len(toolsUsed) > 0 and verbosity>=2: print('|---- jetToolBox: Running '+', '.join(toolsUsed)+'.')
	if verbosity>=2: print('|---- jetToolBox: Creating '+mod["selPATJets"]+' collection.')
	if updateCollectionSubjets and verbosity>=2: print('|---- jetToolBox: Creating '+mod["selPATSubjets"]+' collection.')

	### "return"
	setattr(proc, jetSequence, jetSeq)
	if outputFile!='':
		if hasattr(proc, outputFile): getattr(proc, outputFile).outputCommands += elemToKeep
		else: setattr( proc, outputFile, 
				cms.OutputModule('PoolOutputModule', 
					fileName = cms.untracked.string('jettoolbox.root'), 
					outputCommands = cms.untracked.vstring( elemToKeep ) ) )

	if associateTask:
		from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask
		task = getPatAlgosToolsTask(proc)
		if hasattr(proc, 'endpath'):
			getattr(proc, 'endpath').associate(task)
		else:
			setattr(proc, 'endpath', cms.EndPath(task))
		if outputFile != '': 
			getattr(proc, 'endpath').insert(-1, getattr(proc, outputFile))

	#### removing mc matching for data
	if runOnData:
		from PhysicsTools.PatAlgos.tools.coreTools import removeMCMatching
		removeMCMatching(proc, names=['Jets'], outputModules=[outputFile])

	if verbosity>=3:
		print('|---- jetToolBox: List of modules created (and other internal names):')
		for m in mod:
			print('      '+m+' = '+mod[m])
def addPaths_MC_JMEPFPuppiROI(process):

    process.hltPreMCJMEPFPuppiROI = cms.EDFilter(
        'HLTPrescaler',
        L1GtReadoutRecordTag=cms.InputTag('hltGtStage2Digis'),
        offset=cms.uint32(0))

    process.hltPixelClustersMultiplicity = _nSiPixelClusters.clone(
        src='hltSiPixelClusters', defaultValue=-1.)

    process.hltPFPuppiROI = _puppi.clone(
        candName='hltParticleFlowForBTag',
        vertexName='hltVerticesPFForBTag',
        usePUProxyValue=True,
        PUProxyValue='hltPixelClustersMultiplicity',
    )

    process.HLTPFPuppiSequenceROI = cms.Sequence(
        process.HLTDoCaloSequencePF + process.HLTL2muonrecoSequence +
        process.HLTL3muonrecoSequence + process.HLTTrackReconstructionForBTag +
        process.HLTParticleFlowSequenceForBTag + process.hltVerticesPFForBTag +
        process.hltPixelClustersMultiplicity + process.hltPFPuppiROI)

    ## AK4
    process.hltAK4PFPuppiJetsROI = _ak4PFJetsPuppi.clone(
        src='hltParticleFlowForBTag',
        srcWeights='hltPFPuppiROI',
        applyWeight=True,
    )

    process.hltAK4PFPuppiJetCorrectorL1ROI = cms.EDProducer(
        'L1FastjetCorrectorProducer',
        algorithm=cms.string('AK4PFPuppiHLT'),
        level=cms.string('L1FastJet'),
        srcRho=cms.InputTag('hltFixedGridRhoFastjetAllForBTag'),
    )

    process.hltAK4PFPuppiJetCorrectorL2ROI = cms.EDProducer(
        'LXXXCorrectorProducer',
        algorithm=cms.string('AK4PFPuppiHLT'),
        level=cms.string('L2Relative'))

    process.hltAK4PFPuppiJetCorrectorL3ROI = cms.EDProducer(
        'LXXXCorrectorProducer',
        algorithm=cms.string('AK4PFPuppiHLT'),
        level=cms.string('L3Absolute'))

    process.hltAK4PFPuppiJetCorrectorROI = cms.EDProducer(
        'ChainedJetCorrectorProducer',
        correctors=cms.VInputTag(
            'hltAK4PFPuppiJetCorrectorL1ROI',
            'hltAK4PFPuppiJetCorrectorL2ROI',
            'hltAK4PFPuppiJetCorrectorL3ROI',
        ),
    )

    process.hltAK4PFPuppiJetsCorrectedROI = cms.EDProducer(
        'CorrectedPFJetProducer',
        src=cms.InputTag('hltAK4PFPuppiJetsROI'),
        correctors=cms.VInputTag('hltAK4PFPuppiJetCorrectorROI'),
    )

    process.HLTAK4PFPuppiJetsSequenceROI = cms.Sequence(
        process.hltAK4PFPuppiJetsROI + process.hltAK4PFPuppiJetCorrectorL1ROI +
        process.hltAK4PFPuppiJetCorrectorL2ROI +
        process.hltAK4PFPuppiJetCorrectorL3ROI +
        process.hltAK4PFPuppiJetCorrectorROI +
        process.hltAK4PFPuppiJetsCorrectedROI)

    ## Modifications to PUPPI parameters
    for mod_i in [process.hltPFPuppiROI]:
        for algo_idx in range(len(mod_i.algos)):
            if len(mod_i.algos[algo_idx].MinNeutralPt) != len(
                    mod_i.algos[algo_idx].MinNeutralPtSlope):
                raise RuntimeError(
                    'instance of PuppiProducer is misconfigured:\n\n' +
                    str(mod_i) + ' = ' + mod_i.dumpPython())

            for algoReg_idx in range(len(mod_i.algos[algo_idx].MinNeutralPt)):
                mod_i.algos[algo_idx].MinNeutralPt[
                    algoReg_idx] += 2.56 * mod_i.algos[
                        algo_idx].MinNeutralPtSlope[algoReg_idx]
                mod_i.algos[algo_idx].MinNeutralPtSlope[algoReg_idx] *= 0.00271

    ## Path
    process.MC_JMEPFPuppiROI_v1 = cms.Path(
        process.HLTBeginSequence + process.hltPreMCJMEPFPuppiROI
        ## AK4 Jets
        + process.HLTAK4PFJetsSequenceForBTag  # New
        + process.HLTPFPuppiSequenceROI + process.HLTAK4PFPuppiJetsSequenceROI)

    if process.schedule_():
        process.schedule_().append(process.MC_JMEPFPuppiROI_v1)

    return process
def applySubstructure(process, postfix=""):

    task = getPatAlgosToolsTask(process)

    from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection

    from PhysicsTools.PatAlgos.producersLayer1.jetProducer_cfi import _patJets as patJetsDefault

    #add AK8
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8',
        jetSource=cms.InputTag('ak8PFJetsCHS' + postfix),
        algo='AK',
        rParam=0.8,
        jetCorrections=('AK8PFchs',
                        cms.vstring(['L1FastJet', 'L2Relative',
                                     'L3Absolute']), 'None'),
        genJetCollection=cms.InputTag('slimmedGenJetsAK8'))
    getattr(process, "patJetsAK8" + postfix).userData.userFloats.src = [
    ]  # start with empty list of user floats
    getattr(process, "selectedPatJetsAK8").cut = cms.string("pt > 170")

    ## AK8 groomed masses
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsCHSPruned, ak8PFJetsCHSSoftDrop
    addToProcessAndTask('ak8PFJetsCHSPruned' + postfix,
                        ak8PFJetsCHSPruned.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDrop' + postfix,
                        ak8PFJetsCHSSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsCHS_groomingValueMaps_cfi import ak8PFJetsCHSPrunedMass, ak8PFJetsCHSTrimmedMass, ak8PFJetsCHSFilteredMass, ak8PFJetsCHSSoftDropMass
    addToProcessAndTask('ak8PFJetsCHSPrunedMass' + postfix,
                        ak8PFJetsCHSPrunedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSTrimmedMass' + postfix,
                        ak8PFJetsCHSTrimmedMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSFilteredMass' + postfix,
                        ak8PFJetsCHSFilteredMass.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSSoftDropMass' + postfix,
                        ak8PFJetsCHSSoftDropMass.clone(), process, task)

    getattr(process, "patJetsAK8").userData.userFloats.src += [
        'ak8PFJetsCHSPrunedMass' + postfix,
        'ak8PFJetsCHSSoftDropMass' + postfix
    ]
    getattr(process, "patJetsAK8").addTagInfos = cms.bool(False)

    # add Njetiness
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8' + postfix, process.Njettiness.clone(),
                        process, task)

    getattr(process,
            "NjettinessAK8").src = cms.InputTag("ak8PFJetsCHS" + postfix)
    getattr(process, "NjettinessAK8").cone = cms.double(0.8)
    getattr(process, "patJetsAK8").userData.userFloats.src += [
        'NjettinessAK8' + postfix + ':tau1',
        'NjettinessAK8' + postfix + ':tau2',
        'NjettinessAK8' + postfix + ':tau3'
    ]

    #add AK8 from PUPPI
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi
    addToProcessAndTask('ak4PFJetsPuppi' + postfix, ak4PFJetsPuppi.clone(),
                        process, task)
    addToProcessAndTask('ak8PFJetsPuppi' + postfix, ak8PFJetsPuppi.clone(),
                        process, task)
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppiSoftDrop
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop' + postfix,
                        ak8PFJetsPuppiSoftDrop.clone(), process, task)
    getattr(
        process, "ak8PFJetsPuppi"
    ).doAreaFastjet = True  # even for standard ak8PFJets this is overwritten in RecoJets/Configuration/python/RecoPFJets_cff

    #add AK8 from PUPPI
    from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJetsPuppi
    from RecoJets.JetProducers.ak8PFJets_cfi import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents

    #from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppi, ak8PFJetsPuppiSoftDrop, ak8PFJetsPuppiConstituents, ak8PFJetsCHSConstituents
    addToProcessAndTask('ak4PFJetsPuppi' + postfix, ak4PFJetsPuppi.clone(),
                        process, task)
    addToProcessAndTask('ak8PFJetsPuppiConstituents',
                        ak8PFJetsPuppiConstituents.clone(), process, task)
    addToProcessAndTask('ak8PFJetsCHSConstituents',
                        ak8PFJetsCHSConstituents.clone(), process, task)
    addToProcessAndTask('ak8PFJetsPuppi' + postfix, ak8PFJetsPuppi.clone(),
                        process, task)
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop' + postfix,
                        ak8PFJetsPuppiSoftDrop.clone(), process, task)
    getattr(
        process, "ak8PFJetsPuppi"
    ).doAreaFastjet = True  # even for standard ak8PFJets this is overwritten in RecoJets/Configuration/python/RecoPFJets_cff

    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8Puppi',
        jetSource=cms.InputTag('ak8PFJetsPuppi' + postfix),
        algo='AK',
        rParam=0.8,
        jetCorrections=('AK8PFPuppi', cms.vstring(['L2Relative',
                                                   'L3Absolute']), 'None'),
        btagDiscriminators=(
            [x.value() for x in patJetsDefault.discriminatorSources] +
            ['pfBoostedDoubleSecondaryVertexAK8BJetTags']),
        genJetCollection=cms.InputTag('slimmedGenJetsAK8'))
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src = [
    ]  # start with empty list of user floats
    getattr(process,
            "selectedPatJetsAK8Puppi" + postfix).cut = cms.string("pt > 170")

    from RecoJets.JetAssociationProducers.j2tParametersVX_cfi import j2tParametersVX
    addToProcessAndTask(
        'ak8PFJetsPuppiTracksAssociatorAtVertex' + postfix,
        cms.EDProducer("JetTracksAssociatorAtVertex",
                       j2tParametersVX.clone(coneSize=cms.double(0.8)),
                       jets=cms.InputTag("ak8PFJetsPuppi")), process, task)
    addToProcessAndTask(
        'patJetAK8PuppiCharge' + postfix,
        cms.EDProducer(
            "JetChargeProducer",
            src=cms.InputTag("ak8PFJetsPuppiTracksAssociatorAtVertex"),
            var=cms.string('Pt'),
            exp=cms.double(1.0)), process, task)

    ## AK8 groomed masses
    from RecoJets.Configuration.RecoPFJets_cff import ak8PFJetsPuppiSoftDrop
    addToProcessAndTask('ak8PFJetsPuppiSoftDrop' + postfix,
                        ak8PFJetsPuppiSoftDrop.clone(), process, task)
    from RecoJets.JetProducers.ak8PFJetsPuppi_groomingValueMaps_cfi import ak8PFJetsPuppiSoftDropMass
    addToProcessAndTask('ak8PFJetsPuppiSoftDropMass' + postfix,
                        ak8PFJetsPuppiSoftDropMass.clone(), process, task)
    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src += [
        'ak8PFJetsPuppiSoftDropMass' + postfix
    ]
    getattr(process, "patJetsAK8Puppi" + postfix).addTagInfos = cms.bool(False)

    # add Njetiness
    addToProcessAndTask('NjettinessAK8Puppi' + postfix,
                        process.Njettiness.clone(), process, task)
    getattr(process, "NjettinessAK8Puppi" +
            postfix).src = cms.InputTag("ak8PFJetsPuppi" + postfix)
    getattr(process, "NjettinessAK8Puppi").cone = cms.double(0.8)
    getattr(process, "patJetsAK8Puppi").userData.userFloats.src += [
        'NjettinessAK8Puppi' + postfix + ':tau1',
        'NjettinessAK8Puppi' + postfix + ':tau2',
        'NjettinessAK8Puppi' + postfix + ':tau3'
    ]

    addToProcessAndTask(
        "ak8PFJetsCHSValueMap" + postfix,
        cms.EDProducer(
            "RecoJetToPatJetDeltaRValueMapProducer",
            src=cms.InputTag("ak8PFJetsPuppi" + postfix),
            matched=cms.InputTag("patJetsAK8" + postfix),
            distMax=cms.double(0.8),
            values=cms.vstring([
                'userFloat("ak8PFJetsCHSPrunedMass"' + postfix + ')',
                'userFloat("ak8PFJetsCHSSoftDropMass"' + postfix + ')',
                'userFloat("NjettinessAK8' + postfix + ':tau1")',
                'userFloat("NjettinessAK8' + postfix + ':tau2")',
                'userFloat("NjettinessAK8' + postfix + ':tau3")', 'pt', 'eta',
                'phi', 'mass'
            ]),
            valueLabels=cms.vstring([
                'ak8PFJetsCHSPrunedMass', 'ak8PFJetsCHSSoftDropMass',
                'NjettinessAK8CHSTau1', 'NjettinessAK8CHSTau2',
                'NjettinessAK8CHSTau3', 'pt', 'eta', 'phi', 'mass'
            ])), process, task)

    getattr(process, "patJetsAK8Puppi" + postfix).userData.userFloats.src += [
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix,
                     'ak8PFJetsCHSPrunedMass'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix,
                     'ak8PFJetsCHSSoftDropMass'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau1'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau2'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'NjettinessAK8CHSTau3'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'pt'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'eta'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'phi'),
        cms.InputTag('ak8PFJetsCHSValueMap' + postfix, 'mass'),
    ]

    # add Njetiness
    process.load('RecoJets.JetProducers.nJettinessAdder_cfi')
    task.add(process.Njettiness)
    addToProcessAndTask('NjettinessAK8Subjets' + postfix,
                        process.Njettiness.clone(), process, task)
    getattr(process, "NjettinessAK8Subjets" + postfix).src = cms.InputTag(
        "ak8PFJetsPuppiSoftDrop" + postfix, "SubJets")
    getattr(process, "NjettinessAK8Subjets").cone = cms.double(0.8)

    ## PATify CHS soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFCHSSoftDrop',
        jetSource=cms.InputTag('ak8PFJetsCHSSoftDrop' + postfix),
        btagDiscriminators=['None'],
        jetCorrections=('AK8PFchs', ['L1FastJet', 'L2Relative',
                                     'L3Absolute'], 'None'),
        getJetMCFlavour=False  # jet flavor disabled
    )

    ## PATify puppi soft drop fat jets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFPuppiSoftDrop',
        jetSource=cms.InputTag('ak8PFJetsPuppiSoftDrop' + postfix),
        btagDiscriminators=['None'],
        jetCorrections=('AK8PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        getJetMCFlavour=False  # jet flavor disabled
    )

    ## PATify soft drop subjets
    addJetCollection(
        process,
        postfix=postfix,
        labelName='AK8PFPuppiSoftDropSubjets',
        jetSource=cms.InputTag('ak8PFJetsPuppiSoftDrop' + postfix, 'SubJets'),
        algo='ak',  # needed for subjet flavor clustering
        rParam=0.8,  # needed for subjet flavor clustering
        btagDiscriminators=[
            'pfDeepCSVJetTags:probb', 'pfDeepCSVJetTags:probbb',
            'pfCombinedInclusiveSecondaryVertexV2BJetTags',
            'pfCombinedMVAV2BJetTags'
        ],
        jetCorrections=('AK4PFPuppi', ['L2Relative', 'L3Absolute'], 'None'),
        explicitJTA=True,  # needed for subjet b tagging
        svClustering=True,  # needed for subjet b tagging
        genJetCollection=cms.InputTag('slimmedGenJets'),
        fatJets=cms.InputTag(
            'ak8PFJetsPuppi'),  # needed for subjet flavor clustering
        groomedFatJets=cms.InputTag(
            'ak8PFJetsPuppiSoftDrop')  # needed for subjet flavor clustering
    )
    getattr(process, "selectedPatJetsAK8PFPuppiSoftDrop" +
            postfix).cut = cms.string("pt > 170")
    getattr(process, "patJetsAK8PFPuppiSoftDropSubjets" +
            postfix).userData.userFloats.src += [
                'NjettinessAK8Subjets' + postfix + ':tau1',
                'NjettinessAK8Subjets' + postfix + ':tau2',
                'NjettinessAK8Subjets' + postfix + ':tau3'
            ]

    addToProcessAndTask(
        "slimmedJetsAK8PFPuppiSoftDropSubjets" + postfix,
        cms.EDProducer(
            "PATJetSlimmer",
            src=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDropSubjets"),
            packedPFCandidates=cms.InputTag("packedPFCandidates"),
            dropJetVars=cms.string("1"),
            dropDaughters=cms.string("0"),
            rekeyDaughters=cms.string("1"),
            dropTrackRefs=cms.string("1"),
            dropSpecific=cms.string("1"),
            dropTagInfos=cms.string("1"),
            modifyJets=cms.bool(True),
            mixedDaughters=cms.bool(False),
            modifierConfig=cms.PSet(modifications=cms.VPSet())), process, task)

    ## Establish references between PATified fat jets and subjets using the BoostedJetMerger
    addToProcessAndTask(
        "slimmedJetsAK8PFPuppiSoftDropPacked" + postfix,
        cms.EDProducer(
            "BoostedJetMerger",
            jetSrc=cms.InputTag("selectedPatJetsAK8PFPuppiSoftDrop"),
            subjetSrc=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropSubjets")),
        process, task)

    addToProcessAndTask(
        "packedPatJetsAK8" + postfix,
        cms.EDProducer(
            "JetSubstructurePacker",
            jetSrc=cms.InputTag("selectedPatJetsAK8Puppi" + postfix),
            distMax=cms.double(0.8),
            algoTags=cms.VInputTag(
                cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked" + postfix)),
            algoLabels=cms.vstring('SoftDropPuppi'),
            fixDaughters=cms.bool(True),
            packedPFCandidates=cms.InputTag("packedPFCandidates" + postfix),
        ), process, task)

    # switch off daughter re-keying since it's done in the JetSubstructurePacker (and can't be done afterwards)
    process.slimmedJetsAK8.rekeyDaughters = "0"