From f73002e81ca3d64c33e44f8df28e3df9168bc34b Mon Sep 17 00:00:00 2001
From: Teng Jian Khoo <teng.jian.khoo@cern.ch>
Date: Mon, 30 Nov 2020 09:51:18 +0000
Subject: [PATCH] Rerun jet modifiers after jet calibration, both to update
 4-vec and to ensure that decorations are registered

---
 .../Jet/JetRecConfig/python/JetRecConfig.py   | 36 +++++++-
 .../share/ref_RDOtoRDOTrig_v1Dev_build.ref    | 16 ++--
 .../share/ref_data_v1Dev_build.ref            |  8 +-
 .../TrigEDMConfig/python/TriggerEDMRun3.py    | 56 +++++++-----
 .../HLTMenuConfig/Jet/JetRecoConfiguration.py | 16 ++--
 .../HLTMenuConfig/Jet/JetRecoSequences.py     | 86 +++++++++++++------
 6 files changed, 147 insertions(+), 71 deletions(-)

diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
index e71c285f072..4e1950ae4a4 100644
--- a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
@@ -289,7 +289,8 @@ def getJetAlgorithm(jetname, jetdef, pjContNames, monTool = None):
     return jetalg
 
 ########################################################################
-# Function that substitues JetRecTool + JetAlgorithm
+# New JetRecAlgorithm to replace JetRecTool
+# This call is for a JRA that runs jet-finding
 #
 def getJetRecAlg( jetdef):
     """ """
@@ -318,6 +319,39 @@ def getJetRecAlg( jetdef):
     return jra
 
 
+########################################################################
+# Get a JetRecAlg set up to copy a jet collection and apply mods
+# In this setup we do not resolve dependencies because typically
+# these may be set up already in the original jet collection
+# In future we may wish to add a toggle.
+#
+def getJetCopyAlg(jetsin, jetsoutdef, shallowcopy=True, shallowIO=True):
+
+    jcopy = CompFactory.JetCopier(
+        "copier",
+        InputJets = jetsin,
+        ShallowCopy=shallowcopy,
+        ShallowIO=shallowIO)
+
+    # Convert mod aliases into concrete tools
+    from . import JetModConfig
+    mods = []
+    for mod in jetsoutdef.modifiers:
+        moddef = JetModConfig.aliasToModDef(mod,jetsoutdef)
+        mods.append(JetModConfig.getModifier(jetsoutdef,moddef,moddef.modspec))
+
+    jetsoutname = jetsoutdef.fullname()
+    jra = CompFactory.JetRecAlg(
+        "jetrecalg_copy_"+jetsoutname,
+        Provider = jcopy,
+        Modifiers = mods,
+        OutputContainer = jetsoutname)
+
+    autoconfigureModifiers(jra.Modifiers, jetsoutname)
+
+    return jra
+
+
 ########################################################################
 # For each modifier in the given list with a configurable input container
 # name ("JetContainer"), configure it to containerName.
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index ee1f577f913..c7ce0587966 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -473,7 +473,7 @@ HLT_JetDS_j0_L1J100:
     1: 3
     2: 3
   stepFeatures:
-    0: 81
+    0: 137
     1: 32
     2: 3
 HLT_alfacalib_AlfaPEB_L1ALFA_ANY:
@@ -1371,7 +1371,7 @@ HLT_j0_aggSEP500htSEP30etSEP0eta320_L1J20:
   stepCounts:
     0: 1
   stepFeatures:
-    0: 28
+    0: 50
 HLT_j0_perf_L1J12_EMPTY:
   eventCount: 0
 HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20:
@@ -2723,11 +2723,11 @@ HLT_xe100_cvfpufit_L1XE50:
     0: 10
     1: 6
 HLT_xe100_mht_L1XE50:
-  eventCount: 9
+  eventCount: 7
   stepCounts:
-    0: 9
+    0: 7
   stepFeatures:
-    0: 9
+    0: 7
 HLT_xe100_mhtpufit_em_subjesgscIS_L1XE50:
   eventCount: 6
   stepCounts:
@@ -2783,11 +2783,11 @@ HLT_xe100_trkmht_xe85_tcpufit_xe65_cell_L1XE50:
     0: 6
     1: 5
 HLT_xe110_mht_L1XE50:
-  eventCount: 7
+  eventCount: 6
   stepCounts:
-    0: 7
+    0: 6
   stepFeatures:
-    0: 7
+    0: 6
 HLT_xe110_pfsum_L1XE50:
   eventCount: 4
   stepCounts:
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index b025d4a3582..d625334c127 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -647,7 +647,7 @@ HLT_j0_perf_L1J12_EMPTY:
   stepCounts:
     0: 8
   stepFeatures:
-    0: 117
+    0: 127
 HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20:
   eventCount: 2
   stepCounts:
@@ -1747,13 +1747,13 @@ HLT_xe30_mht_L1XE10:
   stepFeatures:
     0: 14
 HLT_xe30_mhtpufit_em_subjesgscIS_L1XE10:
-  eventCount: 5
+  eventCount: 4
   stepCounts:
     0: 20
-    1: 5
+    1: 4
   stepFeatures:
     0: 20
-    1: 5
+    1: 4
 HLT_xe30_mhtpufit_pf_subjesgscIS_L1XE10:
   eventCount: 3
   stepCounts:
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index 7a7d524b736..84091e726d2 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -62,9 +62,18 @@ JetVarsToKeep = ['ActiveArea', 'ActiveArea4vec_eta', 'ActiveArea4vec_m', 'Active
                  'JetPileupScaleMomentum_eta', 'JetPileupScaleMomentum_m', 'JetPileupScaleMomentum_phi', 'JetPileupScaleMomentum_pt',
                  'JetEtaJESScaleMomentum_eta', 'JetEtaJESScaleMomentum_m', 'JetEtaJESScaleMomentum_phi', 'JetEtaJESScaleMomentum_pt',
                  'JetGSCScaleMomentum_eta', 'JetGSCScaleMomentum_m', 'JetGSCScaleMomentum_phi', 'JetGSCScaleMomentum_pt',
-                 'Jvt', 'JVFCorr', 'NumTrkPt500', 'NumTrkPt1000', 'SizeParameter', 'SumPtTrkPt500', 'SumPtTrkPt1000', 'TrackWidthPt1000', 'SumPtChargedPFOPt500',]
+                 'Jvt', 'JVFCorr', 'NumTrkPt500', 'NumTrkPt1000', 'SizeParameter', 'SumPtTrkPt500', 'SumPtTrkPt1000', 'TrackWidthPt1000', 'SumPtChargedPFOPt500',
+]
 JetVars = '.'.join(JetVarsToKeep)
 
+JetCopyVarsToKeep = ['pt', 'eta', 'phi', 'm',
+                     'JetPileupScaleMomentum_eta', 'JetPileupScaleMomentum_m', 'JetPileupScaleMomentum_phi', 'JetPileupScaleMomentum_pt',
+                     'JetEtaJESScaleMomentum_eta', 'JetEtaJESScaleMomentum_m', 'JetEtaJESScaleMomentum_phi', 'JetEtaJESScaleMomentum_pt',
+                     'JetGSCScaleMomentum_eta', 'JetGSCScaleMomentum_m', 'JetGSCScaleMomentum_phi', 'JetGSCScaleMomentum_pt',
+                     'Jvt'
+                 ]
+JetCopyVars = '.'.join(JetCopyVarsToKeep)
+
 BTagOutput = ['jetLink','BTagTrackToJetAssociator','minimumTrackRelativeEta','maximumTrackRelativeEta','averageTrackRelativeEta','trkSum_ntrk','trkSum_SPt','trkSum_VPt','trkSum_VEta','Muons',]
 BTagOutput_IP2D = ['IP2D_TrackParticleLinks','IP2D_gradeOfTracks','IP2D_weightBofTracks','IP2D_weightCofTracks','IP2D_weightUofTracks','IP2D_sigD0wrtPVofTracks','IP2D_flagFromV0ofTracks','IP2D_nTrks','IP2D_isDefaults','IP2D_cu','IP2D_bu','IP2D_bc',]
 BTagOutput_IP3D = ['IP3D_TrackParticleLinks','IP3D_gradeOfTracks','IP3D_weightBofTracks','IP3D_weightCofTracks','IP3D_weightUofTracks','IP3D_valD0wrtPVofTracks','IP3D_sigD0wrtPVofTracks','IP3D_valZ0wrtPVofTracks','IP3D_sigZ0wrtPVofTracks','IP3D_flagFromV0ofTracks','IP3D_nTrks','IP3D_isDefaults','IP3D_cu','IP3D_bu','IP3D_bc',]
@@ -277,20 +286,23 @@ TriggerHLTListRun3 = [
     ('xAOD::JetAuxContainer#HLT_jet_seedAux.',                  'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Tau'),
 
     # Jet
-    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesIS',                      'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_subjesISAux.'+JetVars,       'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesIS',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMTopoJets_subjesISAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesIS_ftf',                  'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_subjesIS_ftfAux.'+JetVars,   'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_nojcalib_ftf',                  'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_nojcalib_ftfAux.'+JetVars,   'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesgscIS_ftf',                'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_subjesgscIS_ftfAux.'+JetVars, 'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
-
-    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subresjesgscIS_ftf',                'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_subresjesgscIS_ftfAux.'+JetVars, 'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesIS_ftf',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMTopoJets_subjesIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
+                    
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjesgscIS_ftf',                        'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMTopoJets_subjesgscIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
+    
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subresjesgscIS_ftf',                        'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMTopoJets_subresjesgscIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL AODSLIM AODVERYSLIM', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjes',                        'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_subjesAux.'+JetVars,         'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_subjes',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMTopoJets_subjesAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
     ('xAOD::JetContainer#HLT_AntiKt4EMTopoJets_nojcalib',                      'BS ESD AODFULL', 'Jet'),
     ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoJets_nojcalibAux.'+JetVars,       'BS ESD AODFULL', 'Jet'),
@@ -301,8 +313,8 @@ TriggerHLTListRun3 = [
     ('xAOD::JetContainer#HLT_AntiKt4EMTopoCSSKJets_nojcalib',                  'BS ESD AODFULL', 'Jet'),
     ('xAOD::JetAuxContainer#HLT_AntiKt4EMTopoCSSKJets_nojcalibAux.'+JetVars,   'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt10LCTopoJets_subjes',                       'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt10LCTopoJets_subjesAux.'+JetVars,        'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt10LCTopoJets_subjes',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt10LCTopoJets_subjesAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
     ('xAOD::JetContainer#HLT_AntiKt10LCTopoJets_nojcalib',                     'BS ESD AODFULL', 'Jet'),
     ('xAOD::JetAuxContainer#HLT_AntiKt10LCTopoJets_nojcalibAux.'+JetVars,      'BS ESD AODFULL', 'Jet'),
@@ -331,17 +343,17 @@ TriggerHLTListRun3 = [
     ('xAOD::JetContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_nojcalib_ftf',                'BS ESD AODFULL', 'Jet'),
     ('xAOD::JetAuxContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_nojcalib_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf',                'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf',                    'BS ESD AODFULL', 'Jet'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subjesIS_ftf',                'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMPFlowJets_subjesIS_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subjesIS_ftf',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMPFlowJets_subjesIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subjesgscIS_ftf',                'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMPFlowJets_subjesgscIS_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subjesgscIS_ftf',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMPFlowJets_subjesgscIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
-    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf',                'BS ESD AODFULL', 'Jet'),
-    ('xAOD::JetAuxContainer#HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
+    ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf',                        'BS ESD AODFULL', 'Jet', 'alias:JetContainerShallowCopy'),
+    ('xAOD::ShallowAuxContainer#HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftfAux.'+JetCopyVars, 'BS ESD AODFULL', 'Jet'),
 
     ('xAOD::JetContainer#HLT_AntiKt4EMPFlowJets_nojcalib_ftf',                'BS ESD AODFULL', 'Jet'),
     ('xAOD::JetAuxContainer#HLT_AntiKt4EMPFlowJets_nojcalib_ftfAux.'+JetVars, 'BS ESD AODFULL', 'Jet'),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoConfiguration.py
index df72ad99fc2..1f91b6668ff 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoConfiguration.py
@@ -202,9 +202,12 @@ def defineTrackMods(trkopt):
     ]
     return trkmods
 
+def getFilterCut(recoAlg):
+    return {"a4":5000, "a10":50000, "a10r": 50000, "a10t":50000, "a10sd":50000}[recoAlg]
+
 # Translate calib specification into something understood by
 # the calibration config helper
-def defineCalibFilterMods(jetRecoDict,dataSource,rhoKey="auto"):
+def defineCalibMods(jetRecoDict,dataSource,rhoKey="auto"):
 
     # Minimum modifier set for calibration w/o track GSC
     # Should eventually build in more mods, depend on track info etc
@@ -220,7 +223,7 @@ def defineCalibFilterMods(jetRecoDict,dataSource,rhoKey="auto"):
 
         if jetRecoDict["dataType"].endswith("tc"):
             calibContext,calibSeq = {
-                ("a4","subjes"):   ("TrigRun2","JetArea_EtaJES_GSC"),        # Calo GSC only
+                ("a4","subjes"):   ("TrigRun2","JetArea_EtaJES_GSC"), # Calo GSC only
                 ("a4","subjesIS"): ("TrigRun2","JetArea_EtaJES_GSC"), # Calo GSC only
                 ("a4","subjesgscIS"): ("TrigRun2GSC","JetArea_EtaJES_GSC"), # Calo+Trk GSC
                 ("a4","subresjesgscIS"): ("TrigRun2GSC","JetArea_Residual_EtaJES_GSC"), # pu residual + calo+trk GSC
@@ -254,12 +257,9 @@ def defineCalibFilterMods(jetRecoDict,dataSource,rhoKey="auto"):
         if jetalg=="a4":
             calibMods = ["ConstitFourMom_copy",
                          "CaloEnergies", # Needed for GSC
-                         "Calib:"+calibSpec,
-                         "Sort"]
+                         "Calib:"+calibSpec]
         else:
             calibMods = ["ConstitFourMom_copy",
-                         "Calib:"+calibSpec,
-                         "Sort"]
+                         "Calib:"+calibSpec]
 
-    filtercut = {"a4":7000, "a10":50000, "a10r": 50000, "a10t":50000, "a10sd":50000}[jetalg]
-    return calibMods + ["Filter:"+str(filtercut)]
+    return calibMods
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
index 3ff27580630..97d40f5a0de 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py
@@ -74,9 +74,9 @@ def jetRecoSequence( configFlags, clustersKey, **jetRecoDict ):
             clustersKey=clustersKey, **jetRecoDict)
 
 # Normal jet reconstruction, no reclustering or grooming
-def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
+def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
     jetDefString = jetRecoDictToString(jetRecoDict)
-    recoSeq = parOR( "JetRecSeq_"+jetDefString, [])
+    buildSeq = parOR( "JetBuildSeq_"+jetDefString, [])
     trkcolls = getTrkColls(jetRecoDict) if jetRecoDict["trkopt"]!="notrk" else {}
 
     # Add particle flow reconstruction if needed
@@ -87,10 +87,10 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
         (pfseq, pfoPrefix) = RecoFragmentsPool.retrieve(
             PFHLTSequence,
             configFlags, clustersin=clustersKey, tracktype=jetRecoDict["trkopt"])
-        recoSeq += pfseq
-        jetDef = JetRecoConfiguration.defineJets(jetRecoDict,pfoPrefix=pfoPrefix, prefix=jetNamePrefix)
+        buildSeq += pfseq
+        jetDef = JetRecoConfiguration.defineJets(jetRecoDict,pfoPrefix=pfoPrefix,prefix=jetNamePrefix)
     else:
-        jetDef = JetRecoConfiguration.defineJets(jetRecoDict,clustersKey=clustersKey, prefix=jetNamePrefix)
+        jetDef = JetRecoConfiguration.defineJets(jetRecoDict,clustersKey=clustersKey,prefix=jetNamePrefix)
 
     # chosen jet collection
     jetsFullName = jetDef.fullname()
@@ -105,12 +105,12 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
         from JetRecConfig.ConstModHelpers import getConstitModAlg
         constitModAlg = getConstitModAlg(jetDef.inputdef, monTool=monJetRecTool)
         if constitModAlg:
-            recoSeq += constitModAlg
+            buildSeq += constitModAlg
 
     # Add the PseudoJetGetter alg to the sequence
     constitPJAlg = getConstitPJGAlg( jetDef.inputdef )
     constitPJKey = str(constitPJAlg.OutputContainer)
-    recoSeq += conf2toConfigurable( constitPJAlg )
+    buildSeq += conf2toConfigurable( constitPJAlg )
     # Basic list of PseudoJets is just the constituents
     # Append ghosts (tracks) if desired
     pjs = [constitPJKey]
@@ -122,21 +122,8 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
         trkMods = JetRecoConfiguration.defineTrackMods(jetRecoDict["trkopt"])
         jetModList += trkMods
 
-    rhoKey = "auto"
-    if "sub" in jetRecoDict["jetCalib"]:
-        # Add the event shape alg if needed for area subtraction
-        eventShapeAlg = JetInputConfig.buildEventShapeAlg( jetDef,  "HLT_" )
-        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)
-
-    # Import the standard jet modifiers as defined for offline
-    # We can add/configure these differently if desired. 
-    calibMods = JetRecoConfiguration.defineCalibFilterMods(jetRecoDict,dataSource, rhoKey)
-    jetModList += calibMods
-
+    # Sort and filter
+    jetModList += ["Sort", "Filter:"+str(JetRecoConfiguration.getFilterCut(jetRecoDict["recoAlg"]))]
 
     # Get online monitoring tool
     from JetRec import JetOnlineMon
@@ -153,7 +140,47 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
     # Generate a JetAlgorithm to run the jet finding and modifiers
     # (via a JetRecTool instance).
     jetRecAlg = JetRecConfig.getJetAlgorithm(jetsFullName, jetDef, pjs, monTool)
-    recoSeq += conf2toConfigurable( jetRecAlg )
+    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
 
     # End of basic jet reco
     return recoSeq, jetsOut, jetDef
@@ -168,17 +195,20 @@ def groomedJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
     ungroomedJetRecoDict["recoAlg"] = ungroomedJetRecoDict["recoAlg"].rstrip("tsd") # Drop grooming spec
     ungroomedJetRecoDict["jetCalib"] = "nojcalib" # No need to calibrate
 
-    (ungroomedJetRecoSequence,ungroomedJetsName, ungroomedDef) = RecoFragmentsPool.retrieve(
-        standardJetRecoSequence,
+    # 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)
-    recoSeq += conf2toConfigurable( ungroomedJetRecoSequence )
+    recoSeq += ungroomedJetBuildSequence
     # Need to forward the pseudojets of the parents to the groomer
-    parentpjs = getattr(ungroomedJetRecoSequence,"jetalg_{}".format(ungroomedJetsName)).Tools[0].InputPseudoJets
+    # 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()
-    groomDef.modifiers = JetRecoConfiguration.defineCalibFilterMods(jetRecoDict,dataSource)
+    groomDef.modifiers = JetRecoConfiguration.defineCalibMods(jetRecoDict,dataSource)
+    groomDef.modifiers += ["Sort","Filter:"+str(JetRecoConfiguration.getFilterCut(jetRecoDict["recoAlg"]))]
     # Can add substructure mods here
 
     # Get online monitoring tool
-- 
GitLab