Example #1
0
                                slimmedElectronsWithUserData + finalElectrons)
electronTables = cms.Sequence(electronMVATTH + electronTable)
electronMC = cms.Sequence(electronsMCMatchForTable + electronMCTable)

_withUpdate_sequence = cms.Sequence(slimmedElectronsUpdated +
                                    electronSequence.copy())

_withUpdateAnd80XLegacyScale_sequence = _withUpdate_sequence.copy()
_withUpdateAnd80XLegacyScale_sequence.replace(
    slimmedElectronsWithUserData,
    calibratedPatElectrons80XLegacy + bitmapVIDForEleSpring15 +
    bitmapVIDForEleSum16 + slimmedElectronsWithUserData)
run2_miniAOD_80XLegacy.toReplaceWith(electronSequence,
                                     _withUpdateAnd80XLegacyScale_sequence)

_with94XScale_sequence = electronSequence.copy()
_with94XScale_sequence.replace(
    slimmedElectronsWithUserData,
    calibratedPatElectrons94X + slimmedElectronsWithUserData)
run2_nanoAOD_94XMiniAODv1.toReplaceWith(electronSequence,
                                        _with94XScale_sequence)
run2_nanoAOD_94XMiniAODv2.toReplaceWith(electronSequence,
                                        _with94XScale_sequence)

_with_bitmapVIDForEleSpring15AndSum16_sequence = electronSequence.copy()
_with_bitmapVIDForEleSpring15AndSum16_sequence.replace(
    slimmedElectronsWithUserData, bitmapVIDForEleSpring15 +
    bitmapVIDForEleSum16 + slimmedElectronsWithUserData)
run2_nanoAOD_94X2016.toReplaceWith(
    electronSequence, _with_bitmapVIDForEleSpring15AndSum16_sequence)
Example #2
0
        ),
    ))
run2_nanoAOD_94X2016.toReplaceWith(
    slimmedElectronsWithUserData.userIntFromBools,
    cms.PSet(
        # MVAs and HEEP are already pre-computed. Cut-based too, but we re-add it for consistency with the nested bitmap
        cutbasedID_veto=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-veto"),
        cutbasedID_loose=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-loose"),
        cutbasedID_medium=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-medium"),
        cutbasedID_tight=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-tight"),
        cutbasedID_HLT=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronHLTPreselection-Summer16-V1"),
        cutbasedID_Spring15_veto=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Spring15-25ns-V1-standalone-veto"
        ),
        cutbasedID_Spring15_loose=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Spring15-25ns-V1-standalone-loose"
        ),
        cutbasedID_Spring15_medium=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Spring15-25ns-V1-standalone-medium"
        ),
        cutbasedID_Spring15_tight=cms.InputTag(
            "egmGsfElectronIDs:cutBasedElectronID-Spring15-25ns-V1-standalone-tight"
        ),
    ))
for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
    modifier.toModify(
Example #3
0
electronMCTable = cms.EDProducer("CandMCMatchTableProducer",
    src     = electronTable.src,
    mcMap   = cms.InputTag("electronsMCMatchForTable"),
    objName = electronTable.name,
    objType = electronTable.name, #cms.string("Electron"),
    branchName = cms.string("genPart"),
    docString = cms.string("MC matching to status==1 electrons or photons"),
)

electronSequence = cms.Sequence(bitmapVIDForEle + isoForEle + ptRatioRelForEle + slimmedElectronsWithUserData + finalElectrons)
electronTables = cms.Sequence (electronMVATTH + electronTable)
electronMC = cms.Sequence(electronsMCMatchForTable + electronMCTable)

_withUpdate_sequence = cms.Sequence(slimmedElectronsUpdated + electronSequence.copy())
run2_nanoAOD_92X.toReplaceWith(electronSequence, _withUpdate_sequence)

_withUpdateAnd80XLegacyScale_sequence = _withUpdate_sequence.copy()
_withUpdateAnd80XLegacyScale_sequence.replace(slimmedElectronsWithUserData, calibratedPatElectrons80XLegacy + bitmapVIDForEleSpring15 +bitmapVIDForEleSum16 + slimmedElectronsWithUserData)
run2_miniAOD_80XLegacy.toReplaceWith(electronSequence, _withUpdateAnd80XLegacyScale_sequence)

_with94XScale_sequence = electronSequence.copy()
_with94XScale_sequence.replace(slimmedElectronsWithUserData, calibratedPatElectrons94X + slimmedElectronsWithUserData)
run2_nanoAOD_94XMiniAODv1.toReplaceWith(electronSequence, _with94XScale_sequence)
run2_nanoAOD_94XMiniAODv2.toReplaceWith(electronSequence, _with94XScale_sequence)

_with_bitmapVIDForEleSpring15AndSum16_sequence = electronSequence.copy()
_with_bitmapVIDForEleSpring15AndSum16_sequence.replace(slimmedElectronsWithUserData, bitmapVIDForEleSpring15 + bitmapVIDForEleSum16 + slimmedElectronsWithUserData)
run2_nanoAOD_94X2016.toReplaceWith(electronSequence, _with_bitmapVIDForEleSpring15AndSum16_sequence)

Example #4
0
                           softActivityJets10 + finalJets + finalJetsAK8)

from RecoJets.JetProducers.QGTagger_cfi import QGTagger
qgtagger80x = QGTagger.clone(
    srcJets="slimmedJets", srcVertexCollection="offlineSlimmedPrimaryVertices")

_jetSequence_80X = jetSequence.copy()
_jetSequence_80X.replace(tightJetIdLepVeto, looseJetId)
_jetSequence_80X.replace(tightJetIdLepVetoAK8, looseJetIdAK8)
_jetSequence_80X.insert(1, qgtagger80x)
run2_miniAOD_80XLegacy.toReplaceWith(jetSequence, _jetSequence_80X)

_jetSequence_94X2016 = jetSequence.copy()
_jetSequence_94X2016.replace(tightJetIdLepVeto, looseJetId)
_jetSequence_94X2016.replace(tightJetIdLepVetoAK8, looseJetIdAK8)
run2_nanoAOD_94X2016.toReplaceWith(jetSequence, _jetSequence_94X2016)

#after cross linkining
jetTables = cms.Sequence(bjetMVA + bjetNN + jetTable + fatJetTable +
                         subJetTable + saJetTable + saTable)

#MC only producers and tables
jetMC = cms.Sequence(jetMCTable + genJetTable + patJetPartons +
                     genJetFlavourTable + genJetAK8Table +
                     genJetAK8FlavourAssociation + genJetAK8FlavourTable +
                     genSubJetAK8Table)
_jetMC_pre94X = jetMC.copy()
_jetMC_pre94X.insert(_jetMC_pre94X.index(genJetFlavourTable),
                     genJetFlavourAssociation)
_jetMC_pre94X.remove(genSubJetAK8Table)
run2_miniAOD_80XLegacy.toReplaceWith(jetMC, _jetMC_pre94X)
Example #5
0
        mvaSpring16GP_WP90 = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp90"),
        mvaSpring16GP_WP80 = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp80"),
        mvaSpring16HZZ_WPL = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-HZZ-V1-wpLoose"),
        cutbasedID_veto = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-veto"),
        cutbasedID_loose = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-loose"),
        cutbasedID_medium = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-medium"),
        cutbasedID_tight = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-tight"),
        cutbasedID_HLT = cms.InputTag("egmGsfElectronIDs:cutBasedElectronHLTPreselection-Summer16-V1"),
        cutbasedID_HEEP = cms.InputTag("egmGsfElectronIDs:heepElectronID-HEEPV70"),
    )
)
run2_nanoAOD_94X2016.toReplaceWith(slimmedElectronsWithUserData.userIntFromBools,
    cms.PSet(
        # MVAs and HEEP are already pre-computed. Cut-based too, but we re-add it for consistency with the nested bitmap
        cutbasedID_veto = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-veto"),
        cutbasedID_loose = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-loose"),
        cutbasedID_medium = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-medium"),
        cutbasedID_tight = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-tight"),
        cutbasedID_HLT = cms.InputTag("egmGsfElectronIDs:cutBasedElectronHLTPreselection-Summer16-V1"),
    )
)
finalElectrons = cms.EDFilter("PATElectronRefSelector",
    src = cms.InputTag("slimmedElectronsWithUserData"),
    cut = cms.string("pt > 5 ")
)

electronMVATTH= cms.EDProducer("EleBaseMVAValueMapProducer",
    src = cms.InputTag("linkedObjects","electrons"),
    weightFile =  cms.FileInPath("PhysicsTools/NanoAOD/data/el_BDTG_94X.weights.xml"),
    name = cms.string("electronMVATTH"),
    isClassifier = cms.bool(True),
    variablesOrder = cms.vstring(["LepGood_pt","LepGood_eta","LepGood_jetNDauChargedMVASel","LepGood_miniRelIsoCharged","LepGood_miniRelIsoNeutral","LepGood_jetPtRelv2","LepGood_jetBTagCSV","LepGood_jetPtRatio","LepGood_sip3d","LepGood_dxy","LepGood_dz","LepGood_mvaIdFall17noIso"]),
Example #6
0
def addLeptonSubtractedAK8Jets(process,
                               runOnMC,
                               era,
                               useFakeable,
                               addQJets=False):

    assert (era in ["2016", "2017", "2018"])
    suffix = "Fakeable" if useFakeable else "Loose"

    #----------------------------------------------------------------------------
    # produce collection of packedPFCandidates not associated to loose or fakeable electrons or muons
    (leptonSubtractedPFCandsSequence,
     leptonLessPU_str) = addLeptonSubtractedPFCands(process, era, useFakeable,
                                                    'puppi', runOnMC)
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # reconstruct lepton-subtracted AK8 jets
    bTagDiscriminators = [
        'pfCombinedInclusiveSecondaryVertexV2BJetTags',
        'pfBoostedDoubleSecondaryVertexAK8BJetTags', 'pfCombinedMVAV2BJetTags',
        'pfDeepCSVJetTags:probb', 'pfDeepCSVJetTags:probbb'
    ]
    JETCorrLevels = ['L1FastJet', 'L2Relative', 'L3Absolute']
    if not runOnMC:
        JETCorrLevels.append('L2L3Residual')

    jetSequenceAK8LS_str = 'jetSequenceAK8LS%s' % suffix
    NoLep_str = 'NoLep%s' % suffix
    jetToolbox(proc=process,
               jetType='ak8',
               jetSequence=jetSequenceAK8LS_str,
               outputFile='out',
               PUMethod='Puppi',
               JETCorrPayload='AK8PFPuppi',
               postFix=NoLep_str,
               JETCorrLevels=JETCorrLevels,
               miniAOD=True,
               runOnMC=runOnMC,
               newPFCollection=True,
               nameNewPFCollection=leptonLessPU_str,
               addSoftDrop=True,
               addSoftDropSubjets=True,
               addNsub=True,
               subJETCorrPayload='AK4PFPuppi',
               subJETCorrLevels=JETCorrLevels,
               bTagDiscriminators=bTagDiscriminators)
    # CV: fix ordering of modules in jet sequence
    #    (NjettinessAK8PuppiNoLep needs to be run before selectedPatJetsAK8PFPuppiNoLepSoftDropPacked)
    jetSequenceAK8LS = getattr(process, jetSequenceAK8LS_str)
    NjettinessAK8Puppi_str = 'NjettinessAK8Puppi%s' % NoLep_str
    jetSequenceAK8LS.remove(getattr(process, NjettinessAK8Puppi_str))
    jetSequenceAK8LS.replace(
        getattr(process, 'selectedPatJetsAK8PFPuppi%sSoftDropPacked' % NoLep_str),
        getattr(process, NjettinessAK8Puppi_str) + \
        getattr(process, 'selectedPatJetsAK8PFPuppi%sSoftDropPacked' % NoLep_str)
    )
    # CV: disable discriminators that cannot be computed with miniAOD inputs
    #for moduleName in [ "patJetsAK8LSPFPuppi", "patJetsAK8LSPFPuppiSoftDrop", "patJetsAK8LSPFPuppiSoftDropSubjets" ]:
    #    module = getattr(process, moduleName)
    #    module.discriminatorSources = cms.VInputTag()
    fatJetCollectionAK8LS_str = 'packedPatJetsAK8PFPuppi%sSoftDrop' % NoLep_str
    subJetCollectionAK8LS_str = 'selectedPatJetsAK8PFPuppi%sSoftDropPacked:SubJets' % NoLep_str
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # CV: add 'patJetPartons' module to 'genParticleSequence' (which runs at beginning of event processing),
    #     to avoid run-time exception of type:
    #
    #       ----- Begin Fatal Exception 22-Feb-2018 10:16:02 EET-----------------------
    #       An exception of category 'ScheduleExecutionFailure' occurred while
    #          [0] Calling beginJob
    #       Exception Message:
    #       Unrunnable schedule
    #       Module run order problem found:
    #       ...
    #        Running in the threaded framework would lead to indeterminate results.
    #        Please change order of modules in mentioned Path(s) to avoid inconsistent module ordering.
    #       ----- End Fatal Exception -------------------------------------------------
    if hasattr(process, "patJetPartons") and hasattr(
            process, "genParticleSequence") and runOnMC:
        process.genParticleSequence += process.patJetPartons
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # add PF jet ID flags and jet energy corrections for AK4 pat::Jet collection,
    # following what is done for lepton-subtracted AK8 pat::Jets in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/jets_cff.py
    looseJetIdAK8LS_str = 'looseJetIdAK8LS%s' % suffix
    setattr(
        process, looseJetIdAK8LS_str,
        process.looseJetIdAK8.clone(
            src=cms.InputTag(fatJetCollectionAK8LS_str)))
    tightJetIdAK8LS_str = 'tightJetIdAK8LS%s' % suffix
    setattr(
        process, tightJetIdAK8LS_str,
        process.tightJetIdAK8.clone(
            src=cms.InputTag(fatJetCollectionAK8LS_str)))
    for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
        tightJetIdAK8LS = getattr(process, tightJetIdAK8LS_str)
        modifier.toModify(tightJetIdAK8LS.filterParams, version="WINTER16")
    tightJetIdLepVetoAK8LS_str = 'tightJetIdLepVetoAK8LS%s' % suffix
    setattr(
        process, tightJetIdLepVetoAK8LS_str,
        process.tightJetIdLepVetoAK8.clone(
            src=cms.InputTag(fatJetCollectionAK8LS_str)))

    #----------------------------------------------------------------------------
    if addQJets:
        # compute edm::ValueMaps with Qjets volatility (arXiv:1001.5027),
        # following instructions posted by Andrea Marini on JetMET Hypernews (https://hypernews.cern.ch/HyperNews/CMS/get/JetMET/1790/1.html)
        if not hasattr(process, "RandomNumberGeneratorService"):
            process.RandomNumberGeneratorService = cms.Service(
                "RandomNumberGeneratorService")
        QJetsAdderAK8LS_str = 'QJetsAdderAK8LS%s' % suffix
        setattr(process.RandomNumberGeneratorService, QJetsAdderAK8LS_str,
                cms.PSet(initialSeed=cms.untracked.uint32(7)))
        setattr(
            process, QJetsAdderAK8LS_str,
            QJetsAdder.clone(src=cms.InputTag(fatJetCollectionAK8LS_str),
                             jetRad=cms.double(0.8),
                             jetAlgo=cms.string("AK")))
    subStructureAK8_str = "jetsAK8LSsubStructureVars%s" % suffix
    setattr(
        process, subStructureAK8_str,
        cms.EDProducer(
            "JetSubstructureObservableProducer",
            src=cms.InputTag(fatJetCollectionAK8LS_str),
            kappa=cms.double(1.),
        ))
    nb1AK8PuppiSoftDrop_str = 'nb1AK8PuppiSoftDrop%s' % suffix
    setattr(
        process, nb1AK8PuppiSoftDrop_str,
        ecfNbeta1.clone(
            src=cms.InputTag(fatJetCollectionAK8LS_str),
            cuts=cms.vstring('', '', 'pt > 250'),
        ))
    #----------------------------------------------------------------------------

    jetsAK8LSWithUserData_str = 'jetsAK8LSWithUserData%s' % suffix
    setattr(
        process, jetsAK8LSWithUserData_str,
        process.updatedJetsAK8WithUserData.clone(
            src=cms.InputTag(fatJetCollectionAK8LS_str),
            userFloats=cms.PSet(
                jetCharge=cms.InputTag("%s:jetCharge" % subStructureAK8_str),
                pull_dEta=cms.InputTag("%s:pullDEta" % subStructureAK8_str),
                pull_dPhi=cms.InputTag("%s:pullDPhi" % subStructureAK8_str),
                pull_dR=cms.InputTag("%s:pullDR" % subStructureAK8_str),
                n2b1=cms.InputTag("%s:ecfN2" % nb1AK8PuppiSoftDrop_str),
                n3b1=cms.InputTag("%s:ecfN3" % nb1AK8PuppiSoftDrop_str),
            ),
            userInts=cms.PSet(
                tightId=cms.InputTag(tightJetIdAK8LS_str),
                tightIdLepVeto=cms.InputTag(tightJetIdLepVetoAK8LS_str),
            )))
    if addQJets:
        jetsAK8LSWithUserData = getattr(process, jetsAK8LSWithUserData_str)
        jetsAK8LSWithUserData.userFloats.QjetVolatility = cms.InputTag(
            '%s:QjetsVolatility' % QJetsAdderAK8LS_str)

    for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
        jetsAK8LSWithUserData = getattr(process, jetsAK8LSWithUserData_str)
        modifier.toModify(
            jetsAK8LSWithUserData.userInts,
            looseId=cms.InputTag(looseJetIdAK8LS_str),
            tightIdLepVeto=None,
        )
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    subStructureSubJetAK8_str = "subJetsAK8LSsubStructureVars%s" % suffix
    setattr(
        process, subStructureSubJetAK8_str,
        cms.EDProducer(
            "JetSubstructureObservableProducer",
            src=cms.InputTag(subJetCollectionAK8LS_str),
            kappa=cms.double(1.),
        ))
    ecfNbeta1_str = "nb1AK8LSPuppiSoftDropSubjets%s" % suffix
    setattr(process, ecfNbeta1_str,
            ecfNbeta1.clone(src=cms.InputTag(subJetCollectionAK8LS_str), ))
    Njettiness_str = "NjettinessAK8LSSubjets%s" % suffix
    setattr(process, Njettiness_str,
            Njettiness.clone(src=cms.InputTag(subJetCollectionAK8LS_str), ))
    subJetsAK8LSWithUserData_str = 'subJetsAK8LSWithUserData%s' % suffix
    setattr(
        process, subJetsAK8LSWithUserData_str,
        cms.EDProducer(
            "PATJetUserDataEmbedder",
            src=cms.InputTag(subJetCollectionAK8LS_str),
            userFloats=cms.PSet(
                jetCharge=cms.InputTag("%s:jetCharge" %
                                       subStructureSubJetAK8_str),
                pull_dEta=cms.InputTag("%s:pullDEta" %
                                       subStructureSubJetAK8_str),
                pull_dPhi=cms.InputTag("%s:pullDPhi" %
                                       subStructureSubJetAK8_str),
                pull_dR=cms.InputTag("%s:pullDR" % subStructureSubJetAK8_str),
                n2b1=cms.InputTag("%s:ecfN2" % ecfNbeta1_str),
                n3b1=cms.InputTag("%s:ecfN3" % ecfNbeta1_str),
                tau1=cms.InputTag("%s:tau1" % Njettiness_str),
                tau2=cms.InputTag("%s:tau2" % Njettiness_str),
                tau3=cms.InputTag("%s:tau3" % Njettiness_str),
                tau4=cms.InputTag("%s:tau4" % Njettiness_str),
            ),
            userInts=cms.PSet(),
        ))
    #----------------------------------------------------------------------------
    # add lepton-subtracted AK8 jets to nanoAOD Ntuple
    fatJetAK8LSTable_str = 'fatJetAK8LS%sTable' % suffix  # NB! must end with 'Table'
    setattr(
        process, fatJetAK8LSTable_str,
        process.fatJetTable.clone(
            src=cms.InputTag(jetsAK8LSWithUserData_str),
            cut=cms.string("pt > 80 && abs(eta) < 2.4"),
            name=cms.string("FatJetAK8LS%s" % suffix),
            doc=cms.string(
                "lepton-subtracted ak8 fat jets for boosted analysis"),
        ))
    fatJetAK8LSTable = getattr(process, fatJetAK8LSTable_str)
    fatJetAK8LSTable.variables.msoftdrop.expr = cms.string(
        "userFloat('ak8PFJetsPuppi%sSoftDropMass')" % NoLep_str)
    fatJetAK8LSTable.variables.subJetIdx1.expr = cms.string(
        "?subjets('SoftDrop').size()>0?subjets('SoftDrop').at(0).key():-1")
    fatJetAK8LSTable.variables.subJetIdx2.expr = cms.string(
        "?subjets('SoftDrop').size()>1?subjets('SoftDrop').at(1).key():-1")
    fatJetAK8LSTable.variables.tau1.expr = cms.string("userFloat('%s:tau1')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.tau2.expr = cms.string("userFloat('%s:tau2')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.tau3.expr = cms.string("userFloat('%s:tau3')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.tau4.expr = cms.string("userFloat('%s:tau4')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.tau4.expr = cms.string("userFloat('%s:tau4')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.tau4.expr = cms.string("userFloat('%s:tau4')" %
                                                      NjettinessAK8Puppi_str)
    fatJetAK8LSTable.variables.n2b1.expr = cms.string("userFloat('n2b1')")
    fatJetAK8LSTable.variables.n3b1.expr = cms.string("userFloat('n3b1')")
    if addQJets:
        fatJetAK8LSTable.variables.QjetVolatility = Var(
            "userFloat('QjetVolatility')",
            float,
            doc="Qjets volatility, computed according to arXiv:1201.1914",
            precision=10)
        print("Adding Qjet volatility to %s" % jetsAK8LSWithUserData_str)
    else:
        print("NOT adding Qjet volatility to %s" % jetsAK8LSWithUserData_str)

    #----------------------------------------------------------------------------

    if runOnMC:
        #----------------------------------------------------------------------------
        # produce lepton-subtracted generator-level jets
        genjetAK8LS_str = 'genJetAK8LS'
        if not hasattr(process, genjetAK8LS_str):
            setattr(
                process, genjetAK8LS_str,
                ak8GenJets.clone(
                    src=cms.InputTag(LEPTONLESSGENPARTICLEPRODUCER_STR)))

        # add lepton-subtracted generator-level jets to nanoAOD Ntuple
        genjetAK8LSTable_str = 'genJetAK8LSTable'
        if not hasattr(process, genjetAK8LSTable_str):
            setattr(
                process, genjetAK8LSTable_str,
                process.genJetAK8Table.clone(
                    src=cms.InputTag(genjetAK8LS_str),
                    name=cms.string("GenJetAK8LS"),
                    doc=cms.string(
                        "genJetsAK8LS, i.e. ak8 Jets made with visible genparticles excluding prompt leptons and leptons from tau decays"
                    ),
                ))

        # add information on generator-level parton flavor to reconstructed jets
        genJetFlavourAssociationAK8LS_str = 'genJetFlavourAssociationAK8LS%s' % suffix
        setattr(
            process, genJetFlavourAssociationAK8LS_str,
            process.genJetAK8FlavourAssociation.clone(
                jets=cms.InputTag(genjetAK8LS_str)))

        genJetFlavourAK8LSTable = 'genJetFlavourAK8LS%sTable' % suffix  # NB! must end with 'Table'
        setattr(
            process, genJetFlavourAK8LSTable,
            process.genJetAK8FlavourTable.clone(
                src=cms.InputTag(genjetAK8LS_str),
                name=cms.string("GenJetAK8LS"),
                jetFlavourInfos=cms.InputTag(
                    genJetFlavourAssociationAK8LS_str)))
        genSubJetAK8LS_str = "ak8GenJetsNoNuSoftDrop%s" % NoLep_str
        genSubJetAK8Table_str = 'genSubJetAK8LS%sTable' % suffix  # NB! must end with 'Table'
        setattr(
            process,
            genSubJetAK8Table_str,
            process.genSubJetAK8Table.clone(
                src=cms.InputTag(genSubJetAK8LS_str, "SubJets"),
                cut=cms.string("pt > 8"),  # same as for AK4 gen jets
                name=cms.string("SubGenJetAK8LS%s" % suffix),
                doc=cms.string(
                    "%s, i.e. subjets of ak8LS Jets made with visible genparticles"
                    % genSubJetAK8LS_str),
            ))
    #----------------------------------------------------------------------------
    subJetAK8LSTable_str = 'subJetAK8LS%sTable' % suffix  # NB! must end with 'Table'
    setattr(
        process, subJetAK8LSTable_str,
        process.subJetTable.clone(
            src=cms.InputTag(subJetsAK8LSWithUserData_str),
            cut=cms.string(""),
            name=cms.string("SubJetAK8LS%s" % suffix),
            doc=cms.string(
                "lepton-subtracted ak8  sub-jets for boosted analysis"),
        ))
    subJetAK8LSTable = getattr(process, subJetAK8LSTable_str)
    for var in ['n2b1', 'n3b1', 'tau1', 'tau2', 'tau3', 'tau4']:
        getattr(subJetAK8LSTable.variables,
                var).expr = cms.string("userFloat('%s')" % var)
    run2_miniAOD_80XLegacy.toModify(subJetAK8LSTable.variables,
                                    btagCMVA=None,
                                    btagDeepB=None)

    leptonSubtractedJetSequence = cms.Sequence(
        leptonSubtractedPFCandsSequence +
        getattr(process, jetSequenceAK8LS_str) +
        getattr(process, tightJetIdAK8LS_str) +
        getattr(process, tightJetIdLepVetoAK8LS_str) +
        getattr(process, subStructureAK8_str) +
        getattr(process, nb1AK8PuppiSoftDrop_str) +
        getattr(process, jetsAK8LSWithUserData_str) +
        getattr(process, subStructureSubJetAK8_str) +
        getattr(process, ecfNbeta1_str) + getattr(process, Njettiness_str) +
        getattr(process, subJetsAK8LSWithUserData_str) +
        getattr(process, fatJetAK8LSTable_str) +
        getattr(process, subJetAK8LSTable_str))
    if addQJets:
        leptonSubtractedJetSequence.replace(
            getattr(process, jetsAK8LSWithUserData_str),
            getattr(process, QJetsAdderAK8LS_str) +
            getattr(process, jetsAK8LSWithUserData_str))
    if runOnMC:
        leptonSubtractedJetSequence += getattr(process, genjetAK8LS_str) + \
                                       getattr(process, genjetAK8LSTable_str) + \
                                       getattr(process, genJetFlavourAssociationAK8LS_str) + \
                                       getattr(process, genJetFlavourAK8LSTable) + \
                                       getattr(process, genSubJetAK8Table_str)

    _leptonSubtractedJetSequence_80X = leptonSubtractedJetSequence.copy()
    _leptonSubtractedJetSequence_80X.replace(
        getattr(process, tightJetIdLepVetoAK8LS_str),
        getattr(process, looseJetIdAK8LS_str))
    run2_miniAOD_80XLegacy.toReplaceWith(leptonSubtractedJetSequence,
                                         _leptonSubtractedJetSequence_80X)

    _leptonSubtractedJetSequence_94X2016 = leptonSubtractedJetSequence.copy()
    _leptonSubtractedJetSequence_94X2016.replace(
        getattr(process, tightJetIdLepVetoAK8LS_str),
        getattr(process, looseJetIdAK8LS_str))
    run2_nanoAOD_94X2016.toReplaceWith(leptonSubtractedJetSequence,
                                       _leptonSubtractedJetSequence_94X2016)

    leptonSubtractedJetSequence_str = 'leptonSubtractedJetSequenceAK8LS%s' % suffix
    setattr(process, leptonSubtractedJetSequence_str,
            leptonSubtractedJetSequence)
    process.nanoSequence += getattr(process, leptonSubtractedJetSequence_str)
    process.nanoSequenceMC += getattr(process, leptonSubtractedJetSequence_str)
    process.nanoSequenceFS += getattr(process, leptonSubtractedJetSequence_str)
def addLeptonSubtractedAK4Jets(process, runOnMC, era, useFakeable):

    assert (era in ["2016", "2017", "2018"])
    suffix = "Fakeable" if useFakeable else "Loose"

    #----------------------------------------------------------------------------
    # produce collection of packedPFCandidates not associated to loose or fakeable electrons or muons
    (leptonSubtractedPFCandsSequence,
     leptonLessPU_str) = addLeptonSubtractedPFCands(process, era, useFakeable,
                                                    'chs', runOnMC)
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # reconstruct lepton-subtracted AK4 jets
    bTagDiscriminators = [
        'pfCombinedInclusiveSecondaryVertexV2BJetTags',
        'pfCombinedMVAV2BJetTags',
    ]
    JETCorrLevels = ['L1FastJet', 'L2Relative', 'L3Absolute']
    if not runOnMC:
        JETCorrLevels.append('L2L3Residual')

    jetSequenceAK4LS_str = 'jetSequenceAK4LS%s' % suffix
    NoLep_str = 'NoLep%s' % suffix
    jetToolbox(
        proc=process,
        jetType='ak4',
        jetSequence=jetSequenceAK4LS_str,
        outputFile='out',
        PUMethod='CHS',
        JETCorrPayload='AK4PFchs',
        postFix=NoLep_str,
        JETCorrLevels=JETCorrLevels,
        miniAOD=True,
        runOnMC=runOnMC,
        newPFCollection=True,
        nameNewPFCollection=leptonLessPU_str,
        bTagDiscriminators=bTagDiscriminators,
    )
    slimmedJetCollectionAK4LS_str = 'selectedPatJetsAK4PFCHS%s' % NoLep_str

    bTagDiscriminators_ = [
        'pfDeepCSVJetTags:probb',
        'pfDeepCSVJetTags:probbb',
        'pfDeepCSVJetTags:probc',
        'pfDeepFlavourJetTags:probb',
        'pfDeepFlavourJetTags:probbb',
        'pfDeepFlavourJetTags:problepb',
        'pfDeepFlavourJetTags:probc',
    ]
    deepInfoSuffix = 'PlusDeepInfo%s' % NoLep_str
    updateJetCollection(
        process,
        jetSource=cms.InputTag(slimmedJetCollectionAK4LS_str),
        jetCorrections=('AK4PFchs', cms.vstring(JETCorrLevels), 'None'),
        btagDiscriminators=bTagDiscriminators_,
        postfix=deepInfoSuffix,
    )
    jetCollectionAK4LS_str = "selectedUpdatedPatJets%s" % deepInfoSuffix
    getattr(process, jetCollectionAK4LS_str).cut = cms.string('pt > 15')

    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # CV: add 'patJetPartons' module to 'genParticleSequence' (which runs at beginning of event processing),
    #     to avoid run-time exception of type:
    #
    #       ----- Begin Fatal Exception 22-Feb-2018 10:16:02 EET-----------------------
    #       An exception of category 'ScheduleExecutionFailure' occurred while
    #          [0] Calling beginJob
    #       Exception Message:
    #       Unrunnable schedule
    #       Module run order problem found:
    #       ...
    #        Running in the threaded framework would lead to indeterminate results.
    #        Please change order of modules in mentioned Path(s) to avoid inconsistent module ordering.
    #       ----- End Fatal Exception -------------------------------------------------
    if hasattr(process, "patJetPartons") and hasattr(
            process, "genParticleSequence") and runOnMC:
        process.genParticleSequence += process.patJetPartons
    #----------------------------------------------------------------------------

    #----------------------------------------------------------------------------
    # add PF jet ID flags and jet energy corrections for AK4 pat::Jet collection,
    # following what is done for non-lepton-subtracted AK4 pat::Jets in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/jets_cff.py
    looseJetIdAK4LS_str = 'looseJetIdAK4LS%s' % suffix
    setattr(process, looseJetIdAK4LS_str,
            process.looseJetId.clone(src=cms.InputTag(jetCollectionAK4LS_str)))
    tightJetIdAK4LS_str = 'tightJetIdAK4LS%s' % suffix
    setattr(process, tightJetIdAK4LS_str,
            process.tightJetId.clone(src=cms.InputTag(jetCollectionAK4LS_str)))
    for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
        tightJetIdAK4LS = getattr(process, tightJetIdAK4LS_str)
        modifier.toModify(tightJetIdAK4LS.filterParams, version="WINTER16")
    tightJetIdLepVetoAK4LS_str = 'tightJetIdLepVetoAK4LS%s' % suffix
    setattr(
        process, tightJetIdLepVetoAK4LS_str,
        process.tightJetIdLepVeto.clone(
            src=cms.InputTag(jetCollectionAK4LS_str)))

    #----------------------------------------------------------------------------

    bJetVars_str = 'bJetVarsAK4LS%s' % suffix
    setattr(process, bJetVars_str,
            process.bJetVars.clone(src=cms.InputTag(jetCollectionAK4LS_str)))

    qgtagger_str = 'qgtaggerAK4LS%s' % suffix
    setattr(
        process, qgtagger_str,
        process.qgtagger.clone(srcJets=cms.InputTag(jetCollectionAK4LS_str)))

    # ----------------------------------------------------------------------------

    jetSubStructureVars_str = 'jetSubStructureVars%s' % NoLep_str
    setattr(
        process, jetSubStructureVars_str,
        cms.EDProducer(
            "JetSubstructureObservableProducer",
            src=cms.InputTag(jetCollectionAK4LS_str),
            kappa=cms.double(1.),
        ))

    # ----------------------------------------------------------------------------

    pileupJetId_str = 'pileupJetId%s' % NoLep_str
    setattr(
        process, pileupJetId_str,
        pileupJetId.clone(
            jets=cms.InputTag(jetCollectionAK4LS_str),
            inputIsCorrected=True,
            applyJec=False,
            vertexes="offlineSlimmedPrimaryVertices",
        ))

    # ----------------------------------------------------------------------------

    jetsAK4LSWithUserData_str = 'jetsAK4LSWithUserData%s' % suffix
    setattr(
        process, jetsAK4LSWithUserData_str,
        process.updatedJetsWithUserData.clone(
            src=cms.InputTag(jetCollectionAK4LS_str),
            userFloats=cms.PSet(
                leadTrackPt=cms.InputTag("%s:leadTrackPt" % bJetVars_str),
                leptonPtRel=cms.InputTag("%s:leptonPtRel" % bJetVars_str),
                leptonPtRatio=cms.InputTag("%s:leptonPtRatio" % bJetVars_str),
                leptonPtRelInv=cms.InputTag("%s:leptonPtRelInv" %
                                            bJetVars_str),
                leptonPtRelv0=cms.InputTag("%s:leptonPtRelv0" % bJetVars_str),
                leptonPtRatiov0=cms.InputTag("%s:leptonPtRatiov0" %
                                             bJetVars_str),
                leptonPtRelInvv0=cms.InputTag("%s:leptonPtRelInvv0" %
                                              bJetVars_str),
                leptonDeltaR=cms.InputTag("%s:leptonDeltaR" % bJetVars_str),
                leptonPt=cms.InputTag("%s:leptonPt" % bJetVars_str),
                vtxPt=cms.InputTag("%s:vtxPt" % bJetVars_str),
                vtxMass=cms.InputTag("%s:vtxMass" % bJetVars_str),
                vtx3dL=cms.InputTag("%s:vtx3dL" % bJetVars_str),
                vtx3deL=cms.InputTag("%s:vtx3deL" % bJetVars_str),
                ptD=cms.InputTag("%s:ptD" % bJetVars_str),
                genPtwNu=cms.InputTag("%s:genPtwNu" % bJetVars_str),
                qgl=cms.InputTag("%s:qgLikelihood" % qgtagger_str),
                jetCharge=cms.InputTag("%s:jetCharge" %
                                       jetSubStructureVars_str),
                pull_dEta=cms.InputTag("%s:pullDEta" %
                                       jetSubStructureVars_str),
                pull_dPhi=cms.InputTag("%s:pullDPhi" %
                                       jetSubStructureVars_str),
                pull_dR=cms.InputTag("%s:pullDR" % jetSubStructureVars_str),
                puIdDisc=cms.InputTag("%s:fullDiscriminant" % pileupJetId_str),
            ),
            userInts=cms.PSet(
                tightId=cms.InputTag(tightJetIdAK4LS_str),
                tightIdLepVeto=cms.InputTag(tightJetIdLepVetoAK4LS_str),
                vtxNtrk=cms.InputTag("%s:vtxNtrk" % bJetVars_str),
                leptonPdgId=cms.InputTag("%s:leptonPdgId" % bJetVars_str),
                puId=cms.InputTag("%s:fullId" % pileupJetId_str),
            )))
    for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94X2016:
        modifier.toModify(
            getattr(process, jetsAK4LSWithUserData_str).userInts,
            looseId=cms.InputTag(looseJetIdAK4LS_str),
        )
    #----------------------------------------------------------------------------

    bjetNN_str = 'bjetNN%s' % NoLep_str
    setattr(
        process, bjetNN_str,
        process.bjetNN.clone(src=cms.InputTag(jetsAK4LSWithUserData_str), ))

    #----------------------------------------------------------------------------

    # add lepton-subtracted AK4 jets to nanoAOD Ntuple
    jetAK4LSTable_str = 'jetAK4LS%sTable' % suffix  # NB! must end with 'Table'
    setattr(
        process, jetAK4LSTable_str,
        process.jetTable.clone(
            src=cms.InputTag(jetsAK4LSWithUserData_str),
            name=cms.string("JetAK4LS%s" % suffix),
            doc=cms.string("lepton-subtracted ak4 jets"),
            externalVariables=cms.PSet(
                bRegCorr=ExtVar(
                    cms.InputTag("%s:corr" % bjetNN_str),
                    float,
                    doc="pt correction for b-jet energy regression",
                    precision=12),
                bRegRes=ExtVar(cms.InputTag("%s:res" % bjetNN_str),
                               float,
                               doc="res on pt corrected with b-jet regression",
                               precision=8),
            )))
    getattr(process,
            jetAK4LSTable_str).variables.puId = Var("userInt('puId')",
                                                    int,
                                                    doc="Pilup ID flags")
    getattr(process, jetAK4LSTable_str).variables.puIdDisc = Var(
        "userFloat('puIdDisc')", float, doc="Pilup ID discriminant")

    if runOnMC:
        getattr(process, jetAK4LSTable_str).variables.partonFlavour = Var(
            "partonFlavour()", int, doc="flavour from parton matching")
        getattr(process, jetAK4LSTable_str).variables.hadronFlavour = Var(
            "hadronFlavour()", int, doc="flavour from hadron ghost clustering")
        getattr(process, jetAK4LSTable_str).variables.genJetIdx = Var(
            "?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1",
            int,
            doc="index of matched gen jet")

        #----------------------------------------------------------------------------
        # produce lepton-subtracted generator-level jets
        genjetAK4LS_str = 'genJetAK4LS'
        if not hasattr(process, genjetAK4LS_str):
            setattr(
                process, genjetAK4LS_str,
                ak4GenJets.clone(
                    src=cms.InputTag(LEPTONLESSGENPARTICLEPRODUCER_STR)))

        # add lepton-subtracted generator-level jets to nanoAOD Ntuple
        genjetAK4LSTable_str = 'genJetAK4LSTable'
        if not hasattr(process, genjetAK4LSTable_str):
            setattr(
                process, genjetAK4LSTable_str,
                process.genJetTable.clone(
                    src=cms.InputTag(genjetAK4LS_str),
                    name=cms.string("GenJetAK4LS"),
                    doc=cms.string(
                        "genJetsAK4LS, i.e. ak4 Jets made with visible genparticles excluding prompt leptons and leptons from tau decays"
                    ),
                ))

        # add information on generator-level parton flavor to reconstructed jets
        genJetFlavourAssociationAK4LS_str = 'genJetFlavourAssociationAK4LS%s' % suffix
        setattr(
            process, genJetFlavourAssociationAK4LS_str,
            process.genJetFlavourAssociation.clone(
                jets=cms.InputTag(genjetAK4LS_str)))

        genJetFlavourAK4LSTable = 'genJetFlavourAK4LS%sTable' % suffix  # NB! must end with 'Table'
        setattr(
            process, genJetFlavourAK4LSTable,
            process.genJetFlavourTable.clone(
                src=cms.InputTag(genjetAK4LS_str),
                name=cms.string("GenJetAK4LS"),
                jetFlavourInfos=cms.InputTag(
                    genJetFlavourAssociationAK4LS_str)))
        #----------------------------------------------------------------------------

    leptonSubtractedJetSequence = cms.Sequence(
        leptonSubtractedPFCandsSequence +
        getattr(process, jetSequenceAK4LS_str) +
        getattr(process, slimmedJetCollectionAK4LS_str) +
        getattr(process, tightJetIdAK4LS_str) +
        getattr(process, tightJetIdLepVetoAK4LS_str) +
        getattr(process, bJetVars_str) + getattr(process, qgtagger_str) +
        getattr(process, jetSubStructureVars_str) +
        getattr(process, pileupJetId_str) +
        getattr(process, jetsAK4LSWithUserData_str) +
        getattr(process, bjetNN_str) + getattr(process, jetAK4LSTable_str))
    if runOnMC:
        leptonSubtractedJetSequence += getattr(
            process, genjetAK4LS_str) + getattr(process, genjetAK4LSTable_str)
        leptonSubtractedJetSequence += getattr(
            process, genJetFlavourAssociationAK4LS_str) + getattr(
                process, genJetFlavourAK4LSTable)

    #----------------------------------------------------------------------------

    _leptonSubtractedJetSequence_80X = leptonSubtractedJetSequence.copy()
    _leptonSubtractedJetSequence_80X.insert(
        _leptonSubtractedJetSequence_80X.index(
            getattr(process, tightJetIdAK4LS_str)),
        getattr(process, looseJetIdAK4LS_str))
    run2_miniAOD_80XLegacy.toReplaceWith(leptonSubtractedJetSequence,
                                         _leptonSubtractedJetSequence_80X)

    _leptonSubtractedJetSequence_94X2016 = leptonSubtractedJetSequence.copy()
    _leptonSubtractedJetSequence_94X2016.insert(
        _leptonSubtractedJetSequence_94X2016.index(
            getattr(process, tightJetIdAK4LS_str)),
        getattr(process, looseJetIdAK4LS_str))
    run2_nanoAOD_94X2016.toReplaceWith(leptonSubtractedJetSequence,
                                       _leptonSubtractedJetSequence_94X2016)

    leptonSubtractedJetSequence_str = 'leptonSubtractedJetSequenceAK4LS%s' % suffix
    setattr(process, leptonSubtractedJetSequence_str,
            leptonSubtractedJetSequence)
    process.nanoSequence += getattr(process, leptonSubtractedJetSequence_str)
    process.nanoSequenceMC += getattr(process, leptonSubtractedJetSequence_str)
    process.nanoSequenceFS += getattr(process, leptonSubtractedJetSequence_str)