diff --git a/Tracking/Acts/ActsConfig/python/ActsSpacePointFormationConfig.py b/Tracking/Acts/ActsConfig/python/ActsSpacePointFormationConfig.py
index 7faa0b608710bfb31fcc9d1fc87ca5139ff54b7b..7be50fb45ac3e5768ce3ea7b826e88a32b38aa9d 100644
--- a/Tracking/Acts/ActsConfig/python/ActsSpacePointFormationConfig.py
+++ b/Tracking/Acts/ActsConfig/python/ActsSpacePointFormationConfig.py
@@ -2,28 +2,28 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
+from ActsConfig.ActsUtilities import extractChildKwargs
 
-def ActsSpacePointCacheCreatorCfg(flags, name: str = "ActsSPCacheCreator", **kwargs):
-    kwargs.setdefault("PixelSPCacheKey", "ActsPixelSPCache_Back")
-    kwargs.setdefault("StripSPCacheKey", "ActsStripSPCache_Back")
-    kwargs.setdefault("StripOSPCacheKey", "ActsStripOSPCache_Back")
-
+def ActsSpacePointCacheCreatorAlgCfg(flags,
+                                     name: str = "ActsSpacePointCacheCreatorAlg",
+                                     **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
-
+    kwargs.setdefault("PixelSpacePointCacheKey", "ActsPixelSpacePointCache_Back")
+    kwargs.setdefault("StripSpacePointCacheKey", "ActsStripSpacePointCache_Back")
+    kwargs.setdefault("StripOverlapSpacePointCacheKey", "ActsStripOverlapSpacePointCache_Back")
     acc.addEventAlgo(CompFactory.ActsTrk.Cache.CreatorAlg(name, **kwargs))
-
     return acc
 
 def ActsPixelSpacePointToolCfg(flags,
                                name: str = "ActsPixelSpacePointTool",
-                               **kwargs) -> ComponentAccumulator:
+                               **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
     acc.setPrivateTools(CompFactory.ActsTrk.PixelSpacePointFormationTool(name, **kwargs))
     return acc
 
 def ActsStripSpacePointToolCfg(flags,
                                name: str = "ActsStripSpacePointTool",
-                               **kwargs) -> ComponentAccumulator:
+                               **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
     if 'LorentzAngleTool' not in kwargs:
@@ -35,7 +35,7 @@ def ActsStripSpacePointToolCfg(flags,
 
 def ActsCoreStripSpacePointToolCfg(flags,
                                    name: str = "ActsCoreStripSpacePointTool",
-                                   **kwargs) -> ComponentAccumulator:
+                                   **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
     if 'LorentzAngleTool' not in kwargs:
@@ -55,9 +55,12 @@ def ActsCoreStripSpacePointToolCfg(flags,
 
 def ActsPixelSpacePointPreparationAlgCfg(flags,
                                          name: str = "ActsPixelSpacePointPreparationAlg",
-                                         **kwargs) -> ComponentAccumulator:
+                                         *,
+                                         useCache: bool = False,
+                                         **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
+    kwargs.setdefault('InputCollection', 'ITkPixelSpacePoints')
     kwargs.setdefault('DetectorElements', 'ITkPixelDetectorElementCollection')
 
     if 'RegSelTool' not in kwargs:
@@ -69,14 +72,20 @@ def ActsPixelSpacePointPreparationAlgCfg(flags,
         kwargs.setdefault('MonTool', acc.popToolsAndMerge(ActsDataPreparationMonitoringToolCfg(flags,
                                                                                                name = "ActsPixelSpacePointPreparationMonitoringTool")))
 
-    acc.addEventAlgo(CompFactory.ActsTrk.SpacePointDataPreparationAlg(name, **kwargs))
+    if not useCache:
+        acc.addEventAlgo(CompFactory.ActsTrk.SpacePointDataPreparationAlg(name, **kwargs))
+    else:
+        acc.addEventAlgo(CompFactory.ActsTrk.SpacePointCacheDataPreparationAlg(name, **kwargs))
     return acc
 
 def ActsStripSpacePointPreparationAlgCfg(flags,
                                          name: str = "ActsStripSpacePointPreparationAlg",
-                                         **kwargs) -> ComponentAccumulator:
+                                         *,
+                                         useCache: bool = False,
+                                         **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
+    kwargs.setdefault('InputCollection', 'ITkStripSpacePoints')
     kwargs.setdefault('DetectorElements', 'ITkStripDetectorElementCollection')
 
     if 'RegSelTool' not in kwargs:
@@ -88,19 +97,36 @@ def ActsStripSpacePointPreparationAlgCfg(flags,
         kwargs.setdefault('MonTool', acc.popToolsAndMerge(ActsDataPreparationMonitoringToolCfg(flags,
                                                                                                name = "ActsStripSpacePointPreparationMonitoringTool")))
 
-    acc.addEventAlgo(CompFactory.ActsTrk.SpacePointDataPreparationAlg(name, **kwargs))
+    if not useCache:
+        acc.addEventAlgo(CompFactory.ActsTrk.SpacePointDataPreparationAlg(name, **kwargs))
+    else:
+        acc.addEventAlgo(CompFactory.ActsTrk.SpacePointCacheDataPreparationAlg(name, **kwargs))
     return acc
 
+def ActsStripOverlapSpacePointPreparationAlgCfg(flags,
+                                                name: str = 'ActsStripOverlapSpacePointPreparationAlg',
+                                                *,
+                                                useCache: bool = False,
+                                                **kwargs: dict) -> ComponentAccumulator:
+     kwargs.setdefault('InputCollection', 'ITkStripOverlapSpacePoints')
+     return ActsStripSpacePointPreparationAlgCfg(flags, name=name, useCache=useCache, **kwargs)
+
 def ActsPixelSpacePointFormationAlgCfg(flags,
                                        name: str = "ActsPixelSpacePointFormationAlg",
-                                       **kwargs) -> ComponentAccumulator:
+                                       *,
+                                       useCache: bool = False,
+                                       **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
     
     from PixelGeoModelXml.ITkPixelGeoModelConfig import ITkPixelReadoutGeometryCfg
     acc.merge(ITkPixelReadoutGeometryCfg(flags))
 
     kwargs.setdefault('PixelClusters', 'ITkPixelClusters')
-    kwargs.setdefault('PixelSpacePoints', 'ITkPixelSpacePoints')
+    kwargs.setdefault('PixelSpacePoints', 'ITkPixelSpacePoints') 
+
+    if useCache:
+        kwargs.setdefault('SPCacheBackend', 'ActsPixelSpacePointCache_Back')
+        kwargs.setdefault('SPCache', 'ActsPixelSpacePointCache')
     
     if 'SpacePointFormationTool' not in kwargs:
         kwargs.setdefault("SpacePointFormationTool", acc.popToolsAndMerge(ActsPixelSpacePointToolCfg(flags)))
@@ -110,9 +136,7 @@ def ActsPixelSpacePointFormationAlgCfg(flags,
         kwargs.setdefault("MonTool", acc.popToolsAndMerge(ActsPixelSpacePointFormationMonitoringToolCfg(flags)))
 
 
-    if flags.Acts.useCache:
-        kwargs.setdefault('SPCacheBackend', 'ActsPixelSPCache_Back')
-        kwargs.setdefault('SPCache', 'ActsPixelSPCache')
+    if useCache:
         acc.addEventAlgo(CompFactory.ActsTrk.PixelCacheSpacePointFormationAlg(name, **kwargs))
     else:
         acc.addEventAlgo(CompFactory.ActsTrk.PixelSpacePointFormationAlg(name, **kwargs))
@@ -121,16 +145,31 @@ def ActsPixelSpacePointFormationAlgCfg(flags,
 
 def ActsStripSpacePointFormationAlgCfg(flags,
                                        name: str = "ActsStripSpacePointFormationAlg",
-                                       **kwargs) -> ComponentAccumulator:
+                                       *,
+                                       useCache: bool = False,
+                                       **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
     
     from StripGeoModelXml.ITkStripGeoModelConfig import ITkStripReadoutGeometryCfg
     acc.merge(ITkStripReadoutGeometryCfg(flags))
 
+    from BeamSpotConditions.BeamSpotConditionsConfig import BeamSpotCondAlgCfg
+    acc.merge(BeamSpotCondAlgCfg(flags))
+    
+    from InDetConfig.SiSpacePointFormationConfig import ITkSiElementPropertiesTableCondAlgCfg
+    acc.merge(ITkSiElementPropertiesTableCondAlgCfg(flags))
+    
+        
     kwargs.setdefault('StripClusters', 'ITkStripClusters')
     kwargs.setdefault('StripSpacePoints', 'ITkStripSpacePoints')
     kwargs.setdefault('StripOverlapSpacePoints', 'ITkStripOverlapSpacePoints')
-    
+
+    if useCache:
+        kwargs.setdefault('SPCacheBackend', 'ActsStripSpacePointCache_Back')
+        kwargs.setdefault('SPCache', 'ActsStripSpacePointCache')
+        kwargs.setdefault('OSPCacheBackend', 'ActsStripOverlapSpacePointCache_Back')
+        kwargs.setdefault('OSPCache', 'ActsStripOverlapSpacePointCache')
+
     if 'SpacePointFormationTool' not in kwargs:
         from ActsConfig.ActsConfigFlags import SpacePointStrategy
         if flags.Acts.SpacePointStrategy is SpacePointStrategy.ActsCore:
@@ -142,170 +181,224 @@ def ActsStripSpacePointFormationAlgCfg(flags,
         from ActsConfig.ActsMonitoringConfig import ActsStripSpacePointFormationMonitoringToolCfg
         kwargs.setdefault("MonTool", acc.popToolsAndMerge(ActsStripSpacePointFormationMonitoringToolCfg(flags)))
 
-
-
-    if flags.Acts.useCache:
-        kwargs.setdefault('SPCacheBackend', 'ActsStripSPCache_Back')
-        kwargs.setdefault('SPCache', 'ActsStripSPCache')
-        kwargs.setdefault('OSPCacheBackend', 'ActsStripOSPCache_Back')
-        kwargs.setdefault('OSPCache', 'ActsStripOSPCache')
+    if useCache:
         acc.addEventAlgo(CompFactory.ActsTrk.StripCacheSpacePointFormationAlg(name, **kwargs))
     else:
         acc.addEventAlgo(CompFactory.ActsTrk.StripSpacePointFormationAlg(name, **kwargs))
     return acc
 
-def ActsPixelSpacePointCacheDataPreparationAlgCfg(flags,name: str="ActsPixelSpacePointCacheDataPreparationAlg", **kwargs):
-    kwargs.setdefault("InputIDC", "ActsPixelSPCache")
-    kwargs.setdefault("OutputCollection", "ITkPixelSpacePoints_Cached")
-
+def ActsMainSpacePointFormationCfg(flags,
+                                   *,
+                                   RoIs: str = "ActsRegionOfInterest",
+                                   **kwargs: dict) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
-    if 'RegSelTool' not in kwargs:
-        from RegionSelector.RegSelToolConfig import regSelTool_ITkStrip_Cfg
-        kwargs.setdefault('RegSelTool', acc.popToolsAndMerge(regSelTool_ITkStrip_Cfg(flags)))
-        
-    acc.addEventAlgo(CompFactory.ActsTrk.SpacePointCacheDataPreparationAlg(name, **kwargs))
-
-    return acc
-
-def ActsStripSpacePointCacheDataPreparationAlgCfg(flags,name: str="ActsStripSpacePointCacheDataPreparationAlg", **kwargs):
-    kwargs.setdefault("InputIDC", "ActsStripSPCache")
-    kwargs.setdefault("OutputCollection", "ITkStripSpacePoints_Cached")
-
-    acc = ComponentAccumulator()
-
-    if 'RegSelTool' not in kwargs:
-        from RegionSelector.RegSelToolConfig import regSelTool_ITkStrip_Cfg
-        kwargs.setdefault('RegSelTool', acc.popToolsAndMerge(regSelTool_ITkStrip_Cfg(flags)))
-        
-    acc.addEventAlgo(CompFactory.ActsTrk.SpacePointCacheDataPreparationAlg(name, **kwargs))
-
-    return acc
-
-def ActsStripOverlapSpacePointCacheDataPreparationAlgCfg(flags,name: str="ActsStripOverlapSpacePointCacheDataPreparationAlg", **kwargs):
-    kwargs.setdefault("InputIDC", "ActsStripOSPCache")
-    kwargs.setdefault("OutputCollection", "ITkStripOverlapSpacePoints_Cached")
-
-    acc = ComponentAccumulator()
-
-    if 'RegSelTool' not in kwargs:
-        from RegionSelector.RegSelToolConfig import regSelTool_ITkStrip_Cfg
-        kwargs.setdefault('RegSelTool', acc.popToolsAndMerge(regSelTool_ITkStrip_Cfg(flags)))
-        
-    acc.addEventAlgo(CompFactory.ActsTrk.SpacePointCacheDataPreparationAlg(name, **kwargs))
-
-    return acc
-
-def ActsMainSpacePointFormationCfg(flags, RoIs: str = "ActsRegionOfInterest") -> ComponentAccumulator:
-    acc = ComponentAccumulator()
-
-    if flags.Acts.useCache:
-        acc.merge(ActsSpacePointCacheCreatorCfg(flags))
-
-    if flags.Detector.EnableITkPixel:
-        acc.merge(ActsPixelSpacePointFormationAlgCfg(flags,
-                                                     PixelClusters = "ITkPixelClusters_Cached" if flags.Acts.useCache else "ITkPixelClusters"))
-    if flags.Detector.EnableITkStrip and not flags.Tracking.doITkFastTracking:
-        # Need to schedule this here in case the Athena space point formation is not schedule
-        # This is because as of now requires at least ITkSiElementPropertiesTableCondAlgCfg
-        # This may be because the current strip space point formation algorithm is not using Acts
-        # May be not necessary once the Acts-based strip space point maker is ready
-        from StripGeoModelXml.ITkStripGeoModelConfig import ITkStripReadoutGeometryCfg
-        acc.merge(ITkStripReadoutGeometryCfg(flags))
-        
-        from BeamSpotConditions.BeamSpotConditionsConfig import BeamSpotCondAlgCfg
-        acc.merge(BeamSpotCondAlgCfg(flags))
-        
-        from InDetConfig.SiSpacePointFormationConfig import ITkSiElementPropertiesTableCondAlgCfg
-        acc.merge(ITkSiElementPropertiesTableCondAlgCfg(flags))
-        
-        acc.merge(ActsStripSpacePointFormationAlgCfg(flags,
-                                                     StripClusters = "ITkStripClusters_Cached" if flags.Acts.useCache else "ITkStripClusters"))
-
-    if flags.Acts.useCache:
-        if flags.Detector.EnableITkPixel:
-            acc.merge(ActsPixelSpacePointCacheDataPreparationAlgCfg(flags, RoIs=RoIs))
-        if flags.Detector.EnableITkStrip:
-            acc.merge(ActsStripSpacePointCacheDataPreparationAlgCfg(flags, RoIs=RoIs))
-            acc.merge(ActsStripOverlapSpacePointCacheDataPreparationAlgCfg(flags, RoIs=RoIs))
-
-            
-    # Analysis extensions
-    if flags.Acts.doAnalysis:
-        if flags.Detector.EnableITkPixel:
-            from ActsConfig.ActsAnalysisConfig import ActsPixelSpacePointAnalysisAlgCfg
-            acc.merge(ActsPixelSpacePointAnalysisAlgCfg(flags))
-        if flags.Detector.EnableITkStrip and not flags.Tracking.doITkFastTracking:
-            from ActsConfig.ActsAnalysisConfig import ActsStripSpacePointAnalysisAlgCfg, ActsStripOverlapSpacePointAnalysisAlgCfg
-            acc.merge(ActsStripSpacePointAnalysisAlgCfg(flags))
-            acc.merge(ActsStripOverlapSpacePointAnalysisAlgCfg(flags))
-
-    return acc
-
-def ActsConversionSpacePointFormationCfg(flags) -> ComponentAccumulator:
-    acc = ComponentAccumulator()
+    kwargs.setdefault('processPixels', flags.Detector.EnableITkPixel)
+    kwargs.setdefault('processStrips', flags.Detector.EnableITkStrip)
+    kwargs.setdefault('runCacheCreation', flags.Acts.useCache)
+    kwargs.setdefault('runReconstruction', True)
+    kwargs.setdefault('runPreparation', flags.Acts.useCache)  
+    kwargs.setdefault('processOverlapSpacePoints', True)
+    
+    if kwargs['runCacheCreation']:
+        acc.merge(ActsSpacePointCacheCreatorAlgCfg(flags, **extractChildKwargs(prefix='SpacePointCacheCreatorAlg.', **kwargs)))
 
-    if flags.Detector.EnableITkStrip:
-        # For the time being, while we wait for the cache mechanism to be available also for space points,
-        # we do the following:
-        #   - offline: we schedule the Preparation Algorithms and rely of the space point collections created in the main pass
-        #   - online (i.e. with cache): we run space point formation and pass the output directly to seeding
-
-        if not flags.Acts.useCache:
-            acc.merge(ActsStripSpacePointPreparationAlgCfg(flags,
-                                                           name = "ActsConversionStripSpacePointPreparationAlg",
-                                                           RoIs = "ActsConversionRegionOfInterest",
-                                                           InputCollection = "ITkStripSpacePoints",
-                                                           OutputCollection = "ITkConversionStripSpacePoints"))
-        else:            
-            # Need to schedule this here in case the Athena space point formation is not schedule
-            # This is because as of now requires at least ITkSiElementPropertiesTableCondAlgCfg
-            # This may be because the current strip space point formation algorithm is not using Acts
-            # May be not necessary once the Acts-based strip space point maker is ready            
-            from StripGeoModelXml.ITkStripGeoModelConfig import ITkStripReadoutGeometryCfg
-            acc.merge(ITkStripReadoutGeometryCfg(flags))
+    if kwargs['runReconstruction']:
+        if kwargs['processPixels']:
+            acc.merge(ActsPixelSpacePointFormationAlgCfg(flags,**extractChildKwargs(prefix='PixelSpacePointFormationAlg.', **kwargs)))
             
-            from BeamSpotConditions.BeamSpotConditionsConfig import BeamSpotCondAlgCfg
-            acc.merge(BeamSpotCondAlgCfg(flags))
-            
-            from InDetConfig.SiSpacePointFormationConfig import ITkSiElementPropertiesTableCondAlgCfg
-            acc.merge(ITkSiElementPropertiesTableCondAlgCfg(flags))
-            
-            acc.merge(ActsStripSpacePointFormationAlgCfg(flags,
-                                                         name="ActsConversionStripSpacePointFormation",
-                                                         StripClusters="ITkConversionStripClusters_Cached",
-                                                         StripSpacePoints="ITkConversionStripSpacePoints",
-                                                         SPCache = "ActsStripConvSPCache",
-                                                         OSPCache = "ActsStripConvOSPCache",
-                                                         ProcessOverlapForStrip=False))
-            
-            acc.merge(ActsStripSpacePointCacheDataPreparationAlgCfg(flags, "StripSPConvCacheDataPrepAlg",
-                                                                    InputIDC="ActsStripConvSPCache",
-                                                                    OutputCollection="ITkConversionStripSpacePoints_Cached",
-                                                                    RoIs = "ActsConversionRegionOfInterest"))
+        if kwargs['processStrips']:
+            acc.merge(ActsStripSpacePointFormationAlgCfg(flags, **extractChildKwargs(prefix='StripSpacePointFormationAlg.', **kwargs)))
+
+    if kwargs['runPreparation']:
+        if kwargs['processPixels']:
+            acc.merge(ActsPixelSpacePointPreparationAlgCfg(flags, RoIs=RoIs, **extractChildKwargs(prefix='PixelSpacePointPreparationAlg.', **kwargs)))
+        if kwargs['processStrips']:
+            acc.merge(ActsStripSpacePointPreparationAlgCfg(flags, RoIs=RoIs, **extractChildKwargs(prefix='StripSpacePointPreparationAlg.', **kwargs)))
+        if kwargs['processOverlapSpacePoints']:
+            acc.merge(ActsStripOverlapSpacePointPreparationAlgCfg(flags, RoIs=RoIs, **extractChildKwargs(prefix='StripOverlapSpacePointPreparationAlg.', **kwargs)))
             
     # Analysis extensions
     if flags.Acts.doAnalysis:
-        if flags.Detector.EnableITkStrip:
+        if kwargs['processPixels']:
+            from ActsConfig.ActsAnalysisConfig import ActsPixelSpacePointAnalysisAlgCfg
+            acc.merge(ActsPixelSpacePointAnalysisAlgCfg(flags, **extractChildKwargs(prefix='PixelSpacePointAnalysisAlg.', **kwargs)))
+        if kwargs['processStrips']:
             from ActsConfig.ActsAnalysisConfig import ActsStripSpacePointAnalysisAlgCfg
-            acc.merge(ActsStripSpacePointAnalysisAlgCfg(flags,
-                                                        name="ActsConversionStripSpacePointAnalysisAlg",
-                                                        extension="ActsConversion",
-                                                        SpacePointContainerKey="ITkConversionStripSpacePoints"))
-        
+            acc.merge(ActsStripSpacePointAnalysisAlgCfg(flags, **extractChildKwargs(prefix='StripSpacePointAnalysisAlg.', **kwargs)))
+        if kwargs['processOverlapSpacePoints']:
+            from ActsConfig.ActsAnalysisConfig import ActsStripOverlapSpacePointAnalysisAlgCfg
+            acc.merge(ActsStripOverlapSpacePointAnalysisAlgCfg(flags, **extractChildKwargs(prefix='StripOverlapSpacePointAnalysisAlg.', **kwargs)))
+
     return acc
 
 def ActsSpacePointFormationCfg(flags) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
-    # Acts Main pass
-    if flags.Tracking.ActiveConfig.extension == "Acts":
-        acc.merge(ActsMainSpacePointFormationCfg(flags))
-    # Acts Conversion pass
-    elif flags.Tracking.ActiveConfig.extension == "ActsConversion":
-        acc.merge(ActsConversionSpacePointFormationCfg(flags))
-    # Any other pass -> Validation mainly
+    processPixels = flags.Detector.EnableITkPixel
+    processStrips = flags.Detector.EnableITkStrip
+
+    # For conversion pass we do not process pixels since we assume
+    # they have been processed on the primary pass.
+    if flags.Tracking.ActiveConfig.extension == "ActsConversion":
+        processPixels = False
+    elif flags.Tracking.doITkFastTracking:
+        # Fast tracking configuration: disable strip
+        processStrips = False
+        
+    kwargs = dict()
+    kwargs.setdefault('processPixels', processPixels)
+    kwargs.setdefault('processStrips', processStrips)
+
+    # Similarly to Clusterization, space point formation is a three step process at maximum:
+    #   (1) Cache Creation
+    #   (2) Space Point formation algorithm (reconstruction of space points)
+    #   (3) Preparation of collection for downstream algorithms
+    # What step is scheduled depends on the tracking pass and the activation
+    # or de-activation of caching mechanism.
+    
+    # Secondary passes do not need cache creation, that has to be performed
+    # on the primary pass, and only if the caching is enabled.
+    # Reconstruction can run on secondary passes only if the caching is enabled,
+    # this is because we may need to process detector elements not processed
+    # on the primary pass.
+    # Preparation has to be performed on secondary passes always, and on primary
+    # pass only if cache is enabled. In the latter case it is used to collect all
+    # the clusters from all views before passing them to the downstream algorithms
+
+    if flags.Tracking.ActiveConfig.extension in ['ActsConversion']:
+        # Secondary passes
+        kwargs.setdefault('runCacheCreation', False)
+        kwargs.setdefault('runReconstruction', flags.Acts.useCache)
+        kwargs.setdefault('runPreparation', True)
     else:
-        acc.merge(ActsMainSpacePointFormationCfg(flags, RoIs = f"{flags.Tracking.ActiveConfig.extension}RegionOfInterest"))
+        # Primary pass
+        kwargs.setdefault('runCacheCreation', flags.Acts.useCache)
+        kwargs.setdefault('runReconstruction', True)
+        kwargs.setdefault('runPreparation', flags.Acts.useCache)
+
+    # Overlap Space Points may not be required
+    processOverlapSpacePoints = processStrips
+    if flags.Tracking.ActiveConfig.extension in ['ActsConversion']:
+        processOverlapSpacePoints = False
+    kwargs.setdefault('processOverlapSpacePoints', processOverlapSpacePoints)
+        
+    # Name of the RoI to be used
+    roisName = f'{flags.Tracking.ActiveConfig.extension}RegionOfInterest'
+
+    # Cluster Collection name(s) and Space Point Collection name(s)
+    # The name depends on the tracking pass as well as the cache mechanism
+    pixelClustersName = 'ITkPixelClusters'
+    stripClustersName = 'ITkStripClusters'
+    pixelSpacePointsName = 'ITkPixelSpacePoints'
+    stripSpacePointsName = 'ITkStripSpacePoints'
+    stripOverlapSpacePointsName = 'ITkStripOverlapSpacePoints'
+    # Secondary passes modify the collection name
+    if flags.Tracking.ActiveConfig.extension in ['ActsConversion']:
+        pixelClustersName = f'ITk{flags.Tracking.ActiveConfig.extension.replace("Acts", "")}PixelClusters'
+        stripClustersName = f'ITk{flags.Tracking.ActiveConfig.extension.replace("Acts", "")}StripClusters'
+        pixelSpacePointsName = f'ITk{flags.Tracking.ActiveConfig.extension.replace("Acts", "")}PixelSpacePoints'
+        stripSpacePointsName =  f'ITk{flags.Tracking.ActiveConfig.extension.replace("Acts", "")}StripSpacePoints'
+        stripOverlapSpacePointsName = f'ITk{flags.Tracking.ActiveConfig.extension.replace("Acts", "")}StripOverlapSpacePoints'
+    # if cache is enabled, add "_Cached" at the end
+    if flags.Acts.useCache:
+        pixelClustersName += "_Cached"
+        stripClustersName += "_Cached"
 
+    # Primary collections for space points (i.e. produced by primary pass)
+    primaryPixelSpacePointsName = 'ITkPixelSpacePoints'
+    primaryStripSpacePointsName = 'ITkStripSpacePoints'
+    primaryStripOverlapSpacePointsName = 'ITkStripOverlapSpacePoints'
+        
+    # Configuration for (1)
+    if kwargs['runCacheCreation']:
+        kwargs.setdefault('SpacePointCacheCreatorAlg.name', f'{flags.Tracking.ActiveConfig.extension}SpacePointCacheCreatorAlg')
+
+    # Configuration for (2)
+    if kwargs['runReconstruction']:
+        if kwargs['processPixels']:
+            kwargs.setdefault('PixelSpacePointFormationAlg.name', f'{flags.Tracking.ActiveConfig.extension}PixelSpacePointFormationAlg')
+            kwargs.setdefault('PixelSpacePointFormationAlg.useCache', flags.Acts.useCache)
+            kwargs.setdefault('PixelSpacePointFormationAlg.SPCache',  f'{flags.Tracking.ActiveConfig.extension}PixelSpacePointCache')
+            kwargs.setdefault('PixelSpacePointFormationAlg.PixelClusters', pixelClustersName)
+            kwargs.setdefault('PixelSpacePointFormationAlg.PixelSpacePoints', pixelSpacePointsName)
+
+        if kwargs['processStrips']:
+            kwargs.setdefault('StripSpacePointFormationAlg.name', f'{flags.Tracking.ActiveConfig.extension}StripSpacePointFormationAlg')
+            kwargs.setdefault('StripSpacePointFormationAlg.useCache', flags.Acts.useCache)
+            kwargs.setdefault('StripSpacePointFormationAlg.SPCache', f'{flags.Tracking.ActiveConfig.extension}StripSpacePointCache')
+            kwargs.setdefault('StripSpacePointFormationAlg.StripClusters', stripClustersName)
+            kwargs.setdefault('StripSpacePointFormationAlg.StripSpacePoints', stripSpacePointsName)
+
+            # Handling of Overlap Space Points
+            kwargs.setdefault('StripSpacePointFormationAlg.ProcessOverlapForStrip', kwargs['processOverlapSpacePoints'])
+            kwargs.setdefault('StripSpacePointFormationAlg.OSPCache', f'{flags.Tracking.ActiveConfig.extension}StripOverlapSpacePointCache')
+            if kwargs['processOverlapSpacePoints']:
+                kwargs.setdefault('StripSpacePointFormationAlg.StripOverlapSpacePoints', stripOverlapSpacePointsName)
+            else:
+                # Disable keys
+                kwargs.setdefault('StripSpacePointFormationAlg.StripOverlapSpacePoints', '')
+
+    # Configuration for (3)
+    if kwargs['runPreparation']:
+        if kwargs['processPixels']:
+            kwargs.setdefault('PixelSpacePointPreparationAlg.name', f'{flags.Tracking.ActiveConfig.extension}PixelSpacePointPreparationAlg')
+            kwargs.setdefault('PixelSpacePointPreparationAlg.useCache', flags.Acts.useCache)
+            kwargs.setdefault('PixelSpacePointPreparationAlg.OutputCollection', f'{pixelSpacePointsName}_Cached' if kwargs['runReconstruction'] else pixelSpacePointsName)
+            # The input is one between the collection (w/o cache) and the IDC (w/ cache)
+            if not flags.Acts.useCache:
+                # Take the collection from the reconstruction step. If not available take the collection from the primary pass
+                kwargs.setdefault('PixelSpacePointPreparationAlg.InputCollection', pixelSpacePointsName if kwargs['runReconstruction'] else primaryPixelSpacePointsName)
+                kwargs.setdefault('PixelSpacePointPreparationAlg.InputIDC', '')
+            else:
+                kwargs.setdefault('PixelSpacePointPreparationAlg.InputCollection', '')
+                kwargs.setdefault('PixelSpacePointPreparationAlg.InputIDC', f'{flags.Tracking.ActiveConfig.extension}PixelSpacePointCache')
+
+        if kwargs['processStrips']:
+            kwargs.setdefault('StripSpacePointPreparationAlg.name', f'{flags.Tracking.ActiveConfig.extension}StripSpacePointPreparationAlg')
+            kwargs.setdefault('StripSpacePointPreparationAlg.useCache', flags.Acts.useCache)
+            kwargs.setdefault('StripSpacePointPreparationAlg.OutputCollection', f'{stripSpacePointsName}_Cached' if kwargs['runReconstruction'] else stripSpacePointsName)
+            # The input is one between the collection (w/o cache) and the IDC (w/ cache)
+            if not flags.Acts.useCache:
+                # Take the collection from the reconstruction step. If not available take the collection from the primary pass
+                kwargs.setdefault('StripSpacePointPreparationAlg.InputCollection', stripSpacePointsName if kwargs['runReconstruction'] else primaryStripSpacePointsName)
+                kwargs.setdefault('StripSpacePointPreparationAlg.InputIDC', '')
+            else:
+                kwargs.setdefault('StripSpacePointPreparationAlg.InputCollection', '')
+                kwargs.setdefault('StripSpacePointPreparationAlg.InputIDC', f'{flags.Tracking.ActiveConfig.extension}StripSpacePointCache')
+
+        if kwargs['processOverlapSpacePoints']:
+            kwargs.setdefault('StripOverlapSpacePointPreparationAlg.name', f'{flags.Tracking.ActiveConfig.extension}StripOverlapSpacePointPreparationAlg')
+            kwargs.setdefault('StripOverlapSpacePointPreparationAlg.useCache', flags.Acts.useCache)
+            kwargs.setdefault('StripOverlapSpacePointPreparationAlg.OutputCollection',  f'{stripOverlapSpacePointsName}_Cached' if kwargs['runReconstruction'] else stripOverlapSpacePointsName)
+            # The input is one between the collection (w/o cache) and the IDC (w/ cache)
+            if not flags.Acts.useCache:
+                # Take the collection from the reconstruction step. If not available take the collection from the primary pass
+                kwargs.setdefault('StripOverlapSpacePointPreparationAlg.InputCollection', stripOverlapSpacePointsName if kwargs['runReconstruction'] else primaryStripOverlapSpacePointsName)
+                kwargs.setdefault('StripOverlapSpacePointPreparationAlg.InputIDC', '')
+            else:
+                kwargs.setdefault('StripOverlapSpacePointPreparationAlg.InputCollection', '')
+                kwargs.setdefault('StripOverlapSpacePointPreparationAlg.InputIDC', f'{flags.Tracking.ActiveConfig.extension}StripOverlapSpacePointCache')
+
+    # Analysis algo(s)
+    if flags.Acts.doAnalysis:
+        # Run analysis code on the resulting space point collection produced by this tracking pass        
+        # This collection is the result of (3) if it ran, else the result of (2). We are sure at least one of them run
+        if kwargs['processPixels']:
+            kwargs.setdefault('PixelSpacePointAnalysisAlg.name', f'{flags.Tracking.ActiveConfig.extension}PixelSpacePointAnalysisAlg')
+            kwargs.setdefault('PixelSpacePointAnalysisAlg.extension', flags.Tracking.ActiveConfig.extension)
+            kwargs.setdefault('PixelSpacePointAnalysisAlg.SpacePointContainerKey', kwargs['PixelSpacePointPreparationAlg.OutputCollection'] if kwargs['runPreparation'] else kwargs['PixelSpacePointFormationAlg.PixelSpacePoints'])
+
+        if kwargs['processStrips']:
+            kwargs.setdefault('StripSpacePointAnalysisAlg.name', f'{flags.Tracking.ActiveConfig.extension}StripSpacePointAnalysisAlg')
+            kwargs.setdefault('StripSpacePointAnalysisAlg.extension', flags.Tracking.ActiveConfig.extension)
+            kwargs.setdefault('StripSpacePointAnalysisAlg.SpacePointContainerKey', kwargs['StripSpacePointPreparationAlg.OutputCollection'] if kwargs['runPreparation'] else kwargs['StripSpacePointFormationAlg.StripSpacePoints'])
+
+        if kwargs['processOverlapSpacePoints']:
+            kwargs.setdefault('StripOverlapSpacePointAnalysisAlg.name', f'{flags.Tracking.ActiveConfig.extension}StripOverlapSpacePointAnalysisAlg')
+            kwargs.setdefault('StripOverlapSpacePointAnalysisAlg.extension', flags.Tracking.ActiveConfig.extension)
+            kwargs.setdefault('StripOverlapSpacePointAnalysisAlg.SpacePointContainerKey', kwargs['StripOverlapSpacePointPreparationAlg.OutputCollection'] if kwargs['runPreparation'] else kwargs['StripSpacePointFormationAlg.StripOverlapSpacePoints'])
+                
+    acc.merge(ActsMainSpacePointFormationCfg(flags, RoIs=roisName, **kwargs))
     return acc
+
diff --git a/Tracking/Acts/ActsConfig/test/ActsConversionWorkflow.sh b/Tracking/Acts/ActsConfig/test/ActsConversionWorkflow.sh
index 67499d73c9509acc9f7ae9cc247572814a285b1c..798a5387a1b8ad875a38a0896aa04591c428d646 100755
--- a/Tracking/Acts/ActsConfig/test/ActsConversionWorkflow.sh
+++ b/Tracking/Acts/ActsConfig/test/ActsConversionWorkflow.sh
@@ -10,7 +10,7 @@ ignore_pattern="ActsTrackFindingAlg.+ERROR.+Propagation.+reached.+the.+step.+cou
 
 export ATHENA_CORE_NUMBER=1
 Reco_tf.py --CA \
-  --preExec "flags.Acts.doITkConversion=True;flags.Tracking.doTruth=False;flags.Tracking.doITkConversion=False;" \
+  --preExec "flags.Acts.doITkConversion=True;flags.Tracking.doITkConversion=False;" \
   --preInclude "ActsConfig.ActsCIFlags.actsWorkflowFlags" \
   --ignorePatterns "${ignore_pattern}" \
   --inputRDOFile ${input_rdo} \
diff --git a/Tracking/Acts/ActsDataPreparation/src/CacheCreator.cxx b/Tracking/Acts/ActsDataPreparation/src/CacheCreator.cxx
index 000c24e68c872f9fe8b10da556e9707abce6407b..e9ce02b5bedfc9d4b8c8d87db31c6283220f88dc 100644
--- a/Tracking/Acts/ActsDataPreparation/src/CacheCreator.cxx
+++ b/Tracking/Acts/ActsDataPreparation/src/CacheCreator.cxx
@@ -5,23 +5,27 @@
 #include "CacheCreator.h"
 
 namespace ActsTrk::Cache {
-    CreatorAlg::CreatorAlg(const std::string &name,ISvcLocator *pSvcLocator):IDCCacheCreatorBase(name,pSvcLocator)
-    {
-    }
-
-    StatusCode CreatorAlg::initialize(){
-        ATH_CHECK(m_pixelClusterCacheKey.initialize(SG::AllowEmpty));
-        ATH_CHECK(m_stripClusterCacheKey.initialize(SG::AllowEmpty));
+    CreatorAlg::CreatorAlg(const std::string &name,
+			   ISvcLocator *pSvcLocator)
+      : IDCCacheCreatorBase(name,pSvcLocator)
+    {}
 
-        ATH_CHECK(m_pixelSPCacheKey.initialize(SG::AllowEmpty));
-        ATH_CHECK(m_stripSPCacheKey.initialize(SG::AllowEmpty));
-        ATH_CHECK(m_stripOSPCacheKey.initialize(SG::AllowEmpty));
+    StatusCode CreatorAlg::initialize() {
+        ATH_MSG_DEBUG("Initializing " << name() << " ...");
+	
+	m_do_pixClusters = not m_pixelClusterCacheKey.empty();
+        m_do_stripClusters = not m_stripClusterCacheKey.empty();
 
-        m_do_pixClusters = !m_pixelClusterCacheKey.key().empty();
-        m_do_stripClusters = !m_stripClusterCacheKey.key().empty();
+        m_do_pixSpacePoints = not m_pixelSPCacheKey.empty();
+	m_do_stripSpacePoints = not m_stripSPCacheKey.empty();
+	m_do_stripOverlapSpacePoints = not m_stripOSPCacheKey.empty();
+	
+        ATH_CHECK(m_pixelClusterCacheKey.initialize(m_do_pixClusters));
+        ATH_CHECK(m_stripClusterCacheKey.initialize(m_do_stripClusters));
 
-        m_do_pixSP = !m_pixelSPCacheKey.key().empty();
-        m_do_stripSP = !m_stripSPCacheKey.key().empty();
+        ATH_CHECK(m_pixelSPCacheKey.initialize(m_do_pixSpacePoints));
+        ATH_CHECK(m_stripSPCacheKey.initialize(m_do_stripSpacePoints));
+        ATH_CHECK(m_stripOSPCacheKey.initialize(m_do_stripOverlapSpacePoints));
 
         ATH_CHECK(detStore()->retrieve(m_pix_idHelper, "PixelID"));
         ATH_CHECK(detStore()->retrieve(m_strip_idHelper, "SCT_ID"));
@@ -29,25 +33,34 @@ namespace ActsTrk::Cache {
         return StatusCode::SUCCESS;
     }
 
-    StatusCode CreatorAlg::execute(const EventContext& ctx) const{
-        if(m_do_pixClusters){
+    StatusCode CreatorAlg::execute(const EventContext& ctx) const {
+      ATH_MSG_DEBUG("Executing " << name() << " ...");
+      
+        if (m_do_pixClusters) {
             ATH_CHECK(createContainer(m_pixelClusterCacheKey, m_pix_idHelper->wafer_hash_max(), ctx));
+	    ATH_MSG_DEBUG("created pixel cluster container");
         }
 
-        if(m_do_stripClusters){
+        if (m_do_stripClusters) {
             ATH_CHECK(createContainer(m_stripClusterCacheKey, m_strip_idHelper->wafer_hash_max(), ctx));
+	    ATH_MSG_DEBUG("created strip cluster container");
         }
 
-        if(m_do_pixSP){
+        if (m_do_pixSpacePoints) {
             ATH_CHECK(createContainer(m_pixelSPCacheKey, m_pix_idHelper->wafer_hash_max(), ctx));
+	    ATH_MSG_DEBUG("created pixel space point container");
         }
 
-        if(m_do_stripSP){
+        if (m_do_stripSpacePoints) {
             ATH_CHECK(createContainer(m_stripSPCacheKey, m_strip_idHelper->wafer_hash_max(), ctx));
-            ATH_CHECK(createContainer(m_stripOSPCacheKey, m_strip_idHelper->wafer_hash_max(), ctx));
-	    ATH_MSG_DEBUG("created strip sp containers");
+	    ATH_MSG_DEBUG("created strip space point container");
         }
 
+	if (m_do_stripOverlapSpacePoints) {
+	  ATH_CHECK(createContainer(m_stripOSPCacheKey, m_strip_idHelper->wafer_hash_max(), ctx));
+	  ATH_MSG_DEBUG("created overlap strip space point container");
+	}
+
         return StatusCode::SUCCESS;
     }
 }
diff --git a/Tracking/Acts/ActsDataPreparation/src/CacheCreator.h b/Tracking/Acts/ActsDataPreparation/src/CacheCreator.h
index 67cef5ad29c420ee0f0663421550db756930003e..dd0396a9be3f3ac753f3b9efb13e193d861b89f7 100644
--- a/Tracking/Acts/ActsDataPreparation/src/CacheCreator.h
+++ b/Tracking/Acts/ActsDataPreparation/src/CacheCreator.h
@@ -18,6 +18,8 @@ namespace ActsTrk::Cache{
     class CreatorAlg: public IDCCacheCreatorBase{
     public:
         CreatorAlg(const std::string &name,ISvcLocator *pSvcLocator);
+        virtual ~CreatorAlg() = default;
+
         virtual StatusCode initialize () override;
         virtual StatusCode execute (const EventContext& ctx) const override;
 
@@ -25,18 +27,19 @@ namespace ActsTrk::Cache{
         SG::WriteHandleKey<Handles<xAOD::PixelCluster>::IDCBackend> m_pixelClusterCacheKey{this, "PixelClustersCacheKey", ""};
         SG::WriteHandleKey<Handles<xAOD::StripCluster>::IDCBackend> m_stripClusterCacheKey{this, "StripClustersCacheKey", ""};
 
-        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_pixelSPCacheKey{this, "PixelSPCacheKey", ""};
-        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_stripSPCacheKey{this, "StripSPCacheKey", ""};
-        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_stripOSPCacheKey{this, "StripOSPCacheKey", ""};
+        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_pixelSPCacheKey{this, "PixelSpacePointCacheKey", ""};
+        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_stripSPCacheKey{this, "StripSpacePointCacheKey", ""};
+        SG::WriteHandleKey<Handles<xAOD::SpacePoint>::IDCBackend> m_stripOSPCacheKey{this, "StripOverlapSpacePointCacheKey", ""};
 
         const PixelID* m_pix_idHelper{};
         const SCT_ID*  m_strip_idHelper{};
 
-        bool m_do_pixSP{false};
-        bool m_do_stripSP{false};
-
         bool m_do_pixClusters{false};
         bool m_do_stripClusters{false};
-    };
+
+        bool m_do_pixSpacePoints{false};
+        bool m_do_stripSpacePoints{false};
+        bool m_do_stripOverlapSpacePoints{false};
+};
 }
 #endif