def configureZllRecoilCorrection(process,
                                 diTauProducerModuleName,
                                 ZllRecoilCorrectionType,
                                 shiftByUncertainty=0.,
                                 label=""):

    #print("<configureZllRecoilCorrection>:")

    process.load("TauAnalysis.RecoTools.recoZllRecoilCorrection_cfi")

    retVal = {}

    patPFMETsZllRecoilCorrectionModule = cms.EDProducer(
        ZllRecoilCorrectionType,
        process.recoZllRecoilCorrectionParameter,
        src=cms.InputTag(diTauProducerModuleName))
    patPFMETsZllRecoilCorrectionModule.shiftByUncertainty = cms.double(
        shiftByUncertainty)
    retVal[
        'patPFMETsZllRecoilCorrectionModule'] = patPFMETsZllRecoilCorrectionModule
    patPFMETsZllRecoilCorrectionModuleName = composeModuleName(
        ["patPFMETsZllRecoilCorrected", diTauProducerModuleName, label])
    setattr(process, patPFMETsZllRecoilCorrectionModuleName,
            patPFMETsZllRecoilCorrectionModule)
    retVal[
        'patPFMETsZllRecoilCorrectionModuleName'] = patPFMETsZllRecoilCorrectionModuleName

    diTauProducerModule = getattr(process, diTauProducerModuleName)

    diTauProducerModuleZllRecoilCorrected = diTauProducerModule.clone()
    diTauProducerModuleZllRecoilCorrected.srcMET = \
      cms.InputTag(patPFMETsZllRecoilCorrectionModuleName, 'met')
    diTauProducerModuleZllRecoilCorrected.srcReRecoDiTauObjects = \
      cms.InputTag(diTauProducerModuleName)
    diTauProducerModuleZllRecoilCorrected.srcReRecoDiTauToMEtAssociations = \
      cms.InputTag(patPFMETsZllRecoilCorrectionModuleName, 'diTauToMEtAssociations')
    retVal[
        'diTauProducerModuleZllRecoilCorrected'] = diTauProducerModuleZllRecoilCorrected
    diTauProducerModuleZllRecoilCorrectedName = composeModuleName(
        [diTauProducerModuleName, "ZllRecoilCorrected", label])
    setattr(process, diTauProducerModuleZllRecoilCorrectedName,
            diTauProducerModuleZllRecoilCorrected)
    retVal[
        'diTauProducerModuleZllRecoilCorrectedName'] = diTauProducerModuleZllRecoilCorrectedName

    patPFMETsZllRecoilCorrectionSequence = cms.Sequence(
        patPFMETsZllRecoilCorrectionModule *
        diTauProducerModuleZllRecoilCorrected)
    retVal[
        'patPFMETsZllRecoilCorrectionSequence'] = patPFMETsZllRecoilCorrectionSequence
    patPFMETsZllRecoilCorrectionSequenceName = \
      composeModuleName([ "patPFMETsZllRecoilCorrectionSequence", diTauProducerModuleName, label ])
    setattr(process, patPFMETsZllRecoilCorrectionSequenceName,
            patPFMETsZllRecoilCorrectionSequence)
    retVal[
        'patPFMETsZllRecoilCorrectionSequenceName'] = patPFMETsZllRecoilCorrectionSequenceName

    return retVal
def configureZllRecoilCorrection(
    process, diTauProducerModuleName, ZllRecoilCorrectionType, shiftByUncertainty=0.0, label=""
):

    # print("<configureZllRecoilCorrection>:")

    process.load("TauAnalysis.RecoTools.recoZllRecoilCorrection_cfi")

    retVal = {}

    patPFMETsZllRecoilCorrectionModule = cms.EDProducer(
        ZllRecoilCorrectionType, process.recoZllRecoilCorrectionParameter, src=cms.InputTag(diTauProducerModuleName)
    )
    patPFMETsZllRecoilCorrectionModule.shiftByUncertainty = cms.double(shiftByUncertainty)
    retVal["patPFMETsZllRecoilCorrectionModule"] = patPFMETsZllRecoilCorrectionModule
    patPFMETsZllRecoilCorrectionModuleName = composeModuleName(
        ["patPFMETsZllRecoilCorrected", diTauProducerModuleName, label]
    )
    setattr(process, patPFMETsZllRecoilCorrectionModuleName, patPFMETsZllRecoilCorrectionModule)
    retVal["patPFMETsZllRecoilCorrectionModuleName"] = patPFMETsZllRecoilCorrectionModuleName

    diTauProducerModule = getattr(process, diTauProducerModuleName)

    diTauProducerModuleZllRecoilCorrected = diTauProducerModule.clone()
    diTauProducerModuleZllRecoilCorrected.srcMET = cms.InputTag(patPFMETsZllRecoilCorrectionModuleName, "met")
    diTauProducerModuleZllRecoilCorrected.srcReRecoDiTauObjects = cms.InputTag(diTauProducerModuleName)
    diTauProducerModuleZllRecoilCorrected.srcReRecoDiTauToMEtAssociations = cms.InputTag(
        patPFMETsZllRecoilCorrectionModuleName, "diTauToMEtAssociations"
    )
    retVal["diTauProducerModuleZllRecoilCorrected"] = diTauProducerModuleZllRecoilCorrected
    diTauProducerModuleZllRecoilCorrectedName = composeModuleName(
        [diTauProducerModuleName, "ZllRecoilCorrected", label]
    )
    setattr(process, diTauProducerModuleZllRecoilCorrectedName, diTauProducerModuleZllRecoilCorrected)
    retVal["diTauProducerModuleZllRecoilCorrectedName"] = diTauProducerModuleZllRecoilCorrectedName

    patPFMETsZllRecoilCorrectionSequence = cms.Sequence(
        patPFMETsZllRecoilCorrectionModule * diTauProducerModuleZllRecoilCorrected
    )
    retVal["patPFMETsZllRecoilCorrectionSequence"] = patPFMETsZllRecoilCorrectionSequence
    patPFMETsZllRecoilCorrectionSequenceName = composeModuleName(
        ["patPFMETsZllRecoilCorrectionSequence", diTauProducerModuleName, label]
    )
    setattr(process, patPFMETsZllRecoilCorrectionSequenceName, patPFMETsZllRecoilCorrectionSequence)
    retVal["patPFMETsZllRecoilCorrectionSequenceName"] = patPFMETsZllRecoilCorrectionSequenceName

    return retVal
    def _addModule(self, objProdItem, sysName, sysAttributes, pyNameSpace = None, process = None):
        # create module
        moduleType = objProdItem.type_()
        module = cms.EDProducer(moduleType)

        # set module attributes
        # to default values
        for objProdAttrName in dir(objProdItem):
            objProdAttr = getattr(objProdItem, objProdAttrName)
            if isinstance(objProdAttr, cms._ParameterTypeBase) and not objProdAttrName in [ "pluginName", "pluginType" ]:
                if isinstance(objProdAttr, cms.PSet):
                    # CV: need to clone configuration parameters of type cms.PSet,...
                    #     in order to avoid that recursiveSetAttr function
                    #     overwrites objProd "template" object passed to objProdConfigurator constructor !!
                    setattr(module, objProdAttrName, objProdAttr.clone())
                else:
                    setattr(module, objProdAttrName, objProdAttr)

        # set names of source collections
        # to objects shifted in energy/transverse momentum, theta, phi...
        for sysAttrName, sysAttrValue in sysAttributes.items():
            recursiveSetAttr(module, sysAttrName, sysAttrValue)
                
        moduleName = composeModuleName([ getInstanceName(objProdItem, pyNameSpace, process), sysName ])
        module.setLabel(moduleName)

        # if process object exists, attach module to process object;
        # else register module in global python name-space
        if process is not None:
            setattr(process, moduleName, module)
        else:
            pyModule = sys.modules[self.pyModuleName[0]]
            if pyModule is None:
                raise ValueError("'pyModuleName' Parameter invalid !!")
            setattr(pyModule, moduleName, module)

        # add module to sequence
        if self.sequence == None:
            self.sequence = module
        else:
            self.sequence *= module
    def _addModule(self, objProdItem, sysName, sysAttributes, pyNameSpace = None, process = None):
        # create module
        moduleType = objProdItem.type_()
        module = cms.EDProducer(moduleType)

        # set module attributes
        # to default values
        for objProdAttrName in dir(objProdItem):
            objProdAttr = getattr(objProdItem, objProdAttrName)
            if isinstance(objProdAttr, cms._ParameterTypeBase) and not objProdAttrName in [ "pluginName", "pluginType" ]:
                if isinstance(objProdAttr, cms.PSet):
                    # CV: need to clone configuration parameters of type cms.PSet,...
                    #     in order to avoid that recursiveSetAttr function
                    #     overwrites objProd "template" object passed to objProdConfigurator constructor !!
                    setattr(module, objProdAttrName, objProdAttr.clone())
                else:
                    setattr(module, objProdAttrName, objProdAttr)

        # set names of source collections
        # to objects shifted in energy/transverse momentum, theta, phi...
        for sysAttrName, sysAttrValue in sysAttributes.items():
            recursiveSetAttr(module, sysAttrName, sysAttrValue)
                
        moduleName = composeModuleName([ getInstanceName(objProdItem, pyNameSpace, process), sysName ])
        #print "moduleName = %s" % moduleName
        module.setLabel(moduleName)

        # if process object exists, attach module to process object;
        # else register module in global python name-space
        if process is not None:
            setattr(process, moduleName, module)
        else:
            pyModule = sys.modules[self.pyModuleName[0]]
            if pyModule is None:
                raise ValueError("'pyModuleName' Parameter invalid !!")
            setattr(pyModule, moduleName, module)

        # add module to sequence
        self.sequence += module
def configurePatTupleProductionTauIdEffMeasSpecific(
        process,
        patSequenceBuilder=buildGenericTauSequence,
        hltProcess="HLT",
        isMC=False,
        isEmbedded=False,
        runSVfit=False):

    # check that patSequenceBuilder and patTauCleanerPrototype are defined and non-null
    if patSequenceBuilder is None:
        raise ValueError("Undefined 'patSequenceBuilder' Parameter !!")

    #--------------------------------------------------------------------------------
    # produce "basic" PAT objects
    #--------------------------------------------------------------------------------

    process.load("PhysicsTools.PatAlgos.cleaningLayer1.tauCleaner_cfi")
    patCaloTauCleanerPrototype = process.cleanPatTaus.clone(
        preselection=cms.string(''),
        checkOverlaps=cms.PSet(),
        finalCut=cms.string(
            'caloTauTagInfoRef().jetRef().pt() > 5 & abs(caloTauTagInfoRef().jetRef().eta()) < 2.5'
        ))
    patPFTauCleanerPrototype = process.cleanPatTaus.clone(
        preselection=cms.string(''),
        checkOverlaps=cms.PSet(),
        finalCut=cms.string(
            'pfJetRef().pt() > 5 & abs(pfJetRef().eta()) < 2.5'))

    patTupleConfig = configurePatTupleProduction(process, patSequenceBuilder,
                                                 patPFTauCleanerPrototype,
                                                 patCaloTauCleanerPrototype,
                                                 True, hltProcess, isMC, False)

    if isMC:
        addJetCollection(
            process,
            cms.InputTag('smearedAK5PFJets'),
            'SmearedAK5',
            'PF',
            doJTA=False,
            doBTagging=True,
            jetCorrLabel=
            None,  # CV: jet corrections already applied on reco::PFJet input
            doType1MET=False,
            genJetCollection=cms.InputTag("ak5GenJets"),
            doJetID=True,
            jetIdLabel="ak5",
            outputModules=[])
    else:
        addJetCollection(
            process,
            cms.InputTag('calibratedAK5PFJets'),
            'CalibratedAK5',
            'PF',
            doJTA=False,
            doBTagging=True,
            jetCorrLabel=
            None,  # CV: jet corrections already applied on reco::PFJet input
            doType1MET=False,
            doJetID=True,
            jetIdLabel="ak5",
            outputModules=[])

    # add "raw" (uncorrected) CaloMET,
    # needed to parametrize efficiency turn-on of HLT_IsoMu15_L1ETM20 cross-trigger
    process.patCaloMet = process.patMETs.clone(
        metSource=cms.InputTag('met'), addMuonCorrections=cms.bool(False))

    process.patCaloMetNoHF = process.patMETs.clone(
        metSource=cms.InputTag('metNoHF'), addMuonCorrections=cms.bool(False))

    process.producePatTupleTauIdEffMeasSpecific = cms.Sequence(
        process.patTupleProductionSequence + process.caloTauSequence
        # store TaNC inputs as discriminators
        #+ process.produceTancMVAInputDiscriminators
        #+ process.pfTauSequenceFixedCone
        #+ process.pfTauSequenceShrinkingCone
        + process.pfTauSequenceHPS + process.pfTauSequenceHPSpTaNC +
        process.patCaloMet + process.patCaloMetNoHF)

    #--------------------------------------------------------------------------------
    # select "the" primary event Vertex
    #--------------------------------------------------------------------------------

    process.load("TauAnalysis.RecoTools.recoVertexSelection_cff")
    process.producePatTupleTauIdEffMeasSpecific += process.selectPrimaryVertex

    #--------------------------------------------------------------------------------
    # produce collections of "global" and "stand-alone" Muons for di-Muon veto
    #--------------------------------------------------------------------------------

    process.selectedPatMuonsLoose = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag('patMuons'),
        cut=cms.string(
            '(isGlobalMuon() | isStandAloneMuon() | isTrackerMuon()) & pt > 5.0'
        ),
        filter=cms.bool(False))
    process.producePatTupleTauIdEffMeasSpecific += process.selectedPatMuonsLoose

    #--------------------------------------------------------------------------------
    # define Muon momentum scale corrections
    #--------------------------------------------------------------------------------

    process.load("TauAnalysis.RecoTools.patMuonMomentumCorrection_cfi")
    if isMC:
        process.poolDBESSourceMuScleFitCentralValue.toGet[0].tag = cms.string(
            'MuScleFit_Scale_Z_MC_Startup_innerTrack')
    else:
        process.poolDBESSourceMuScleFitCentralValue.toGet[0].tag = cms.string(
            'MuScleFit_Scale_Z_36_invPb_innerTrack_Dec22_v1')
    process.patMuonsMuScleFitCorrectedMomentum.MuonLabel = cms.InputTag(
        'selectedPatMuonsVBTFid')
    # CV: MuScleFit muon momentum corrections do not work in CMSSW_5_2_x (May 4th 2012)
    ##process.producePatTupleTauIdEffMeasSpecific += process.patMuonsMuScleFitCorrectedMomentum

    ##process.load("TauAnalysis.RecoTools.patLeptonSystematics_cff")
    ##process.patMuonsMuScleFitCorrectedMomentumShiftUp.MuonLabel = process.patMuonsMuScleFitCorrectedMomentum.MuonLabel
    ##process.patMuonsMuScleFitCorrectedMomentumShiftDown.MuonLabel = process.patMuonsMuScleFitCorrectedMomentum.MuonLabel
    ##process.producePatTupleTauIdEffMeasSpecific += process.patMuonsMuScleFitCorrectedMomentumShiftUp
    ##process.producePatTupleTauIdEffMeasSpecific += process.patMuonsMuScleFitCorrectedMomentumShiftDown

    #--------------------------------------------------------------------------------
    # define Muon selection
    #--------------------------------------------------------------------------------

    process.selectedPatMuonsForTauIdEffPFRelIso = cms.EDFilter("PATMuonSelector",
        cut = cms.string(
            '(userIsolation("pat::User1Iso")' + \
            ' + max(0., userIsolation("pat::PfNeutralHadronIso") + userIsolation("pat::PfGammaIso")' + \
            '          - 0.5*userIsolation("pat::User2Iso"))) < 0.50*pt'
        ),
        filter = cms.bool(False)
    )

    patMuonSelConfiguratorForTauIdEff = objSelConfigurator(
        [process.selectedPatMuonsForTauIdEffPFRelIso],
        # CV: MuScleFit muon momentum corrections do not work in CMSSW_5_2_x (May 4th 2012)
        #src = "patMuonsMuScleFitCorrectedMomentum",
        src="selectedPatMuonsVBTFid",
        pyModuleName=__name__,
        doSelIndividual=False)
    setattr(patMuonSelConfiguratorForTauIdEff, "systematics", muonSystematics)
    process.selectPatMuonsForTauIdEff = patMuonSelConfiguratorForTauIdEff.configure(
        process=process)
    process.producePatTupleTauIdEffMeasSpecific += process.selectPatMuonsForTauIdEff

    #--------------------------------------------------------------------------------
    # define Muon selection for di-Muon veto
    #--------------------------------------------------------------------------------

    process.selectedPatMuonsForTauIdEffZmumuHypotheses = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuons"),
        cut=cms.string(
            'isGlobalMuon() | isTrackerMuon() | isStandAloneMuon()'),
        filter=cms.bool(False))

    process.allDiMuPairForTauIdEffZmumuHypotheses = cms.EDProducer(
        "PATDiMuPairProducer",
        useLeadingTausOnly=cms.bool(False),
        srcLeg1=cms.InputTag(
            composeModuleName(
                ['selectedPatMuonsForTauIdEffPFRelIso', "cumulative"])),
        srcLeg2=cms.InputTag('selectedPatMuonsForTauIdEffZmumuHypotheses'),
        dRmin12=cms.double(0.01),
        srcMET=cms.InputTag(''),
        recoMode=cms.string(""),
        verbosity=cms.untracked.int32(0))

    process.selectedDiMuPairForTauIdEffZmumuHypotheses = cms.EDFilter(
        "PATDiMuPairSelector",
        src=cms.InputTag("allDiMuPairForTauIdEffZmumuHypotheses"),
        cut=cms.string('charge = 0'),
        filter=cms.bool(False))

    process.produceDiMuPairsForTauIdEff = cms.Sequence(
        process.selectedPatMuonsForTauIdEffZmumuHypotheses *
        process.allDiMuPairForTauIdEffZmumuHypotheses *
        process.selectedDiMuPairForTauIdEffZmumuHypotheses)

    process.producePatTupleTauIdEffMeasSpecific += process.produceDiMuPairsForTauIdEff

    #--------------------------------------------------------------------------------
    # define Electron selection (needed for pat::Jet overlap removal)
    #--------------------------------------------------------------------------------

    process.load("TauAnalysis/RecoTools/patLeptonSelection_cff")
    process.producePatTupleTauIdEffMeasSpecific += process.selectPatElectrons

    #--------------------------------------------------------------------------------
    # define Jet energy scale corrections
    #--------------------------------------------------------------------------------

    process.load("TauAnalysis.RecoTools.patJetSystematics_cff")
    # CV: shift jet energy by 3 standard-deviations,
    #     so that template morphing remains an interpolation and no extrapolation is needed
    setattr(process.patJetsJECshiftUp, "varyByNsigmas", cms.double(3.0))
    setattr(process.patJetsJECshiftDown, "varyByNsigmas", cms.double(3.0))
    process.producePatTupleTauIdEffMeasSpecific += process.prodSmearedJets

    #--------------------------------------------------------------------------------
    # produce collections of Tau-Jets and of Muon + Tau-jet candidate pairs
    #--------------------------------------------------------------------------------

    # CV: do not run SVFit and PFMetSignificance algorithms,
    #     as they use a significant amount of time (2011/05/27)
    #retVal_pfTauFixedCone = \
    #    buildSequenceTauIdEffMeasSpecific(process,
    #                                      'selectedPatMuonsForTauIdEffPFRelIso',
    #                                      [ "PFTau", "FixedCone" ], patTupleConfig["pfTauCollectionFixedCone"], False,
    #                                      None,
    #                                      'patType1CorrectedPFMet',
    #                                      isMC = isMC, isEmbedded = isEmbedded,
    #                                      runSVfit = False)
    #process.producePatTupleTauIdEffMeasSpecific += retVal_pfTauFixedCone["sequence"]
    #retVal_pfTauShrinkingCone = \
    #    buildSequenceTauIdEffMeasSpecific(process,
    #                                      'selectedPatMuonsForTauIdEffPFRelIso',
    #                                      [ "PFTau", "ShrinkingCone" ], patTupleConfig["pfTauCollectionShrinkingCone"], False,
    #                                      None,
    #                                      'patType1CorrectedPFMet',
    #                                      isMC = isMC, isEmbedded = isEmbedded,
    #                                      runSVfit = False)
    #process.producePatTupleTauIdEffMeasSpecific += retVal_pfTauShrinkingCone["sequence"]
    # CV: save HPS taus passing the following tau id. discriminators
    #     for measurement of tau charge misidentification rate
    savePFTauHPS = \
        "pt > 15.0 & abs(eta) < 2.5 & " \
       + "tauID('decayModeFinding') > 0.5 & " \
       + "(tauID('byLooseIsolation') > 0.5 |" \
       + " tauID('byLooseIsolationDeltaBetaCorr') > 0.5 |" \
       + " tauID('byLooseCombinedIsolationDeltaBetaCorr') > 0.5) & " \
       + "tauID('againstElectronLoose') > 0.5 & " \
       + "tauID('againstMuonTight') > 0.5"
    retVal_pfTauHPS = \
        buildSequenceTauIdEffMeasSpecific(process,
                                          'selectedPatMuonsForTauIdEffPFRelIso',
                                          [ "PFTau", "HPS" ], patTupleConfig["pfTauCollectionHPS"], True,
                                          savePFTauHPS,
                                          'patType1CorrectedPFMet',
                                          isMC = isMC, isEmbedded = isEmbedded,
                                          runSVfit = runSVfit)
    process.producePatTupleTauIdEffMeasSpecific += retVal_pfTauHPS["sequence"]
    # CV: save HPS+TaNC taus passing the following tau id. discriminators
    #     for measurement of tau charge misidentification rate
    #savePFTauHPSpTaNC = \
    #    "pt > 15.0 & abs(eta) < 2.5 & " \
    #   + "tauID('leadingTrackFinding') > 0.5 & " \
    #   + "tauID('byTaNCloose') > 0.5 & " \
    #   + "tauID('againstElectronLoose') > 0.5 & " \
    #   + "tauID('againstMuonTight') > 0.5"
    #retVal_pfTauHPSpTaNC = \
    #    buildSequenceTauIdEffMeasSpecific(process,
    #                                      'selectedPatMuonsForTauIdEffPFRelIso',
    #                                      [ "PFTau", "HPSpTaNC" ], patTupleConfig["pfTauCollectionHPSpTaNC"], True,
    #                                      savePFTauHPSpTaNC,
    #                                      'patType1CorrectedPFMet',
    #                                      isMC = isMC, isEmbedded = isEmbedded,
    #                                      runSVfit = runSVfit)
    #process.producePatTupleTauIdEffMeasSpecific += retVal_pfTauHPSpTaNC["sequence"]

    retVal = {}
    #retVal["pfTauFixedCone"] = retVal_pfTauFixedCone
    #retVal["pfTauShrinkingCone"] = retVal_pfTauShrinkingCone
    retVal["pfTauHPS"] = retVal_pfTauHPS
    #retVal["pfTauHPSpTaNC"] = retVal_pfTauHPSpTaNC
    retVal["algorithms"] = [
        #"pfTauFixedCone",
        #"pfTauShrinkingCone",
        "pfTauHPS",
        #"pfTauHPSpTaNC"
    ]
    return retVal
def produceTauIdEffMeasPATTuple(process, isMC, isEmbedded, HLTprocessName, pfCandidateCollection, runSVfit):

    # produce PAT objects common between PAT-tuple and Ntuple production
    produceTauIdEffMeasPATTuple_base(process, isMC, isEmbedded, HLTprocessName, pfCandidateCollection, runSVfit)

    #--------------------------------------------------------------------------------
    #
    # CV: add (new) SVfit algorithm;
    #     for speed reasons, run SVfit in 'fit' mode only
    #    (using combination of PS + MET likelihoods + logM regularization term
    #     to reconstruct mass of tau lepton pair, as described in CMS AN-11-165)
    #
    muTauPairProducers = [
        #"allMuPFTauHPSpairsForTauIdEff",
        #"allMuPFTauHPSpairsForTauIdEffSysJetEnUp",
        #"allMuPFTauHPSpairsForTauIdEffSysJetEnDown",
        #"allMuPFTauHPSpairsForTauIdEffSysTauJetEnUp",
        #"allMuPFTauHPSpairsForTauIdEffSysTauJetEnDown",
        #"allMuPFTauHPSpTaNCpairsForTauIdEff",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysJetEnUp",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysJetEnDown",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysTauJetEnUp",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysTauJetEnDown"
    ]
    for muTauPairProducer in muTauPairProducers:
        muTauPairProducerModule = getattr(process, muTauPairProducer)

        muTauPairProducerModule.doSVreco = cms.bool(True)
        
        muTauPairProducerModule.nSVfit = cms.PSet()
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit = cms.PSet()
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config = copy.deepcopy(process.nSVfitConfig_template)
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config.event.resonances.A.daughters.leg1 = cms.PSet(
            src = muTauPairProducerModule.srcLeg1,
            likelihoodFunctions = cms.VPSet(process.nSVfitMuonLikelihoodPhaseSpace),
            builder = process.nSVfitTauToMuBuilder
        )
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config.event.resonances.A.daughters.leg2 = cms.PSet(
            src = muTauPairProducerModule.srcLeg2,
            likelihoodFunctions = cms.VPSet(process.nSVfitTauLikelihoodPhaseSpace),
            builder = process.nSVfitTauToHadBuilder
        )
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.algorithm = cms.PSet(
            pluginName = cms.string("nSVfitAlgorithmByLikelihoodMaximization"),
            pluginType = cms.string("NSVfitAlgorithmByLikelihoodMaximization"),
            minimizer  = cms.vstring("Minuit2", "Migrad"),
            maxObjFunctionCalls = cms.uint32(5000),
            verbosity = cms.int32(0)
        )

        muTauPairProducerModule.doPFMEtSign = cms.bool(True)

        pfJetCollection = 'selectedPatJetsAK5PFAntiOverlapWithMuonsVeto'
        if isMC:
            pfJetCollection = 'selectedPatJetsAK5PFsmearedAntiOverlapWithMuonsVeto'
        muTauPairProducerModule.pfMEtSign = cms.PSet(
            srcPFJets = cms.InputTag(pfJetCollection),
            srcPFCandidates = cms.InputTag('particleFlow'),
            resolution = process.METSignificance_params,
            dRoverlapPFJet = cms.double(0.3),
            dRoverlapPFCandidate = cms.double(0.1)
        )
    #--------------------------------------------------------------------------------

    #-------------------------------------------------------------------------------------------------------------------------
    #
    # add Data to Monte-Carlo correction factors
    # (simple doubles)
    #
    if isMC:
        # add Data/MC correction factor for muon trigger efficiency
        process.muonTriggerEfficiencyCorrection = cms.EDProducer("PATMuonEfficiencyCorrectionProducer",
           inputFileName = cms.FileInPath("TauAnalysis/TauIdEfficiency/data/singleMuHLTeff.root"),
           lutName = cms.string('hEff'),
           parametrization = cms.PSet(
               src = cms.VInputTag(composeModuleName(['selectedPatMuonsForTauIdEffPFRelIso', "cumulative"])),
               x = cms.string("eta()"),
               y = cms.string("pt()"),
               z = cms.string("0.")
           ),
           noObjectSubstituteValue = cms.double(0.) # weight returned in case all 'src' collections do not contain any entries
        )
        process.producePatTupleTauIdEffMeasSpecific += process.muonTriggerEfficiencyCorrection
        
        # add reweighting factors (rho-Neutral correction)
        # to correct for Data/MC differences in modeling out-out-time pile-up
        process.load("TauAnalysis.RecoTools.vertexMultiplicityVsRhoPFNeutralReweight_cfi")
        process.producePatTupleTauIdEffMeasSpecific += process.produceVertexMultiplicityVsRhoPFNeutralReweights
    #-------------------------------------------------------------------------------------------------------------------------

    #--------------------------------------------------------------------------------
    # add event counter for Mauro's "self baby-sitting" technology
    process.processedEventsPATtupleProduction = cms.EDProducer("EventCountProducer")
    process.eventCounterPath = cms.Path(process.processedEventsPATtupleProduction)
    #--------------------------------------------------------------------------------

    #--------------------------------------------------------------------------------
    #
    # save PAT-tuple
    #
    process.patTupleOutputModule = cms.OutputModule("PoolOutputModule",
        cms.PSet(
            outputCommands = cms.untracked.vstring(
                'drop *',
                'keep EventAux_*_*_*',
                'keep LumiSummary_*_*_*',                       
                'keep edmMergeableCounter_*_*_*',
                'keep *_gtDigis_*_*',
                'keep *_hltL1GtObjectMap_*_*',
                'keep *_TriggerResults_*_*',                                            
                'keep *_selectedPatMuonsForTauIdEffPFRelIsoCumulative_*_*',
                'keep *_selectedPatMuonsForTauIdEffZmumuHypotheses_*_*',
                'keep *_selectedDiMuPairForTauIdEffZmumuHypotheses_*_*',
                'keep *_patJetsSmearedAK5PF_*_*',
                'keep *_patJetsCalibratedAK5PF_*_*',                                            
                #'keep *_selectedPatPFTausFixedConeForTauIdEff*_*_*',
                #'keep *_selectedPatPFTausShrinkingConeForTauIdEff*_*_*',
                'keep *_selectedPatPFTausHPSforTauIdEff*_*_*',
                #'keep *_selectedPatPFTausHPSpTaNCforTauIdEff*_*_*',
                #'keep *_selectedMuPFTauFixedConePairsDzForTauIdEff*_*_*',
                #'keep *_selectedMuPFTauShrinkingConePairsDzForTauIdEff*_*_*',
                'keep *_selectedMuPFTauHPSpairsDzForTauIdEff*_*_*',
                #'keep *_selectedMuPFTauHPSpTaNCpairsDzForTauIdEff*_*_*',
                'keep *_offlinePrimaryVertices_*_*',
                'keep *_offlinePrimaryVerticesWithBS_*_*',
                'keep *_selectedPrimaryVertexHighestPtTrackSum_*_*',
                # keep CaloMEt objects                                                            
                'keep *_patCaloMet*_*_*',                                  
                # keep PFMEt objects                                               
                'keep *_patPFMet*_*_*',
                'keep *_patType1CorrectedPFMet*_*_*',
                # CV: additional collections needed to run nSVfit algorithm                                                        
                #'keep recoTracks_generalTracks_*_*',                                             
                #'keep *_ak5PFJets_*_*',
                #'keep *_particleFlow_*_*'
            )               
        ),
        process.tauIdEffSampleEventSelection,
        fileName = cms.untracked.string("tauIdEffMeasPATtuple.root")      
    )

    process.patTupleOutputModule.outputCommands.extend(patTriggerEventContent)

    if isMC:
        process.patTupleOutputModule.outputCommands.extend(
          cms.untracked.vstring(
                'keep *_smearedPatJetsAK5PF*_*_*',
                'keep *_muonTriggerEfficiencyCorrection_*_*',
                'keep *_vertexMultiplicityReweight*_*_*',
                'keep *_vertexMultiplicityReweight*_*_*',
                'keep *_vertexMultiplicityVsRhoPFNeutralReweight_*_*',
                'keep *_addPileupInfo_*_*',
                'keep *_genParticles_*_*',
                'keep *_tauGenJets_*_*',
                'keep *_tauGenJetsSelectorAllHadrons_*_*',
                'keep *_genMetTrue_*_*',
                # CV: additional collections needed to run nSVfit algorithm  
                #'keep *_smearedAK5PFJets_*_*'
            )
        )
    #--------------------------------------------------------------------------------

    process.printEventContent = cms.EDAnalyzer("EventContentAnalyzer") 

    process.p = cms.Path(
        process.prePatProductionSequence
       + process.producePatTupleTauIdEffMeasSpecific
     ##+ process.printEventContent
    )

    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True)
    )

    process.o = cms.EndPath(process.patTupleOutputModule)

    #--------------------------------------------------------------------------------  
    #
    # CV: keep Z --> tau+ tau- --> muon + tau-jet events
    #     passing Pt and eta cuts on generator level
    #    (for studying preselection efficiencies)
    #
    if isMC:
        process.load('PhysicsTools.JetMCAlgos.TauGenJets_cfi')
        process.load('TauAnalysis.GenSimTools.gen_decaysFromZs_cfi')

        process.genMuonWithinAccFilter = cms.EDFilter("PATCandViewCountFilter",
            src = cms.InputTag('genMuonsFromZtautauDecaysWithinAcceptance'),
            minNumber = cms.uint32(1),
            maxNumber = cms.uint32(1000)
        )

        process.genHadTauWithinAccFilter = cms.EDFilter("PATCandViewCountFilter",
            src = cms.InputTag('genHadronsFromZtautauDecaysWithinAcceptance'),
            minNumber = cms.uint32(1),
            maxNumber = cms.uint32(1000)
        )

        process.genZtoMuTauWithinAccSkimPath = cms.Path(
            process.tauGenJets
           + process.produceGenDecayProductsFromZs
           + process.genMuonWithinAccFilter + process.genHadTauWithinAccFilter
        )
    
        extSkimPaths = process.patTupleOutputModule.SelectEvents.SelectEvents.value()
        extSkimPaths.append('genZtoMuTauWithinAccSkimPath')
        process.patTupleOutputModule.SelectEvents.SelectEvents = cms.vstring(extSkimPaths)
    #-------------------------------------------------------------------------------- 

    # define order in which different paths are run
    if isMC:
        process.schedule = cms.Schedule(
            process.p,
            #process.muonPFTauFixedConeSkimPath,
            #process.muonPFTauShrinkingConeSkimPath,
            process.muonPFTauHPSskimPath,
            #process.muonPFTauHPSpTaNCskimPath,
            process.genZtoMuTauWithinAccSkimPath,
            process.o
        )
    else:
        process.schedule = cms.Schedule(
            process.p,
            #process.muonPFTauFixedConeSkimPath,
            #process.muonPFTauShrinkingConeSkimPath,
            process.muonPFTauHPSskimPath,
            #process.muonPFTauHPSpTaNCskimPath,
            process.o
        )
Exemple #7
0
def buildConfigFile_FWLiteTauIdEffAnalyzer(sampleToAnalyze,
                                           jobId,
                                           inputFilePath,
                                           fwliteInput_firstRun,
                                           fwliteInput_lastRun,
                                           tauIds,
                                           binning,
                                           sysUncertainties,
                                           outputFilePath,
                                           recoSampleDefinitions,
                                           regions,
                                           intLumiData,
                                           hltPaths,
                                           srcWeights,
                                           tauChargeMode,
                                           disableTauCandPreselCuts,
                                           muonPtMin,
                                           tauLeadTrackPtMin,
                                           tauAbsIsoMax,
                                           caloMEtPtMin,
                                           pfMEtPtMin,
                                           plot_hltPaths,
                                           fillControlPlots,
                                           requireUniqueMuTauPair=False):
    """Build cfg.py file to run FWLiteTauIdEffAnalyzer macro to run on PAT-tuples,
       apply event selections and fill histograms for A/B/C/D regions"""

    print "<buildConfigFile_FWLiteTauIdEffAnalyzer>:"
    print " processing sample %s" % sampleToAnalyze

    # CV: check that tauChargeMode parameter matches either of the modes
    #     define in TauAnalysis/TauIdEfficiency/src/TauIdEffEventSelector.cc
    if not (tauChargeMode == "tauLeadTrackCharge"
            or tauChargeMode == "tauSignalChargedHadronSum"):
        raise ValueError(
            "Invalid configuration parameter 'tauChargeMode' = %s !!" %
            tauChargeMode)

    disableTauCandPreselCuts_string = getStringRep_bool(
        disableTauCandPreselCuts)

    inputFileNames = os.listdir(inputFilePath)
    #print(inputFileNames)

    # check if inputFile is PAT-tuple and
    # matches sampleToAnalyze, jobId
    inputFile_regex = \
      r"tauIdEffMeasPATTuple_%s_%s_(?P<hash>[a-zA-Z0-9]*).root" % (sampleToAnalyze, jobId)
    inputFileNames_sample = []
    fwliteInput_fileNames = ""
    for inputFileName in inputFileNames:
        inputFile_matcher = re.compile(inputFile_regex)
        if inputFile_matcher.match(inputFileName):
            inputFileNames_sample.append(
                os.path.join(inputFilePath, inputFileName))
            fwliteInput_fileNames += "process.fwliteInput.fileNames.append('%s')\n" % os.path.join(
                inputFilePath, inputFileName)

    print " found %i input files." % len(inputFileNames_sample)

    if len(inputFileNames_sample) == 0:
        print("Sample %s has no input files --> skipping !!" % sampleToAnalyze)
        return

    # find name of associated "process"
    process_matched = None
    processes = recoSampleDefinitions['MERGE_SAMPLES'].keys()
    for process in processes:
        process_samples = []
        if 'samples' in recoSampleDefinitions['MERGE_SAMPLES'][process].keys():
            process_samples = recoSampleDefinitions['MERGE_SAMPLES'][process][
                'samples']
        else:
            process_samples.append(process)
        for sample in process_samples:
            if sample == sampleToAnalyze:
                process_matched = process
    if process_matched and process_matched.startswith('Data'):
        process_matched = 'Data'

    print("sample = %s: process_matched = %s" %
          (sampleToAnalyze, process_matched))

    if not process_matched:
        print("No process associated to sample %s --> skipping !!" %
              sampleToAnalyze)
        return

    print(" building config file...")

    processType = recoSampleDefinitions['RECO_SAMPLES'][sampleToAnalyze][
        'type']

    regions_string = make_inputFileNames_vstring(regions)

    sysUncertainties_expanded = ["CENTRAL_VALUE"]
    if processType != 'Data':
        for sysUncertainty in sysUncertainties:
            sysUncertainties_expanded.append(sysUncertainty + "Up")
            sysUncertainties_expanded.append(sysUncertainty + "Down")
    print " sysUncertainties = %s" % sysUncertainties_expanded

    tauIds_string = make_tauIds_string(tauIds)

    binning_string = make_binning_string(binning)

    hltPaths_string = make_inputFileNames_vstring(hltPaths[processType])
    plot_hltPaths_string = make_inputFileNames_vstring(plot_hltPaths)
    weights_string = make_inputFileNames_vstring(srcWeights[processType])

    srcGenParticles = ''
    fillGenMatchHistograms = False
    if processType != 'Data' and \
      (process_matched.find('Ztautau')   != -1 or
       process_matched.find('Zmumu')     != -1 or
       process_matched.find('ZplusJets') != -1 or
       process_matched.find('WplusJets') != -1):
        srcGenParticles = 'genParticles'
        fillGenMatchHistograms = True

    configFileNames = []
    outputFileNames = []
    logFileNames = []

    for sysUncertainty in sysUncertainties_expanded:

        outputFileName = None
        if sysUncertainty != "CENTRAL_VALUE":
            outputFileName = 'analyzeTauIdEffHistograms_%s_%s_%s.root' % (
                sampleToAnalyze, sysUncertainty, jobId)
        else:
            outputFileName = 'analyzeTauIdEffHistograms_%s_%s.root' % (
                sampleToAnalyze, jobId)
        outputFileName_full = os.path.join(outputFilePath, outputFileName)

        srcMuTauPairs = 'selectedMuPFTauHPSpairsDzForTauIdEff'
        if sysUncertainty not in [
                "CENTRAL_VALUE", "CaloMEtResponseUp", "CaloMEtResponseDown"
        ]:
            srcMuTauPairs = composeModuleName(
                [srcMuTauPairs, sysUncertainty, "cumulative"])
        else:
            srcMuTauPairs = composeModuleName([srcMuTauPairs, "cumulative"])
        srcJets = None
        if not processType == 'Data':
            srcJets = 'patJetsSmearedAK5PF'
        else:
            srcJets = 'patJetsCalibratedAK5PF'

        allEvents_DBS = -1
        xSection = 0.0
        if not processType == 'Data':
            allEvents_DBS = recoSampleDefinitions['RECO_SAMPLES'][
                sampleToAnalyze]['events_processed']
            xSection = recoSampleDefinitions['RECO_SAMPLES'][sampleToAnalyze][
                'x_sec']

        config = \
"""
import FWCore.ParameterSet.Config as cms

process = cms.PSet()

process.fwliteInput = cms.PSet(
    fileNames = cms.vstring(),

    firstRun = cms.int32(%i),
    lastRun = cms.int32(%i),
    
    maxEvents = cms.int32(-1),
    
    outputEvery = cms.uint32(1000)
)

%s
    
process.fwliteOutput = cms.PSet(
    fileName = cms.string('%s')
)

process.tauIdEffAnalyzer = cms.PSet(

    process = cms.string('%s'),
    type = cms.string('%s'),

    regions = cms.vstring(
%s
    ),
    
    tauIds = cms.VPSet(
%s
    ),
    
    binning = cms.PSet(
%s
    ),
    
    sysShift = cms.string('%s'),

    srcHLTresults = cms.InputTag('TriggerResults::HLT'),
    hltPaths = cms.vstring(%s),
    
    srcGoodMuons = cms.InputTag('selectedPatMuonsForTauIdEffPFRelIsoCumulative'),
    
    srcMuTauPairs = cms.InputTag('%s'),
    requireUniqueMuTauPair = cms.bool(%s),
    srcCaloMEt = cms.InputTag('patCaloMetNoHF'),
    srcJets = cms.InputTag('%s'),
    #svFitMassHypothesis = cms.string('psKine_MEt_logM_fit'),
    svFitMassHypothesis = cms.string('psKine_MEt_int'),
    tauChargeMode = cms.string('%s'),
    disableTauCandPreselCuts = cms.bool(%s),
    eventSelCuts = cms.PSet(
        muonPtMin         = cms.double(%f),
        tauLeadTrackPtMin = cms.double(%f),
        tauAbsIsoMax      = cms.double(%f),
        caloMEtPtMin      = cms.double(%f),
        pfMEtPtMin        = cms.double(%f)
    ),

    srcVertices = cms.InputTag('offlinePrimaryVertices'),

    srcGenParticles = cms.InputTag('%s'),
    fillGenMatchHistograms = cms.bool(%s),
    skipPdgIdsGenParticleMatch = cms.vint32(12, 14, 16),

    plot_hltPaths = cms.vstring(%s),

    weights = cms.VInputTag(%s),
    # CV: restrict event weights to avoid problem with too low Monte Carlo event statistics
    #     and large pile-up reweighting factors in Spring'12 MC production
    minWeight = cms.double(0.),
    maxWeight = cms.double(3.),

    muonIsoProbExtractor = cms.PSet(
        inputFileName = cms.FileInPath('TauAnalysis/TauIdEfficiency/data_nocrab/train_kNNmuonIsolation_kNN.weights.xml'),
        parametrization = cms.VPSet(            
            cms.PSet(
                name = cms.string('logMuonPt'),
                expression = cms.string('log(pt)')
            ),
            cms.PSet(
                name = cms.string('absMuonEta'),
                expression = cms.string('abs(eta)')
            )
        ),
        selection = cms.string(
            '(userIsolation("pat::User1Iso")' + \
            ' + max(0., userIsolation("pat::PfNeutralHadronIso") + userIsolation("pat::PfGammaIso")' + \
            '          - 0.5*userIsolation("pat::User2Iso"))) > 0.20*pt'
        )
    ),
    #applyMuonIsoWeights = cms.bool(False),
    applyMuonIsoWeights = cms.bool(True),

    # CV: only book histograms needed to run tau id. efficiency fit;
    #     drop all control plots
    fillControlPlots = cms.bool(%s),

    # CV: 'srcEventCounter' is defined in TauAnalysis/Skimming/test/skimTauIdEffSample_cfg.py
    srcEventCounter = cms.InputTag('processedEventsSkimming'),
    allEvents_DBS = cms.int32(%i),
    
    xSection = cms.double(%f),
    
    intLumiData = cms.double(%f),

    srcLumiProducer = cms.InputTag('lumiProducer')
)
""" % (fwliteInput_firstRun, fwliteInput_lastRun, fwliteInput_fileNames, outputFileName_full,
        process_matched, processType,
        regions_string, tauIds_string, binning_string, sysUncertainty, hltPaths_string,
        srcMuTauPairs, getStringRep_bool(requireUniqueMuTauPair), srcJets, tauChargeMode, disableTauCandPreselCuts_string,
        muonPtMin, tauLeadTrackPtMin, tauAbsIsoMax, caloMEtPtMin, pfMEtPtMin,
        srcGenParticles, getStringRep_bool(fillGenMatchHistograms), plot_hltPaths_string,
        weights_string, getStringRep_bool(fillControlPlots), allEvents_DBS, xSection, intLumiData)

        outputFileNames.append(outputFileName_full)

        configFileName = None
        if sysUncertainty != "CENTRAL_VALUE":
            configFileName = "analyzeTauIdEffPATtuple_%s_%s_%s_cfg.py" % (
                sampleToAnalyze, sysUncertainty, jobId)
        else:
            configFileName = "analyzeTauIdEffPATtuple_%s_%s_cfg.py" % (
                sampleToAnalyze, jobId)
        configFileName_full = os.path.join(outputFilePath, configFileName)
        configFile = open(configFileName_full, "w")
        configFile.write(config)
        configFile.close()
        configFileNames.append(configFileName_full)

        logFileName = configFileName.replace('_cfg.py', '.log')
        logFileName_full = os.path.join(outputFilePath, logFileName)
        logFileNames.append(logFileName_full)

    retVal = {}
    retVal['configFileNames'] = configFileNames
    retVal['outputFileNames'] = outputFileNames
    retVal['logFileNames'] = logFileNames

    return retVal
#nSVfitProducer_template = process.nSVfitProducerByIntegration
nSVfitProducer_template = process.nSVfitProducerByLikelihoodMaximization

for optRESnSVfitName, optRESnSVfit in nSVfitRESoptions.items():

    # adjust MET likelihood to "toy" Monte Carlo resolution
    nSVfitEventLikelihoodMEt_customized = cms.PSet(
        pluginName=cms.string("nSVfitEventLikelihoodMEt"),
        pluginType=cms.string("NSVfitEventLikelihoodMEt"),
        resolution=cms.PSet(parSigma=optRESnSVfit['metResolutionX'],
                            parBias=cms.string("0."),
                            perpSigma=optRESnSVfit['metResolutionY'],
                            perpBias=cms.string("0.")))
    setattr(
        process,
        composeModuleName(
            ["nSVfitEventLikelihoodMEt_customized", optRESnSVfitName]),
        nSVfitEventLikelihoodMEt_customized)

    for optLLnSVfitName, optLLnSVfit in nSVfitLLoptions.items():

        nSVfitElecMuPairHypotheses = copy.deepcopy(nSVfitProducer_template)
        nSVfitElecMuPairHypotheses.config.event.resonances.A.daughters.leg1 = \
          process.nSVfitConfig_template.event.resonances.A.daughters.leg1.clone(
            src = optRESnSVfit['srcElectrons'],
            likelihoodFunctions = cms.VPSet(process.nSVfitElectronLikelihoodPhaseSpace),
            builder = process.nSVfitTauToElecBuilder
        )
        nSVfitElecMuPairHypotheses.config.event.resonances.A.daughters.leg2 = \
          process.nSVfitConfig_template.event.resonances.A.daughters.leg2.clone(
            src = optRESnSVfit['srcMuons'],
            likelihoodFunctions = cms.VPSet(process.nSVfitMuonLikelihoodPhaseSpace),
 def get_moduleName(name, sysName = None):
     moduleName_base = name
     if sysName is not None:
         moduleName_base = composeModuleName([ name, sysName ])
     return composeModuleName([ moduleName_base, "Individual" ])
Exemple #10
0
 def get_moduleName(name, sysName=None):
     moduleName_base = name
     if sysName is not None:
         moduleName_base = composeModuleName([name, sysName])
     return composeModuleName([moduleName_base, "Cumulative"])
Exemple #11
0
def produceTauIdEffMeasPATTuple(process, isMC, isEmbedded, HLTprocessName,
                                pfCandidateCollection, runSVfit):

    # produce PAT objects common between PAT-tuple and Ntuple production
    produceTauIdEffMeasPATTuple_base(process, isMC, isEmbedded, HLTprocessName,
                                     pfCandidateCollection, runSVfit)

    #--------------------------------------------------------------------------------
    #
    # CV: add (new) SVfit algorithm;
    #     for speed reasons, run SVfit in 'fit' mode only
    #    (using combination of PS + MET likelihoods + logM regularization term
    #     to reconstruct mass of tau lepton pair, as described in CMS AN-11-165)
    #
    muTauPairProducers = [
        #"allMuPFTauHPSpairsForTauIdEff",
        #"allMuPFTauHPSpairsForTauIdEffSysJetEnUp",
        #"allMuPFTauHPSpairsForTauIdEffSysJetEnDown",
        #"allMuPFTauHPSpairsForTauIdEffSysTauJetEnUp",
        #"allMuPFTauHPSpairsForTauIdEffSysTauJetEnDown",
        #"allMuPFTauHPSpTaNCpairsForTauIdEff",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysJetEnUp",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysJetEnDown",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysTauJetEnUp",
        #"allMuPFTauHPSpTaNCpairsForTauIdEffSysTauJetEnDown"
    ]
    for muTauPairProducer in muTauPairProducers:
        muTauPairProducerModule = getattr(process, muTauPairProducer)

        muTauPairProducerModule.doSVreco = cms.bool(True)

        muTauPairProducerModule.nSVfit = cms.PSet()
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit = cms.PSet()
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config = copy.deepcopy(
            process.nSVfitConfig_template)
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config.event.resonances.A.daughters.leg1 = cms.PSet(
            src=muTauPairProducerModule.srcLeg1,
            likelihoodFunctions=cms.VPSet(
                process.nSVfitMuonLikelihoodPhaseSpace),
            builder=process.nSVfitTauToMuBuilder)
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.config.event.resonances.A.daughters.leg2 = cms.PSet(
            src=muTauPairProducerModule.srcLeg2,
            likelihoodFunctions=cms.VPSet(
                process.nSVfitTauLikelihoodPhaseSpace),
            builder=process.nSVfitTauToHadBuilder)
        muTauPairProducerModule.nSVfit.psKine_MEt_logM_fit.algorithm = cms.PSet(
            pluginName=cms.string("nSVfitAlgorithmByLikelihoodMaximization"),
            pluginType=cms.string("NSVfitAlgorithmByLikelihoodMaximization"),
            minimizer=cms.vstring("Minuit2", "Migrad"),
            maxObjFunctionCalls=cms.uint32(5000),
            verbosity=cms.int32(0))

        muTauPairProducerModule.doPFMEtSign = cms.bool(True)

        pfJetCollection = 'selectedPatJetsAK5PFAntiOverlapWithMuonsVeto'
        if isMC:
            pfJetCollection = 'selectedPatJetsAK5PFsmearedAntiOverlapWithMuonsVeto'
        muTauPairProducerModule.pfMEtSign = cms.PSet(
            srcPFJets=cms.InputTag(pfJetCollection),
            srcPFCandidates=cms.InputTag('particleFlow'),
            resolution=process.METSignificance_params,
            dRoverlapPFJet=cms.double(0.3),
            dRoverlapPFCandidate=cms.double(0.1))
    #--------------------------------------------------------------------------------

    #-------------------------------------------------------------------------------------------------------------------------
    #
    # add Data to Monte-Carlo correction factors
    # (simple doubles)
    #
    if isMC:
        # add Data/MC correction factor for muon trigger efficiency
        process.muonTriggerEfficiencyCorrection = cms.EDProducer(
            "PATMuonEfficiencyCorrectionProducer",
            inputFileName=cms.FileInPath(
                "TauAnalysis/TauIdEfficiency/data/singleMuHLTeff.root"),
            lutName=cms.string('hEff'),
            parametrization=cms.PSet(src=cms.VInputTag(
                composeModuleName(
                    ['selectedPatMuonsForTauIdEffPFRelIso', "cumulative"])),
                                     x=cms.string("eta()"),
                                     y=cms.string("pt()"),
                                     z=cms.string("0.")),
            noObjectSubstituteValue=cms.double(
                0.
            )  # weight returned in case all 'src' collections do not contain any entries
        )
        process.producePatTupleTauIdEffMeasSpecific += process.muonTriggerEfficiencyCorrection

        # add reweighting factors (rho-Neutral correction)
        # to correct for Data/MC differences in modeling out-out-time pile-up
        process.load(
            "TauAnalysis.RecoTools.vertexMultiplicityVsRhoPFNeutralReweight_cfi"
        )
        process.producePatTupleTauIdEffMeasSpecific += process.produceVertexMultiplicityVsRhoPFNeutralReweights
    #-------------------------------------------------------------------------------------------------------------------------

    #--------------------------------------------------------------------------------
    # add event counter for Mauro's "self baby-sitting" technology
    process.processedEventsPATtupleProduction = cms.EDProducer(
        "EventCountProducer")
    process.eventCounterPath = cms.Path(
        process.processedEventsPATtupleProduction)
    #--------------------------------------------------------------------------------

    #--------------------------------------------------------------------------------
    #
    # save PAT-tuple
    #
    process.patTupleOutputModule = cms.OutputModule(
        "PoolOutputModule",
        cms.PSet(outputCommands=cms.untracked.vstring(
            'drop *',
            'keep EventAux_*_*_*',
            'keep LumiSummary_*_*_*',
            'keep edmMergeableCounter_*_*_*',
            'keep *_gtDigis_*_*',
            'keep *_hltL1GtObjectMap_*_*',
            'keep *_TriggerResults_*_*',
            'keep *_selectedPatMuonsForTauIdEffPFRelIsoCumulative_*_*',
            'keep *_selectedPatMuonsForTauIdEffZmumuHypotheses_*_*',
            'keep *_selectedDiMuPairForTauIdEffZmumuHypotheses_*_*',
            'keep *_patJetsSmearedAK5PF_*_*',
            'keep *_patJetsCalibratedAK5PF_*_*',
            #'keep *_selectedPatPFTausFixedConeForTauIdEff*_*_*',
            #'keep *_selectedPatPFTausShrinkingConeForTauIdEff*_*_*',
            'keep *_selectedPatPFTausHPSforTauIdEff*_*_*',
            #'keep *_selectedPatPFTausHPSpTaNCforTauIdEff*_*_*',
            #'keep *_selectedMuPFTauFixedConePairsDzForTauIdEff*_*_*',
            #'keep *_selectedMuPFTauShrinkingConePairsDzForTauIdEff*_*_*',
            'keep *_selectedMuPFTauHPSpairsDzForTauIdEff*_*_*',
            #'keep *_selectedMuPFTauHPSpTaNCpairsDzForTauIdEff*_*_*',
            'keep *_offlinePrimaryVertices_*_*',
            'keep *_offlinePrimaryVerticesWithBS_*_*',
            'keep *_selectedPrimaryVertexHighestPtTrackSum_*_*',
            # keep CaloMEt objects
            'keep *_patCaloMet*_*_*',
            # keep PFMEt objects
            'keep *_patPFMet*_*_*',
            'keep *_patType1CorrectedPFMet*_*_*',
            # CV: additional collections needed to run nSVfit algorithm
            #'keep recoTracks_generalTracks_*_*',
            #'keep *_ak5PFJets_*_*',
            #'keep *_particleFlow_*_*'
        )),
        process.tauIdEffSampleEventSelection,
        fileName=cms.untracked.string("tauIdEffMeasPATtuple.root"))

    process.patTupleOutputModule.outputCommands.extend(patTriggerEventContent)

    if isMC:
        process.patTupleOutputModule.outputCommands.extend(
            cms.untracked.vstring(
                'keep *_smearedPatJetsAK5PF*_*_*',
                'keep *_muonTriggerEfficiencyCorrection_*_*',
                'keep *_vertexMultiplicityReweight*_*_*',
                'keep *_vertexMultiplicityReweight*_*_*',
                'keep *_vertexMultiplicityVsRhoPFNeutralReweight_*_*',
                'keep *_addPileupInfo_*_*',
                'keep *_genParticles_*_*',
                'keep *_tauGenJets_*_*',
                'keep *_tauGenJetsSelectorAllHadrons_*_*',
                'keep *_genMetTrue_*_*',
                # CV: additional collections needed to run nSVfit algorithm
                #'keep *_smearedAK5PFJets_*_*'
            ))
    #--------------------------------------------------------------------------------

    process.printEventContent = cms.EDAnalyzer("EventContentAnalyzer")

    process.p = cms.Path(process.prePatProductionSequence +
                         process.producePatTupleTauIdEffMeasSpecific
                         ##+ process.printEventContent
                         )

    process.options = cms.untracked.PSet(wantSummary=cms.untracked.bool(True))

    process.o = cms.EndPath(process.patTupleOutputModule)

    #--------------------------------------------------------------------------------
    #
    # CV: keep Z --> tau+ tau- --> muon + tau-jet events
    #     passing Pt and eta cuts on generator level
    #    (for studying preselection efficiencies)
    #
    if isMC:
        process.load('PhysicsTools.JetMCAlgos.TauGenJets_cfi')
        process.load('TauAnalysis.GenSimTools.gen_decaysFromZs_cfi')

        process.genMuonWithinAccFilter = cms.EDFilter(
            "PATCandViewCountFilter",
            src=cms.InputTag('genMuonsFromZtautauDecaysWithinAcceptance'),
            minNumber=cms.uint32(1),
            maxNumber=cms.uint32(1000))

        process.genHadTauWithinAccFilter = cms.EDFilter(
            "PATCandViewCountFilter",
            src=cms.InputTag('genHadronsFromZtautauDecaysWithinAcceptance'),
            minNumber=cms.uint32(1),
            maxNumber=cms.uint32(1000))

        process.genZtoMuTauWithinAccSkimPath = cms.Path(
            process.tauGenJets + process.produceGenDecayProductsFromZs +
            process.genMuonWithinAccFilter + process.genHadTauWithinAccFilter)

        extSkimPaths = process.patTupleOutputModule.SelectEvents.SelectEvents.value(
        )
        extSkimPaths.append('genZtoMuTauWithinAccSkimPath')
        process.patTupleOutputModule.SelectEvents.SelectEvents = cms.vstring(
            extSkimPaths)
    #--------------------------------------------------------------------------------

    # define order in which different paths are run
    if isMC:
        process.schedule = cms.Schedule(
            process.p,
            #process.muonPFTauFixedConeSkimPath,
            #process.muonPFTauShrinkingConeSkimPath,
            process.muonPFTauHPSskimPath,
            #process.muonPFTauHPSpTaNCskimPath,
            process.genZtoMuTauWithinAccSkimPath,
            process.o)
    else:
        process.schedule = cms.Schedule(
            process.p,
            #process.muonPFTauFixedConeSkimPath,
            #process.muonPFTauShrinkingConeSkimPath,
            process.muonPFTauHPSskimPath,
            #process.muonPFTauHPSpTaNCskimPath,
            process.o)
    def _addModule(self, objSelItem, srcParam, sysName = None, process = None):
        # create module
        module = cms.EDProducer(self.boolEventSelFlagProducer)

        # set module attributes
        moduleName = None
        if sysName is None:
            moduleName = objSelItem.pluginName.value()
        else:
            moduleName = composeModuleName([ objSelItem.pluginName.value(), sysName ])
        module.setLabel(moduleName)

        selectors = []
        
        for src_i in srcParam:

            assert len(src_i) == 2, "'src_i' Parameter must have exactly 2 elements !!"

            exclAttributeNames = [ "src", "src_cumulative", "src_individual", "systematics" ]
            selector = cms.PSet()
            for objSelAttrName in dir(objSelItem):
                objSelAttr = getattr(objSelItem, objSelAttrName)
                if isinstance(objSelAttr, cms._ParameterTypeBase) and not objSelAttrName in exclAttributeNames:
                    setattr(selector, objSelAttrName, objSelAttr)

            selector_i = copy.deepcopy(selector)
                
            if sysName is None:
                setattr(selector_i, "src", src_i[0])
            else:
                src_extensions = [ "Cumulative", "cumulative", "Individual", "individual" ]
                for src_extension in src_extensions:
                    if src_i[0].value().endswith(src_extension):
                        src_iBase = src_i[0].value()[:src_i[0].value().rindex(src_extension)]
                        src_iExt = src_extension
                        setattr(selector_i, "src", cms.InputTag(composeModuleName([ src_iBase, sysName, src_iExt ])))
                if not hasattr(selector_i, "src"):
                    setattr(selector_i, "src", cms.InputTag(composeModuleName([ src_i[0].value(), sysName ])))

            if src_i[1] is not None:
                setattr(selector_i, "instanceName", cms.string(src_i[1]))
                
            selectors.append(selector_i)

        setattr(module, "selectors", cms.VPSet(*selectors))

        # if process object exists, attach module to process object;
        # else register module in global python name-space
        if process is not None:
            setattr(process, moduleName, module)
        else:
            pyModule = sys.modules[self.pyModuleName]
            if pyModule is None:
                raise ValueError("'pyModuleName' Parameter invalid !!")
            setattr(pyModule, moduleName, module)

        # add module to sequence
        if self.sequence == None:
            self.sequence = module
        else:
            self.sequence *= module
Exemple #13
0
    def _addModule(self, objSelItem, srcParam, sysName=None, process=None):
        # create module
        module = cms.EDProducer(self.boolEventSelFlagProducer)

        # set module attributes
        moduleName = None
        if sysName is None:
            moduleName = objSelItem.pluginName.value()
        else:
            moduleName = composeModuleName(
                [objSelItem.pluginName.value(), sysName])
        module.setLabel(moduleName)

        selectors = []

        for src_i in srcParam:

            assert len(
                src_i
            ) == 2, "'src_i' Parameter must have exactly 2 elements !!"

            exclAttributeNames = [
                "src", "src_cumulative", "src_individual", "systematics"
            ]
            selector = cms.PSet()
            for objSelAttrName in dir(objSelItem):
                objSelAttr = getattr(objSelItem, objSelAttrName)
                if isinstance(objSelAttr, cms._ParameterTypeBase
                              ) and not objSelAttrName in exclAttributeNames:
                    setattr(selector, objSelAttrName, objSelAttr)

            selector_i = copy.deepcopy(selector)

            if sysName is None:
                setattr(selector_i, "src", src_i[0])
            else:
                src_extensions = [
                    "Cumulative", "cumulative", "Individual", "individual"
                ]
                for src_extension in src_extensions:
                    if src_i[0].value().endswith(src_extension):
                        src_iBase = src_i[0].value()[:src_i[0].value().
                                                     rindex(src_extension)]
                        src_iExt = src_extension
                        setattr(
                            selector_i, "src",
                            cms.InputTag(
                                composeModuleName(
                                    [src_iBase, sysName, src_iExt])))
                if not hasattr(selector_i, "src"):
                    setattr(
                        selector_i, "src",
                        cms.InputTag(
                            composeModuleName([src_i[0].value(), sysName])))

            if src_i[1] is not None:
                setattr(selector_i, "instanceName", cms.string(src_i[1]))

            selectors.append(selector_i)

        setattr(module, "selectors", cms.VPSet(*selectors))

        # if process object exists, attach module to process object;
        # else register module in global python name-space
        if process is not None:
            setattr(process, moduleName, module)
        else:
            pyModule = sys.modules[self.pyModuleName]
            if pyModule is None:
                raise ValueError("'pyModuleName' Parameter invalid !!")
            setattr(pyModule, moduleName, module)

        # add module to sequence
        if self.sequence == None:
            self.sequence = module
        else:
            self.sequence *= module
Exemple #14
0
 def get_moduleName(name, sysName=None):
     moduleName_base = name
     if sysName is not None:
         moduleName_base = composeModuleName([name, sysName])
     return composeModuleName([moduleName_base, "Individual"])
nSVfitProducer_template = process.nSVfitProducerByLikelihoodMaximization

for optRESnSVfitName, optRESnSVfit in nSVfitRESoptions.items():

    # adjust MET likelihood to "toy" Monte Carlo resolution
    nSVfitEventLikelihoodMEt_customized = cms.PSet(
        pluginName = cms.string("nSVfitEventLikelihoodMEt"),
        pluginType = cms.string("NSVfitEventLikelihoodMEt"),
        resolution = cms.PSet(
            parSigma = optRESnSVfit['metResolutionX'],
            parBias = cms.string("0."),
            perpSigma = optRESnSVfit['metResolutionY'],
            perpBias = cms.string("0.")
        )
    )
    setattr(process, composeModuleName(["nSVfitEventLikelihoodMEt_customized", optRESnSVfitName]), nSVfitEventLikelihoodMEt_customized)
        
    for optLLnSVfitName, optLLnSVfit in nSVfitLLoptions.items():
                
        nSVfitElecMuPairHypotheses = copy.deepcopy(nSVfitProducer_template)
        nSVfitElecMuPairHypotheses.config.event.resonances.A.daughters.leg1 = \
          process.nSVfitConfig_template.event.resonances.A.daughters.leg1.clone(
            src = optRESnSVfit['srcElectrons'],
            likelihoodFunctions = cms.VPSet(process.nSVfitElectronLikelihoodPhaseSpace),
            builder = process.nSVfitTauToElecBuilder
        )
        nSVfitElecMuPairHypotheses.config.event.resonances.A.daughters.leg2 = \
          process.nSVfitConfig_template.event.resonances.A.daughters.leg2.clone(
            src = optRESnSVfit['srcMuons'],
            likelihoodFunctions = cms.VPSet(process.nSVfitMuonLikelihoodPhaseSpace),
            builder = process.nSVfitTauToMuBuilder
Exemple #16
0
def buildSequenceTauIdEffMeasSpecific(process,
                                      patMuonCollectionName = "selectedPatMuonsForTauIdEffPFRelIsoCumulative",
                                      tauIdAlgorithmName = None, patTauCollectionName = "patTaus", applyTauJEC = False,
                                      savePatTaus = None,
                                      patMEtCollectionName = "patType1CorrectedPFMet",
                                      isMC = False, isEmbedded = False,
                                      runSVfit = False):

    #print("<buildSequenceTauIdEffMeasSpecific>:")
    #print(" patTauCollectionName = %s" % patTauCollectionName)
    #print(" isMC = %s" % isMC)

    # check that tauIdAlgorithmName is defined, non-null and composed of two parts
    if tauIdAlgorithmName is None or len(tauIdAlgorithmName) != 2:
        raise ValueError("Undefined of invalid 'tauIdAlgorithmName' Parameter !!")

    patTauProducerName = "".join(patTauCollectionName)

    sequenceName = composeModuleName(["sequenceTauIdEffMeasSpecific", "".join(tauIdAlgorithmName)])
    sequence = cms.Sequence()
    setattr(process, sequenceName, sequence)
    
    #--------------------------------------------------------------------------------
    # define loose Tau-jet candidate selection
    #--------------------------------------------------------------------------------

    patTauSelectionModules = []

    process.load("TauAnalysis.RecoTools.patLeptonSelection_cff")
    selectedPatTausAntiOverlapWithMuonsVetoName = \
        "selectedPat%ss%sAntiOverlapWithMuonsVeto" % (tauIdAlgorithmName[0], tauIdAlgorithmName[1])
    selectedPatTausAntiOverlapWithMuonsVeto = process.selectedPatTausForMuTauAntiOverlapWithMuonsVeto.clone(
        dRmin = cms.double(0.5),
        srcNotToBeFiltered = cms.VInputTag(composeModuleName([patMuonCollectionName, "cumulative"]))
    )
    setattr(process, selectedPatTausAntiOverlapWithMuonsVetoName, selectedPatTausAntiOverlapWithMuonsVeto)
    patTauSelectionModules.append(selectedPatTausAntiOverlapWithMuonsVeto)

    process.load("RecoTauTag.RecoTau.PFRecoTauQualityCuts_cfi")
    selectedPatPFTausForTauIdEffName = \
        composeModuleName(["selectedPat%ss%s" % (tauIdAlgorithmName[0], tauIdAlgorithmName[1]), "ForTauIdEff"])
    selectedPatPFTausForTauIdEff = cms.EDFilter("PATPFTauSelectorForTauIdEff",
        minJetPt = cms.double(15.0),
        maxJetEta = cms.double(2.3),
        trackQualityCuts = process.PFTauQualityCuts.signalQualityCuts,
        minLeadTrackPt = cms.double(5.0),
        maxDzLeadTrack = cms.double(0.2),
        maxLeadTrackPFElectronMVA = cms.double(0.6),
        #applyECALcrackVeto = cms.bool(True),
        applyECALcrackVeto = cms.bool(False),                                        
        minDeltaRtoNearestMuon = cms.double(0.5),
        muonSelection = cms.string("isGlobalMuon() | isTrackerMuon() | isStandAloneMuon()"),
        srcMuon = cms.InputTag('patMuons'),
        pfIsolation = cms.PSet(
            chargedParticleIso = cms.PSet(
                ptMin = cms.double(1.0),        
                dRvetoCone = cms.double(0.15),
                dRisoCone = cms.double(0.6)
            ),
            neutralHadronIso = cms.PSet(
                ptMin = cms.double(1000.),        
                dRvetoCone = cms.double(0.15),        
                dRisoCone = cms.double(0.)
            ),
            photonIso = cms.PSet(
                ptMin = cms.double(1.5),        
                dPhiVeto = cms.double(-1.),  # asymmetric Eta x Phi veto region 
                dEtaVeto = cms.double(-1.),  # to account for photon conversions in electron isolation case        
                dRvetoCone = cms.double(0.15),
                dRisoCone = cms.double(0.6)
            ),
            pileUpCorr = cms.PSet(
                method = cms.string("deltaBeta"),
                chargedToNeutralFactor = cms.double(0.50)
            )                                        
        ),
        maxPFIsoPt = cms.double(5.0),
        srcPFIsoCandidates = cms.InputTag('particleFlow'),
        srcPFNoPileUpCandidates = cms.InputTag('pfNoPileUp'),                             
        srcBeamSpot = cms.InputTag('offlineBeamSpot'),
        srcVertex = cms.InputTag('offlinePrimaryVertices'),
        filter = cms.bool(False)                                                  
    )
    # CV: comment-out for now, in order to make sure there is no bias
    #     on the tau id. efficiency measurement
    #if savePatTaus is not None:
    #    setattr(selectedPatPFTausForTauIdEff, "save", cms.string(savePatTaus))
    setattr(process, selectedPatPFTausForTauIdEffName, selectedPatPFTausForTauIdEff)
    patTauSelectionModules.append(selectedPatPFTausForTauIdEff)

    # for MC   apply L1FastJet + L2 + L3 jet-energy corrections,
    # for Data apply L1FastJet + L2 + L3 + L2/L3 residual corrections
    #
    # CV: Ztautau samples produced via MCEmbedding technique are technically "Data',
    #     L2/L3 residual jet energy corrections **must not** be applied, however,
    #     since the tau-jet response is taken from the Monte Carlo simulation
    #
    if isMC or isEmbedded:
        setattr(selectedPatPFTausForTauIdEff, "jetEnergyCorrection", cms.string('ak5PFL1FastL2L3'))
    else:
        setattr(selectedPatPFTausForTauIdEff, "jetEnergyCorrection", cms.string('ak5PFL1FastL2L3Residual'))

    patTauSelConfigurator = objSelConfigurator(
        patTauSelectionModules,
        src = patTauCollectionName,
        pyModuleName = __name__,
        doSelIndividual = False
    )
    patTauSelectionSequenceName = "selectPat%ss%sForTauIdEff" % (tauIdAlgorithmName[0], tauIdAlgorithmName[1])
    patTauSelectionSequence = patTauSelConfigurator.configure(process = process)
    setattr(process, patTauSelectionSequenceName, patTauSelectionSequence)
    sequence += patTauSelectionSequence

    selTauCollectionName = selectedPatPFTausForTauIdEffName
    
    patTauCollections = []
    for patTauSelectionModule in patTauSelectionModules:
        patTauCollections.append(composeModuleName([patTauSelectionModule.label(), "cumulative"]))
    patTauForTauIdEffCounter = cms.EDAnalyzer("PATCandViewCountAnalyzer",
        src = cms.VInputTag(patTauCollections),
        minNumEntries = cms.int32(1),
        maxNumEntries = cms.int32(1000)                                   
    )
    patTauForTauIdEffCounterName = "pat%s%sForTauIdEffCounter" % (tauIdAlgorithmName[0], tauIdAlgorithmName[1])
    setattr(process, patTauForTauIdEffCounterName, patTauForTauIdEffCounter)
    sequence += patTauForTauIdEffCounter

    #--------------------------------------------------------------------------------
    # produce collections of Tau-jet candidates shifted Up/Down in energy
    #
    # NOTE: Tau-jet energy shifts/smearing needs to be applied
    #       **after** PATPFTauSelectorForTauIdEff module is run,
    #       as the PATPFTauSelectorForTauIdEff module sets Tau-jet momentum to PFJet momentum,
    #       regardless of any shifts/smearing applied to Tau-jet momentum
    #
    #--------------------------------------------------------------------------------

    tauSystematics = None
    if isMC:
        # CV: shift Tau-jet energy by 3 standard-deviations,
        #     so that template morphing remains an interpolation and no extrapolation is needed
        patTausJECshiftUpModuleName = composeModuleName([patTauSelectionModule.label(), "TauJetEnUp", "cumulative"])
        patTausJECshiftUpModule = cms.EDProducer("ShiftedPATTauJetProducer",
            src = cms.InputTag(composeModuleName([selTauCollectionName, "cumulative"])),
            jetCorrPayloadName = cms.string('AK5PF'),
            jetCorrUncertaintyTag = cms.string('Uncertainty'),
            addResidualJES = cms.bool(False),                                     
            shiftBy = cms.double(+3.)
        )
        setattr(process, patTausJECshiftUpModuleName, patTausJECshiftUpModule)
        sequence += patTausJECshiftUpModule

        patTausJECshiftDownModuleName = composeModuleName([patTauSelectionModule.label(), "TauJetEnDown", "cumulative"])
        patTausJECshiftDownModule = patTausJECshiftUpModule.clone(
            shiftBy = cms.double(-3.)
        )
        setattr(process, patTausJECshiftDownModuleName, patTausJECshiftDownModule)
        sequence += patTausJECshiftDownModule

        process.load("RecoMET.METProducers.METSigParams_cfi")
        patTausJERshiftUpModuleName = composeModuleName([patTauSelectionModule.label(), "TauJetResUp", "cumulative"])
        patTausJERshiftUpModule = cms.EDProducer("SmearedPATTauJetProducer",
            src = cms.InputTag(composeModuleName([selTauCollectionName, "cumulative"])),
            inputFileName = cms.FileInPath('PhysicsTools/PatUtils/data/pfJetResolutionMCtoDataCorrLUT.root'),
            lutName = cms.string('pfJetResolutionMCtoDataCorrLUT'),
            jetResolutions = process.METSignificance_params,
            srcGenJets = cms.InputTag('ak5GenJetsNoNu'),
            dRmaxGenJetMatch = cms.string('TMath::Min(0.5, 0.1 + 0.3*TMath::Exp(-0.05*(genJetPt - 10.)))'),
            sigmaMaxGenJetMatch = cms.double(5.),
            smearBy = cms.double(0.),                                     
            shiftBy = cms.double(+3.)                          
        )
        setattr(process, patTausJERshiftUpModuleName, patTausJERshiftUpModule)
        sequence += patTausJERshiftUpModule

        patTausJERshiftDownModuleName = composeModuleName([patTauSelectionModule.label(), "TauJetResDown", "cumulative"])
        patTausJERshiftDownModule = patTausJERshiftUpModule.clone(
            shiftBy = cms.double(-3.)
        )
        setattr(process, patTausJERshiftDownModuleName, patTausJERshiftDownModule)
        sequence += patTausJERshiftDownModule

    #--------------------------------------------------------------------------------
    # define selection of Muon + Tau-jet candidate pairs
    #--------------------------------------------------------------------------------

    process.load("TauAnalysis.CandidateTools.muTauPairProduction_cff")
    allMuTauPairsModuleName = composeModuleName(["allMu", "".join(tauIdAlgorithmName), "PairsForTauIdEff"])
    allMuTauPairsModule = process.allMuTauPairs.clone(
        srcLeg1 = cms.InputTag(composeModuleName([patMuonCollectionName, "cumulative"])),
        srcLeg2 = cms.InputTag(composeModuleName([selTauCollectionName,  "cumulative"])),
        dRmin12 = cms.double(0.5),
        srcMET = cms.InputTag(patMEtCollectionName),
        doSVreco = cms.bool(runSVfit),
        doPFMEtSign = cms.bool(runSVfit),
        doMtautauMin = cms.bool(runSVfit)
    )
    if not runSVfit:
        if hasattr(allMuTauPairsModule, "nSVfit"):
            delattr(allMuTauPairsModule, "nSVfit")
        if hasattr(allMuTauPairsModule, "pfMEtSign"):
            delattr(allMuTauPairsModule, "pfMEtSign")
    else:
        # CV: for speed reasons, run NSVfit algorithm in "fit" mode only, not in "integration" mode
        if hasattr(allMuTauPairsModule, "nSVfit") and hasattr(allMuTauPairsModule.nSVfit, "psKine_MEt_logM_int"):
            delattr(allMuTauPairsModule.nSVfit, "psKine_MEt_logM_int")
    
    if isMC:
        setattr(allMuTauPairsModule, "srcGenParticles", cms.InputTag('genParticles'))
    else:
        setattr(allMuTauPairsModule, "srcGenParticles", cms.InputTag(''))
    setattr(process, allMuTauPairsModuleName, allMuTauPairsModule)
    sequence += allMuTauPairsModule
    muTauPairProdConfigurator_systematics = None
    if isMC:
        muTauPairProdConfigurator_systematics = {
            "TauJetEnUp" : {
                "srcLeg2" : cms.InputTag(patTausJECshiftUpModuleName),
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetEnUp"]))
            },
            "TauJetEnDown" : {
                "srcLeg2" : cms.InputTag(patTausJECshiftDownModuleName),
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetEnDown"]))
            },
            "TauJetResUp" : {
                "srcLeg2" : cms.InputTag(patTausJERshiftUpModuleName),
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetResUp"]))
            },
            "TauJetResDown" : {
                "srcLeg2" : cms.InputTag(patTausJERshiftDownModuleName),
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetResDown"]))
            },
            "JetEnUp" : {
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetEnUp"]))
            },
            "JetEnDown" : {
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "JetEnDown"]))
            },
            "UnclusteredEnUp" : {
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "UnclusteredEnUp"]))
            },
            "UnclusteredEnDown" : {
                "srcMET"  : cms.InputTag(composeModuleName([patMEtCollectionName, "UnclusteredEnDown"]))
            }
        }
    muTauPairProdConfigurator = objProdConfigurator(
        allMuTauPairsModule,
        pyModuleName = __name__
    )
    if isMC:
        setattr(muTauPairProdConfigurator, "systematics", muTauPairProdConfigurator_systematics)   

    prodMuTauPairSequenceName = composeModuleName(["prodMu", "".join(tauIdAlgorithmName), "PairsForTauIdEff"])
    prodMuTauPairSequence = muTauPairProdConfigurator.configure(process = process)
    setattr(process, prodMuTauPairSequenceName, prodMuTauPairSequence)
    sequence += prodMuTauPairSequence

    muTauPairSystematicsForTauIdEff = {
        "TauJetEnUp"        : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "TauJetEnUp"])),
        "TauJetEnDown"      : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "TauJetEnDown"])),
        "TauJetResUp"       : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "TauJetResUp"])),
        "TauJetResDown"     : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "TauJetResDown"])),
        "JetEnUp"           : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "JetEnUp"])),
        "JetEnDown"         : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "JetEnDown"])),
        "UnclusteredEnUp"   : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "UnclusteredEnUp"])),
        "UnclusteredEnDown" : cms.InputTag(composeModuleName([allMuTauPairsModuleName, "UnclusteredEnDown"]))
    }

    #print("muTauPairSystematicsForTauIdEff:", muTauPairSystematicsForTauIdEff)

    process.load("TauAnalysis.CandidateTools.muTauPairSelection_cfi")
    selectedMuTauPairsAntiOverlapVetoModuleName = \
      composeModuleName(["selectedMu", "".join(tauIdAlgorithmName), "PairsAntiOverlapVetoForTauIdEff"])
    selectedMuTauPairsAntiOverlapVetoModule = process.selectedMuTauPairsAntiOverlapVeto.clone(
        cut = cms.string('dR12 > 0.5')
    )
    setattr(process, selectedMuTauPairsAntiOverlapVetoModuleName, selectedMuTauPairsAntiOverlapVetoModule)
    selectedMuTauPairsDzModuleName = \
      composeModuleName(["selectedMu", "".join(tauIdAlgorithmName), "PairsDzForTauIdEff"])
    selectedMuTauPairsDzModule = selectedMuTauPairsAntiOverlapVetoModule.clone(
        #cut = cms.string('abs(leg1().vertex().z() - leg2().vertex().z()) < 0.2')
        cut = cms.string('abs(leg1().vertex().z() - leg2().vertex().z()) < 1.e+3')
    )
    setattr(process, selectedMuTauPairsDzModuleName, selectedMuTauPairsDzModule)    
    muTauPairSelConfigurator = objSelConfigurator(
        [ selectedMuTauPairsAntiOverlapVetoModule,
          selectedMuTauPairsDzModule ],
        src = allMuTauPairsModuleName,
        pyModuleName = __name__,
        doSelIndividual = False
    )
    if isMC:
        setattr(muTauPairSelConfigurator, "systematics", muTauPairSystematicsForTauIdEff)
    muTauPairSelectionSequenceName = composeModuleName(["selectMu", "".join(tauIdAlgorithmName), "PairsForTauIdEff"])
    #print "muTauPairSelectionSequenceName = %s" % muTauPairSelectionSequenceName
    muTauPairSelectionSequence = muTauPairSelConfigurator.configure(process = process)
    setattr(process, muTauPairSelectionSequenceName, muTauPairSelectionSequence)
    sequence += muTauPairSelectionSequence

    muTauPairForTauIdEffCounter = cms.EDAnalyzer("PATCandViewCountAnalyzer",
        src = cms.VInputTag(
            allMuTauPairsModuleName,
            composeModuleName([selectedMuTauPairsAntiOverlapVetoModuleName, "cumulative"]),                         
            composeModuleName([selectedMuTauPairsDzModuleName, "cumulative"])
        ),      
        minNumEntries = cms.int32(1),
        maxNumEntries = cms.int32(1000)                                   
    )
    muTauPairForTauIdEffCounterName = composeModuleName(["mu", "".join(tauIdAlgorithmName), "PairForTauIdEffCounter"])
    setattr(process, muTauPairForTauIdEffCounterName, muTauPairForTauIdEffCounter)
    sequence += muTauPairForTauIdEffCounter

    retVal = {}
    retVal["sequence"] = sequence
    retVal["patTauCollections"] = [
        composeModuleName([selTauCollectionName,                                                          "cumulative"])
    ]
    retVal["muTauPairCollections"] = [
        composeModuleName([selectedMuTauPairsDzModuleName,                                                "cumulative"])
    ]
    if isMC:
        retVal["patTauCollections"].extend([
            composeModuleName([selTauCollectionName,                                 "TauJetEnUp",        "cumulative"]),
            composeModuleName([selTauCollectionName,                                 "TauJetEnDown",      "cumulative"]),
            composeModuleName([selTauCollectionName,                                 "TauJetResUp",       "cumulative"]),
            composeModuleName([selTauCollectionName,                                 "TauJetResDown",     "cumulative"])
        ])
        retVal["muTauPairCollections"].extend([
            composeModuleName([selectedMuTauPairsDzModuleName,                       "TauJetEnUp",        "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "TauJetEnDown",      "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "TauJetResUp",       "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "TauJetResDown",     "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "JetEnUp",           "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "JetEnDown",         "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "UnclusteredEnUp",   "cumulative"]),
            composeModuleName([selectedMuTauPairsDzModuleName,                       "UnclusteredEnDown", "cumulative"])        
        ])
    return retVal
 def get_moduleName(name, sysName = None):
     moduleName_base = name
     if sysName is not None:
         moduleName_base = composeModuleName([ name, sysName ])
     return composeModuleName([ moduleName_base, "Cumulative" ])