# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration # # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence from AnaAlgorithm.DualUseConfig import createAlgorithm, createService, addPrivateTool from AsgAnalysisAlgorithms.AsgAnalysisAlgorithmsTest import pileupConfigFiles from AnalysisAlgorithmsConfig.ConfigSequence import ConfigSequence from AnalysisAlgorithmsConfig.ConfigAccumulator import ConfigAccumulator # Config: triggerChains = [ 'HLT_2mu14', 'HLT_mu20_mu8noL1', 'HLT_2e17_lhvloose_nod0' ] electronMinPt = 10e3 electronMaxEta = None photonMinPt = 10e3 photonMaxEta = None muonMinPt = None muonMaxEta = None tauMinPt = None tauMaxEta = None jetMinPt = None jetMaxEta = None def addOutputCopyAlgorithms (algSeq, postfix, inputContainer, outputContainer, selection) : """add a uniformly filtered set of deep copies based on the systematics dependent selection""" if postfix[0] != '_' : postfix = '_' + postfix if selection != '' : unionalg = createAlgorithm( 'CP::AsgUnionSelectionAlg', 'UnionSelectionAlg' + postfix) unionalg.preselection = selection unionalg.particles = inputContainer unionalg.selectionDecoration = 'outputSelect' algSeq += unionalg copyalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg', 'DeepCopyAlg' + postfix ) copyalg.input = inputContainer copyalg.output = outputContainer if selection != '' : copyalg.selection = ['outputSelect'] else : copyalg.selection = [] copyalg.deepCopy = False algSeq += copyalg def makeSequenceOld (dataType, algSeq, vars, forCompare, isPhyslite, noPhysliteBroken) : # Include, and then set up the pileup analysis sequence: prwfiles, lumicalcfiles = pileupConfigFiles(dataType) if not isPhyslite : from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ makePileupAnalysisSequence pileupSequence = makePileupAnalysisSequence( dataType, userPileupConfigs=prwfiles, userLumicalcFiles=lumicalcfiles, ) pileupSequence.configure( inputName = {}, outputName = {} ) # Add the pileup sequence to the job: algSeq += pileupSequence # Add the pileup sequence to the job: vars += [ 'EventInfo.runNumber -> runNumber', 'EventInfo.eventNumber -> eventNumber', ] # Include, and then set up the jet analysis algorithm sequence: from JetAnalysisAlgorithms.JetAnalysisSequence import makeJetAnalysisSequence jetContainer = 'AntiKt4EMPFlowJets' if isPhyslite : input = 'AnalysisJets' else : input = jetContainer jetSequence = makeJetAnalysisSequence( dataType, jetContainer, runJvtUpdate = True, runNNJvtUpdate = True, enableCutflow=True, enableKinematicHistograms=True, shallowViewOutput = False, runGhostMuonAssociation = not isPhyslite) if not noPhysliteBroken : from FTagAnalysisAlgorithms.FTagAnalysisSequence import makeFTagAnalysisSequence btagger = "DL1r" btagWP = "FixedCutBEff_77" makeFTagAnalysisSequence( jetSequence, dataType, jetContainer, noEfficiency = False, legacyRecommendations = True, enableCutflow=True, btagger = btagger, btagWP = btagWP ) vars += [ 'OutJets_%SYS%.ftag_select_' + btagger + '_' + btagWP + ' -> jet_ftag_select_%SYS%', ] if dataType != 'data' : vars += [ 'OutJets_%SYS%.ftag_effSF_' + btagger + '_' + btagWP + '_%SYS% -> jet_ftag_eff_%SYS%' ] jetSequence.configure( inputName = input, outputName = 'AnaJets_%SYS%' ) # Include, and then set up the jet analysis algorithm sequence: from JetAnalysisAlgorithms.JetJvtAnalysisSequence import makeJetJvtAnalysisSequence jvtSequence = makeJetJvtAnalysisSequence( dataType, jetContainer, enableCutflow=True, shallowViewOutput = False ) jvtSequence.configure( inputName = { 'jets' : 'AnaJets_%SYS%' }, outputName = { } ) # Add the sequences to the job: algSeq += jetSequence algSeq += jvtSequence vars += ['OutJets_%SYS%.pt -> jet_pt_%SYS%', 'OutJets_NOSYS.phi -> jet_phi', 'OutJets_NOSYS.eta -> jet_eta', ] if dataType != 'data' : vars += [ 'OutJets_%SYS%.jvt_effSF_%SYS% -> jet_jvtEfficiency_%SYS%', ] if not forCompare : vars += [ # 'EventInfo.jvt_effSF_%SYS% -> jvtSF_%SYS%', # 'EventInfo.fjvt_effSF_%SYS% -> fjvtSF_%SYS%', # 'OutJets_%SYS%.fjvt_effSF_NOSYS -> jet_fjvtEfficiency_%SYS%', ] # Include, and then set up the muon analysis algorithm sequence: from MuonAnalysisAlgorithms.MuonAnalysisSequence import makeMuonAnalysisSequence if isPhyslite : input = 'AnalysisMuons' else : input = 'Muons' muonSequenceMedium = makeMuonAnalysisSequence( dataType, deepCopyOutput = False, shallowViewOutput = False, workingPoint = 'Medium.Iso', postfix = 'medium', enableCutflow=True, enableKinematicHistograms=True, ptSelectionOutput = True ) # FIX ME: the current version of the `MuonSelectionTool` doesn't work # on the current version of PHYSLITE, and needs a new PHYSLITE production # campaign if noPhysliteBroken : muonSequenceMedium.__delattr__ ('MuonSelectionAlg_medium') muonSequenceMedium.configure( inputName = input, outputName = 'AnaMuonsMedium_%SYS%' ) algSeq += muonSequenceMedium muonSequenceTight = makeMuonAnalysisSequence( dataType, deepCopyOutput = False, shallowViewOutput = False, workingPoint = 'Tight.Iso', postfix = 'tight', enableCutflow=True, enableKinematicHistograms=True, ptSelectionOutput = True ) muonSequenceTight.removeStage ("calibration") # FIX ME: the current version of the `MuonSelectionTool` doesn't work # on the current version of PHYSLITE, and needs a new PHYSLITE production # campaign if noPhysliteBroken : muonSequenceTight.__delattr__ ('MuonSelectionAlg_tight') muonSequenceTight.configure( inputName = 'AnaMuonsMedium_%SYS%', outputName = 'AnaMuons_%SYS%') algSeq += muonSequenceTight vars += [ 'OutMuons_NOSYS.eta -> mu_eta', 'OutMuons_NOSYS.phi -> mu_phi', 'OutMuons_%SYS%.pt -> mu_pt_%SYS%', 'OutMuons_NOSYS.charge -> mu_charge', 'OutMuons_%SYS%.baselineSelection_medium -> mu_select_medium_%SYS%', 'OutMuons_%SYS%.baselineSelection_tight -> mu_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutMuons_%SYS%.muon_effSF_medium_%SYS% -> mu_effSF_medium_%SYS%', 'OutMuons_%SYS%.muon_effSF_tight_%SYS% -> mu_effSF_tight_%SYS%', ] # Include, and then set up the electron analysis sequence: from EgammaAnalysisAlgorithms.ElectronAnalysisSequence import \ makeElectronAnalysisSequence if isPhyslite : input = 'AnalysisElectrons' else : input = 'Electrons' likelihood = True recomputeLikelihood=False if likelihood: workingpoint = 'LooseLHElectron.Loose_VarRad' else: workingpoint = 'LooseDNNElectron.Loose_VarRad' # FIXME: fails for PHYSLITE with missing data item # ptvarcone30_Nonprompt_All_MaxWeightTTVALooseCone_pt1000 if noPhysliteBroken : workingpoint = workingpoint.split('.')[0] + '.NonIso' electronSequence = makeElectronAnalysisSequence( dataType, workingpoint, postfix = 'loose', recomputeLikelihood=recomputeLikelihood, enableCutflow=True, enableKinematicHistograms=True, shallowViewOutput = False ) electronSequence.configure( inputName = input, outputName = 'AnaElectrons_%SYS%' ) algSeq += electronSequence vars += [ 'OutElectrons_%SYS%.pt -> el_pt_%SYS%', 'OutElectrons_NOSYS.phi -> el_phi', 'OutElectrons_NOSYS.eta -> el_eta', 'OutElectrons_NOSYS.charge -> el_charge', 'OutElectrons_%SYS%.baselineSelection_loose -> el_select_loose_%SYS%', ] if dataType != 'data': vars += [ 'OutElectrons_%SYS%.effSF_loose_%SYS% -> el_effSF_loose_%SYS%', ] # Include, and then set up the photon analysis sequence: from EgammaAnalysisAlgorithms.PhotonAnalysisSequence import \ makePhotonAnalysisSequence if isPhyslite : input = 'AnalysisPhotons' else : input = 'Photons' photonSequence = makePhotonAnalysisSequence( dataType, 'Tight.FixedCutTight', postfix = 'tight', recomputeIsEM=False, enableCutflow=True, enableKinematicHistograms=True, shallowViewOutput = False ) photonSequence.configure( inputName = input, outputName = 'AnaPhotons_%SYS%' ) algSeq += photonSequence vars += [ 'OutPhotons_%SYS%.pt -> ph_pt_%SYS%', 'OutPhotons_NOSYS.phi -> ph_phi', 'OutPhotons_NOSYS.eta -> ph_eta', 'OutPhotons_%SYS%.baselineSelection_tight -> ph_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutPhotons_%SYS%.ph_effSF_tight_%SYS% -> ph_effSF_tight_%SYS%', ] # Include, and then set up the tau analysis algorithm sequence: from TauAnalysisAlgorithms.TauAnalysisSequence import makeTauAnalysisSequence if isPhyslite : input = 'AnalysisTauJets' else : input = 'TauJets' tauSequence = makeTauAnalysisSequence( dataType, 'Tight', postfix = 'tight', enableCutflow=True, enableKinematicHistograms=True, shallowViewOutput = False ) tauSequence.configure( inputName = input, outputName = 'AnaTauJets_%SYS%' ) # Add the sequence to the job: algSeq += tauSequence vars += [ 'OutTauJets_%SYS%.pt -> tau_pt_%SYS%', 'OutTauJets_NOSYS.phi -> tau_phi', 'OutTauJets_NOSYS.eta -> tau_eta', 'OutTauJets_NOSYS.charge -> tau_charge', 'OutTauJets_%SYS%.baselineSelection_tight -> tau_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutTauJets_%SYS%.tau_effSF_tight_%SYS% -> tau_effSF_tight_%SYS%', ] # temporarily disabled until di-taus are supported in R22 # # Include, and then set up the tau analysis algorithm sequence: # from TauAnalysisAlgorithms.DiTauAnalysisSequence import makeDiTauAnalysisSequence # diTauSequence = makeDiTauAnalysisSequence( dataType, 'Tight', postfix = 'tight' ) # diTauSequence.configure( inputName = 'DiTauJets', outputName = 'AnaDiTauJets_%SYS%' ) # Add the sequence to the job: # disabling this, the standard test files don't have DiTauJets # algSeq += diTauSequence # set up pt-eta selection for all the object types # currently disabling most cuts, but leaving these as placeholders # the cuts I have are mostly to silence MET building warnings selalg = createAlgorithm( 'CP::AsgSelectionAlg', 'UserElectronsSelectionAlg' ) addPrivateTool( selalg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) if electronMinPt is not None : selalg.selectionTool.minPt = electronMinPt if electronMaxEta is not None : selalg.selectionTool.maxEta = electronMaxEta selalg.selectionDecoration = 'selectPtEta' selalg.particles = 'AnaElectrons_%SYS%' algSeq += selalg selalg = createAlgorithm( 'CP::AsgSelectionAlg', 'UserPhotonsSelectionAlg' ) addPrivateTool( selalg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) if photonMinPt is not None : selalg.selectionTool.minPt = photonMinPt if photonMaxEta is not None : selalg.selectionTool.maxEta = photonMaxEta selalg.selectionDecoration = 'selectPtEta' selalg.particles = 'AnaPhotons_%SYS%' algSeq += selalg selalg = createAlgorithm( 'CP::AsgSelectionAlg', 'UserMuonsSelectionAlg' ) addPrivateTool( selalg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) if muonMinPt is not None : selalg.selectionTool.minPt = muonMinPt if muonMaxEta is not None : selalg.selectionTool.maxEta = muonMaxEta selalg.selectionDecoration = 'selectPtEta' selalg.particles = 'AnaMuons_%SYS%' algSeq += selalg selalg = createAlgorithm( 'CP::AsgSelectionAlg', 'UserTauJetsSelectionAlg' ) addPrivateTool( selalg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) if tauMinPt is not None : selalg.selectionTool.minPt = tauMinPt if tauMaxEta is not None : selalg.selectionTool.maxEta = tauMaxEta selalg.selectionDecoration = 'selectPtEta' selalg.particles = 'AnaTauJets_%SYS%' algSeq += selalg selalg = createAlgorithm( 'CP::AsgSelectionAlg', 'UserJetsSelectionAlg' ) addPrivateTool( selalg, 'selectionTool', 'CP::AsgPtEtaSelectionTool' ) if jetMinPt is not None : selalg.selectionTool.minPt = jetMinPt if jetMaxEta is not None : selalg.selectionTool.maxEta = jetMaxEta selalg.selectionDecoration = 'selectPtEta' selalg.particles = 'AnaJets_%SYS%' algSeq += selalg # Now make view containers for the inputs to the met calculation metInputs = { 'jets' : 'METJets_%SYS%', 'taus' : 'METTauJets_%SYS%', 'muons' : 'METMuons_%SYS%', 'electrons' : 'METElectrons_%SYS%', 'photons' : 'METPhotons_%SYS%' } viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg','METElectronsViewAlg' ) viewalg.selection = [ 'selectPtEta', 'baselineSelection_loose,as_char' ] viewalg.input = 'AnaElectrons_%SYS%' viewalg.output = 'METElectrons_%SYS%' algSeq += viewalg viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg','METPhotonsViewAlg' ) viewalg.selection = [ 'selectPtEta', 'baselineSelection_tight,as_char' ] viewalg.input = 'AnaPhotons_%SYS%' viewalg.output = 'METPhotons_%SYS%' algSeq += viewalg viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg','METMuonsViewAlg' ) viewalg.selection = [ 'selectPtEta', 'baselineSelection_medium,as_char' ] viewalg.input = 'AnaMuons_%SYS%' viewalg.output = 'METMuons_%SYS%' algSeq += viewalg viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg','METTauJetsViewAlg' ) viewalg.selection = [ 'selectPtEta', 'baselineSelection_tight,as_char' ] viewalg.input = 'AnaTauJets_%SYS%' viewalg.output = 'METTauJets_%SYS%' algSeq += viewalg viewalg = createAlgorithm( 'CP::AsgViewFromSelectionAlg','METJetsViewAlg' ) viewalg.selection = [ 'selectPtEta' ] viewalg.input = 'AnaJets_%SYS%' viewalg.output = 'METJets_%SYS%' algSeq += viewalg # Include, and then set up the met analysis algorithm sequence: from MetAnalysisAlgorithms.MetAnalysisSequence import makeMetAnalysisSequence if isPhyslite : metSuffix = 'AnalysisMET' else : metSuffix = jetContainer[:-4] metSequence = makeMetAnalysisSequence( dataType, metSuffix=metSuffix ) metSequence.configure( inputName = metInputs, outputName = 'AnaMET_%SYS%' ) # Add the sequence to the job: algSeq += metSequence if not forCompare : vars += [ 'AnaMET_%SYS%.mpx -> met_mpx_%SYS%', 'AnaMET_%SYS%.mpy -> met_mpy_%SYS%', 'AnaMET_%SYS%.sumet -> met_sumet_%SYS%', 'AnaMET_%SYS%.name -> met_name_%SYS%', ] # Make view containers holding as inputs for OR orInputs = { 'photons' : 'AnaPhotons_%SYS%', 'muons' : 'AnaMuons_%SYS%', 'jets' : 'AnaJets_%SYS%', 'taus' : 'AnaTauJets_%SYS%' } selectalg = createAlgorithm( 'CP::AsgSelectionAlg','ORElectronsSelectAlg' ) selectalg.preselection = 'selectPtEta&&baselineSelection_loose,as_char' selectalg.particles = 'AnaElectrons_%SYS%' selectalg.selectionDecoration = 'preselectOR,as_char' algSeq += selectalg orInputs['electrons'] = 'AnaElectrons_%SYS%' selectalg = createAlgorithm( 'CP::AsgSelectionAlg','ORPhotonsSelectAlg' ) selectalg.preselection = 'selectPtEta&&baselineSelection_tight,as_char' selectalg.particles = 'AnaPhotons_%SYS%' selectalg.selectionDecoration = 'preselectOR,as_char' algSeq += selectalg selectalg = createAlgorithm( 'CP::AsgSelectionAlg','ORMuonsSelectAlg' ) selectalg.preselection = 'selectPtEta&&baselineSelection_medium,as_char' selectalg.particles = 'AnaMuons_%SYS%' selectalg.selectionDecoration = 'preselectOR,as_char' algSeq += selectalg selectalg = createAlgorithm( 'CP::AsgSelectionAlg','ORTauJetsSelectAlg' ) selectalg.preselection = 'selectPtEta&&baselineSelection_tight,as_char' selectalg.particles = 'AnaTauJets_%SYS%' selectalg.selectionDecoration = 'preselectOR,as_char' algSeq += selectalg selectalg = createAlgorithm( 'CP::AsgSelectionAlg','ORJetsSelectAlg' ) selectalg.preselection = 'selectPtEta' selectalg.particles = 'AnaJets_%SYS%' selectalg.selectionDecoration = 'preselectOR,as_char' algSeq += selectalg # Include, and then set up the overlap analysis algorithm sequence: from AsgAnalysisAlgorithms.OverlapAnalysisSequence import \ makeOverlapAnalysisSequence overlapSequence = makeOverlapAnalysisSequence( dataType, doMuPFJetOR=True, doTaus=False, enableCutflow=True, shallowViewOutput = False, inputLabel = 'preselectOR', outputLabel = 'passesOR' ) overlapSequence.configure( inputName = { 'electrons' : 'AnaElectrons_%SYS%', 'photons' : 'AnaPhotons_%SYS%', 'muons' : 'AnaMuons_%SYS%', 'jets' : 'AnaJets_%SYS%', 'taus' : 'AnaTauJets_%SYS%' }, outputName = { } ) # FIX ME: temporarily disabling this for data, as there are some # errors with missing primary vertices if dataType != 'data' : algSeq += overlapSequence if not forCompare : vars += [ 'OutJets_%SYS%.passesOR_%SYS% -> jet_select_or_%SYS%', 'OutElectrons_%SYS%.passesOR_%SYS% -> el_select_or_%SYS%', 'OutPhotons_%SYS%.passesOR_%SYS% -> ph_select_or_%SYS%', 'OutMuons_%SYS%.passesOR_%SYS% -> mu_select_or_%SYS%', 'OutTauJets_%SYS%.passesOR_%SYS% -> tau_select_or_%SYS%', ] if dataType != 'data' : # Include, and then set up the generator analysis sequence: from AsgAnalysisAlgorithms.GeneratorAnalysisSequence import \ makeGeneratorAnalysisSequence generatorSequence = makeGeneratorAnalysisSequence( dataType, saveCutBookkeepers=True, runNumber=284500, cutBookkeepersSystematics=True ) algSeq += generatorSequence if not forCompare : vars += [ 'EventInfo.generatorWeight_%SYS% -> generatorWeight_%SYS%', ] # Include, and then set up the trigger analysis sequence: from TriggerAnalysisAlgorithms.TriggerAnalysisSequence import \ makeTriggerAnalysisSequence triggerSequence = makeTriggerAnalysisSequence( dataType, triggerChains=triggerChains, noFilter=True ) # FIXME: temporarily disabling this for comparisons, as there is no # corresponding configuration block. also, maybe it should be possible # to disable filtering in the algorithm, i.e. just store the trigger # decision without throwing away events. if not forCompare : algSeq += triggerSequence vars += ['EventInfo.trigPassed_' + t + ' -> trigPassed_' + t for t in triggerChains] # make filtered output containers addOutputCopyAlgorithms (algSeq, 'Electrons', 'AnaElectrons_%SYS%', 'OutElectrons_%SYS%', 'selectPtEta&&baselineSelection_loose,as_char') addOutputCopyAlgorithms (algSeq, 'Photons', 'AnaPhotons_%SYS%', 'OutPhotons_%SYS%', 'selectPtEta&&baselineSelection_tight,as_char') addOutputCopyAlgorithms (algSeq, 'Muons', 'AnaMuons_%SYS%', 'OutMuons_%SYS%', 'selectPtEta&&baselineSelection_medium,as_char') addOutputCopyAlgorithms (algSeq, 'TauJets', 'AnaTauJets_%SYS%', 'OutTauJets_%SYS%', 'selectPtEta&&baselineSelection_tight,as_char') addOutputCopyAlgorithms (algSeq, 'Jets', 'AnaJets_%SYS%', 'OutJets_%SYS%', 'selectPtEta') def makeSequenceBlocks (dataType, algSeq, vars, forCompare, isPhyslite, noPhysliteBroken) : if not isPhyslite : # Include, and then set up the pileup analysis sequence: prwfiles, lumicalcfiles = pileupConfigFiles(dataType) from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ makePileupAnalysisSequence pileupSequence = makePileupAnalysisSequence( dataType, userPileupConfigs=prwfiles, userLumicalcFiles=lumicalcfiles, ) pileupSequence.configure( inputName = {}, outputName = {} ) # Add the pileup sequence to the job: algSeq += pileupSequence vars += [ 'EventInfo.runNumber -> runNumber', 'EventInfo.eventNumber -> eventNumber', ] configSeq = ConfigSequence () # Include, and then set up the electron analysis algorithm sequence: from EgammaAnalysisAlgorithms.ElectronAnalysisConfig import makeElectronCalibrationConfig, makeElectronWorkingPointConfig likelihood = True recomputeLikelihood=False if likelihood: workingpoint = 'LooseLHElectron.Loose_VarRad' else: workingpoint = 'LooseDNNElectron.Loose_VarRad' # FIXME: fails for PHYSLITE with missing data item # ptvarcone30_Nonprompt_All_MaxWeightTTVALooseCone_pt1000 if noPhysliteBroken : workingpoint = workingpoint.split('.')[0] + '.NonIso' makeElectronCalibrationConfig (configSeq, 'AnaElectrons') makeElectronWorkingPointConfig (configSeq, 'AnaElectrons', workingpoint, postfix = 'loose', recomputeLikelihood=recomputeLikelihood) vars += [ 'OutElectrons_NOSYS.eta -> el_eta', 'OutElectrons_NOSYS.phi -> el_phi', 'OutElectrons_%SYS%.pt -> el_pt_%SYS%', 'OutElectrons_%SYS%.baselineSelection_loose -> el_select_loose_%SYS%', ] if dataType != 'data': vars += [ 'OutElectrons_%SYS%.effSF_loose_%SYS% -> el_effSF_loose_%SYS%', ] # Include, and then set up the photon analysis algorithm sequence: from EgammaAnalysisAlgorithms.PhotonAnalysisConfig import makePhotonCalibrationConfig, makePhotonWorkingPointConfig makePhotonCalibrationConfig (configSeq, 'AnaPhotons', recomputeIsEM=False) makePhotonWorkingPointConfig (configSeq, 'AnaPhotons', 'Tight.FixedCutTight', postfix = 'tight', recomputeIsEM=False) vars += [ 'OutPhotons_NOSYS.eta -> ph_eta', 'OutPhotons_NOSYS.phi -> ph_phi', 'OutPhotons_%SYS%.pt -> ph_pt_%SYS%', 'OutPhotons_%SYS%.baselineSelection_tight -> ph_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutPhotons_%SYS%.ph_effSF_tight_%SYS% -> ph_effSF_tight_%SYS%', ] # Include, and then set up the muon analysis algorithm sequence: from MuonAnalysisAlgorithms.MuonAnalysisConfig import makeMuonCalibrationConfig, makeMuonWorkingPointConfig makeMuonCalibrationConfig (configSeq, 'AnaMuons') makeMuonWorkingPointConfig (configSeq, 'AnaMuons', workingPoint='Medium.Iso', postfix='medium') makeMuonWorkingPointConfig (configSeq, 'AnaMuons', workingPoint='Tight.Iso', postfix='tight') vars += [ 'OutMuons_NOSYS.eta -> mu_eta', 'OutMuons_NOSYS.phi -> mu_phi', 'OutMuons_%SYS%.pt -> mu_pt_%SYS%', 'OutMuons_%SYS%.baselineSelection_medium -> mu_select_medium_%SYS%', 'OutMuons_%SYS%.baselineSelection_tight -> mu_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutMuons_%SYS%.muon_effSF_medium_%SYS% -> mu_effSF_medium_%SYS%', ] vars += [ 'OutMuons_%SYS%.muon_effSF_tight_%SYS% -> mu_effSF_tight_%SYS%', ] # Include, and then set up the tau analysis algorithm sequence: from TauAnalysisAlgorithms.TauAnalysisConfig import makeTauCalibrationConfig, makeTauWorkingPointConfig makeTauCalibrationConfig (configSeq, 'AnaTauJets') makeTauWorkingPointConfig (configSeq, 'AnaTauJets', workingPoint='Tight', postfix='tight') vars += [ 'OutTauJets_NOSYS.eta -> tau_eta', 'OutTauJets_NOSYS.phi -> tau_phi', 'OutTauJets_%SYS%.pt -> tau_pt_%SYS%', 'OutTauJets_%SYS%.baselineSelection_tight -> tau_select_tight_%SYS%', ] if dataType != 'data': vars += [ 'OutTauJets_%SYS%.tau_effSF_tight_%SYS% -> tau_effSF_tight_%SYS%', ] # Include, and then set up the jet analysis algorithm sequence: from JetAnalysisAlgorithms.JetAnalysisConfig import makeJetAnalysisConfig jetContainer = 'AntiKt4EMPFlowJets' makeJetAnalysisConfig( configSeq, 'AnaJets', jetContainer, runJvtUpdate = True, runNNJvtUpdate = True ) vars += ['OutJets_%SYS%.pt -> jet_pt_%SYS%', 'OutJets_NOSYS.phi -> jet_phi', 'OutJets_NOSYS.eta -> jet_eta', ] from JetAnalysisAlgorithms.JetJvtAnalysisConfig import makeJetJvtAnalysisConfig makeJetJvtAnalysisConfig( configSeq, 'AnaJets', jetContainer ) if dataType != 'data': vars += [ 'OutJets_%SYS%.jvt_effSF_%SYS% -> jet_jvtEfficiency_%SYS%', ] from AsgAnalysisAlgorithms.AsgAnalysisConfig import makePtEtaSelectionConfig makePtEtaSelectionConfig (configSeq, 'AnaElectrons', selectionDecoration='selectPtEta', minPt=electronMinPt, maxEta=electronMaxEta) makePtEtaSelectionConfig (configSeq, 'AnaPhotons', selectionDecoration='selectPtEta', minPt=photonMinPt, maxEta=photonMaxEta) makePtEtaSelectionConfig (configSeq, 'AnaMuons', selectionDecoration='selectPtEta', minPt=muonMinPt, maxEta=muonMaxEta) makePtEtaSelectionConfig (configSeq, 'AnaTauJets', selectionDecoration='selectPtEta', minPt=tauMinPt, maxEta=tauMaxEta) makePtEtaSelectionConfig (configSeq, 'AnaJets', selectionDecoration='selectPtEta', minPt=jetMinPt, maxEta=jetMaxEta) from AsgAnalysisAlgorithms.AsgAnalysisConfig import makeOutputThinningConfig makeOutputThinningConfig (configSeq, 'AnaElectrons', selection='selectPtEta&&baselineSelection_loose,as_char', outputName='OutElectrons') makeOutputThinningConfig (configSeq, 'AnaPhotons', selection='selectPtEta&&baselineSelection_tight,as_char', outputName='OutPhotons') makeOutputThinningConfig (configSeq, 'AnaMuons', selection='selectPtEta&&baselineSelection_medium,as_char', outputName='OutMuons') makeOutputThinningConfig (configSeq, 'AnaTauJets', selection='selectPtEta&&baselineSelection_tight,as_char', outputName='OutTauJets') makeOutputThinningConfig (configSeq, 'AnaJets', selection='selectPtEta', outputName='OutJets') configAccumulator = ConfigAccumulator (dataType, algSeq, isPhyslite=isPhyslite) configSeq.fullConfigure (configAccumulator) def makeSequence (dataType, useBlocks, forCompare, noSystematics, hardCuts = False, isPhyslite = False, noPhysliteBroken = False) : # do some harder cuts on all object types, this is mostly used for # benchmarking if hardCuts : global electronMinPt electronMinPt = 27e3 global photonMinPt photonMinPt = 27e3 global muonMinPt muonMinPt = 27e3 global tauMinPt tauMinPt = 27e3 global jetMinPt jetMinPt = 45e3 algSeq = AlgSequence() # Set up the systematics loader/handler service: sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) if not noSystematics : sysService.sigmaRecommended = 1 vars = [] if not useBlocks : makeSequenceOld (dataType, algSeq, vars=vars, forCompare=forCompare, isPhyslite=isPhyslite, noPhysliteBroken=noPhysliteBroken) else : makeSequenceBlocks (dataType, algSeq, vars=vars, forCompare=forCompare, isPhyslite=isPhyslite, noPhysliteBroken=noPhysliteBroken) # Add an ntuple dumper algorithm: treeMaker = createAlgorithm( 'CP::TreeMakerAlg', 'TreeMaker' ) treeMaker.TreeName = 'analysis' # the auto-flush setting still needs to be figured out #treeMaker.TreeAutoFlush = 0 algSeq += treeMaker ntupleMaker = createAlgorithm( 'CP::AsgxAODNTupleMakerAlg', 'NTupleMaker' ) ntupleMaker.TreeName = 'analysis' ntupleMaker.Branches = vars # ntupleMaker.OutputLevel = 2 # For output validation algSeq += ntupleMaker treeFiller = createAlgorithm( 'CP::TreeFillerAlg', 'TreeFiller' ) treeFiller.TreeName = 'analysis' algSeq += treeFiller return algSeq