diff --git a/TileCalorimeter/TileRecUtils/CMakeLists.txt b/TileCalorimeter/TileRecUtils/CMakeLists.txt
index 59c81edaec82c54c5431dc60ac9182346e8b85c3..f00392b415d1d4ba029b7475b8b1a62ab943b7c7 100644
--- a/TileCalorimeter/TileRecUtils/CMakeLists.txt
+++ b/TileCalorimeter/TileRecUtils/CMakeLists.txt
@@ -111,6 +111,11 @@ atlas_add_test( TileRawChannelBuilderOptConfig_test
                  PROPERTIES TIMEOUT 300
                  POST_EXEC_SCRIPT nopost.sh)
 
+atlas_add_test( TileDQstatusConfig_test
+                 SCRIPT python -m TileRecUtils.TileDQstatusConfig
+                 PROPERTIES TIMEOUT 300
+                 POST_EXEC_SCRIPT nopost.sh)
+
 atlas_add_test( TileRawChannelCorrectionConfig_test
                  SCRIPT python -m TileRecUtils.TileRawChannelCorrectionConfig
                  PROPERTIES TIMEOUT 300
diff --git a/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderConfig.py b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..a43b42eeeb45b79790ac26cf06fdfc4a08152441
--- /dev/null
+++ b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderConfig.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+
+"""Define method to construct configured base Tile raw channel builder tool"""
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+
+_runTypes = {'PHY' : 1, 'LAS' : 2, 'BILAS' : 2, 'PED' : 4, 'CIS' : 8, 'MONOCIS' : 8}
+
+def TileRawChannelBuilderCfg(flags, TileRawChannelBuilder, name):
+    """Return component accumulator with configured private base Tile raw channel builder tool
+
+    Arguments:
+        flags  -- Athena configuration flags (ConfigFlags)
+        TileRawChannelbuilder -- concrete Tile raw channel builder tool
+        name -- name of Tile raw channel builder tool
+    """
+
+    acc = ComponentAccumulator()
+
+    runType = flags.Tile.RunType
+    runType = runType.upper()
+
+    if runType not in _runTypes.keys():
+        raise(Exception("Invalid Tile run type: %s" % runType))
+
+    from TileRecUtils.TileDQstatusConfig import TileDQstatusAlgCfg
+    acc.merge( TileDQstatusAlgCfg(flags) )
+
+    from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
+    acc.merge( TileInfoLoaderCfg(flags) )
+
+    from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
+    acc.merge( TileCablingSvcCfg(flags) )
+
+    tileRawChannelBuilder = TileRawChannelBuilder(name)
+
+    tileRawChannelBuilder.RunType = _runTypes[runType]
+    tileRawChannelBuilder.calibrateEnergy = False
+    tileRawChannelBuilder.AmpMinForAmpCorrection = flags.Tile.AmpMinForAmpCorrection
+    tileRawChannelBuilder.TimeMinForAmpCorrection = flags.Tile.TimeMinForAmpCorrection
+    tileRawChannelBuilder.TimeMaxForAmpCorrection = flags.Tile.TimeMaxForAmpCorrection
+
+    tileRawChannelContainerDSP = ""
+    if flags.Tile.NoiseFilter == 1:
+        from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionToolsCfg
+        correctionTools = acc.popToolsAndMerge( TileRawChannelCorrectionToolsCfg(flags) )
+        tileRawChannelBuilder.NoiseFilterTools = correctionTools
+
+        if not (flags.Input.isMC or flags.Overlay.DataOverlay):
+            tileRawChannelContainerDSP = 'TileRawChannelCntCorrected'
+            from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionAlgCfg
+            acc.merge( TileRawChannelCorrectionAlgCfg(flags) )
+
+    tileRawChannelBuilder.DSPContainer = tileRawChannelContainerDSP
+
+    acc.setPrivateTools( tileRawChannelBuilder )
+
+    return acc
+
+
+if __name__ == "__main__":
+
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior = 1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import DEBUG
+
+    # Test setup
+    log.setLevel(DEBUG)
+
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.Tile.RunType = 'PHY'
+    ConfigFlags.Tile.NoiseFilter = 1
+    ConfigFlags.lock()
+
+    ConfigFlags.dump()
+
+    acc = ComponentAccumulator()
+
+    from TileRecUtils.TileRecUtilsConf import TileRawChannelBuilderFitFilter
+    rchBuilderFitAcc = TileRawChannelBuilderCfg(ConfigFlags, TileRawChannelBuilderFitFilter)
+    print( acc.popToolsAndMerge(rchBuilderFitAcc) )
+
+    from TileRecUtils.TileRecUtilsConf import TileRawChannelBuilderOpt2Filter
+    rchBuilderOpt2Acc = TileRawChannelBuilderCfg(ConfigFlags, TileRawChannelBuilderOpt2Filter)
+    print( acc.popToolsAndMerge(rchBuilderOpt2Acc) )
+
+
+    acc.printConfig(withDetails = True, summariseProps = True)
+    acc.store( open('TileRawChannelBuilder.pkl','w') )
+
+
diff --git a/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderFitConfig.py b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderFitConfig.py
index ad146a793b59f62d9d0b97041fa58647cd8275f0..8604ba5ef498c08c54e18c67984ec65394557f74 100644
--- a/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderFitConfig.py
+++ b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderFitConfig.py
@@ -4,9 +4,6 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
-_runTypes = {'PHY' : 1, 'LAS' : 2, 'BILAS' : 2, 'PED' : 4, 'CIS' : 8, 'MONOCIS' : 8}
-
-
 def TileRawChannelBuilderFitFilterCfg(flags, **kwargs):
     """Return component accumulator with configured private Tile Fit raw channel builder tool
 
@@ -14,29 +11,17 @@ def TileRawChannelBuilderFitFilterCfg(flags, **kwargs):
         flags  -- Athena configuration flags (ConfigFlags)
     """
 
-    acc = ComponentAccumulator()
-
-    runType = flags.Tile.RunType
-    runType = runType.upper()
-
-    if runType not in _runTypes.keys():
-        raise(Exception("Invalid Tile run type: %s" % runType))
-
-    from TileRecUtils.TileDQstatusConfig import TileDQstatusAlgCfg
-    acc.merge( TileDQstatusAlgCfg(flags) )
-
-    from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
-    acc.merge( TileInfoLoaderCfg(flags) )
-
     from TileRecUtils.TileRecUtilsConf import TileRawChannelBuilderFitFilter
-    tileRawChannelBuilderFit = TileRawChannelBuilderFitFilter()
+    from TileRawChannelBuilderConfig import TileRawChannelBuilderCfg
+
+    name = 'TileRawChannelBuilderFitFilter'
+    acc = TileRawChannelBuilderCfg(flags, TileRawChannelBuilderFitFilter, name)
+    tileRawChannelBuilderFit = acc.getPrimary()
 
     from TileConditions.TileSampleNoiseConfig import TileCondToolNoiseSampleCfg
     sampleNoiseTool = acc.popToolsAndMerge( TileCondToolNoiseSampleCfg(flags) )
     tileRawChannelBuilderFit.TileCondToolNoiseSample = sampleNoiseTool
 
-    tileRawChannelBuilderFit.RunType = _runTypes[runType]
-    tileRawChannelBuilderFit.calibrateEnergy = flags.Tile.calibrateEnergy
     tileRawChannelBuilderFit.correctTime = flags.Tile.correctTime
     tileRawChannelBuilderFit.FrameLength = 7
     tileRawChannelBuilderFit.TileRawChannelContainer = 'TileRawChannelFit'
@@ -46,19 +31,6 @@ def TileRawChannelBuilderFitFilterCfg(flags, **kwargs):
         timingTool = acc.popToolsAndMerge( TileCondToolTimingCfg(flags) )
         tileRawChannelBuilderFit.TileCondToolTiming = timingTool
 
-    tileRawChannelContainerDSP = ""
-    if flags.Tile.NoiseFilter == 1:
-        from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionToolsCfg
-        correctionTools = acc.popToolsAndMerge( TileRawChannelCorrectionToolsCfg(flags) )
-        tileRawChannelBuilderFit.NoiseFilterTools = correctionTools
-
-        if not (flags.Input.isMC or flags.Overlay.DataOverlay):
-            tileRawChannelContainerDSP = 'TileRawChannelCntCorrected'
-            from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionAlgCfg
-            acc.merge( TileRawChannelCorrectionAlgCfg(flags) )
-
-    tileRawChannelBuilderFit.DSPContainer = tileRawChannelContainerDSP
-
     acc.setPrivateTools( tileRawChannelBuilderFit )
 
     return acc
diff --git a/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderOptConfig.py b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderOptConfig.py
index eb6e62548ad61b6a14af9294a794414656d3cffe..6263edfe314ea3a9e75576bdb900c96d54edd21d 100644
--- a/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderOptConfig.py
+++ b/TileCalorimeter/TileRecUtils/python/TileRawChannelBuilderOptConfig.py
@@ -4,8 +4,6 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
-_runTypes = {'PHY' : 1, 'LAS' : 2, 'BILAS' : 2, 'PED' : 4, 'CIS' : 8, 'MONOCIS' : 8}
-
 def TileRawChannelBuilderOpt2FilterCfg(flags, **kwargs):
     """Return component accumulator with configured private Tile raw channel builder tool (Opt2)
 
@@ -14,28 +12,18 @@ def TileRawChannelBuilderOpt2FilterCfg(flags, **kwargs):
         Method -- flavour of Tile Optimal Filtering method. Defaults to Opt2. Possible values: Opt2, OptATLAS, OF1
     """
 
-    acc = ComponentAccumulator()
-
     method = kwargs.get('Method', 'Opt2')
     if method not in ['Opt2', 'OptATLAS', 'OF1']:
         raise(Exception("Invalid Tile Optimal Filtering method: %s" % method))
 
     name = 'TileRawChannelBuilder' + method
 
-    runType = flags.Tile.RunType
-    runType = runType.upper()
-
-    if runType not in _runTypes.keys():
-        raise(Exception("Invalid Tile run type: %s" % runType))
-
-    from TileRecUtils.TileDQstatusConfig import TileDQstatusAlgCfg
-    acc.merge( TileDQstatusAlgCfg(flags) )
-
-    from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
-    acc.merge( TileInfoLoaderCfg(flags) )
-
     from TileRecUtils.TileRecUtilsConf import TileRawChannelBuilderOpt2Filter
-    tileRawChannelBuilderOpt = TileRawChannelBuilderOpt2Filter(name)
+    from TileRawChannelBuilderConfig import TileRawChannelBuilderCfg
+    acc = TileRawChannelBuilderCfg(flags, TileRawChannelBuilderOpt2Filter, name)
+    tileRawChannelBuilderOpt = acc.getPrimary()
+
+    useIterations = (method == 'Opt2')
 
     if flags.Tile.OfcFromCOOL:
         ofcType = 'OF2' if method != 'OF1' else 'OF1'
@@ -47,27 +35,22 @@ def TileRawChannelBuilderOpt2FilterCfg(flags, **kwargs):
 
     tileRawChannelBuilderOpt.TileCondToolOfc = ofcTool
 
-    outputContainer = 'TileRawChannel' + {'OptATLAS':flags.Tile.RawChannelContainer}.get(method, method)
+    outputContainer = flags.Tile.RawChannelContainer if method == 'OptATLAS' else 'TileRawChannel' + method
 
     tileRawChannelBuilderOpt.TileRawChannelContainer = outputContainer
-    tileRawChannelBuilderOpt.RunType = _runTypes[runType]
-    tileRawChannelBuilderOpt.calibrateEnergy = False
-    tileRawChannelBuilderOpt.BestPhase = False if method == 'Opt2' else flags.Tile.BestPhaseFromCOOL
+    tileRawChannelBuilderOpt.BestPhase = False if useIterations else flags.Tile.BestPhaseFromCOOL
     tileRawChannelBuilderOpt.OF2 = True if method != 'OF1' else False
-    tileRawChannelBuilderOpt.MaxIterations = 5 if method == 'Opt2' else 1
-    tileRawChannelBuilderOpt.Minus1Iteration = True if method == 'Opt2' else False
-    tileRawChannelBuilderOpt.AmplitudeCorrection = False if method == 'Opt2' else flags.Tile.correctAmplitude
+    tileRawChannelBuilderOpt.MaxIterations = 5 if useIterations else 1
+    tileRawChannelBuilderOpt.Minus1Iteration = True if useIterations else False
+    tileRawChannelBuilderOpt.AmplitudeCorrection = False if useIterations else flags.Tile.correctAmplitude
     tileRawChannelBuilderOpt.TimeCorrection = False if method != 'OptATLAS' else flags.Tile.correctTimeNI
-    tileRawChannelBuilderOpt.AmpMinForAmpCorrection = flags.Tile.AmpMinForAmpCorrection
-    tileRawChannelBuilderOpt.TimeMinForAmpCorrection = flags.Tile.TimeMinForAmpCorrection
-    tileRawChannelBuilderOpt.TimeMaxForAmpCorrection = flags.Tile.TimeMaxForAmpCorrection
 
-    if (flags.Tile.BestPhaseFromCOOL and method != 'Opt2') or flags.Tile.correctTime:
+    if (flags.Tile.BestPhaseFromCOOL and not useIterations) or flags.Tile.correctTime:
         from TileConditions.TileTimingConfig import TileCondToolTimingCfg
         timingTool = acc.popToolsAndMerge( TileCondToolTimingCfg(flags) )
         tileRawChannelBuilderOpt.TileCondToolTiming = timingTool
 
-    if flags.Tile.BestPhaseFromCOOL and method != 'Opt2':
+    if flags.Tile.BestPhaseFromCOOL and not useIterations:
         # Can't correct time and use best phase at the same time without iteration
         tileRawChannelBuilderOpt.correctTime = False
     else:
@@ -76,19 +59,6 @@ def TileRawChannelBuilderOpt2FilterCfg(flags, **kwargs):
     if method == 'OF1':
         tileRawChannelBuilderOpt.PedestalMode = -1
 
-    tileRawChannelContainerDSP = ""
-    if flags.Tile.NoiseFilter == 1:
-        from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionToolsCfg
-        correctionTools = acc.popToolsAndMerge( TileRawChannelCorrectionToolsCfg(flags) )
-        tileRawChannelBuilderOpt.NoiseFilterTools = correctionTools
-
-        if not (flags.Input.isMC or flags.Overlay.DataOverlay):
-            tileRawChannelContainerDSP = 'TileRawChannelCntCorrected'
-            from TileRecUtils.TileRawChannelCorrectionConfig import TileRawChannelCorrectionAlgCfg
-            acc.merge( TileRawChannelCorrectionAlgCfg(flags) )
-
-    tileRawChannelBuilderOpt.DSPContainer = tileRawChannelContainerDSP
-
     acc.setPrivateTools( tileRawChannelBuilderOpt )
 
     return acc
diff --git a/TileCalorimeter/TileRecUtils/python/TileRawChannelMakerConfig.py b/TileCalorimeter/TileRecUtils/python/TileRawChannelMakerConfig.py
index 9ffd6bd84a18a2d816b51fc0e3140d2959fb249b..6ef416d9aa38f5e008428889fc184101907f4442 100644
--- a/TileCalorimeter/TileRecUtils/python/TileRawChannelMakerConfig.py
+++ b/TileCalorimeter/TileRecUtils/python/TileRawChannelMakerConfig.py
@@ -81,10 +81,13 @@ if __name__ == "__main__":
     ConfigFlags.Tile.doOpt2 = True
     ConfigFlags.Tile.doOptATLAS = True
     ConfigFlags.Tile.NoiseFilter = 1
+
+    ConfigFlags.fillFromArgs()
+
     ConfigFlags.lock()
 
-    from AthenaConfiguration.MainServicesConfig import MainServicesSerialCfg
-    acc = MainServicesSerialCfg()
+    from AthenaConfiguration.MainServicesConfig import MainServicesThreadedCfg
+    acc = MainServicesThreadedCfg(ConfigFlags)
 
     from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
     acc.merge( TrigBSReadCfg(ConfigFlags) )