diff --git a/Calorimeter/CaloRec/python/CaloTopoClusterConfig.py b/Calorimeter/CaloRec/python/CaloTopoClusterConfig.py
index 7f334ebd4458aafe89e96d7e0028bfc962d7c952..a3120b9b97140791b94e50ca40b059c325502b7e 100644
--- a/Calorimeter/CaloRec/python/CaloTopoClusterConfig.py
+++ b/Calorimeter/CaloRec/python/CaloTopoClusterConfig.py
@@ -76,7 +76,7 @@ def getTopoClusterLocalCalibTools(configFlags):
     LCDeadMaterial   = CaloLCDeadMaterialTool("LCDeadMaterial")
     LCDeadMaterial.HadDMCoeffKey       = "HadDMCoeff2"
     LCDeadMaterial.ClusterRecoStatus   = 0
-    LCDeadMaterial.WeightModeDM        = 2 
+    LCDeadMaterial.WeightModeDM        = 2
     LCDeadMaterial.UseHadProbability   = True
     LCDeadMaterial.WeightingOfNegClusters = configFlags.Calo.TopoCluster.doTreatEnergyCutAsAbsolute
 
@@ -101,13 +101,13 @@ def getTopoMoments(configFlags):
     TopoMoments.MaxAxisAngle = 20*deg
     TopoMoments.TwoGaussianNoise = configFlags.Calo.TopoCluster.doTwoGaussianNoise
     TopoMoments.MinBadLArQuality = 4000
-    TopoMoments.MomentsNames = ["FIRST_PHI" 
+    TopoMoments.MomentsNames = ["FIRST_PHI"
                                 ,"FIRST_ETA"
-                                ,"SECOND_R" 
+                                ,"SECOND_R"
                                 ,"SECOND_LAMBDA"
                                 ,"DELTA_PHI"
                                 ,"DELTA_THETA"
-                                ,"DELTA_ALPHA" 
+                                ,"DELTA_ALPHA"
                                 ,"CENTER_X"
                                 ,"CENTER_Y"
                                 ,"CENTER_Z"
@@ -115,12 +115,12 @@ def getTopoMoments(configFlags):
                                 ,"CENTER_LAMBDA"
                                 ,"LATERAL"
                                 ,"LONGITUDINAL"
-                                ,"FIRST_ENG_DENS" 
-                                ,"ENG_FRAC_EM" 
-                                ,"ENG_FRAC_MAX" 
-                                ,"ENG_FRAC_CORE" 
-                                ,"FIRST_ENG_DENS" 
-                                ,"SECOND_ENG_DENS" 
+                                ,"FIRST_ENG_DENS"
+                                ,"ENG_FRAC_EM"
+                                ,"ENG_FRAC_MAX"
+                                ,"ENG_FRAC_CORE"
+                                ,"FIRST_ENG_DENS"
+                                ,"SECOND_ENG_DENS"
                                 ,"ISOLATION"
                                 ,"ENG_BAD_CELLS"
                                 ,"N_BAD_CELLS"
@@ -222,7 +222,7 @@ def getTopoCalibMoments(configFlags):
                                      ,"ENG_CALIB_FRAC_EM"
                                      ,"ENG_CALIB_FRAC_HAD"
                                      ,"ENG_CALIB_FRAC_REST"]
-    
+
     TopoCalibMoments.CalibrationHitContainerNames = ["LArCalibrationHitInactive"
                                                      ,"LArCalibrationHitActive"
                                                      ,"TileCalibHitActiveCell"
@@ -231,43 +231,11 @@ def getTopoCalibMoments(configFlags):
                                                        ,"TileCalibHitDeadMaterial"]
     return TopoCalibMoments
 
-# Steering options for trigger
-# Maybe offline reco options should be extracted from flags elsewhere
-def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib=None,sequenceName='AthAlgSeq'):
+def CaloTopoClusterToolCfg(configFlags, cellsname):
     result=ComponentAccumulator()
-    if (sequenceName != 'AthAlgSeq'):
-        from AthenaCommon.CFElements import seqAND
-        #result.mainSeq( seqAND( sequenceName ) )
-        result.addSequence( seqAND(sequenceName) )
-
-    if not clustersname:
-        clustersname = "CaloTopoClusters"
-
-    from LArGeoAlgsNV.LArGMConfig import LArGMCfg
-    from TileGeoModel.TileGMConfig import TileGMCfg
-    from CaloTools.CaloNoiseCondAlgConfig import CaloNoiseCondAlgCfg
-    # Schedule total noise cond alg
-    result.merge(CaloNoiseCondAlgCfg(configFlags,"totalNoise"))
-    # Schedule electronic noise cond alg (needed for LC weights)
-    result.merge(CaloNoiseCondAlgCfg(configFlags,"electronicNoise"))
-    
-    CaloTopoClusterMaker, CaloTopoClusterSplitter, CaloClusterMaker, CaloClusterSnapshot=CompFactory.getComps("CaloTopoClusterMaker","CaloTopoClusterSplitter","CaloClusterMaker","CaloClusterSnapshot",)
-
-    result.merge(LArGMCfg(configFlags))
-
-    from LArCalibUtils.LArHVScaleConfig import LArHVScaleCfg
-    result.merge(LArHVScaleCfg(configFlags))
-
-    result.merge(TileGMCfg(configFlags))
-
-    if not doLCCalib:
-        theCaloClusterSnapshot=CaloClusterSnapshot(OutputName=clustersname+"snapshot",SetCrossLinks=True)
-    else:
-        theCaloClusterSnapshot=CaloClusterSnapshot(OutputName=clustersname,SetCrossLinks=True)
-         
     # maker tools
-    TopoMaker = CaloTopoClusterMaker("TopoMaker")
-        
+    TopoMaker = CompFactory.CaloTopoClusterMaker("TopoMaker")
+
     TopoMaker.CellsName = cellsname
     TopoMaker.CalorimeterNames=["LAREM",
                                 "LARHEC",
@@ -281,7 +249,7 @@ def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib
                                    "TileBar0", "TileBar1", "TileBar2",
                                    "TileExt0", "TileExt1", "TileExt2",
                                    "TileGap1", "TileGap2", "TileGap3",
-                                   "FCAL0", "FCAL1", "FCAL2"] 
+                                   "FCAL0", "FCAL1", "FCAL2"]
     TopoMaker.NeighborOption = "super3D"
     TopoMaker.RestrictHECIWandFCalNeighbors  = False
     TopoMaker.RestrictPSNeighbors  = True
@@ -294,18 +262,22 @@ def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib
     TopoMaker.CutOOTseed = configFlags.Calo.TopoCluster.extendTimeCut and configFlags.Calo.TopoCluster.doTimeCut
     TopoMaker.UseTimeCutUpperLimit = configFlags.Calo.TopoCluster.useUpperLimitForTimeCut
     TopoMaker.TimeCutUpperLimit = 20.0
-    
-    # note E or AbsE 
+
+    # note E or AbsE
     #
     # the following property must be set to TRUE in order to make double
-    # sided cuts on the seed and the cluster level 
+    # sided cuts on the seed and the cluster level
     #
     TopoMaker.SeedCutsInAbsE                 = True
     TopoMaker.ClusterEtorAbsEtCut            = 0.0*MeV
     # use 2-gaussian or single gaussian noise for TileCal
     TopoMaker.TwoGaussianNoise = configFlags.Calo.TopoCluster.doTwoGaussianNoise
-        
-    TopoSplitter = CaloTopoClusterSplitter("TopoSplitter")
+    result.setPrivateTools(TopoMaker)
+    return result
+
+def CaloTopoClusterSplitterToolCfg(configFlags):
+    result=ComponentAccumulator()
+    TopoSplitter = CompFactory.CaloTopoClusterSplitter("TopoSplitter")
     # cells from the following samplings will be able to form local
     # maxima. The excluded samplings are PreSamplerB, EMB1,
     # PreSamplerE, EME1, all Tile samplings, all HEC samplings and the
@@ -326,6 +298,45 @@ def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib
     TopoSplitter.ShareBorderCells = True
     TopoSplitter.RestrictHECIWandFCalNeighbors  = False
     TopoSplitter.WeightingOfNegClusters = configFlags.Calo.TopoCluster.doTreatEnergyCutAsAbsolute
+    result.setPrivateTools(TopoSplitter)
+    return result
+
+# Steering options for trigger
+# Maybe offline reco options should be extracted from flags elsewhere
+def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib=None,sequenceName='AthAlgSeq'):
+    result=ComponentAccumulator()
+    if (sequenceName != 'AthAlgSeq'):
+        from AthenaCommon.CFElements import seqAND
+        #result.mainSeq( seqAND( sequenceName ) )
+        result.addSequence( seqAND(sequenceName) )
+
+    if not clustersname:
+        clustersname = "CaloTopoClusters"
+
+    from LArGeoAlgsNV.LArGMConfig import LArGMCfg
+    from TileGeoModel.TileGMConfig import TileGMCfg
+    from CaloTools.CaloNoiseCondAlgConfig import CaloNoiseCondAlgCfg
+    # Schedule total noise cond alg
+    result.merge(CaloNoiseCondAlgCfg(configFlags,"totalNoise"))
+    # Schedule electronic noise cond alg (needed for LC weights)
+    result.merge(CaloNoiseCondAlgCfg(configFlags,"electronicNoise"))
+
+    CaloClusterMaker, CaloClusterSnapshot=CompFactory.getComps("CaloClusterMaker","CaloClusterSnapshot",)
+
+    result.merge(LArGMCfg(configFlags))
+
+    from LArCalibUtils.LArHVScaleConfig import LArHVScaleCfg
+    result.merge(LArHVScaleCfg(configFlags))
+
+    result.merge(TileGMCfg(configFlags))
+
+    if not doLCCalib:
+        theCaloClusterSnapshot=CaloClusterSnapshot(OutputName=clustersname+"snapshot",SetCrossLinks=True)
+    else:
+        theCaloClusterSnapshot=CaloClusterSnapshot(OutputName=clustersname,SetCrossLinks=True)
+
+    TopoMaker = result.popToolsAndMerge( CaloTopoClusterToolCfg(configFlags, cellsname=cellsname))
+    TopoSplitter = result.popToolsAndMerge( CaloTopoClusterSplitterToolCfg(configFlags) )
     #
     # the following options are not set, since these are the default
     # values
@@ -333,13 +344,13 @@ def CaloTopoClusterCfg(configFlags,cellsname="AllCalo",clustersname="",doLCCalib
     # NeighborOption                = "super3D",
     # NumberOfCellsCut              = 4,
     # EnergyCut                     = 500*MeV,
-        
+
 
     CaloTopoCluster=CaloClusterMaker(clustersname)
     CaloTopoCluster.ClustersOutputName=clustersname
 
     CaloTopoCluster.ClusterMakerTools = [TopoMaker, TopoSplitter]
-    
+
     from CaloBadChannelTool.CaloBadChanToolConfig import CaloBadChanToolCfg
     caloBadChanTool = result.popToolsAndMerge( CaloBadChanToolCfg(configFlags) )
     CaloClusterBadChannelList=CompFactory.CaloClusterBadChannelList
@@ -375,20 +386,20 @@ if __name__=="__main__":
 
     ConfigFlags.lock()
 
-    from AthenaConfiguration.MainServicesConfig import MainServicesCfg 
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
     from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
 
     cfg=MainServicesCfg(ConfigFlags)
     cfg.merge(PoolReadCfg(ConfigFlags))
     # from IOVDbSvc.IOVDbSvcConfig import IOVDbSvcCfg
     # cfg.mergeAll(IOVDbSvcCfg(ConfigFlags))
-    
+
     theKey="CaloCalTopoClustersNew"
 
     topoAcc=CaloTopoClusterCfg(ConfigFlags)
     topoAlg = topoAcc.getPrimary()
     topoAlg.ClustersOutputName=theKey
-    
+
     cfg.merge(topoAcc)
 
     from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
@@ -405,11 +416,11 @@ if __name__=="__main__":
         StreamName = 'StreamAOD'
     )
     cfg.addEventAlgo(theNegativeEnergyCaloClustersThinner,"AthAlgSeq")
-  
+
 #    cfg.getService("StoreGateSvc").Dump=True
 
     cfg.run(10)
     #f=open("CaloTopoCluster.pkl","wb")
     #cfg.store(f)
     #f.close()
-    
+
diff --git a/Trigger/TrigAlgorithms/TrigCaloRec/python/TrigCaloRecConfig.py b/Trigger/TrigAlgorithms/TrigCaloRec/python/TrigCaloRecConfig.py
index 484a9ac0bd534e62450343c8f20ff05942267147..e5e8f3b313a8b11f8985ef29758ab66117c1c1d7 100755
--- a/Trigger/TrigAlgorithms/TrigCaloRec/python/TrigCaloRecConfig.py
+++ b/Trigger/TrigAlgorithms/TrigCaloRec/python/TrigCaloRecConfig.py
@@ -1707,3 +1707,85 @@ class TrigCaloClusterCalibratorMT_LC(TrigCaloClusterCalibratorMT):
         self.MonTool.defineHistogram('Eta', path='EXPERT', type='TH1F', title="Cluster #eta; #eta ; Number of Clusters", xbins=100, xmin=-2.5, xmax=2.5)
         self.MonTool.defineHistogram('Phi', path='EXPERT', type='TH1F', title="Cluster #phi; #phi ; Number of Clusters", xbins=64, xmin=-3.2, xmax=3.2)
         self.MonTool.defineHistogram('Eta,Phi', path='EXPERT', type='TH2F', title="Number of Clusters; #eta ; #phi ; Number of Clusters", xbins=100, xmin=-2.5, xmax=2.5, ybins=128, ymin=-3.2, ymax=3.2)
+
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+
+def hltCaloCellMakerCfg(flags, FS=False, roisKey='UNSPECIFIED'):
+    acc = ComponentAccumulator()
+    from TrigT2CaloCommon.TrigCaloDataAccessConfig import trigCaloDataAccessSvcCfg
+    acc.merge(trigCaloDataAccessSvcCfg(flags))
+
+    cellMaker = CompFactory.HLTCaloCellMaker('HLTCaloCellMaker'+ ('FS' if FS else 'RoI'),
+                                             CellsName='CaloCells',
+                                             TrigDataAccessMT=acc.getService('TrigCaloDataAccessSvc'),
+                                             monitorCells=True,
+                                             ExtraInputs=[('TileEMScale', 'ConditionStore+TileEMScale'),
+                                                          ('TileBadChannels', 'ConditionStore+TileBadChannels'),
+                                                          ('LArOnOffIdMapping', 'ConditionStore+LArOnOffIdMap')], # TODO check if this depends on data/MC
+                                             RoIs=roisKey)
+
+    acc.addEventAlgo(cellMaker)
+    return acc
+
+def hltTopoClusterMakerCfg(flags, FS=False):
+    acc = ComponentAccumulator()
+    from CaloRec.CaloTopoClusterConfig import CaloTopoClusterToolCfg, CaloTopoClusterSplitterToolCfg
+    topoMaker = acc.popToolsAndMerge(CaloTopoClusterToolCfg(flags, cellsname='CaloCells'))
+    topoSplitter = acc.popToolsAndMerge(CaloTopoClusterSplitterToolCfg(flags))
+
+
+    topoMoments = CompFactory.CaloClusterMomentsMaker ('TrigTopoMoments')
+    topoMoments.MaxAxisAngle = 20*deg
+    topoMoments.TwoGaussianNoise = flags.Calo.TopoCluster.doTwoGaussianNoise
+    topoMoments.MinBadLArQuality = 4000
+    topoMoments.MomentsNames = ['FIRST_PHI',
+                                'FIRST_ETA',
+                                'SECOND_R' ,
+                                'SECOND_LAMBDA',
+                                'DELTA_PHI',
+                                'DELTA_THETA',
+                                'DELTA_ALPHA' ,
+                                'CENTER_X',
+                                'CENTER_Y',
+                                'CENTER_Z',
+                                'CENTER_MAG',
+                                'CENTER_LAMBDA',
+                                'LATERAL',
+                                'LONGITUDINAL',
+                                'FIRST_ENG_DENS',
+                                'ENG_FRAC_EM',
+                                'ENG_FRAC_MAX',
+                                'ENG_FRAC_CORE' ,
+                                'FIRST_ENG_DENS',
+                                'SECOND_ENG_DENS',
+                                'ISOLATION',
+                                'ENG_BAD_CELLS',
+                                'N_BAD_CELLS',
+                                'N_BAD_CELLS_CORR',
+                                'BAD_CELLS_CORR_E',
+                                'BADLARQ_FRAC',
+                                'ENG_POS',
+                                'SIGNIFICANCE',
+                                'CELL_SIGNIFICANCE',
+                                'CELL_SIG_SAMPLING',
+                                'AVG_LAR_Q',
+                                'AVG_TILE_Q'
+                                ]
+    from TrigEDMConfig.TriggerEDMRun3 import recordable
+    alg = CompFactory.TrigCaloClusterMakerMT('TrigCaloClusterMaker_topo'+('FS' if FS else 'RoI'),
+                                             Cells = 'CaloCells',
+                                             CaloClusters=recordable('HLT_TopoCaloClustersRoI'),
+                                             ClusterMakerTools = [ topoMaker, topoSplitter, topoMoments] # moments are missing yet
+                                            )
+    acc.addEventAlgo(alg)
+    return acc
+
+
+def hltCaloTopoClusteringCfg(flags, FS=False, roisKey='UNSPECIFIED'):
+    acc = ComponentAccumulator()
+    acc.merge(hltCaloCellMakerCfg(flags, FS=FS, roisKey=roisKey))
+    acc.merge(hltTopoClusterMakerCfg(flags, FS=FS))
+    return acc
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigEgammaPrecisionCaloHypoTool.py b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigEgammaPrecisionCaloHypoTool.py
index 2d4e405e1a51ca0d614cc6d8c3ae4300c260ca76..a2d0687ba5f77c6d8d3a93c8ced30250586b0312 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigEgammaPrecisionCaloHypoTool.py
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigEgammaPrecisionCaloHypoTool.py
@@ -4,9 +4,8 @@ from AthenaCommon.SystemOfUnits import GeV
 
 def _IncTool(name, threshold, sel):
 
-    from TrigEgammaHypo.TrigEgammaHypoConf import TrigEgammaPrecisionCaloHypoToolInc    
-
-    tool = TrigEgammaPrecisionCaloHypoToolInc( name ) 
+    from AthenaConfiguration.ComponentFactory import CompFactory
+    tool = CompFactory.TrigEgammaPrecisionCaloHypoToolInc(name)
 
     from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool, defineHistogram
     monTool = GenericMonitoringTool("MonTool_"+name)
@@ -22,7 +21,7 @@ def _IncTool(name, threshold, sel):
     monTool.Histograms += [ defineHistogram('CutCounter', type='TH1I', path='EXPERT', title="PrecisionCalo Hypo Passed Cuts;Cut",
                                             xbins=13, xmin=-1.5, xmax=12.5,  opt="kCumulative", xlabels=cuts) ]
 
-    monTool.HistPath = 'PrecisionCaloHypo/'+tool.name()
+    monTool.HistPath = 'PrecisionCaloHypo/'+tool.getName()
     tool.MonTool = monTool
 
 
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
index f824ab4af1ed5377953ddf9f0c5e55eb12c968e2..b524cd9622b49b5fa48baa5602963cb029ac25c1 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
@@ -106,6 +106,8 @@ acc.foreach_component("*/L1Decoder/*Tool").OutputLevel = DEBUG # tools
 acc.foreach_component("*HLTTop/*Hypo*").OutputLevel = DEBUG # hypo algs
 acc.foreach_component("*HLTTop/*Hypo*/*Tool*").OutputLevel = INFO # hypo tools
 acc.foreach_component("*HLTTop/RoRSeqFilter/*").OutputLevel = INFO# filters
+acc.foreach_component("*/FPrecisionCalo").OutputLevel = DEBUG# filters
+acc.foreach_component("*/CHElectronFTF").OutputLevel = DEBUG# filters
 acc.foreach_component("*HLTTop/*Input*").OutputLevel = DEBUG # input makers
 acc.foreach_component("*HLTTop/*HLTEDMCreator*").OutputLevel = WARNING # messaging from the EDM creators
 acc.foreach_component("*HLTTop/*GenericMonitoringTool*").OutputLevel = WARNING # silcence mon tools (addressing by type)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/ElectronRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/ElectronRecoSequences.py
index fe7decdc9385acfa6c4b76c83fcb5716812c75ca..0d8f6ad75f625453ebcb2112aea651becb8f1257 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/ElectronRecoSequences.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/ElectronRecoSequences.py
@@ -1,5 +1,5 @@
 #
-#  Copyright (C) 2002-2010 CERN for the benefit of the ATLAS collaboration
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 #
 
 from AthenaConfiguration.ComponentFactory import CompFactory
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
index a509b32e047afeb161eba7f4a199734c84f21e23..031a5b0a752d3ea0106e0f86787ae4bbff66575b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
@@ -2,101 +2,129 @@
 
 from TriggerMenuMT.HLTMenuConfig.Electron.ElectronRecoSequences import l2CaloRecoCfg, l2CaloHypoCfg
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import CAMenuSequence, \
-    ChainStep, Chain, createStepView, EmptyMenuSequence, InViewReco
+    ChainStep, Chain, EmptyMenuSequence, InViewReco, SelectionCA
 
 from TrigEgammaHypo.TrigEgammaFastCaloHypoTool import TrigEgammaFastCaloHypoToolFromDict
-from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from TrigEDMConfig.TriggerEDMRun3 import recordable
 from AthenaConfiguration.ComponentFactory import CompFactory
 from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import getChainMultFromDict
 
 
 
-def generateChains( flags,  chainDict ):
-    import pprint
-    pprint.pprint( chainDict )
+def generateChains(flags, chainDict):
 
-    firstStepName = 'FastCaloElectron'
-    stepReco, stepView = createStepView(firstStepName)
+    def __fastCalo():
+        selAcc=SelectionCA('FastCaloElectron')
+        selAcc.mergeReco(l2CaloRecoCfg(flags))
 
-    accCalo = ComponentAccumulator()
-    accCalo.addSequence(stepView)
+        # this alg needs EventInfo decorated with the  pileup info
+        from LumiBlockComps.LumiBlockMuWriterConfig import LumiBlockMuWriterCfg
+        selAcc.merge(LumiBlockMuWriterCfg(flags))
 
-    l2CaloReco = l2CaloRecoCfg(flags)
-    accCalo.merge(l2CaloReco, sequenceName=stepReco.getName())
+        l2CaloHypo = l2CaloHypoCfg(flags,
+                                   name='L2ElectronCaloHypo',
+                                   CaloClusters=recordable('HLT_FastCaloEMClusters'))
 
-    # this alg needs EventInfo decorated with the  pileup info
-    from LumiBlockComps.LumiBlockMuWriterConfig import LumiBlockMuWriterCfg
-    accCalo.merge( LumiBlockMuWriterCfg(flags) )
+        selAcc.addHypoAlgo(l2CaloHypo)
 
-    l2CaloHypo =  l2CaloHypoCfg( flags, name = 'L2ElectronCaloHypo',
-                                 CaloClusters = recordable('HLT_FastCaloEMClusters'))
+        fastCaloSequence = CAMenuSequence(selAcc,
+                                          HypoToolGen=TrigEgammaFastCaloHypoToolFromDict)
 
-    accCalo.addEventAlgo(l2CaloHypo, sequenceName=stepView.getName())
+        # this cannot work for asymmetric combined chains....FP
+        return ChainStep(name=selAcc.name, Sequences=[fastCaloSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
 
-    fastCaloSequence = CAMenuSequence(accCalo,
-                                     HypoToolGen = TrigEgammaFastCaloHypoToolFromDict)
+    def __ftf():
+        selAcc=SelectionCA('ElectronFTF')
 
-    accCalo.printConfig()
-    # this cannot work for asymmetric combined chains....FP
-    fastCaloStep = ChainStep(name=firstStepName, Sequences=[fastCaloSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
-    
+        # # # fast ID (need to be customised because require secialised configuration of the views maker - i.e. parent has to be linked)
+        name = "IMFastElectron"
+        evtViewMaker = CompFactory.EventViewCreatorAlgorithm(name,
+                                                              ViewFallThrough = True,
+                                                              RoIsLink        = 'initialRoI',
+                                                              RoITool         = CompFactory.ViewCreatorInitialROITool(),
+                                                              InViewRoIs      = name+'RoIs',
+                                                              Views           = name+'Views',
+                                                              ViewNodeName    = name+"InView",
+                                                              RequireParentView = True)
+        del name
 
+        from TrigInDetConfig.TrigInDetConfig import trigInDetFastTrackingCfg
+        idTracking = trigInDetFastTrackingCfg(flags, roisKey=evtViewMaker.InViewRoIs, signatureName="Electron")
 
-    secondStepName = 'ElectronFTF'
-    stepReco, stepView = createStepView(secondStepName)
+        fastInDetReco = InViewReco('FastElectron', viewMaker=evtViewMaker)
+        fastInDetReco.mergeReco(idTracking)
+        fastInDetReco.addRecoAlgo(CompFactory.AthViews.ViewDataVerifier(name='VDVElectronFastCalo',
+                                  DataObjects=[('xAOD::TrigEMClusterContainer', 'StoreGateSvc+HLT_FastCaloEMClusters')]) )
 
-    accTrk = ComponentAccumulator()
-    accTrk.addSequence(stepView)
+        from TrigEgammaHypo.TrigEgammaFastElectronFexMTConfig import fastElectronFexAlgCfg
+        fastInDetReco.mergeReco(fastElectronFexAlgCfg(flags, rois=evtViewMaker.InViewRoIs))
+        selAcc.mergeReco(fastInDetReco)
 
-    # # # fast ID (need to be customised because require secialised configuration of the views maker - i.e. parent has to be linked)
-    name = "IMFastElectron"
-    evtViewMaker = CompFactory.EventViewCreatorAlgorithm(name,
-                                                          ViewFallThrough = True,
-                                                          RoIsLink        = 'initialRoI',
-                                                          RoITool         = CompFactory.ViewCreatorInitialROITool(),
-                                                          InViewRoIs      = name+'RoIs',
-                                                          Views           = name+'Views',
-                                                          ViewNodeName    = name+"InView",
-                                                          RequireParentView = True)
-    del name
+        fastElectronHypoAlg = CompFactory.TrigEgammaFastElectronHypoAlgMT()
+        fastElectronHypoAlg.Electrons = 'HLT_FastElectrons'
+        fastElectronHypoAlg.RunInView = True
+        selAcc.addHypoAlgo(fastElectronHypoAlg)
 
-    from TrigInDetConfig.TrigInDetConfig import trigInDetFastTrackingCfg
-    idTracking = trigInDetFastTrackingCfg(flags, roisKey=evtViewMaker.InViewRoIs, signatureName="Electron")
+        from TrigEgammaHypo.TrigEgammaFastElectronHypoTool import TrigEgammaFastElectronHypoToolFromDict
+        fastInDetSequence = CAMenuSequence(selAcc,
+                                           HypoToolGen=TrigEgammaFastElectronHypoToolFromDict)
 
-    fastInDetReco = InViewReco("FastElectron", viewMaker=evtViewMaker)
-    fastInDetReco.mergeReco(idTracking)
-    fastInDetReco.addRecoAlgo(CompFactory.AthViews.ViewDataVerifier(name='VDVElectronFastCalo',
-                              DataObjects=[('xAOD::TrigEMClusterContainer', 'StoreGateSvc+HLT_FastCaloEMClusters')]))
-
-    from TrigEgammaHypo.TrigEgammaFastElectronFexMTConfig import fastElectronFexAlgCfg
-    fastInDetReco.mergeReco(fastElectronFexAlgCfg(flags, rois=evtViewMaker.InViewRoIs))
-
-    accTrk.merge(fastInDetReco, sequenceName=stepReco.getName())
-
-
-    fastElectronHypoAlg = CompFactory.TrigEgammaFastElectronHypoAlgMT()
-    fastElectronHypoAlg.Electrons = "HLT_FastElectrons"
-    fastElectronHypoAlg.RunInView = True
-    accTrk.addEventAlgo(fastElectronHypoAlg, sequenceName=stepView.getName())
-
-    from TrigEgammaHypo.TrigEgammaFastElectronHypoTool import TrigEgammaFastElectronHypoToolFromDict
-    fastInDetSequence = CAMenuSequence(accTrk, 
-                                       HypoToolGen = TrigEgammaFastElectronHypoToolFromDict)
-
-    fastInDetStep = ChainStep( name=secondStepName, Sequences=[fastInDetSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
+        return ChainStep( name=selAcc.name, Sequences=[fastInDetSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
 
     l1Thresholds=[]
     for part in chainDict['chainParts']:
         l1Thresholds.append(part['L1threshold'])
-    
-    # # # EF calo
+
+    # # # Precision calo
+    def __precisonCalo():
+        recoAcc = InViewReco('ElectronRoITopoClusterReco')
+        recoAcc.addRecoAlgo(CompFactory.AthViews.ViewDataVerifier(name='VDV'+recoAcc.name,
+                                                                  DataObjects=[('TrigRoiDescriptorCollection', recoAcc.inputMaker().InViewRoIs),
+                                                                               ('CaloBCIDAverage', 'StoreGateSvc+CaloBCIDAverage')]))
+
+        from TrigCaloRec.TrigCaloRecConfig import hltCaloTopoClusteringCfg
+        recoAcc.mergeReco(hltCaloTopoClusteringCfg(flags,
+                                                   FS=False,
+                                                   roisKey=recoAcc.inputMaker().InViewRoIs)) # RoI
+
+        copier = CompFactory.egammaTopoClusterCopier('TrigEgammaTopoClusterCopierPrecisionCaloRoIs',
+                                                     InputTopoCollection='HLT_TopoCaloClustersRoI',
+                                                     OutputTopoCollection='HLT_CaloEMClusters',
+                                                     OutputTopoCollectionShallow='tmp_HLT_CaloEMClusters')
+        recoAcc.addRecoAlgo(copier)
+
+        selAcc = SelectionCA('PrecisionCalo')
+        selAcc.mergeReco(recoAcc)
+        hypoAlg = CompFactory.TrigEgammaPrecisionCaloHypoAlgMT(name='ElectronPrecisionCaloHypo',
+                                                               CaloClusters=recordable('HLT_CaloEMClusters'))
+        selAcc.addHypoAlgo(hypoAlg)
+        from TrigEgammaHypo.TrigEgammaPrecisionCaloHypoTool import TrigEgammaPrecisionCaloHypoToolFromDict
+        menuSequence = CAMenuSequence(selAcc,
+                                      HypoToolGen=TrigEgammaPrecisionCaloHypoToolFromDict)
+        return ChainStep(name=selAcc.name, Sequences=[menuSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
 
     # # # Precison tracking
-    
+
 
     # # # offline egamma
     emptyStep = ChainStep(name="EmptyElStep", Sequences=[EmptyMenuSequence("EmptyElStep")], chainDicts=[chainDict])
-    chain = Chain(chainDict['chainName'], L1Thresholds=l1Thresholds, ChainSteps=[fastCaloStep, fastInDetStep, emptyStep, emptyStep])
-    
+    chain = Chain(chainDict['chainName'], L1Thresholds=l1Thresholds,
+                            ChainSteps=[__fastCalo(), __ftf(), __precisonCalo(), emptyStep, emptyStep,])
+
     return chain
+
+if __name__ == "__main__":
+    # run with: python -m TriggerMenuMT.HLTMenuConfig.Electron.generateElectron
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior=1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.lock()
+    from ..Menu.DictFromChainName import dictFromChainName
+    chain = generateChains(ConfigFlags, dictFromChainName('HLT_e26_L1EM15'))
+    for step in chain.steps:
+        for s in step.sequences:
+            if not isinstance(s, EmptyMenuSequence):
+                s.ca.printConfig(withDetails=True, summariseProps=False) # flip the last arg to see all settings
+                s.ca.wasMerged() # to silence check for orphanted CAs
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
index 394f04c9a13fd178dc364a8f6d7cfe2f783693e7..023c5dcc0011f223216a66b2f2da763cb4965a92 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
@@ -927,6 +927,21 @@ class InViewReco(ComponentAccumulator):
     def inputMaker( self ):
         return self.viewMakerAlg
 
+class SelectionCA(ComponentAccumulator):
+    def __init__(self, name):
+        self.name = name
+        super( SelectionCA, self ).__init__()
+        self.stepRecoSequence, self.stepViewSequence = createStepView(name)
+        self.addSequence(self.stepViewSequence)
+
+    def mergeReco(self, other):
+        self.merge(other, sequenceName=self.stepRecoSequence.name)
+
+    def mergeHypo(self, other):
+        self.merge(other, sequenceName=self.stepViewSequence.name)
+
+    def addHypoAlgo(self, algo):
+        self.addEventAlgo(algo, sequenceName=self.stepViewSequence.name)
 
 class RecoFragmentsPool(object):
     """ Class to host all the reco fragments that need to be reused """
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/generateMuon.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/generateMuon.py
index ab0236cf8252ff24fbcc90b4da4282c058b16e37..cce859909024bc5102ff9787458ebe59bbb5ebe6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/generateMuon.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/generateMuon.py
@@ -400,11 +400,11 @@ def generateChains( flags, chainDict ):
         l1Thresholds.append(part['L1threshold'])
 
     log.debug('dictionary is: %s\n', pprint.pformat(chainDict))
-
+    def _empty(name):
+        return ChainStep(name="EmptyNoL2MuComb", Sequences=[EmptyMenuSequence("EmptyNoL2MuComb")], chainDicts=[chainDict])
     if 'msonly' in chainDict['chainName']:
-        emptyStep = ChainStep(name="EmptyNoL2MuComb", Sequences=[EmptyMenuSequence("EmptyNoL2MuComb")], chainDicts=[chainDict])
-        chain = Chain( name=chainDict['chainName'], L1Thresholds=l1Thresholds, ChainSteps=[ l2muFastStep, emptyStep, efmuMSStep, emptyStep ] )
+        chain = Chain( name=chainDict['chainName'], L1Thresholds=l1Thresholds, ChainSteps=[ l2muFastStep, _empty("EmptyNoL2MuComb"), efmuMSStep, _empty("EmptyNoEFCB"), _empty("JustEmpty") ] )
     else:
-        chain = Chain( name=chainDict['chainName'], L1Thresholds=l1Thresholds, ChainSteps=[ l2muFastStep, l2muCombStep, efmuMSStep, efmuCBStep ] )
+        chain = Chain( name=chainDict['chainName'], L1Thresholds=l1Thresholds, ChainSteps=[ l2muFastStep, l2muCombStep, efmuMSStep, efmuCBStep, _empty("JustEmpty") ] )
     return chain