Newer
Older
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
from AthenaCommon.CFElements import parOR
from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import RecoFragmentsPool
from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable
from JetRecConfig.JetRecConfig import getConstitPJGAlg, getJetAlgorithm
from JetRecConfig import JetInputConfig
from JetRecConfig import JetRecConfig
from TrigEDMConfig.TriggerEDMRun3 import recordable
from . import JetRecoConfiguration
from .JetRecoConfiguration import jetRecoDictToString
###############################################################################################
# Sequences for input information
# Calo cell unpacking and topocluster reconstruction
def jetClusterSequence(configFlags, RoIs, clusterCalib):
# Start by adding the topocluster reco sequence
from TriggerMenuMT.HLTMenuConfig.CommonSequences.CaloSequenceSetup import (
caloClusterRecoSequence, LCCaloClusterRecoSequence)
if clusterCalib == "em":
topoClusterSequence, clustersKey = RecoFragmentsPool.retrieve(
caloClusterRecoSequence, flags=None, RoIs=RoIs)
elif clusterCalib == "lcw":
topoClusterSequence, clustersKey = RecoFragmentsPool.retrieve(
LCCaloClusterRecoSequence, flags=None, RoIs=RoIs)
else:
raise ValueError("Invalid value for calib: '{}'".format(clusterCalib))
return topoClusterSequence, clustersKey
###############################################################################################
# Sequences that set up the concrete jet finding job
# Need to do this hacky extraction to get around the inability
# to hash dicts as input to RecoFragmentsPool.retrieve
from .JetTrackingConfig import trkcollskeys
def getTrkColls(jetRecoDict):
trkcolls = {key:jetRecoDict[key] for key in trkcollskeys}
return trkcolls
# The top-level sequence, forwards arguments as appropriate to
# standard jet reco, grooming or reclustering sequences
# If tracking is required, then the trkcolls dict (returned by the
# JetTrackingSequence) must also be passed as kwargs
def jetRecoSequence( configFlags, clustersKey, **jetRecoDict ):
jetalg, jetradius, extra = JetRecoConfiguration.interpretRecoAlg(jetRecoDict["recoAlg"])
doGrooming = extra in ["t","sd"]
doRecluster = extra == "r"
dataSource = "mc" if configFlags.Input.isMC else "data"
return RecoFragmentsPool.retrieve(
reclusteredJetRecoSequence,
configFlags, dataSource=dataSource,
clustersKey=clustersKey, **jetRecoDict)
return RecoFragmentsPool.retrieve(
groomedJetRecoSequence,
configFlags, dataSource=dataSource,
clustersKey=clustersKey, **jetRecoDict)
return RecoFragmentsPool.retrieve(
standardJetRecoSequence,
configFlags, dataSource=dataSource,
clustersKey=clustersKey, **jetRecoDict)
# Normal jet reconstruction, no reclustering or grooming

Teng Jian Khoo
committed
def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
jetDefString = jetRecoDictToString(jetRecoDict)

Teng Jian Khoo
committed
buildSeq = parOR( "JetBuildSeq_"+jetDefString, [])
trkcolls = getTrkColls(jetRecoDict) if jetRecoDict["trkopt"]!="notrk" else {}
# Add particle flow reconstruction if needed
if jetRecoDict["constitType"] == "pf":
if not trkcolls:
raise RuntimeError("PFlow jet chain requested with no tracking option!")
from eflowRec.PFHLTSequence import PFHLTSequence
(pfseq, pfoPrefix) = RecoFragmentsPool.retrieve(
PFHLTSequence,
configFlags, clustersin=clustersKey, tracktype=jetRecoDict["trkopt"])

Teng Jian Khoo
committed
buildSeq += pfseq
jetDef = JetRecoConfiguration.defineJets(jetRecoDict,pfoPrefix=pfoPrefix,prefix=jetNamePrefix)

Teng Jian Khoo
committed
jetDef = JetRecoConfiguration.defineJets(jetRecoDict,clustersKey=clustersKey,prefix=jetNamePrefix)
# chosen jet collection
jetsFullName = jetDef.fullname()
jetsOut = recordable(jetsFullName)
JetRecConfig.instantiateAliases(jetDef)
doConstitMods = jetRecoDict["constitMod"]+jetRecoDict["constitType"] in ["sktc","cssktc", "pf", "csskpf"]
if doConstitMods:
# Get online monitoring jet rec tool
from JetRecTools import OnlineMon
monJetRecTool = OnlineMon.getMonTool_Algorithm("HLTJets/"+jetsFullName+"/")
from JetRecConfig.ConstModHelpers import getConstitModAlg
constitModAlg = getConstitModAlg(jetDef.inputdef, monTool=monJetRecTool)
if constitModAlg:

Teng Jian Khoo
committed
buildSeq += constitModAlg
# Add the PseudoJetGetter alg to the sequence
constitPJAlg = getConstitPJGAlg( jetDef.inputdef )
constitPJKey = str(constitPJAlg.OutputContainer)

Teng Jian Khoo
committed
buildSeq += conf2toConfigurable( constitPJAlg )
# Basic list of PseudoJets is just the constituents
# Append ghosts (tracks) if desired
pjs = [constitPJKey]
if trkcolls:
pjs.append(trkcolls["GhostTracks"])
jetModList = []
if trkcolls:
trkMods = JetRecoConfiguration.defineTrackMods(jetRecoDict["trkopt"])
jetModList += trkMods

Teng Jian Khoo
committed
# Sort and filter
jetModList += ["Sort", "Filter:"+str(JetRecoConfiguration.getFilterCut(jetRecoDict["recoAlg"]))]
# Get online monitoring tool
from JetRec import JetOnlineMon
monTool = JetOnlineMon.getMonTool_TrigJetAlgorithm("HLTJets/"+jetsFullName+"/")
jetDef.modifiers = jetModList
# recall instantiateAliases because we updated the modifiers
JetRecConfig.instantiateAliases(jetDef)
# make sure all our JetModifier have their track inputs set up according to trkopt
from JetRecConfig.JetModConfig import jetModWithAlternateTrk
jetModWithAlternateTrk(jetDef, jetRecoDict['trkopt'] )
# Generate a JetAlgorithm to run the jet finding and modifiers
# (via a JetRecTool instance).
jetRecAlg = JetRecConfig.getJetAlgorithm(jetsFullName, jetDef, pjs, monTool)

Teng Jian Khoo
committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
buildSeq += conf2toConfigurable( jetRecAlg )
return buildSeq, jetsOut, jetDef
def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
jetDefString = jetRecoDictToString(jetRecoDict)
if jetRecoDict["jetCalib"]=="nojcalib":
return RecoFragmentsPool.retrieve( standardJetBuildSequence, configFlags, dataSource=dataSource,
clustersKey=clustersKey,**jetRecoDict)
# Schedule reconstruction w/o calibration
# This is just a starting point -- will change so that
# the calibration is only ever done at the end for ungroomed
_jetRecoDictNoJCalib = dict(jetRecoDict)
_jetRecoDictNoJCalib["jetCalib"] = "nojcalib"
buildSeq, jetsNoCalib, jetDefNoCalib = RecoFragmentsPool.retrieve( standardJetBuildSequence, configFlags, dataSource=dataSource,
clustersKey=clustersKey, **_jetRecoDictNoJCalib)
recoSeq = parOR( "JetRecSeq_"+jetDefString, [buildSeq])
# Get the calibration tool if desired.
jetDef = jetDefNoCalib.clone()
jetDef.suffix = jetDefNoCalib.suffix.replace("nojcalib",jetRecoDict["jetCalib"])
jetsOut = jetDef.fullname()
rhoKey = "auto"
if "sub" in jetRecoDict["jetCalib"]:
# Add the event shape alg if needed for area subtraction
eventShapeAlg = JetInputConfig.buildEventShapeAlg( jetDef, jetNamePrefix )
recoSeq += conf2toConfigurable(eventShapeAlg)
# Not currently written because impossible to merge
# across event views, which is maybe a concern in
# the case of regional PFlow
rhoKey = str(eventShapeAlg.EventDensityTool.OutputContainer)
jetDef.modifiers = JetRecoConfiguration.defineCalibMods(jetRecoDict,dataSource,rhoKey)
jetDef.modifiers += jetDefNoCalib.modifiers[:-2] # Leave off sort + filter
copyCalibAlg = JetRecConfig.getJetCopyAlg(jetsin=jetsNoCalib,jetsoutdef=jetDef)
recoSeq += copyCalibAlg
return recoSeq, jetsOut, jetDef
# Grooming needs the ungroomed jets to be built first,
# so call the basic jet reco seq, then add a grooming alg
def groomedJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
jetDefString = jetRecoDictToString(jetRecoDict)
recoSeq = parOR( "JetGroomSeq_"+jetDefString, [])
ungroomedJetRecoDict = dict(jetRecoDict)
ungroomedJetRecoDict["recoAlg"] = ungroomedJetRecoDict["recoAlg"].rstrip("tsd") # Drop grooming spec
ungroomedJetRecoDict["jetCalib"] = "nojcalib" # No need to calibrate

Teng Jian Khoo
committed
# Only jet building -- we do jet calib in a larger sequence via copy+calib
(ungroomedJetBuildSequence,ungroomedJetsName,ungroomedDef) = RecoFragmentsPool.retrieve(
standardJetBuildSequence,
configFlags, dataSource=dataSource, clustersKey=clustersKey,
**ungroomedJetRecoDict)

Teng Jian Khoo
committed
recoSeq += ungroomedJetBuildSequence
# Need to forward the pseudojets of the parents to the groomer

Teng Jian Khoo
committed
# Should try to do this in a nicer way...
parentpjs = getattr(ungroomedJetBuildSequence,"jetalg_{}".format(ungroomedJetsName)).Tools[0].InputPseudoJets
groomDef = JetRecoConfiguration.defineGroomedJets(jetRecoDict,ungroomedDef)
groomedJetsFullName = groomDef.fullname()

Teng Jian Khoo
committed
groomDef.modifiers = JetRecoConfiguration.defineCalibMods(jetRecoDict,dataSource)
groomDef.modifiers += ["Sort","Filter:"+str(JetRecoConfiguration.getFilterCut(jetRecoDict["recoAlg"]))]
# Can add substructure mods here
# Get online monitoring tool
from JetRec import JetOnlineMon
monTool = JetOnlineMon.getMonTool_TrigJetAlgorithm("HLTJets/"+groomedJetsFullName+"/")
from JetRecConfig.JetGroomConfig import getJetGroomAlg_jetAlg, instantiateGroomingAliases
instantiateGroomingAliases(groomDef)
groomalg = getJetGroomAlg_jetAlg(groomDef,parentpjs,monTool)
recoSeq += conf2toConfigurable( groomalg )
jetsOut = recordable(groomedJetsFullName)
jetDef = groomDef
return recoSeq, jetsOut, jetDef
# Reclustering -- call the basic jet reco and add this to the sequence,
# then add another jet algorithm to run the reclustering step
def reclusteredJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
jetDefString = jetRecoDictToString(jetRecoDict)
recoSeq = parOR( "JetReclusterSeq_"+jetDefString, [])
basicJetRecoDict = dict(jetRecoDict)
basicJetRecoDict["recoAlg"] = "a4" # Standard size for reclustered
(basicJetRecoSequence,basicJetsName, basicJetDef) = RecoFragmentsPool.retrieve(
standardJetRecoSequence,
configFlags, dataSource=dataSource, clustersKey=clustersKey,
**basicJetRecoDict)
recoSeq += basicJetRecoSequence
rcJetPtMin = 15e3 # 15 GeV minimum pt for jets to be reclustered
from JetRec.JetRecConf import JetViewAlg
filteredJetsName = basicJetsName+"_pt15"
recoSeq += JetViewAlg("jetview_"+filteredJetsName,
InputContainer=basicJetsName,
OutputContainer=filteredJetsName,
PtMin=rcJetPtMin)
rcJetDef = JetRecoConfiguration.defineReclusteredJets(jetRecoDict, filteredJetsName)
rcJetsFullName = jetNamePrefix+rcJetDef.basename+"Jets_"+jetRecoDict["jetCalib"]
rcModList = [] # Could set substructure mods
rcJetDef.modifiers = rcModList
rcConstitPJAlg = getConstitPJGAlg( rcJetDef.inputdef )
rcConstitPJKey = str(rcConstitPJAlg.OutputContainer)
recoSeq += conf2toConfigurable( rcConstitPJAlg )
# Get online monitoring tool
from JetRec import JetOnlineMon
monTool = JetOnlineMon.getMonTool_TrigJetAlgorithm("HLTJets/"+rcJetsFullName+"/")
rcPJs = [rcConstitPJKey]
rcJetRecAlg = getJetAlgorithm(rcJetsFullName, rcJetDef, rcPJs, monTool)
recoSeq += conf2toConfigurable( rcJetRecAlg )
jetsOut = recordable(rcJetsFullName)
return recoSeq, jetsOut, jetDef