Skip to content
Snippets Groups Projects
  • Mark Andrew Owen's avatar
    30c29cc2
    Prototye for how to get the needed chain information to the jet configuration. · 30c29cc2
    Mark Andrew Owen authored and Frank Winklmeier's avatar Frank Winklmeier committed
    What I changed:
    - JetChainConfiguration now represents the configuration of all the jet parts of the chain (e.g. j80_j60) rather than just a single leg.
    - Because of this GenerateJetChainDefs no longer splits the chain defs.
    - Similarly, in GenerateBjetChainDefs, the jet part of the chain is created from the unsplit chain def.
    - The extractRecoDict function in JetRecoConfiguration now handles a vector of chain parts and checks the settings are consistent in the different parts.
    30c29cc2
    History
    Prototye for how to get the needed chain information to the jet configuration.
    Mark Andrew Owen authored and Frank Winklmeier's avatar Frank Winklmeier committed
    What I changed:
    - JetChainConfiguration now represents the configuration of all the jet parts of the chain (e.g. j80_j60) rather than just a single leg.
    - Because of this GenerateJetChainDefs no longer splits the chain defs.
    - Similarly, in GenerateBjetChainDefs, the jet part of the chain is created from the unsplit chain def.
    - The extractRecoDict function in JetRecoConfiguration now handles a vector of chain parts and checks the settings are consistent in the different parts.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
JetRecoConfiguration.py 6.93 KiB
#
#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
#

##########################################################################################
# Helper functions to digest the reconstruction options dictionary
# and translate it into the python configuration objects used by
# jet reco code.

from JetRecConfig.JetDefinition import JetConstit, xAODType, JetDefinition
from AthenaCommon.Logging import logging
log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.Jet.JetRecoConfiguration")

# Extract the jet reco dict from the chainDict
def extractRecoDict(chainParts):
    # interpret the reco configuration only
    # eventually should just be a subdict in the chainDict
    recoKeys = ['recoAlg','dataType','calib','jetCalib','trkopt','cleaning']
    recoDict = {}
    for p in chainParts:
        for k in recoKeys:
            # Look for our key in the chain part
            if k in p.keys():
                # found the key, check for consistency with other chain parts of this chain
                if k in recoDict.keys():
                    if p[k] != recoDict[k]:
                        log.error('Inconsistent reco setting for' + k)
                        exit(1)
                # copy this entry to the reco dictionary
                recoDict[k] = p[k]

    return recoDict

# Define the jet constituents to be interpreted by JetRecConfig
# When actually specifying the reco, clustersKey should be
# set, but default to None to allow certain checks, in particular
# grooming configuration
def defineJetConstit(jetRecoDict,clustersKey=None,pfoPrefix=None):
    constitMods = []
    if "sk" in jetRecoDict["dataType"]:
        constitMods.append("SK")

    # Get the details of the constituent definition:
    # type, mods and the input container name
    if jetRecoDict["dataType"]=="pf":
        jetConstit = JetConstit( xAODType.ParticleFlow, constitMods)
        if pfoPrefix is None:
            raise RuntimeError("JetRecoConfiguration: Cannot define PF jets without pfo prefix!")
        jetConstit.rawname = pfoPrefix+"ParticleFlowObjects"
        jetConstit.inputname = pfoPrefix+"CHSParticleFlowObjects"
        
    if "tc" in jetRecoDict["dataType"]:
        # apply this scale
        if jetRecoDict["calib"] == "em":
            constitMods = ["EM"] + constitMods
        elif jetRecoDict["calib"] == "lcw":
            constitMods = ["LC"] + constitMods
        # read from this cluster collection,
        # overriding the standard offline collection
        jetConstit = JetConstit( xAODType.CaloCluster, constitMods)
        if clustersKey is not None:
            jetConstit.rawname = clustersKey
            if jetRecoDict["dataType"]=="tc":
                jetConstit.inputname = clustersKey
        # apply constituent pileup suppression
        if "cs" in jetRecoDict["dataType"]:
            constitMods.append("CS")
        if "sk" in jetRecoDict["dataType"]:
            constitMods.append("SK")
    return jetConstit

# Arbitrary min pt for fastjet, set to be low enough for MHT(?)
# Could/should adjust higher for large-R
def defineJets(jetRecoDict,clustersKey=None,pfoPrefix=None):
    radius = float(jetRecoDict["recoAlg"].lstrip("a").rstrip("tr"))/10
    jetConstit = defineJetConstit(jetRecoDict,clustersKey,pfoPrefix)
    jetDef = JetDefinition( "AntiKt", radius, jetConstit, ptmin=5000.)
    return jetDef

def defineReclusteredJets(jetRecoDict):
    rcJetConstit = JetConstit( xAODType.Jet, [])
    rcJetDef = JetDefinition( "AntiKt", 1.0, rcJetConstit)
    return rcJetDef

def defineGroomedJets(jetRecoDict,ungroomedDef,ungroomedJetsName):
    from JetRecConfig.JetGrooming import JetTrimming
    # Only actually one type now, but leave open possibility of others
    groomDef = {
        "t":JetTrimming(ungroomedDef,ungroomedJetsName,smallR=0.2,ptfrac=0.05)
        }[jetRecoDict["recoAlg"][-1]]
    return groomDef

##########################################################################################
# Generation of modifier lists. So far only calib, but can add track, substructure mods

from JetRecConfig.StandardJetMods import jetmoddict

# Make generating the list a bit more comprehensible
def getModSpec(modname,modspec=''):
    return (jetmoddict[modname],str(modspec))

def defineTrackMods(trkopt):
    trkmods = [
        (jetmoddict["TrackMoments"],trkopt),
        (jetmoddict["JVF"],trkopt),
        (jetmoddict["JVT"],trkopt)
    ]
    return trkmods

# Translate calib specification into something understood by
# the calibration config helper
def defineCalibFilterMods(jetRecoDict,dataSource,rhoKey="auto"):
    # Minimum modifier set for calibration w/o track GSC
    # Should eventually build in more mods, depend on track info etc
    jetalg = jetRecoDict["recoAlg"]
    if jetRecoDict["jetCalib"] == "nojcalib" or jetalg=="a10r":
        calibMods = []
    else:
        if jetRecoDict["trkopt"]=="notrk" and "gsc" in jetRecoDict["jetCalib"]:
            raise ValueError("Track GSC requested but no track source provided!")

        if jetRecoDict["trkopt"]=="notrk" and "subres" in jetRecoDict["jetCalib"]:
            raise ValueError("Pileup residual calibration requested but no track source provided!")

        if jetRecoDict["dataType"]=="tc":
            calibContext,calibSeq = {
                ("a4","subjes"):   ("TrigRun2","JetArea_EtaJES_GSC"),        # Calo GSC only
                ("a4","subjesIS"): ("TrigRun2","JetArea_EtaJES_GSC_Insitu"), # Calo GSC only
                ("a4","subjesgscIS"): ("TrigRun2GSC","JetArea_EtaJES_GSC_Insitu"), # Calo+Trk GSC
                ("a4","subresjesgscIS"): ("TrigRun2GSC","JetArea_Residual_EtaJES_GSC_Insitu"), # pu residual + calo+trk GSC
                ("a10","subjes"):  ("TrigUngroomed","JetArea_EtaJES"),
                ("a10t","jes"):    ("TrigTrimmed","EtaJES_JMS"),
                }[(jetRecoDict["recoAlg"],jetRecoDict["jetCalib"])]

            pvname = ""
            gscDepth = "EM3"
            if "gsc" in jetRecoDict["jetCalib"]:
                gscDepth = "trackWIDTH"
                pvname = "HLT_EFHistoPrmVtx"

        elif jetRecoDict["dataType"]=="pf":
            gscDepth = "auto"
            calibContext = "TrigLS2"
            calibSeq = "JetArea_Residual_EtaJES_GSC"
            if jetRecoDict["jetCalib"].endswith("IS"):
                calibSeq += "_Insitu"
            pvname = "HLT_EFHistoPrmVtx"

        calibSpec = ":".join( [calibContext, dataSource, calibSeq, rhoKey, pvname, gscDepth] )
        from .TriggerJetMods import ConstitFourMom_copy
        if jetalg=="a4":
            calibMods = [(ConstitFourMom_copy,""),
                         getModSpec("CaloEnergies"), # Needed for GSC
                         getModSpec("Calib",calibSpec),
                         getModSpec("Sort")]
        else:
            calibMods = [(ConstitFourMom_copy,""),
                         getModSpec("Calib",calibSpec),
                         getModSpec("Sort")]

    filtercut = {"a4":5000, "a10":50000, "a10r": 50000, "a10t":100000}[jetalg]
    return calibMods + [getModSpec("Filter",filtercut)]