diff --git a/Reconstruction/Jet/JetCalibTools/python/JetCalibToolsConfig.py b/Reconstruction/Jet/JetCalibTools/python/JetCalibToolsConfig.py
index 57e9d3bde7ab5fbd59f9523b370e24e4ed1b2bf8..6e8660d39bd6a4fde19517f7d70cbd8fb1c7aa37 100644
--- a/Reconstruction/Jet/JetCalibTools/python/JetCalibToolsConfig.py
+++ b/Reconstruction/Jet/JetCalibTools/python/JetCalibToolsConfig.py
@@ -31,8 +31,7 @@ topocontexts = {
     "T0":("JES_MC15cRecommendation_May2016_rel21.config","00-04-77","JetArea_Residual_EtaJES"),
     # Omit smearing, to avoid any efficiency loss
     "AnalysisLatest":("JES_data2017_2016_2015_Consolidated_EMTopo_2018_Rel21.config","00-04-82","JetArea_Residual_EtaJES_GSC_Insitu"),
-    "TrigSubJES":("JES_MC15cRecommendation_May2016_Trigger.config","00-04-77","JetArea_EtaJES"),
-    "TrigSubJESIS":("JES_MC15cRecommendation_May2016_Trigger.config","00-04-77","JetArea_EtaJES_GSC_Insitu"),
+    "TrigRun2":("JES_MC15cRecommendation_May2016_Trigger.config","00-04-77","JetArea_EtaJES_GSC_Insitu"),
 }
 
 rscanlc2 = {
@@ -44,10 +43,10 @@ rscanlc6 = {
 }
 
 fatjetcontexts = {
-    "CombinedMass": ("JES_MC16recommendation_FatJet_JMS_comb_19Jan2018.config","00-04-81","EtaJES_JMS"),
-    "CaloMass":     ("JES_MC16recommendation_FatJet_JMS_calo_29Nov2017.config","00-04-81","EtaJES_JMS"),
-    "TAMass":       ("JES_MC16recommendation_FatJet_JMS_TA_29Nov2017.config","00-04-81","EtaJES_JMS"),
-    "TrigSubJES": ("JES_Full2012dataset_Rscan_June2014.config","00-04-77","JetArea_EtaJES"),
+    "CombinedMass":  ("JES_MC16recommendation_FatJet_JMS_comb_19Jan2018.config","00-04-81","EtaJES_JMS"),
+    "CaloMass":      ("JES_MC16recommendation_FatJet_JMS_calo_29Nov2017.config","00-04-81","EtaJES_JMS"),
+    "TAMass":        ("JES_MC16recommendation_FatJet_JMS_TA_29Nov2017.config","00-04-81","EtaJES_JMS"),
+    "TrigUngroomed": ("JES_Full2012dataset_Rscan_June2014.config","00-04-77","JetArea_EtaJES"),
 }
 
 # List AFII config files separately, to avoid needing to specify a different context
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
index 7e9832da72a59adc0360c12d378adfabd570b522..769ccca1c49cb1d781a4f3ce8457044386e7b46c 100644
--- a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
@@ -204,6 +204,25 @@ def expandPrereqs(reqtype,prereqs):
     return reqdefs
 
 
+########################################################################
+# Function producing an EventShapeAlg to calculate
+# medaian energy density for pileup correction
+#
+def getEventShapeAlg( constit, constitpjkey, nameprefix="" ):
+
+    rhokey = "Kt4"+constit.label+"EventShape"
+    rhotoolname = "EventDensity_Kt4"+constit.label
+    
+    from EventShapeTools import EventShapeToolsConf
+    rhotool = EventShapeToolsConf.EventDensityTool(rhotoolname)
+    rhotool.InputContainer = constitpjkey
+    rhotool.OutputContainer = rhokey
+    
+    eventshapealg = EventShapeToolsConf.EventDensityAthAlg("{0}{1}Alg".format(nameprefix,rhotoolname))
+    eventshapealg.EventDensityTool = rhotool
+
+    return eventshapealg
+
 ########################################################################
 # Function for setting up inputs to jet finding
 #
@@ -302,17 +321,7 @@ def JetInputCfg(inputdeps, configFlags, sequenceName):
             if rhokey in filecontents:
                 jetlog.debug("Event density {0} for label {1} already in input file.".format(rhokey, constit.label))
             else:
-                rhotoolname = "EventDensity_Kt4"+constit.label
-
-                jetlog.debug("Setting up event density calculation Kt4{0}".format(constit.label))
-                from EventShapeTools import EventShapeToolsConf
-                rhotool = EventShapeToolsConf.EventDensityTool(rhotoolname)
-                rhotool.InputContainer = constitpjkey
-                rhotool.OutputContainer = rhokey
-
-                eventshapealg = EventShapeToolsConf.EventDensityAthAlg("{0}Alg".format(rhotoolname))
-                eventshapealg.EventDensityTool = rhotool
-                components.addEventAlgo(eventshapealg)
+                components.addEventAlgo( getEventShapeAlg(constit,constitpjkey) )
 
     return components
 
diff --git a/Reconstruction/eflowRec/python/PFHLTSequence.py b/Reconstruction/eflowRec/python/PFHLTSequence.py
new file mode 100644
index 0000000000000000000000000000000000000000..6306f77441fb6c32684a576a64b5220a45e58d4b
--- /dev/null
+++ b/Reconstruction/eflowRec/python/PFHLTSequence.py
@@ -0,0 +1,138 @@
+from eflowRec import eflowRecConf
+from InDetTrackSelectionTool import InDetTrackSelectionToolConf
+# PFTrackSelector
+# This handles the track selection (including lepton veto)
+# and extrapolation into the calorimeter.
+# Parameters: track & vertex container names (offline, HLT, FTK)
+def getPFTrackSel(tracksin, verticesin):
+
+    # Configure the extrapolator
+    def getExtrapolator():
+        # Set up with trigger extrapolator instance
+        # FIXME: reconfigure for lower tolerance to speed up
+        # from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
+        from TrackToCalo.TrackToCaloConf import Trk__ParticleCaloExtensionTool
+        from InDetTrigRecExample.InDetTrigConfigRecLoadTools import InDetTrigExtrapolator
+        return Trk__ParticleCaloExtensionTool(Extrapolator = InDetTrigExtrapolator)
+
+    TrackCaloExtensionTool = eflowRecConf.eflowTrackCaloExtensionTool(TrackCaloExtensionTool=getExtrapolator())
+
+    # Configure the track selector
+    PFTrackSelector = eflowRecConf.PFTrackSelector("PFTrackSelector")
+    PFTrackSelector.trackExtrapolatorTool = TrackCaloExtensionTool
+
+    TrackSelectionTool = InDetTrackSelectionToolConf.InDet__InDetTrackSelectionTool(
+        CutLevel = "TightPrimary",
+        minPt = 500.0)
+    PFTrackSelector.trackSelectionTool = TrackSelectionTool
+
+    # Disable lepton veto as not reconstructed for hadronic triggers
+    PFTrackSelector.electronsName = ""
+    PFTrackSelector.muonsName = ""
+    # Specify input track and vertex containers
+    PFTrackSelector.tracksName = tracksin
+    PFTrackSelector.VertexContainer = verticesin
+
+    return PFTrackSelector
+
+# PFAlgorithm
+# This runs the cell-level subtraction:
+#   1. Match clusters to tracks
+#   2. Iteratively remove expected calo energy
+#   3. Calculate cluster moments and apply LC calibration
+# For HLT purposes, no LC calibration is applied and only
+# one essential moment (CENTER_MAG) is computed. This is
+# needed for origin corrections.
+def getPFAlg(clustersin):
+
+    # The tool to handle cell-level subtraction, default parameters
+    CellEOverPTool = eflowRecConf.eflowCellEOverPTool_mc12_JetETMiss()
+
+    # Need a few instances of PFTrackClusterMatchingTool with different distance cuts
+    def getPFMatchingTool(name,matchcut):
+        matchingtool = eflowRecConf.PFTrackClusterMatchingTool(name)
+        matchingtool.TrackPositionType   = 'EM2EtaPhi' # str
+        matchingtool.ClusterPositionType = 'PlainEtaPhi' # str
+        matchingtool.DistanceType        = 'EtaPhiSquareDistance' # str
+        matchingtool.MatchCut = matchcut*matchcut
+
+    # Default energy subtraction where a single cluster satisfies the expected
+    # track calo energy
+    PFCellLevelSubtractionTool = eflowRecConf.PFCellLevelSubtractionTool("PFCellLevelSubtractionTool",
+        eflowCellEOverPTool        = CellEOverPTool,
+        # Uses a deltaR' cut (deltaR corrected for cluster width in eta/phi) to
+        # match clusters to tracks
+        PFTrackClusterMatchingTool = eflowRecConf.PFTrackClusterMatchingTool("CalObjBldMatchingTool"),
+        # Additional matching tools used to determine cluster weights
+        # These deal with dense environments in which subtraction is difficult.
+        PFTrackClusterMatchingTool_015 = getPFMatchingTool(name="MatchingTool_Pull_015",matchcut=0.15),
+        PFTrackClusterMatchingTool_02  = getPFMatchingTool(name="MatchingTool_Pull_02",  matchcut=0.2)
+        )
+
+    # A second cell-level subtraction tool that handles cases where more than one
+    # cluster is needed to recover the full track expected energy
+    # Reuse the default E/P subtraction tool
+    PFRecoverSplitShowersTool = eflowRecConf.PFRecoverSplitShowersTool("PFRecoverSplitShowersTool",
+        eflowCellEOverPTool = CellEOverPTool,
+        PFTrackClusterMatchingTool = getPFMatchingTool("MatchingTool_RecoverSS",0.2)
+        )
+
+    # Configure moment calculation using topocluster moment calculator
+    PFMomentCalculatorTool = eflowRecConf.PFMomentCalculatorTool("PFMomentCalculatorTool")
+    # Only need CENTER_MAG (depth in calo) for origin corrections
+    from CaloRec import CaloRecConf
+    PFMomentCalculatorTool.CaloClusterMomentsMaker = CaloRecConf.CaloClusterMomentsMaker("PFClusterMomentsMaker",
+        # Originally from CaloTopoClusterFlags
+        TwoGaussianNoise = True,
+        # Needed for origin correction
+        MomentsNames = ["CENTER_MAG"]
+        )
+    # Makes a temporary cluster collection for moment calculation
+    PFMomentCalculatorTool.PFClusterCollectionTool = eflowRecConf.PFClusterCollectionTool()
+
+    pfClusterSel = eflowRecConf.PFClusterSelectorTool("PFClusterSelectorTool",
+        clustersName=clustersin,
+        calClustersName="")
+    PFAlgorithm = eflowRecConf.PFAlgorithm("PFAlgorithm",
+        PFClusterSelectorTool = pfClusterSel,
+        SubtractionToolList = [PFCellLevelSubtractionTool,PFRecoverSplitShowersTool],
+        BaseToolList = [PFMomentCalculatorTool]
+        )
+    
+    return PFAlgorithm
+
+# Convert internal eflowRec track/cluster objects into xAOD neutral/charged
+# particle flow objects
+def getPFOCreators():
+    PFOChargedCreatorAlgorithm = eflowRecConf.PFOChargedCreatorAlgorithm("PFOChargedCreatorAlgorithm",
+        PFOOutputName="HLTChargedParticleFlowObjects"
+        )
+
+    PFONeutralCreatorAlgorithm =  eflowRecConf.PFONeutralCreatorAlgorithm("PFONeutralCreatorAlgorithm",
+        PFOOutputName="HLTNeutralParticleFlowObjects",
+        DoClusterMoments=False # Only CENTER_MAG
+        )
+    return PFOChargedCreatorAlgorithm, PFONeutralCreatorAlgorithm
+
+# Generate the full PF reco sequence, assuming tracks, vertices, clusters
+# will be created upstream
+def PFHLTSequence(clustersin,tracktype="Offline"):
+    trackvtxcontainers = {
+        "Offline":  ("InDetTrackParticles","PrimaryVertices"),
+        "HLT":      ("",""), # Not set up -- ask MET?
+        "FTK":      ("FTK_TrackParticleContainer","FTK_VertexContainer"),
+        "FTKRefit": ("FTK_TrackParticleContainer_Refit","FTK_VertexContainer_Refit")
+        }
+
+    tracksin,verticesin = trackvtxcontainers[tracktype]
+
+    PFTrkSel = getPFTrackSel(tracksin, verticesin)
+    PFAlg = getPFAlg(clustersin)
+    PFNCreator, PFCCreator = getPFOCreators()
+
+    # Create HLT "parallel OR" sequence holding the PF algs
+    # Can be inserted into the jet building sequence
+    from AthenaCommon.CFElements import parOR
+    pfSequence = parOR("PFSeq_"+tracktype, [PFTrkSel,PFAlg,PFCCreator,PFNCreator])
+
+    return pfSequence
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/jetDefs.py b/Trigger/TrigValidation/TrigUpgradeTest/python/jetDefs.py
deleted file mode 100644
index 4d9daeeebf76f4bf6d2c88e123eddc707feadf2a..0000000000000000000000000000000000000000
--- a/Trigger/TrigValidation/TrigUpgradeTest/python/jetDefs.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-#
-
-
-from AthenaCommon.CFElements import parOR, seqAND
-from AthenaCommon.Constants import ERROR
-
-
-def jetAthSequence(ConfigFlags):
-    from TrigT2CaloCommon.CaloDef import clusterFSInputMaker
-    InputMakerAlg= clusterFSInputMaker()
-
-    dataOrMC = "data" 
-    #if ConfigFlags.Input.isMC:
-    #    dataOrMC = "mc"
-    # want to make this automatic.
-
-    jetDefString = ConfigFlags.jetdefinition
-    jetDefString += "_"+dataOrMC
-
-   
-    (recoSequence, sequenceOut) = jetRecoSequence( jetDefString )
-
-    JetAthSequence =  seqAND("jetAthSequence_"+jetDefString,[InputMakerAlg, recoSequence ])
-    return (JetAthSequence, InputMakerAlg, sequenceOut)
-
-    
-def jetRecoSequence(  jetDefString , RoIs = 'FSJETRoI'):
-
-    dataType = "data"
-    if jetDefString.endswith("mc"):
-        dataType = "mc"
-
-    # construct calibration key word.
-    calibSeq = ""
-    if "subjesis" in jetDefString:
-        calibSeq += "SubJESIS"
-    elif "subjes" in jetDefString:
-        calibSeq += "SubJES"
-    if calibSeq: calibSeq = "Trig"+calibSeq
-
-    radius = 0.4
-    if "a10_" in jetDefString:
-        radius = 1.0
-        #if calibSeq:
-        #    calibSeq += "JMS"
-
-    doLC=False
-    jetConstitName = "EM"
-    if "lcw" in jetDefString: 
-        doLC=True
-        jetConstitName = "LC"
-
-    # now avoid duplicate tool name errors for a4 emtopo and a10r chains.
-    extraSuffix = ""
-    if "a10r_" in jetDefString:
-        extraSuffix += "a10r"
-
-    cellMakerAlgo = _getHLTCellMakerAlgoForJets("cellMaker"+jetConstitName, RoIs, outputEDM='CaloCells'+jetConstitName, OutputLevel=ERROR) 
-    topoClusterMakerAlgo = _getHLTTopoClusterMakerAlgoForJets( "topoClusterMaker"+jetConstitName, inputEDM=cellMakerAlgo.CellsName, doLC=doLC, OutputLevel=ERROR)
-
-    caloMakerSequence = parOR("TopoClusterRecoSequence"+jetConstitName+extraSuffix+calibSeq, [cellMakerAlgo, topoClusterMakerAlgo]) 
-    caloclusters = topoClusterMakerAlgo.CaloClusters
-
-    from JetRecConfig.JetDefinition import JetConstit, JetDefinition, xAODType, JetModifier
-  
-    # chosen jet collection
-    prefix = "TrigAntiKt4"
-    if "a10_" in jetDefString:
-        prefix = "TrigAntiKt10"
-    jetsFullName = prefix+jetConstitName+calibSeq
-    trigJetConstit = JetConstit( xAODType.CaloCluster, [jetConstitName]) # 'EM' or 'LC' for trigger jets
-    trigJetConstit.istrigger = False
-    trigJetConstit.ptmin = 2e3
-    trigJetConstit.ptminfilter = 7e3
-    trigJetDef = JetDefinition( "AntiKt", radius, trigJetConstit)#, ptmin=trigMinPt,ptminfilter=trigMinPt)
-
-    from JetRecConfig import JetRecConfig
-
-    modList = [ (JetModifier("JetCaloEnergies", "jetens"), '') ]
-    modList += [ (JetModifier("JetSorter","jetsort"), '') ]
-    if calibSeq:
-   	 from JetCalibTools import JetCalibToolsConfig
-   	 jetCalibTool = JetCalibToolsConfig.getJetCalibTool( trigJetDef.basename, calibSeq, dataType )
-   	 modList += [(JetModifier("JetCalibrationTool", jetCalibTool.name()), calibSeq+':'+dataType)]
-    modList += [ ( JetModifier("JetFilterTool","jetptfilter"), str(int(trigJetConstit.ptminfilter)))  ]
-
-    trigJetConstit.rawname = caloclusters
-    trigJetConstit.inputname = jetConstitName+trigJetConstit.inputname
-    constitAlg = _getConstitAlg( trigJetConstit )
-    jetRecoSequence = parOR( "JetRecSeq_"+jetsFullName+"_"+extraSuffix, [constitAlg])
-
-    constitPJAlg = _getConstitPJGAlg( trigJetConstit )
-    constitPJKey = constitPJAlg.PJGetter.OutputContainer
-
-    pjs = [constitPJKey]
-
-    jetRecoSequence += constitPJAlg 
-        
-    eventShapeAlg = _getEventShapeAlg( trigJetConstit, constitPJKey )
-    jetRecoSequence += eventShapeAlg                    
-
-    # Generate a JetAlgorithm to run the jet finding and modifiers
-    # (via a JetRecTool instance).
-    jetRecAlg = JetRecConfig.getJetAlgorithm(jetsFullName, trigJetDef, pjs, modList)
-
-    jetRecoSequence += jetRecAlg
-
-    # check if asked for reclustering
-    if 'a10r' in jetDefString:
-
-        a10rJetsFullName = "TrigAntiKt10rSubJESIS"
-        a10rJetConstit = JetConstit( xAODType.Jet, [])
-        trigAntiKt10rJetDef = JetDefinition( "AntiKt", 1.0, a10rJetConstit)
-
-        a10rmodList= []
-        a10rJetConstit.inputname = jetsFullName 
-
-        a10rconstitPJAlg = _getConstitPJGAlg( a10rJetConstit )
-        a10rconstitPJKey = a10rconstitPJAlg.PJGetter.OutputContainer
-        jetRecoSequence += a10rconstitPJAlg
-
-        a10rpjs = [a10rconstitPJKey]
-        a10rjetRecAlg = JetRecConfig.getJetAlgorithm(a10rJetsFullName, trigAntiKt10rJetDef, a10rpjs, a10rmodList)
-
-        jetRecoSequence += a10rjetRecAlg
-        jetsFullName = a10rJetsFullName
-
-    sequenceOut = jetsFullName
-
-    caloMakerSequence += jetRecoSequence
-
-    jetRecoFullSequence = caloMakerSequence
-
-    return (jetRecoFullSequence,sequenceOut)
-
-def _getConstitAlg( constit ):
-
-        from JetRecConfig import ConstModHelpers
-        constitalg = ConstModHelpers.getConstitModAlg(constit)
-        return constitalg
-
-def _getConstitPJGAlg(basedef):
-
-    from JetRec import JetRecConf
-    getter = JetRecConf.PseudoJetGetter("pjg_"+basedef.label,
-        InputContainer = basedef.inputname,
-        OutputContainer = "PseudoJet"+basedef.label,
-        Label = basedef.label,
-        SkipNegativeEnergy=True,
-        GhostScale=0.
-        )
-
-    pjgalg = JetRecConf.PseudoJetAlgorithm(
-        "pjgalg_"+basedef.label,
-        PJGetter = getter
-        )
-    return pjgalg
-
-def _getGhostPJGAlg(ghostdef):
-
-    label = "Ghost"+ghostdef.inputtype
-    kwargs = {
-        "OutputContainer":    "PseudoJet"+label,
-        "Label":              label,
-        "SkipNegativeEnergy": True,
-        "GhostScale":         1e-40
-        }
-
-    from JetRec import JetRecConf
-    pjgclass = JetRecConf.PseudoJetGetter
-    if ghostdef.inputtype=="MuonSegment":
-        # Muon segments have a specialised type
-        pjgclass = JetRecConf.MuonSegmentPseudoJetGetter
-        kwargs = {
-            "InputContainer":"MuonSegments",
-            "OutputContainer":"PseudoJet"+label,
-            "Label":label,
-            "Pt":1e-20
-            }
-    elif ghostdef.inputtype=="Track":
-        kwargs["InputContainer"] = "JetSelectedTracks"
-    elif ghostdef.inputtype.startswith("TruthLabel"):
-        truthsuffix = ghostdef.inputtype[5:]
-        kwargs["InputContainer"] = "TruthLabel"+truthsuffix
-    elif ghostdef.inputtype == "Truth":
-        kwargs["InputContainer"] = "JetInputTruthParticles"
-    else:
-        raise ValueError("Unhandled ghost type {0} received!".format(ghostdef.inputtype))
-
-    getter = pjgclass("pjg_"+label, **kwargs)
-
-    pjgalg = JetRecConf.PseudoJetAlgorithm(
-        "pjgalg_"+label,
-        PJGetter = getter
-        )
-    return pjgalg
-
-def _getTrackPrepAlg( trackPrepAlgName ):
-
-    from JetRecTools import JetRecToolsConfig
-    from JetRec import JetRecConf
-    # Jet track selection
-    jettrackselloose = JetRecToolsConfig.getTrackSelTool()
-    jettvassoc = JetRecToolsConfig.getTrackVertexAssocTool()
-
-    jettrkprepalg = JetRecConf.JetAlgorithm(trackPrepAlgName)
-    jettrkprepalg.Tools = [ jettrackselloose, jettvassoc ]
-
-    return jettrkprepalg
-
-def _getEventShapeAlg( constit, constitpjkey ):
-
-    rhokey = "Kt4"+constit.label+"EventShape"
-    rhotoolname = "EventDensity_Kt4"+constit.label
-    
-    from EventShapeTools import EventShapeToolsConf
-    rhotool = EventShapeToolsConf.EventDensityTool(rhotoolname)
-    rhotool.InputContainer = constitpjkey
-    rhotool.OutputContainer = rhokey
-    
-    eventshapealg = EventShapeToolsConf.EventDensityAthAlg("{0}Alg".format(rhotoolname))
-    eventshapealg.EventDensityTool = rhotool
-
-    return eventshapealg
-
-def _getHLTCellMakerAlgoForJets( name, RoIs, outputEDM='CaloCells', OutputLevel=ERROR ):
-
-    from AthenaCommon.AppMgr import ServiceMgr as svcMgr
-    if not hasattr(svcMgr,'TrigCaloDataAccessSvc'):
-      from TrigT2CaloCommon.TrigT2CaloCommonConf import TrigCaloDataAccessSvc
-      svcMgr+=TrigCaloDataAccessSvc()
-      svcMgr.TrigCaloDataAccessSvc.OutputLevel=ERROR
-    from AthenaCommon.AppMgr import ServiceMgr as svcMgr
-    from TrigCaloRec.TrigCaloRecConfig import HLTCaloCellMaker
-
-    inputEDM = RoIs
-    algo=HLTCaloCellMaker(name)
-    algo.RoIs=inputEDM
-    algo.TrigDataAccessMT=svcMgr.TrigCaloDataAccessSvc
-    algo.OutputLevel=OutputLevel
-    algo.CellsName=outputEDM
-   
-    return algo
-
-def _getHLTTopoClusterMakerAlgoForJets(name, inputEDM, doLC=False, OutputLevel=ERROR):
-
-    from TrigCaloRec.TrigCaloRecConfig import TrigCaloClusterMakerMT_topo
-
-    algo = TrigCaloClusterMakerMT_topo(name, doMoments=True, doLC=doLC, cells=inputEDM)
-    algo.CaloClusters="caloclusters"
-    if doLC:
-        algo.CaloClusters+="LC"
-    algo.OutputLevel=OutputLevel
-    return algo
-
-def _getJetFilterTool( threshold ):
-	
-    from JetRec import JetRecConf
-    threshold = int(threshold)
-    jetptfilter = JetRecConf.JetFilterTool("jetptfilter_{0}mev".format(threshold))
-    jetptfilter.PtMin = threshold     
-    return jetptfilter
-
-
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py b/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py
index 6d21d9a8137af419497fa4cbc3828a5d51f8b825..a597d280d59ee356d16345ca4075a54a64055143 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py
@@ -1,27 +1,24 @@
 #  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 #
 
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence
-from AthenaConfiguration.AllConfigFlags import ConfigFlags
-    
-def jetMenuSequence(jet_def_string, hypoName):
+from TriggerMenuMT.HLTMenuConfig.Jet.JetMenuSequences import jetMenuSequence
+
+def jetMenuSequenceFromString(jet_def_string):
     """ Function to create the jet Menu Sequence"""
    
-    ConfigFlags.jetdefinition=jet_def_string
-    ## RoIs = 'FSJETRoI'
-    #reco sequence
-    from TrigUpgradeTest.jetDefs import jetAthSequence
-    #(JetAthSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(jetAthSequence,ConfigFlags)
-    (JetAthSequence, InputMakerAlg, sequenceOut) = jetAthSequence(ConfigFlags)
-     
-    #hypo
-    from TrigHLTJetHypo.TrigHLTJetHypoConf import TrigJetHypoAlgMT
-    from TrigHLTJetHypo.TrigJetHypoToolConfig import trigJetHypoToolFromDict
-    hypo = TrigJetHypoAlgMT(hypoName)
-    hypo.Jets = sequenceOut
-
+    # Translate the definition string into an approximation
+    # of the "recoParts" in the jet chainParts.
+    jetRecoDict = {}
+    # Insert values from string
+    # Python names are more descriptive. May want to sync
+    # these names with the SignatureDict, needs coordination with
+    # menu group when they start to implement this
+    jetalg, inputtype, clusterscale, jetcalib = jet_def_string.split('_')
+    jetRecoDict = {
+        "recoAlg":  jetalg,
+        "dataType": inputtype,
+        "calib":    clusterscale,
+        "jetCalib": jetcalib
+        }
 
-    return  MenuSequence( Sequence    = JetAthSequence,
-                          Maker       = InputMakerAlg,
-                          Hypo        = hypo,
-                          HypoToolGen = trigJetHypoToolFromDict )
+    return jetMenuSequence(None,**jetRecoDict) # First arg dummy flags for RecoFragmentsPool
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
index bbaf5295faa100bc2c6e56b97dcb1d3c352d8896..42304d54d0cca43fe43f9dd035449fb9dcfce5cc 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
@@ -124,40 +124,39 @@ if opt.doMuonSlice == True:
 # jet chains
 ##################################################################
 if opt.doJetSlice == True:
-    #from TriggerMenuMT.HLTMenuConfig.Jet.JetSequenceSetup import jetMenuSequence
-    from TrigUpgradeTest.jetMenuDefs import jetMenuSequence
+    from TrigUpgradeTest.jetMenuDefs import jetMenuSequenceFromString
 
     # small-R jets, different calibrations
-    jetSeq_a4_emtopo = jetMenuSequence("a4_emtopo_subjesis", "TrigJetHypoAlgMT_a4_emtopo")
-    step_a4_emtopo =ChainStep("Step_jet_a4_emtopo", [jetSeq_a4_emtopo])
+    jetSeq_a4_tc_em = jetMenuSequenceFromString("a4_tc_em_subjesIS")
+    step_a4_tc_em =ChainStep("Step_jet_a4_tc_em", [jetSeq_a4_tc_em])
 
-    jetSeq_a4_emtopo_subjes = jetMenuSequence("a4_emtopo_subjes", "TrigJetHypoAlgMT_a4_emtopo_subjes")
-    step_a4_emtopo_subjes = ChainStep("Step_jet_a4_subjes_emtopo", [jetSeq_a4_emtopo_subjes])
+    jetSeq_a4_tc_em_subjes = jetMenuSequenceFromString("a4_tc_em_subjes")
+    step_a4_tc_em_subjes = ChainStep("Step_jet_a4_subjes_tc_em", [jetSeq_a4_tc_em_subjes])
 
-    jetSeq_a4_emtopo_nocalib = jetMenuSequence("a4_emtopo_nocalib", "TrigJetHypoAlgMT_a4_emtopo_nocalib")
-    step_a4_emtopo_nocalib=ChainStep("Step_jet_a4_nocalib_emtopo", [jetSeq_a4_emtopo_nocalib])
+    jetSeq_a4_tc_em_nocalib = jetMenuSequenceFromString("a4_tc_em_nojcalib")
+    step_a4_tc_em_nocalib=ChainStep("Step_jet_a4_nojcalib_tc_em", [jetSeq_a4_tc_em_nocalib])
 
-    jetSeq_a4_lcw = jetMenuSequence("a4_lcw_subjesis", "TrigJetHypoAlgMT_a4_lcw")
-    step_a4_lcw=ChainStep("Step_jet_a4_lcw", [jetSeq_a4_lcw])
+    jetSeq_a4_tc_lcw = jetMenuSequenceFromString("a4_tc_lcw_subjesIS")
+    step_a4_tc_lcw=ChainStep("Step_jet_a4_tc_lcw", [jetSeq_a4_tc_lcw])
 
     # large-R jets
-    jetSeq_a10_lcw_subjes = jetMenuSequence("a10_lcw_subjes", "TrigJetHypoAlgMT_a10_lcw_subjes")
-    step_a10_lcw_subjes=ChainStep("Step_jet_a10_subjes_lcw", [jetSeq_a10_lcw_subjes])
+    jetSeq_a10_tc_lcw_subjes = jetMenuSequenceFromString("a10_tc_lcw_subjes")
+    step_a10_tc_lcw_subjes=ChainStep("Step_jet_a10_subjes_tc_lcw", [jetSeq_a10_tc_lcw_subjes])
 
-    jetSeq_a10r = jetMenuSequence("a10r_emtopo_subjesis", "TrigJetHypoAlgMT_a10r")
+    jetSeq_a10r = jetMenuSequenceFromString("a10r_tc_em_subjesIS")
     step_a10r=ChainStep("Step_jet_a10r", [jetSeq_a10r])
     
     jetChains  = [
-        Chain(name='HLT_j45', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j85', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j420', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j260_320eta490', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j225_gsc420_boffperf_split', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_j460_a10_lcw_subjes', Seed="L1_J20",  ChainSteps=[step_a10_lcw_subjes]  ),
+        Chain(name='HLT_j45', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j85', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j420', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j260_320eta490', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j225_gsc420_boffperf_split', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_j460_a10_lcw_subjes', Seed="L1_J20",  ChainSteps=[step_a10_tc_lcw_subjes]  ),
         Chain(name='HLT_j460_a10r', Seed="L1_J20",  ChainSteps=[step_a10r]  ),
-        Chain(name='HLT_3j200', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ),
-        Chain(name='HLT_5j70_0eta240', Seed="L1_J20",  ChainSteps=[step_a4_emtopo]  ), # 5j70_0eta240_L14J15 (J20 until multi-object L1 seeds supported) 
+        Chain(name='HLT_3j200', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ),
+        Chain(name='HLT_5j70_0eta240', Seed="L1_J20",  ChainSteps=[step_a4_tc_em]  ), # 5j70_0eta240_L14J15 (J20 until multi-object L1 seeds supported)
         ]
 
     testChains += jetChains
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.ref b/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.ref
index 87eb4f6220f091849621687d591775aa7a3d4439..48e4fdfcb2099e76c64c42a61e650bcd3b8dcc81 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.ref
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.ref
@@ -1,5 +1,5 @@
-TrigSignatureMoniMT                                INFO Chains passing step (1st row events & 2nd row decision counts
-TrigSignatureMoniMT                                INFO Chain name                   L1,      AfterPS, [... steps ...], Output
+TrigSignatureMoniMT                                INFO Chains passing step (1st row events & 2nd row decision counts):
+TrigSignatureMoniMT                                INFO Chain name                   L1,      AfterPS,  step1     step2     step3     step4     step5     Output
 TrigSignatureMoniMT                                INFO All                           20        20        0         0         0         0         0         20        
 TrigSignatureMoniMT                                INFO HLT_2mu6Comb_L1MU6            20        20        0         0         0         0         0         0         
 TrigSignatureMoniMT                                INFO HLT_2mu6Comb_L1MU6 decisions                      0         0         0         0         0         
@@ -27,10 +27,14 @@ TrigSignatureMoniMT                                INFO HLT_j260_320eta490_L1J20
 TrigSignatureMoniMT                                INFO HLT_j260_320eta490_L1J20 decisions                    0         0         0         0         0         
 TrigSignatureMoniMT                                INFO HLT_j420_L1J20                20        20        0         0         0         0         0         0         
 TrigSignatureMoniMT                                INFO HLT_j420_L1J20 decisions                          0         0         0         0         0         
-TrigSignatureMoniMT                                INFO HLT_j45_L1J20                 20        20        4         0         0         0         0         4         
-TrigSignatureMoniMT                                INFO HLT_j45_L1J20 decisions                           4         0         0         0         0         
-TrigSignatureMoniMT                                INFO HLT_j85_L1J20                 20        20        0         0         0         0         0         0         
-TrigSignatureMoniMT                                INFO HLT_j85_L1J20 decisions                           0         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j45_L1J20                 20        20        5         0         0         0         0         5         
+TrigSignatureMoniMT                                INFO HLT_j45_L1J20 decisions                           5         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j460_a10_lcw_subjes_L1J20 20        20        0         0         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j460_a10_lcw_subjes_L1J20 decisions                    0         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j460_a10r_L1J20           20        20        0         0         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j460_a10r_L1J20 decisions                     0         0         0         0         0         
+TrigSignatureMoniMT                                INFO HLT_j85_L1J20                 20        20        1         0         0         0         0         1         
+TrigSignatureMoniMT                                INFO HLT_j85_L1J20 decisions                           1         0         0         0         0         
 TrigSignatureMoniMT                                INFO HLT_mu20_ivar_L1MU6           20        20        3         2         2         0         0         2         
 TrigSignatureMoniMT                                INFO HLT_mu20_ivar_L1MU6 decisions                     3         2         2         0         0         
 TrigSignatureMoniMT                                INFO HLT_mu6Comb_L1MU6             20        20        3         2         0         0         0         2         
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/GenerateJetChainDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/GenerateJetChainDefs.py
index 582460c3dd9815fcc834415159cd65f8c1129a50..0a9e54852836d65dfb198a259ff80d0f44867222 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/GenerateJetChainDefs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/GenerateJetChainDefs.py
@@ -1,7 +1,7 @@
 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDict
-from TriggerMenuMT.HLTMenuConfig.Jet.JetDef import JetChainConfiguration as JetChainConfiguration
+from TriggerMenuMT.HLTMenuConfig.Jet.JetChainConfiguration import JetChainConfiguration
 
 
 from AthenaCommon.Logging import logging
@@ -25,9 +25,12 @@ def generateChainConfigs( chainDict ):
         listOfChainDefs += [Jet]
         log.debug('length of chaindefs %s', len(listOfChainDefs) )
         
-
+    # We should never use multiple reco definitions, as this
+    # cannot be handled by the hypos.
+    # FIXME: Check that all jet reco configs are identical
     if len(listOfChainDefs)>1:
-        log.warning("Implement case for multi-electron chain!!") 
+        # Add reco consistency checking between all 
+        log.warning("Multiple jet chainParts detected; reco consistency checks not yet implemented")
         theChainDef = listOfChainDefs[0] #needs to be implemented properly
     else:
         theChainDef = listOfChainDefs[0]
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
similarity index 63%
rename from Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetDef.py
rename to Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
index 398b8722b7fb16c279fa4e45b16ac2d9115b8c96..39e0cf2c131478d1e3de380d7f78443f58fef5e9 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
@@ -8,15 +8,6 @@ log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.Egamma.JetDef")
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep, RecoFragmentsPool
 
-from TriggerMenuMT.HLTMenuConfig.Jet.JetSequenceSetup import jetMenuSequence
-
-#----------------------------------------------------------------
-# fragments generating configuration will be functions in New JO, 
-# so let's make them functions already now
-#----------------------------------------------------------------
-def jetSequence1Cfg( flags ):    
-    return jetMenuSequence()
-
 #----------------------------------------------------------------
 # Class to configure chain
 #----------------------------------------------------------------
@@ -24,6 +15,11 @@ class JetChainConfiguration(ChainConfigurationBase):
 
     def __init__(self, chainDict):
         ChainConfigurationBase.__init__(self,chainDict)
+
+        # interpret the reco configuration only
+        # eventually should just be a subdict in the chainDict
+        recoKeys = ['recoAlg','dataType','calib','jetCalib','trkopt','cleaning']
+        self.recoDict = { key:self.dict["chainParts"][key] for key in recoKeys }
         
     # ----------------------
     # Assemble the chain depending on information from chainName
@@ -34,13 +30,9 @@ class JetChainConfiguration(ChainConfigurationBase):
         # --------------------
         # define here the names of the steps and obtain the chainStep configuration 
         # --------------------
-        stepDictionary = {
-            "": [self.getJetSequence1()]
-        }
-        
-        ## This needs to be configured by the Jet Developer!!
-        key = self.chainPart['extra'] 
-        steps=stepDictionary[key]
+        # Only one step for now, but we might consider adding steps for
+        # reclustering and trimming workflows
+        steps=[self.getJetChainStep()]
 
         chainSteps = []
         for step in steps:
@@ -53,10 +45,15 @@ class JetChainConfiguration(ChainConfigurationBase):
     # --------------------
     # Configuration of steps
     # --------------------
-    def getJetSequence1(self):
-        stepName = "Step1_jet"
+    def getJetChainStep(self):
+        from TriggerMenuMT.HLTMenuConfig.Jet.JetMenuSequences import jetMenuSequence
+        from TriggerMenuMT.HLTMenuConfig.Jet.JetRecoSequences import jetRecoDictToString
+
+        jetDefStr = jetRecoDictToString(self.recoDict)
+
+        stepName = "Step1_jet_"+jetDefStr
         log.debug("Configuring step " + stepName)
-        jetSeq1 = RecoFragmentsPool.retrieve( jetSequence1Cfg, None ) # the None will be used for flags in future
+        jetSeq1 = RecoFragmentsPool.retrieve( jetMenuSequence, None, **self.recoDict ) # the None will be used for flags in future
         return ChainStep(stepName, [jetSeq1])
         
             
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetMenuSequences.py
similarity index 73%
rename from Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceSetup.py
rename to Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetMenuSequences.py
index d97294178a4ce1fad36c8ec27d070a5312b4cc01..2e3fa9c8cc2b025f2c6934f0f5e66618de8b2162 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetMenuSequences.py
@@ -2,23 +2,21 @@
 #
 
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import RecoFragmentsPool, MenuSequence
-from AthenaConfiguration.AllConfigFlags import ConfigFlags
     
-def jetMenuSequence():
+def jetMenuSequence(dummyFlags,**recoDict):
     """ Function to create the jet Menu Sequence"""
     
     ## RoIs = 'FSJETRoI'
     #reco sequence
-    from TriggerMenuMT.HLTMenuConfig.Jet.JetSequenceDefs import jetAthSequence
-    (JetAthSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(jetAthSequence,ConfigFlags)
-     
+    from TriggerMenuMT.HLTMenuConfig.Jet.JetRecoSequences import jetAthSequence, jetRecoDictToString
+    (JetAthSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(jetAthSequence,None,**recoDict)
+    
     #hypo
     from TrigHLTJetHypo.TrigHLTJetHypoConf import TrigJetHypoAlgMT
     from TrigHLTJetHypo.TrigJetHypoToolConfig import trigJetHypoToolFromDict
-    hypo = TrigJetHypoAlgMT("TrigJetHypoAlgMT")
+    hypo = TrigJetHypoAlgMT("TrigJetHypoAlgMT_"+jetRecoDictToString(recoDict))
     hypo.Jets = sequenceOut
 
-
     return  MenuSequence( Sequence    = JetAthSequence,
                           Maker       = InputMakerAlg,
                           Hypo        = hypo,
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1a42b68239e0a7a08f084a6e86050824fd916c0
--- /dev/null
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
@@ -0,0 +1,178 @@
+#
+#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#
+
+
+from AthenaCommon.CFElements import parOR, seqAND
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import RecoFragmentsPool
+
+# Translate the reco dict to a string for suffixing etc
+def jetRecoDictToString(jetRecoDict):
+    strtemp = "{recoAlg}_{dataType}_{calib}_{jetCalib}"
+    return strtemp.format(**jetRecoDict)
+
+# Configure reco from a dict of options
+# Start from a FullScan inputs maker
+def jetAthSequence(dummyFlags, **jetRecoDict):
+    from TrigT2CaloCommon.CaloDef import clusterFSInputMaker
+    InputMakerAlg= clusterFSInputMaker()
+
+    # Does nothing now, but may need to use this to toggle Insitu calib step
+    # in which case it should be deduced from input flags
+    dataSource = "data" # or mc
+
+    (recoSequence, sequenceOut) = RecoFragmentsPool.retrieve( jetRecoSequence, None, dataSource=dataSource, **jetRecoDict )
+
+    jetDefString = jetRecoDictToString(jetRecoDict)
+    JetAthSequence =  seqAND("jetAthSequence_"+jetDefString,[InputMakerAlg, recoSequence ])
+    return (JetAthSequence, InputMakerAlg, sequenceOut)
+
+# Dummy flag arg needed so that each reco sequence is held separately
+# in the RecoFragmentsPool -- only the kwargs are used to distinguish
+# different sequences. New convention is just to pass "None" for flags
+def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict):
+
+    jetDefString = jetRecoDictToString(jetRecoDict)
+    recoSeq = parOR( "JetRecSeq_"+jetDefString, [])
+
+    recoAlg = jetRecoDict["recoAlg"]
+    doGrooming = recoAlg.endswith("t") # Maybe other grooming strategies
+    doRecluster = recoAlg.endswith("r")
+    radius = float(recoAlg.lstrip("a").rstrip("tr"))/10
+    jetNamePrefix = "Trig"
+
+    from JetRecConfig.JetDefinition import JetConstit, xAODType, JetDefinition
+    from JetRecConfig.JetRecConfig import getConstitPJGAlg, getJetAlgorithm
+    if doRecluster:
+        # Reclustering -- recursively call the basic jet reco and add this to the sequence,
+        # then add another jet algorithm to run the reclustering step
+        basicJetRecoDict = dict(jetRecoDict)
+        basicJetRecoDict["recoAlg"] = "a4"
+        (basicJetRecoSequence,basicJetsName) = RecoFragmentsPool.retrieve(jetRecoSequence,None,dataSource=dataSource, **basicJetRecoDict)
+        recoSeq += basicJetRecoSequence
+
+        rcJetConstit = JetConstit( xAODType.Jet, [])
+        rcJetDef = JetDefinition( "AntiKt", 1.0, rcJetConstit)
+        rcJetsFullName = jetNamePrefix+rcJetDef.basename+"RCJets_"+jetRecoDict["jetCalib"]
+
+        rcModList= []
+        rcJetConstit.inputname = basicJetsName
+
+        rcConstitPJAlg = getConstitPJGAlg( rcJetConstit )
+        rcConstitPJKey = rcConstitPJAlg.PJGetter.OutputContainer
+        recoSeq += rcConstitPJAlg
+
+        rcPJs = [rcConstitPJKey]
+        rcJetRecAlg = getJetAlgorithm(rcJetsFullName, rcJetDef, rcPJs, rcModList)
+
+        recoSeq += rcJetRecAlg
+
+        sequenceOut = rcJetsFullName
+
+    elif doGrooming:
+        # Grooming needs to be set up similarly to reclustering
+        # --> build ungroomed jets, then add a grooming alg        
+        pass
+    else:
+        # Normal jet reconstruction, no reclustering or grooming
+
+        # Start by adding the topocluster reco sequence
+        # We always make LCW topoclusters, then deal with
+        # calibration states later
+        from TrigT2CaloCommon.CaloDef import HLTFSTopoRecoSequence
+        (topoClusterSequence, clustersKey) = RecoFragmentsPool.retrieve(HLTFSTopoRecoSequence,RoIs)
+        recoSeq += topoClusterSequence
+
+        # Potentially add particle flow reconstruction
+        # Work in progress
+        if jetRecoDict["dataType"] == "pf":
+            from eflowRec.PFHLTSequence import PFHLTSequence
+            pfseq = RecoFragmentsPool.retrieve(PFHLTSequence,clustersKey)
+            recoSeq += pfseq
+
+        # Define the jet constituents to be interpreted by JetRecConfig
+        def defineJetConstit(jetRecoDict,clustersKey):
+            # Get the details of the constituent definition:
+            # type, mods and the input container name
+            if "tc" in jetRecoDict["dataType"]:
+                # apply this scale
+                if jetRecoDict["calib"] == "em":
+                    constitMods = ["EM"]
+                elif jetRecoDict["calib"] == "lcw":
+                    constitMods = ["LC"]
+                # read from this cluster collection,
+                # overriding the standard offline collection
+                jetConstit = JetConstit( xAODType.CaloCluster, constitMods )
+                jetConstit.rawname = clustersKey
+                # apply constituent pileup suppression
+                if "sk" in jetRecoDict["dataType"]:
+                    constitMods.append("SK")
+                else:
+                    jetConstit.inputname = clustersKey
+            return jetConstit
+
+        jetConstit = defineJetConstit(jetRecoDict,clustersKey)
+        doConstitMods = ("sk" in jetRecoDict["dataType"])
+        if doConstitMods:
+            from JetRecConfig.ConstModHelpers import getConstitModAlg
+            recoSeq += getConstitModAlg(jetConstit,"HLT")
+        
+        # Arbitrary min pt for fastjet, set to be low enough for MHT(?)
+        # Could/should adjust higher for large-R
+        jetDef = JetDefinition( "AntiKt", radius, jetConstit, ptmin=5000.)
+        
+        # chosen jet collection
+        jetsFullName = jetNamePrefix+jetDef.basename+"Jets_"+jetRecoDict["jetCalib"]
+        sequenceOut = jetsFullName
+
+        from JetRecConfig import JetRecConfig
+        # Import the standard jet modifiers as defined for offline
+        # We can add/configure these differently if desired. In particular,
+        # we could define a TriggerJetMods module if settings need to
+        # diverge substantially e.g. track/vertex collections
+        from JetRecConfig.StandardJetMods import jetmoddict
+        # Make generating the list a bit more comprehensible
+        def getModSpec(modname,modspec=''):
+            return (jetmoddict[modname],str(modspec))
+        # Minimum modifier set for calibration w/o track GSC
+        # Should eventually build in more mods, depend on track info etc
+        calibMods = []
+
+        if jetRecoDict["jetCalib"] != "nojcalib":
+            # Translate calib specification into something understood by
+            # the calibration config helper
+            calibContext,calibSeq = {
+                ("a4","subjes"):   ("TrigRun2","JetArea_EtaJES_GSC"),        # Calo GSC only
+                ("a4","subjesIS"): ("TrigRun2","JetArea_EtaJES_GSC_Insitu"), # Calo GSC only
+                ("a10","subjes"):  ("TrigUngroomed","JetArea_EtaJES"),
+                }[(jetRecoDict["recoAlg"],jetRecoDict["jetCalib"])]
+
+            calibSpec = calibContext+":"+dataSource+":"+calibSeq
+            calibMods = [getModSpec("ConstitFourMom"),
+                         getModSpec("CaloEnergies"),
+                         getModSpec("Calib",calibSpec),
+                         getModSpec("Sort")]
+        jetModList = calibMods + [getModSpec("Filter",5000)]
+
+        # Add the PseudoJetGetter alg to the sequence
+        constitPJAlg = getConstitPJGAlg( jetConstit )
+        constitPJKey = constitPJAlg.PJGetter.OutputContainer
+        recoSeq += constitPJAlg
+        # Basic list of PseudoJets is just the constituents
+        # Append ghosts (tracks) if desired
+        pjs = [constitPJKey]
+
+        if "sub" in jetRecoDict["jetCalib"]:
+            # Add the event shape alg if needed for area subtraction
+            from JetRecConfig.JetRecConfig import getEventShapeAlg
+            eventShapeAlg = getEventShapeAlg( jetConstit, constitPJKey, "TrigJet" )
+            recoSeq += eventShapeAlg
+
+        # Generate a JetAlgorithm to run the jet finding and modifiers
+        # (via a JetRecTool instance).
+        jetRecAlg = JetRecConfig.getJetAlgorithm(jetsFullName, jetDef, pjs, jetModList)
+        recoSeq += jetRecAlg
+        # End of basic jet reco
+        pass
+
+    return (recoSeq,sequenceOut)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceDefs.py
deleted file mode 100644
index e5e3da26ab99f7e461cda57c79fc77d1e942deda..0000000000000000000000000000000000000000
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetSequenceDefs.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-#
-
-from AthenaCommon.CFElements import seqAND
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import RecoFragmentsPool
-
-## def jetFSInputMaker( ):
-##   """ Creates the jet inputMaker for FS"""
-##   RoIs = jetCollections.L1RoIs
-##   #'FSJETRoI'
-##   from DecisionHandling.DecisionHandlingConf import InputMakerForRoI
-##   InputMakerAlg = InputMakerForRoI("JetInputMaker", RoIsLink="initialRoI")
-##   InputMakerAlg.RoIs=RoIs
-##   return InputMakerAlg
-
-
-def jetAthSequence(ConfigFlags):
-    from TrigT2CaloCommon.CaloDef import clusterFSInputMaker
-    InputMakerAlg= clusterFSInputMaker()
-    (recoSequence, sequenceOut) = jetRecoSequence()
-
-    JetAthSequence =  seqAND("jetAthSequence",[InputMakerAlg, recoSequence ])
-    return (JetAthSequence, InputMakerAlg, sequenceOut)
-
-    
-def jetRecoSequence(RoIs = 'FSJETRoI'):
-    from TrigT2CaloCommon.CaloDef import HLTFSTopoRecoSequence
-    (jetRecoSequence, caloclusters) = RecoFragmentsPool.retrieve(HLTFSTopoRecoSequence, RoIs)
-
-    from AthenaCommon.AppMgr import ToolSvc
-    # Jet Reco:
-
-    # PseudoJetAlgorithm uses a tool to convert IParticles (eg CaloClusters)
-    # to PseudoJets, which are the input to FastJet. The PseudoJets are
-    # stored in a PseudoJetContainer, which is written top the event store.
-
-    from JetRec.JetRecConf import (PseudoJetAlgorithm,
-                                       PseudoJetGetter)
-
-
-    pseudoJetGetter = PseudoJetGetter('simpleJobPJGetter')
-    pseudoJetGetter.InputContainer = caloclusters
-    pseudoJetGetter.OutputContainer = 'PseudoJetEMTopo'
-    pseudoJetGetter.Label = ''
-
-    ToolSvc += pseudoJetGetter
-
-    algo3 = PseudoJetAlgorithm()
-    algo3.PJGetter = pseudoJetGetter
-
-    jetRecoSequence += algo3
-
-
-
-    # JetAlgorithm and its Tools... Reads in PseudoJetContainers,
-    # alls FastJet to cluster PseudoJets,
-    # and then convert the output of FastJet (new pseudojets) to Atlas jets.
-
-    from JetRec.JetRecConf import (JetAlgorithm,
-                                   JetRecTool,
-                                   JetFromPseudojet,
-                                   JetFinder)
-
-
-    name = 'simpleJob'
-
-    # jet from Pseudo jet takes a pseudo jet returned by FastJet
-    jetBuilder = JetFromPseudojet(name+'JetBuilder')
-    ToolSvc += jetBuilder
-
-    jetFinder = JetFinder(name+'JetFinder')
-    jetFinder.JetBuilder = jetBuilder
-    jetFinder.JetAlgorithm = 'AntiKt'
-    jetFinder.VariableRMinRadius = -1
-    jetFinder.VariableRMassScale = -1
-    jetFinder.GhostArea = 0.01
-    jetFinder.JetRadius = 0.4
-    jetFinder.PtMin = 7000. 
-    jetFinder.RandomOption = 1  #  1: used run/evt number to make seed
-
-    ToolSvc += jetFinder
-
-    jetRecTool = JetRecTool()
-    jetRecTool.InputContainer = ''  # name of a jet collection.
-    jetRecTool.OutputContainer = 'jets'
-    jetRecTool.JetFinder = jetFinder
-    jetRecTool.JetModifiers = []
-    jetRecTool.Trigger = False
-    jetRecTool.InputPseudoJets = ['StoreGateSvc+PseudoJetEMTopo']
-
-    ToolSvc += jetRecTool
-
-    algo4 = JetAlgorithm()
-    algo4.Tools = [jetRecTool]
-    jetRecoSequence += algo4
-
-
-    sequenceOut= jetRecTool.OutputContainer
-
-    return (jetRecoSequence,sequenceOut)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/README.md b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..91146d2d8e0d70e403ba33c9f385d5998432a2f8
--- /dev/null
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/README.md
@@ -0,0 +1,39 @@
+# Overview of HLT jet reco configuration modules
+
+## GenerateJetChainDefs.py
+
+Called by the menu code in `[TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py](https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py)` to translate the HLT chain item into a concrete algorithm sequence.
+
+The menu code creates a chain dictionary from the chain name, of which the jet parts are given to `GenerateJetChainDefs.generateChainConfigs` to be interpreted by `JetChainConfiguration`.
+
+## JetChainConfiguration.py
+
+Defines the `JetChainConfiguration` object responsible for interpreting the chain dictionary and building a `Chain` object that is returned to the menu.
+
+This extracts the reco configuration from the jet chain dictionary, using it to generate a `MenuSequence` that forms the jet `ChainStep`. It may be desirable to implement multiple `ChainSteps` for filtering purposes in the future, mainly to allow fast reco and filtering before slower reco is executed.
+
+`JetChainConfiguration` internally calls `JetMenuSequences.jetMenuSequence()` to produce the `MenuSequence` item, which contains a reco sequence followed by a hypo selection.
+
+## JetMenuSequences.py
+
+The jet chains are currently made up of only a single step, which runs reco+hypo. The menu sequence is constructed from:
+* a concrete reco sequence, generated by `JetRecoSequences.jetAthSequence()`;
+* the `InputMakerAlg` for this sequence (largely irrelevant as jets work in FullScan rather than in EventViews);
+* a hypo alg (one instance per jet collection i.e. reco config); and
+*  a hypo tool generator function that will define the selection based on the `chainDict` contents (configuration defined in `TrigHLTJetHypo`).
+
+The reco sequence and hypo alg names are suffixed with a string summarising the reco options.
+
+## JetRecoSequences.py
+
+This module provides the `jetAthSequence()` and `jetRecoSequence()` functions that define the reconstruction sequence for any given reconstruction configuration.
+
+The `jetAthSequence` holds the full reconstruction as well as an `InputMakerAlg` which for FullScan jet triggers (AFAIK) mostly serves to communicate L1 seed information to determine which hypo tools should be run.
+
+The reconstruction sequence is determined from the contents of the reco information in the `chainDict`, and will contain some subset of:
+* Calo reco sequence: cell unpacking and topoclustering -- one instance shared between all jet chains
+* Constituent modifications [optional] -- pileup suppression on topoclusters or corrections to PFlow four-vectors
+* PseudoJetGetters & algs -- conversion of the ATLAS EDM into `fastjet` EDM
+* JetAlgorithm -- holds the jet finder tools and any modifiers e.g. calibration
+The reco sequence may be nested further in the case of reclustering or trimming workflows, in which case the "basic" jet reco from clusters is embedded in a second sequence, which continues by running the second step reconstruction.
+Configuration of the Athena components is handled by the `Reconstruction/Jet/JetRecConfig` package.
\ No newline at end of file
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index 6cf942c9e463280b8d4c0880ac3230e047bfba63..e3ce86e53db869661babf091496603c7a4c30a50 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -78,6 +78,9 @@ def setupMenu():
 
         ChainProp(name='HLT_j225_gsc420_boffperf_split_L1J20', groups=SingleJetGroup), 
         ChainProp(name='HLT_j260_320eta490_L1J20', groups=SingleJetGroup),
+
+        ChainProp(name='HLT_j460_a10_lcw_subjes_L1J20', groups=SingleJetGroup),        
+        ChainProp(name='HLT_j460_a10r_L1J20', groups=SingleJetGroup),        
         
         ChainProp(name='HLT_3j200_L1J20', groups=MultiJetGroup),
         ChainProp(name='HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20', groups=SingleJetGroup),