Commit d2791f2e authored by Pierre Antoine Delsart's avatar Pierre Antoine Delsart Committed by Frank Winklmeier
Browse files

Adapt new jet config for full reco support and fix ATLASRECTS-6398

parent 3d71f085
......@@ -78,8 +78,9 @@ def getConstitFourMomTool(jetdef, modspec=""):
cfourmom.AltConstitScales = [0]
cfourmom.AltJetScales = ["JetConstitScaleMomentum"]
else:
clstate = "CALIBRATED" if "LCTopo" in jetdef.basename else "UNCALIBRATED"
cfourmom.AltConstitColls = ["CaloCalTopoClusters"]
cfourmom.AltConstitScales = [CaloClusterStates["CALIBRATED"]]
cfourmom.AltConstitScales = [CaloClusterStates[clstate]]
cfourmom.AltJetScales = [""]
# Drop the LC-calibrated four-mom for EMTopo jets as we only wanted it as a possibility
# in MET CST calculations but never used it
......
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
# jobOption fragment to schedule jetbuilding in a runII config style standard reconstruction,
# BUT using the new runIII jet config
from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable, ComponentAccumulator
from JetRecConfig.StandardSmallRJets import AntiKt4EMPFlow, AntiKt4LCTopo, AntiKt4EMTopo, AntiKt4Truth
from JetRecConfig.StandardLargeRJets import AntiKt10LCTopo
from JetRecConfig.JetRecConfig import getJetDefAlgs
from JetRecConfig.StandardJetConstits import stdConstitDic
from JetCalibTools.JetCalibToolsConfig import pflowcontexts, topocontexts
def reOrderAlgs(algs):
"""In runIII the scheduler automatically orders algs, so the JetRecConfig helpers do not try to enforce the correct ordering.
This is not the case in runII config for which this jobO is intended --> This function makes sure some jet-related algs are well ordered.
"""
evtDensityAlgs = [ (i,alg) for (i,alg) in enumerate(algs) if alg.getType() == 'EventDensityAthAlg' ]
pjAlgs = [ (i,alg) for (i,alg) in enumerate(algs) if alg.getType() == 'PseudoJetAlgorithm' ]
pairsToswap = []
for i,edalg in evtDensityAlgs:
edInput = edalg.EventDensityTool.InputContainer
for j,pjalg in pjAlgs:
if j<i: continue
if edInput == str(pjalg.OutputContainer):
pairsToswap.append( (i,j) )
for (i,j) in pairsToswap:
algs[i], algs[j] = algs[j], algs[i]
return algs
##
# Temporary hack : JetConstituentModSequence for EMPFlow seems to be scheduled
# somewhere else in the standard reco chain with a different alg name as the alg created by JetRecConfig helpers.
# The trick below will make so the new helpers do NOT schedule a JetConstituentModSequence and thus avoid conflicts.
stdConstitDic.EMPFlow._locked = False
stdConstitDic.EMPFlow.inputname = stdConstitDic.EMPFlow.containername
# the Standard list of jets to run :
jetdefs = [AntiKt4EMTopo, AntiKt4EMPFlow , AntiKt4LCTopo, AntiKt4Truth , AntiKt10LCTopo]
# we'll remember the EventDensity collections we create.
evtDensities = []
#--------------------------------------------------------------
# Create the jet algs from the jet definitions
#--------------------------------------------------------------
for jd in jetdefs:
algs, jetdef_i = getJetDefAlgs(ConfigFlags, jd, True)
algs = reOrderAlgs( [a for a in algs if a is not None])
for a in algs:
topSequence += conf2toConfigurable(a)
if "EventDensityAthAlg" in a.getType():
evtDensities.append( str(a.EventDensityTool.OutputContainer) )
#--------------------------------------------------------------
# Build output container list.
#--------------------------------------------------------------
for jetdef in jetdefs:
jetFlags.jetAODList += [ f"xAOD::JetContainer#{jetdef.fullname()}" ]
auxprefix = ""
# if jetrec.Trigger:
# auxprefix = "Trig"
jetFlags.jetAODList += [ f"xAOD::Jet{auxprefix}AuxContainer#{jetdef.fullname()}Aux." ,
f"xAOD::JetAuxContainer#{jetdef.fullname()}Aux.-PseudoJet"]
if jetFlags.useTracks() and jetFlags.useTopo():
jetFlags.jetAODList += [ "xAOD::CaloClusterContainer#EMOriginTopoClusters" ,
"xAOD::CaloClusterContainer#LCOriginTopoClusters" ,
"xAOD::ShallowAuxContainer#LCOriginTopoClustersAux.",
"xAOD::ShallowAuxContainer#EMOriginTopoClustersAux."]
jetFlags.jetAODList += [ "xAOD::PFOContainer#CHSChargedParticleFlowObjects",
"xAOD::PFOContainer#CHSNeutralParticleFlowObjects",
"xAOD::ShallowAuxContainer#CHSChargedParticleFlowObjectsAux.",
"xAOD::ShallowAuxContainer#CHSNeutralParticleFlowObjectsAux."]
# save event shapes set with the JetAlgorithm
for edname in evtDensities:
jetFlags.jetAODList += [ f"xAOD::EventShape#{edname}",
f"xAOD::EventShapeAuxInfo#{edname}Aux.",]
......@@ -12,7 +12,8 @@ StatusCode PseudoJetMerger::initialize() {
ATH_MSG_DEBUG("Initializing...");
if(m_inputPJC.empty() || m_outcoll.key().empty()) {
ATH_MSG_ERROR("Either input or output collection is empty!");
if(m_inputPJC.empty() ) { ATH_MSG_ERROR("Input container array is empty! "<< m_inputPJC.size() );}
else {ATH_MSG_ERROR("OutputContainer container array is empty! "<< m_outcoll.key() );}
return StatusCode::FAILURE;
}
......
......@@ -10,7 +10,7 @@ The functions here are scaning reccursively all the aliases, building the corres
collecting them in a JetDefinition.
"""
from .JetDefinition import JetInputExternal, JetInputConstit, JetModifier
from .JetDefinition import JetInputExternal, JetInputConstit, JetModifier, JetInputConstitSeq
class _dummyJetDef:
def __init__(self):
......@@ -115,15 +115,15 @@ def solveConstitDependencies(constitseq, parentjetdef, inplace=False):
stdInputExtDic.setdefault( constitseq.inputname, JetInputExternal( constitseq.inputname, constitseq.basetype) )
# we re-use the solveInputExternalDependencies to instantiate the prereqs
constitseq.prereqs += ['input:'+constitseq.inputname] # make sure the external input to these constituents are taken into account.
solveInputExternalDependencies( constitseq, parentjetdef)
# JetInputConstit don't have modifiers, we can return immediately
if not hasattr( constitseq, "modifiers") : return constitseq
# instantiate the JetConstitModifier (those don't have dependencies)
for mod in constitseq.modifiers:
modInstance = stdContitModifDic[ mod ].clone()
constitseq._instanceMap[mod] = modInstance
if isinstance( constitseq, JetInputConstitSeq):
# instantiate the JetConstitModifier and add their dependencies to the actual constit sequence
for mod in constitseq.modifiers:
modInstance = stdContitModifDic[ mod ].clone()
parentjetdef._prereqDic[f'cmod:{mod}'] = modInstance
solveInputExternalDependencies( modInstance, parentjetdef, inplace=True)
# the rest of dependencies are handled similarly as JetInputExternal :
solveInputExternalDependencies( constitseq, parentjetdef)
return constitseq
......
......@@ -400,7 +400,7 @@ def JetRecCfg_reorder(jetdef, configFlags, returnFinalJetDef=False):
they are in proper order.
Re-ordering is done manually, according to various input alg type.
"""
res = JetRecConfig.JetRecCfg_original(jetdef, configFlags, returnFinalJetDef)
res = JetRecConfig.JetRecCfg_original(configFlags, jetdef , returnFinalJetDef)
acc , _ = res if returnFinalJetDef else (res,None)
algs = acc.algs
......
......@@ -64,6 +64,7 @@ from AthenaCommon.SystemOfUnits import MeV
@clonable
@onlyAttributesAreProperties
class JetDefinition(object):
_allowedattributes = ['_cflags'] # onlyAttributesAreProperties will add all properties to this list.
def __init__(self,
algorithm, # The fastjet clustering algorithm
radius, # The jet radius specifier (clustering cutoff)
......@@ -110,7 +111,8 @@ class JetDefinition(object):
# used internally to resolve dependencies
self._prereqDic = {}
self._prereqOrder = []
self._internalAtt = {}
self._internalAtt = {}
self._cflags = None # pointer to AthenaConfiguration.ConfigFlags. Mainly to allow to invoke building of input dependencies which are outside Jet domain during std reco
self._locked = lock
......@@ -251,8 +253,6 @@ class JetModifier(object):
# These will be set as the Gaudi properties of the C++ tool
self.properties = properties
self._instanceMap = {}
#self._locked = lock
......@@ -523,7 +523,6 @@ class JetInputConstitSeq(JetInputConstit):
self.inputname = inputname or name
self.modifiers = modifiers
self._instanceMap = dict() # internal maps of modifier to actual configuration object
self._locked = lock
......@@ -549,7 +548,7 @@ class JetInputConstitSeq(JetInputConstit):
# Define a string conversion for printing
def __str__(self):
return f"JetInputConstitSeq({self.name}, {self.inputname} , {self.outputname})"
return f"JetInputConstitSeq({self.name}, {self.inputname} , {self.containername})"
# Need to override __repr__ for printing in lists etc
__repr__ = __str__
......@@ -569,17 +568,23 @@ class JetConstitModifier(object):
def __init__(self,
name,
tooltype,
properties={}):
prereqs= [],
properties={},
):
self.name = name
self.tooltype = tooltype
self.properties = properties
self.prereqs = prereqs
self.filterfn = _condAlwaysPass # we might want to make this a proper attribute in the future
@make_lproperty
def name(self): pass
@make_lproperty
def tooltype(self): pass
@make_lproperty
def properties(self): pass
@make_lproperty
def prereqs(self): pass
......
......@@ -56,7 +56,7 @@ def getEventShapeName( parentjetdef, inputspec):
return nameprefix+"Kt4"+label+"EventShape"
def buildEventShapeAlg( parentjetdef, inputspec ):
def buildEventShapeAlg( parentjetdef, inputspec, voronoiRf = 0.9 ):
"""Function producing an EventShapeAlg to calculate
median energy density for pileup correction"""
......@@ -65,12 +65,18 @@ def buildEventShapeAlg( parentjetdef, inputspec ):
label = parentjetdef.inputdef.label
rhotoolname = "EventDensity_"+nameprefix+"Kt4"+label
rhotool = CompFactory.EventDensityTool(rhotoolname)
rhotool.InputContainer = "PseudoJet"+label # same as in PseudoJet algs
rhotool.OutputContainer = rhokey
rhotool = CompFactory.EventDensityTool(
rhotoolname,
InputContainer = "PseudoJet"+label, # same as in PseudoJet algs
OutputContainer = rhokey,
JetRadius = parentjetdef.radius,
UseFourMomArea = True,
VoronoiRfact = voronoiRf,
JetAlgorithm = "Kt",)
eventshapealg = CompFactory.EventDensityAthAlg("{0}{1}Alg".format(nameprefix,rhotoolname))
eventshapealg.EventDensityTool = rhotool
eventshapealg = CompFactory.EventDensityAthAlg(
"{0}{1}Alg".format(nameprefix,rhotoolname),
EventDensityTool = rhotool )
return eventshapealg
......@@ -36,7 +36,7 @@ __all__ = ["JetRecCfg", "JetInputCfg"]
#
# Top level functions returning ComponentAccumulator out of JetDefinition
def JetRecCfg(jetdef, configFlags, returnConfiguredDef=False):
def JetRecCfg( configFlags, jetdef, returnConfiguredDef=False):
"""Top-level function for running jet finding or grooming.
This returns a ComponentAccumulator that can be merged with others
......@@ -47,7 +47,7 @@ def JetRecCfg(jetdef, configFlags, returnConfiguredDef=False):
- jetdef : jet or grooming definition
- configFlags : the AthenaConfiguration.AllConfigFlags.ConfigFlags, mainly for input file
peeking such that we don't attempt to reproduce stuff that's already
in the input file.
in the input file. And also to be able to invoke building of inputs outside of Jet domain during reco from RAW/RDO.
- returnConfiguredDef : is for debugging. It will also returns the cloned JetDefinition which contains the calculated dependencies.
"""
......@@ -62,18 +62,21 @@ def JetRecCfg(jetdef, configFlags, returnConfiguredDef=False):
# call the relevant function according to jetdef_i type
if isinstance(jetdef, JetDefinition):
algs, jetdef_i = getJetDefAlgs(jetdef, configFlags, True)
algs, jetdef_i = getJetDefAlgs(configFlags, jetdef , True)
elif isinstance(jetdef, GroomingDefinition):
algs, jetdef_i = getJetGroomAlgs(jetdef, configFlags, True)
algs, jetdef_i = getJetGroomAlgs(configFlags, jetdef, True)
for a in algs:
components.addEventAlgo( a , sequenceName = sequenceName )
if isinstance(a, ComponentAccumulator):
components.merge(a )
else:
components.addEventAlgo( a , sequenceName = sequenceName )
if returnConfiguredDef: return components, jetdef_i
return components
def JetInputCfg(jetOrConstitdef, configFlags, context="default"):
def JetInputCfg(configFlags,jetOrConstitdef , context="default"):
"""Returns a ComponentAccumulator containing algs needed to build inputs to jet finding as defined by jetOrConstitdef
jetOrConstitdef can either be
......@@ -91,7 +94,7 @@ def JetInputCfg(jetOrConstitdef, configFlags, context="default"):
return components
def PseudoJetCfg(jetdef, configFlags):
def PseudoJetCfg(jetdef):
"""Builds a ComponentAccumulator for creating PseudoJetContainer needed by jetdef.
THIS updates jetdef._internalAtt['finalPJContainer']
"""
......@@ -105,10 +108,10 @@ def PseudoJetCfg(jetdef, configFlags):
########################################################################
########################################################################
#
# Top level functions returning list of algs out of JetDefinition
# Mid level functions returning list of algs out of JetDefinition
def getJetDefAlgs(jetdef, configFlags, returnConfiguredDef=False, monTool=None):
def getJetDefAlgs(configFlags, jetdef , returnConfiguredDef=False, monTool=None):
""" Create the algorithms necessary to build the jet collection defined by jetdef.
This internally finds all the dependencies declared into jetdef (through input, ghosts & modifiers)
......@@ -117,17 +120,21 @@ def getJetDefAlgs(jetdef, configFlags, returnConfiguredDef=False, monTool=None)
if returnConfiguredDef==True, also returns the fully configured clone of jetdef containing solved dependencies (debugging)
monTool is to allow the trigger config to pass a monitoring tool.
returns a list containing either algs or ComponentAccumulator
(ComponentAccumulator occurs only (?) in reco from RDO/RAW when we need to build externals such as clusters or tracks : in this case we call the main config functions from external packages)
"""
# Scan the dependencies of this jetdef, also converting all aliases it contains
# into config objects and returning a fully configured copy.
jetdef_i = solveDependencies(jetdef)
jetdef_i._cflags = configFlags
# check if the conditions are compatible with the inputs & modifiers of this jetdef_i.
# if in standardRecoMode we will remove whatever is incompatible and still try to run
# if not, we raise an exception
canrun = removeComponentFailingConditions(jetdef_i, configFlags, raiseOnFailure= not jetdef_i.standardRecoMode)
canrun = removeComponentFailingConditions(jetdef_i, raiseOnFailure= not jetdef_i.standardRecoMode)
if not canrun :
if returnConfiguredDef:
return [], jetdef_i
......@@ -153,7 +160,7 @@ def getJetDefAlgs(jetdef, configFlags, returnConfiguredDef=False, monTool=None)
return algs, jetdef_i
return algs
def getJetGroomAlgs(groomdef, configFlags, returnConfiguredDef=False, monTool=None):
def getJetGroomAlgs(configFlags, groomdef, returnConfiguredDef=False, monTool=None):
"""Instantiate and schedule all the algorithms needed to run the grooming alg 'groomdef' and
add them in the ComponentAccumulator 'components'
......@@ -166,7 +173,7 @@ def getJetGroomAlgs(groomdef, configFlags, returnConfiguredDef=False, monTool=No
# Find dependencies from modifier aliases and get a fully configured groomdef
# ( This also detects input dependencies, see below)
groomdef_i = solveGroomingDependencies(groomdef)
# Transfer the input & ghost dependencies onto the parent jet alg,
# so they are handled when instatiating the parent jet algs
groomdef_i.ungroomeddef.ghostdefs += [ g.split(':')[1] for g in groomdef_i._prereqOrder if g.startswith('ghost:')]
......@@ -177,7 +184,7 @@ def getJetGroomAlgs(groomdef, configFlags, returnConfiguredDef=False, monTool=No
# Retrieve algs needed to build the parent (ungroomed) jets
# (we always want it even if the parent jets are already in the input file because
# we need to rebuild the pseudoJet)
algs, ungroomeddef_i = getJetDefAlgs(groomdef_i.ungroomeddef, configFlags, True)
algs, ungroomeddef_i = getJetDefAlgs(configFlags, groomdef_i.ungroomeddef , True)
groomdef_i._ungroomeddef = ungroomeddef_i # set directly the internal members to avoid complication. This is fine, since we've been cloning definitions.
algs += [ getJetRecGroomAlg(groomdef_i, monTool=monTool) ]
......@@ -204,7 +211,7 @@ def getPseudoJetAlgs(jetdef):
constitpjalg = getConstitPJGAlg( jetdef.inputdef )
#print("aaaa" , constitpjalg, constitpjalg.OutputContainer)
finalPJContainer = constitpjalg.OutputContainer
finalPJContainer = str(constitpjalg.OutputContainer)
pjalglist = [constitpjalg]
# Schedule the ghost PseudoJetAlgs
......@@ -216,7 +223,7 @@ def getPseudoJetAlgs(jetdef):
ghostdef = jetdef._prereqDic[ghostkey]
ghostpjalg = getGhostPJGAlg( ghostdef )
pjalglist.append(ghostpjalg)
pjContNames.append( ghostpjalg.OutputContainer )
pjContNames.append( str(ghostpjalg.OutputContainer) ) #
# .. and merge them together with the input constituents
mergeId = mergedPJId( pjContNames )
......@@ -242,7 +249,7 @@ def mergedPJId(pjList):
return str(_mergedPJContainers.setdefault(t, currentSize))
def getInputAlgs(jetOrConstitdef, configFlags, context="default", monTool=None):
def getInputAlgs(jetOrConstitdef, configFlags=None, context="default", monTool=None):
"""Returns the list of configured algs needed to build inputs to jet finding as defined by jetOrConstitdef
jetOrConstitdef can either be
......@@ -253,6 +260,7 @@ def getInputAlgs(jetOrConstitdef, configFlags, context="default", monTool=None):
The returned list may contain several algs, including constituent modifications algs, track selection, copying of
input truth particles and event density calculations
It may also contain ComponentAccumulator, only (?) in reco from RDO/RAW when we need to build externals such as clusters or tracks : in this case we call the main config functions from external packages)
"""
......@@ -260,8 +268,9 @@ def getInputAlgs(jetOrConstitdef, configFlags, context="default", monTool=None):
if isinstance(jetOrConstitdef, JetInputConstit):
# technically we need a JetDefinition, so just build an empty one only containing our JetInputConstit
jetlog.info("Setting up jet inputs from JetInputConstit : "+jetOrConstitdef.name)
jetdef = solveDependencies( JetDefinition('Kt', 0., jetOrConstitdef, context=context) )
canrun = removeComponentFailingConditions(jetdef, configFlags, raiseOnFailure= not jetdef.standardRecoMode)
jetdef = solveDependencies( JetDefinition('Kt', 0., jetOrConstitdef, context=context) )
jetdef._cflags = configFlags
canrun = removeComponentFailingConditions(jetdef, raiseOnFailure= not jetdef.standardRecoMode)
if not canrun:
return []
else:
......@@ -271,7 +280,7 @@ def getInputAlgs(jetOrConstitdef, configFlags, context="default", monTool=None):
# We won't prepare an alg if the input already exists in the in input file
try:
filecontents = configFlags.Input.Collections
filecontents = jetdef._cflags.Input.Collections
except Exception:
filecontents = []
# local function to check if the container of the JetInputXXXX 'c' is already in filecontents :
......@@ -285,7 +294,7 @@ def getInputAlgs(jetOrConstitdef, configFlags, context="default", monTool=None):
for inputfull in inputdeps:
inputInstance = jetdef._prereqDic[inputfull]
if isInInput( inputInstance ):
jetlog.debug(f"Input container for {inputInstance} already in input file.")
jetlog.info(f"Input container for {inputInstance} already in input file.")
continue
if isinstance(inputInstance, JetInputConstit):
......@@ -481,7 +490,7 @@ def getConstitModAlg(parentjetdef, constitSeq, monTool=None):
if constitSeq.inputname == constitSeq.containername: return
for step in sequence:
modInstance = constitSeq._instanceMap[ step ]
modInstance = parentjetdef._prereqDic[ f'cmod:{step}' ]
if not modInstance.tooltype: continue
toolclass = getattr( CompFactory, modInstance.tooltype)
......@@ -583,14 +592,17 @@ def getModifier(jetdef, moddef, modspec):
def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
def removeComponentFailingConditions(jetdef, configflags=None, raiseOnFailure=True):
"""Filters the lists jetdef.modifiers and jetdef.ghosts (and jetdef._prereqOrder), so only the components
comptatible with configflags are selected.
If configflags==None : assume jetdef._cflags is properly set (this is done by higher-level functions)
The compatibility is ultimately tested using the component 'filterfn' attributes.
Internally calls the function isComponentPassingConditions() (see below)
"""
jetlog.info("Standard Reco mode : filtering components in "+str(jetdef))
if jetdef._cflags is None:
jetdef._cflags = configflags
## TODO :
## do not raise an exceptin immediately. Instead collect all failure
......@@ -607,7 +619,7 @@ def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
for comp in inList:
fullkey = basekey+comp
cInstance = jetdef._prereqDic[fullkey]
ok, reason = isComponentPassingConditions(cInstance, configflags, jetdef._prereqDic)
ok, reason = isComponentPassingConditions(cInstance, jetdef._cflags, jetdef._prereqDic)
if not ok :
if raiseOnFailure:
raise Exception("JetDefinition {} can NOT be scheduled. Failure of {} {} reason={}".format(
......@@ -615,7 +627,8 @@ def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
nOut+=1
jetlog.info(f"{fullname} : removing {compType} {comp} reason={reason}")
jetdef._prereqOrder.remove(fullkey)
if fullkey in jetdef._prereqOrder:
jetdef._prereqOrder.remove(fullkey)
if compType=='ghost':
jetdef._prereqOrder.remove('input:'+comp)
else:
......@@ -627,14 +640,19 @@ def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
# ---------
# first check if the input can be obtained. If not return.
#jetdef.inputdef.prereqs += ['input:'+jetdef.inputdef.inputname] # this is technically necesary.
ok,reason = isComponentPassingConditions( jetdef.inputdef, configflags, jetdef._prereqDic)
ok,reason = isComponentPassingConditions( jetdef.inputdef, jetdef._cflags, jetdef._prereqDic)
if not ok:
if raiseOnFailure:
raise Exception(f"JetDefinition {jetdef} can NOT be scheduled. Failure of input {jetdef.inputdef.name} reason={reason}" )
jetlog.info(f"IMPORTANT : removing {jetdef} because input incompatible with job conditions. Reason={reason} ")
return False
if isinstance( jetdef.inputdef, JetInputConstitSeq):
# remove ConstitModifiers failing conditions.
jetdef.inputdef.modifiers = filterList( jetdef.inputdef.modifiers, 'cmod' )
# call the helper function to perform filtering :
jetdef.ghostdefs = filterList( jetdef.ghostdefs, "ghost")
jetdef.modifiers = filterList( jetdef.modifiers, "mod")
......@@ -642,9 +660,6 @@ def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
filterList( list(jetdef._prereqOrder), "")
return True
# def removeComponentFailingConditions(jetdef, configflags, raiseOnFailure=True):
# for
def isComponentPassingConditions(component, configflags, prereqDic):
"""Test if component is compatible with configflags.
......
......@@ -15,7 +15,7 @@
########################################################################
from .JetDefinition import xAODType, JetInputConstitSeq, JetInputExternal, JetConstitModifier, JetInputConstit
from .StandardJetContext import inputsFromContext
# Prepare dictionnaries to hold all of our standard definitions.
# They will be filled from the list below
......@@ -36,7 +36,38 @@ def isMC(flags):
(probably worth re-allocating somehere else)"""
return flags.Input.isMC, "Input file is not MC"
def standardReco(input):
"""Returns a helper function which invokes the standard reco configuration for the container 'input'
(where input is external to the jet domain).
We group the definition of functions here rather than separately, so that we can change them
automatically to a void function in case we're in an Analysis release.
"""
from .JetRecConfig import isAnalysisRelease
if isAnalysisRelease():
return lambda *l:None
# TEMPORARY
# don't try to invoke anything as long as we're invoked from a runII-style config
from AthenaCommon.Configurable import Configurable
if not Configurable.configurableRun3Behavior:
return lambda *l:None
if input=='CaloClusters':
def f(jetdef,spec):
from CaloRec.CaloRecoConfig import CaloRecoCfg
return CaloRecoCfg(jetdef._cflags)
elif input=='Tracks':
def f(jetdef,spec):
from InDetConfig.TrackRecoConfig import TrackRecoCfg
return TrackRecoCfg(jetdef._cflags)
elif input=="Muons":
def f(jetdef,spec):
from MuonConfig.MuonReconstructionConfig import MuonReconstructionCfg
return MuonReconstructionCfg(jetdef._cflags)
return f
########################################################################
## List of standard input sources for jets.
......@@ -48,30 +79,52 @@ _stdInputList = [
# it will be called as : algoBuilder(jetdef, spec) where jetdef is the parent JetDefinition
# *****************************
JetInputExternal("CaloCalTopoClusters", xAODType.CaloCluster),
JetInputExternal("CaloCalTopoClusters", xAODType.CaloCluster, algoBuilder= standardReco("CaloClusters") ),
# *****************************
JetInputExternal("JetETMissParticleFlowObjects", xAODType.ParticleFlow),
JetInputExternal("JetETMissParticleFlowObjects", xAODType.ParticleFlow, # no algobuilder available yet for PFlow
prereqs = ["input:InDetTrackParticles"],
),
# *****************************
JetInputExternal("JetSelectedTracks", xAODType.TrackParticle, algoBuilder = lambda jdef,_ : jrtcfg.getTrackSelAlg(jdef.context ) ),
JetInputExternal("JetTrackUsedInFitDeco", xAODType.TrackParticle, algoBuilder = inputcfg.buildJetTrackUsedInFitDeco),
JetInputExternal("JetTrackVtxAssoc", xAODType.TrackParticle, algoBuilder = inputcfg.buildJetTrackVertexAssoc,
prereqs = ["input:JetTrackUsedInFitDeco"] ),
JetInputExternal("InDetTrackParticles", xAODType.TrackParticle,
algoBuilder = standardReco("Tracks"),
filterfn = lambda flags : (not flags.InDet.disableTracking, "Tracking is disabled") ,
),
JetInputExternal("PrimaryVertices", xAODType.Vertex,
prereqs = ["input:InDetTrackParticles"],
),
JetInputExternal("JetSelectedTracks", xAODType.TrackParticle,
prereqs= inputsFromContext("Tracks"), # in std context, this is InDetTrackParticles (see StandardJetContext)
algoBuilder = lambda jdef,_ : jrtcfg.getTrackSelAlg(jdef.context )
),
JetInputExternal("JetTrackUsedInFitDeco", xAODType.TrackParticle,