diff --git a/DataQuality/DQOnlinePostprocessing/python/atlas_oh.py b/DataQuality/DQOnlinePostprocessing/python/atlas_oh.py
index 9844e4fd423a678c5fb87c5299a2d7f2ba3dafa7..80a2622898f9316139875f696c5e315b44e44b06 100644
--- a/DataQuality/DQOnlinePostprocessing/python/atlas_oh.py
+++ b/DataQuality/DQOnlinePostprocessing/python/atlas_oh.py
@@ -46,7 +46,7 @@ class OHInputModule(InputModule):
             raise ValueError("Must specify 'source' as an "
                              "option to OHInputModule")
         self.source = options['source']
-        self.partition, self.server, self.provider = self.source.split(':')
+        self.partition, self.server, self.provider = self.source.split(';')
         self.prefix = options.get('prefix', '')
         if not IPCPartition(self.partition).isValid():
             raise ValueError(f'Input partition {self.partition} does not exist')
@@ -134,7 +134,7 @@ class OHOutputModule(OutputModule):
             raise ValueError("Must specify 'target' as an option "
                              "to OHInputModule")
         self.target = options['target']
-        self.partition, self.server, self.provider = self.target.split(':')
+        self.partition, self.server, self.provider = self.target.split(';')
         self.partition = ispy.IPCPartition(self.partition)
         if not self.partition.isValid():
             raise ValueError(f'Output partition {self.partition.name()} is not valid')
diff --git a/TileCalorimeter/TileMonitoring/CMakeLists.txt b/TileCalorimeter/TileMonitoring/CMakeLists.txt
index 8f95b22b336c11ae7a3f5c3e6f68533885a36a12..834b51cf4f6148d873360cc67575fcae565df2c9 100644
--- a/TileCalorimeter/TileMonitoring/CMakeLists.txt
+++ b/TileCalorimeter/TileMonitoring/CMakeLists.txt
@@ -32,6 +32,7 @@ atlas_add_component( TileMonitoring
 atlas_install_headers( TileMonitoring )
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py )
+atlas_install_data( data/*.yaml )
 
 # Tests:
 atlas_add_test( TileCellMonitorAlgorithm_test
diff --git a/TileCalorimeter/TileMonitoring/data/TileDigiNoisePostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileDigiNoisePostProc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5955c13830d30ee03f74cd9f5fd37ee6b266e9b8
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/data/TileDigiNoisePostProc.yaml
@@ -0,0 +1,12 @@
+#
+#  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+#
+# Post-processing of histograms from Tile digi noise monitoring
+## Separate blocks with ---
+---
+Input: [ 'Tile/DigiNoise/TileDigiNoisePed_(?P<partition>[L|E]B[C|A])_(?P<gain>[H|L]G)' ]
+Output: [ 'Tile/DigiNoise/TileDigiNoiseLFN_{partition}_{gain}' ]
+Function: TileMonitoring.TilePostProcessing.getProfile2D_RMS
+Parameters: { title: 'Low frequency noise (LFN)', name: 'TileDigiNoiseLFN'}
+Description: Produce Tile 2D with low frequency noise (LFN) per partition
+
diff --git a/TileCalorimeter/TileMonitoring/data/TileRawChanNoisePostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileRawChanNoisePostProc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..88184f75c41c90507138921e08fc00237c7b0ec2
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/data/TileRawChanNoisePostProc.yaml
@@ -0,0 +1,33 @@
+#
+#  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+#
+# Post-processing of histograms from Tile Raw channel noise monitoring
+## Separate blocks with ---
+Input: [ 'Tile/RawChannelNoise/LBA/(?P<module>LBA[0-6]\d{1})/TileRawChannelNoise_(?P=module)_[ABCDE]\d[0-5\*]?_ch_(?P<channel>\d{1,2})_HG' ]
+Output: [ 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RMS_LBA', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Sigma_LBA',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Chi2_LBA', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Probability_LBA',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RmsOverSigma_LBA']
+Function: TileMonitoring.TilePostProcessing.getTilePartitionRawChannelNoise
+Description: Produces 2D histograms with Tile raw channel noise for LBA partition
+---
+Input: [ 'Tile/RawChannelNoise/LBC/(?P<module>LBC[0-6]\d{1})/TileRawChannelNoise_(?P=module)_[ABCDE]\d[0-5\*]?_ch_(?P<channel>\d{1,2})_HG' ]
+Output: [ 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RMS_LBC', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Sigma_LBC',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Chi2_LBC', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Probability_LBC',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RmsOverSigma_LBC' ]
+Function: TileMonitoring.TilePostProcessing.getTilePartitionRawChannelNoise
+Description: Produces 2D histograms with Tile raw channel noise for LBC partition
+---
+Input: [ 'Tile/RawChannelNoise/EBA/(?P<module>EBA[0-6]\d{1})/TileRawChannelNoise_(?P=module)_[ABCDE]\d[0-5\*]?_ch_(?P<channel>\d{1,2})_HG' ]
+Output: [ 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RMS_EBA', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Sigma_EBA',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Chi2_EBA', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Probability_EBA',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RmsOverSigma_EBA' ]
+Function: TileMonitoring.TilePostProcessing.getTilePartitionRawChannelNoise
+Description: Produces 2D histograms with Tile raw channel noise for EBA partition
+---
+Input: [ 'Tile/RawChannelNoise/EBC/(?P<module>EBC[0-6]\d{1})/TileRawChannelNoise_(?P=module)_[ABCDE]\d[0-5\*]?_ch_(?P<channel>\d{1,2})_HG' ]
+Output: [ 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RMS_EBC', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Sigma_EBC',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Chi2_EBC', 'Tile/RawChannelNoise/Summary/TileRawChannelNoise_Probability_EBC',
+          'Tile/RawChannelNoise/Summary/TileRawChannelNoise_RmsOverSigma_EBC' ]
+Function: TileMonitoring.TilePostProcessing.getTilePartitionRawChannelNoise
+Description: Produces 2D histograms with Tile raw channel noise for EBC partition
+
diff --git a/TileCalorimeter/TileMonitoring/data/TileTMDBPostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileTMDBPostProc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..37982b5014dd31d5092ae813b1b01a09550bf1b8
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/data/TileTMDBPostProc.yaml
@@ -0,0 +1,18 @@
+#
+#  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+#
+# Post-processing of histograms from Tile TMDB monitoring
+## Separate blocks with ---
+---
+Input: [ 'Tile/TMDBDigits/TMDB_DigitsPedestal_(?P<partition>[L|E]B[C|A])' ]
+Output: [ 'Tile/TMDBDigits/TMDB_DigitsLFN_{partition}' ]
+Function: TileMonitoring.TilePostProcessing.getProfile2D_RMS
+Parameters: { title: 'LFN in TMDB', name: 'TMDB_DigitsLFN' }
+Description: Produce Tile TMDB 2D plots with LFN per partition
+---
+Input: [ 'Tile/TMDB/TMDB_Energy_(?P<partition>[L|E]B[C|A])' ]
+Output: [ 'Tile/TMDB/TMDB_Noise_{partition}' ]
+Function: TileMonitoring.TilePostProcessing.getProfile2D_RMS
+Parameters: { title: 'Noise [MeV] in TMDB', name: 'TMDB_Noise'}
+Description: Produce Tile TMDB 2D plots with noise per partition
+
diff --git a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py
index c7fb323794f0ed1059e0c77f13d68a8a12b73deb..8eaa49d5bfd51147f6118a2366edda6a4ec7851d 100644
--- a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py
+++ b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 #
 #  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 #
@@ -7,6 +8,9 @@
 @brief Functions for post-processing of histograms from TileMonitoring for the Run III
 '''
 
+import os, sys, signal, subprocess
+from AthenaCommon.Utils.unixtools import find_datafile
+
 def getProfile2D_RMS(inputs, title, name):
     """ This function produces 2D histogram with RMS from Profile2D per Tile partition """
 
@@ -28,3 +32,140 @@ def getProfile2D_RMS(inputs, title, name):
     inputProfile.GetYaxis().Copy(outputHistogram.GetYaxis())
 
     return [outputHistogram]
+
+
+def getTilePartitionRawChannelNoise(inputs):
+    """ This function produces 2D histograms with Tile raw channel noise per partition """
+
+    import ROOT
+    # Force batch mode
+    ROOT.gROOT.SetBatch(True)
+
+    from TileMonitoring.TileMonitoringCfgHelper import getLabels
+    from TileCalibBlobObjs.Classes import TileCalibUtils as Tile
+
+    def _getTilePartitionHistogram2D(name, title, partition, run):
+        fullName = 'TileRawChannelNoise_{}_{}'.format(name, partition)
+        fullTitle = 'Run {} Partition {}: {}'.format(run, partition, title)
+        histogram = ROOT.TH2F(fullName, fullTitle,
+                              Tile.MAX_DRAWER, 0.5, Tile.MAX_DRAWER + 0.5,
+                              Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5)
+        moduleLables = getLabels(('modules'), partition)
+        channelLables = getLabels(('channels'), partition)
+        for axis,labels in ((histogram.GetXaxis(), moduleLables), (histogram.GetYaxis(), channelLables)):
+            for bin in range(0, len(labels)):
+                axis.SetBinLabel(bin + 1, labels[bin])
+        return histogram
+
+
+    partition = inputs[0][0]['module'][:3]
+    run = str(inputs[0][1][0].GetTitle()).split(' ')[1]
+
+    rmsHistogram = _getTilePartitionHistogram2D('RMS', 'RMS of gaussians', partition, run)
+    sigmaHistogram = _getTilePartitionHistogram2D('Sigma', 'Sigma of gaussians', partition, run)
+    chi2Histogram = _getTilePartitionHistogram2D('Chi2', 'Chi2 of gaussians', partition, run)
+    probabilityHistogram = _getTilePartitionHistogram2D('Prob', 'Probability of gaussians', partition, run)
+    rmsOverSigmaHistogram = _getTilePartitionHistogram2D('RmsOverSigma', 'RMS/Sigma of gaussians', partition, run)
+
+    fitfunction = ROOT.TF1("total", "gaus(0)")
+    fitfunction.SetLineColor(2)
+
+    for input in inputs:
+
+        module = int(input[0]['module'][3:])
+        channel = int(input[0]['channel'])
+
+        plot = input[1][0]
+
+        nEntries = plot.GetEntries()
+
+        if nEntries > 100:
+
+            rms = plot.GetRMS()
+            rmsHistogram.Fill(module, channel, rms)
+
+            fitfunction.SetParameters(0.1 * nEntries, 0., 0.7 * rms)
+
+            binWidth = plot.GetBinWidth(0)
+            lowLimit = binWidth * 0.5
+            highLimit = max(rms * 1.05, binWidth * 2.0)
+
+            fitfunction.SetParLimits(0, 0., nEntries)
+            fitfunction.FixParameter(1, 0.)
+            fitfunction.SetParLimits(2, lowLimit, highLimit)
+
+            plot.Fit(fitfunction, "BQ")
+
+            sigma = fitfunction.GetParameter(2)
+            chi2 = fitfunction.GetChisquare()
+            prob = fitfunction.GetProb()
+
+            sigmaHistogram.Fill(module, channel, sigma)
+            chi2Histogram.Fill(module, channel, chi2)
+            probabilityHistogram.Fill(module, channel, prob)
+            rmsOverSigmaHistogram.Fill(module, channel, rms/sigma)
+
+    return [rmsHistogram, sigmaHistogram, chi2Histogram, probabilityHistogram, rmsOverSigmaHistogram]
+
+
+if __name__== '__main__':
+
+    import argparse
+    parser= argparse.ArgumentParser()
+
+    parser.add_argument('--stateless', action="store_true", help='Run Online Tile Post Processing in partition')
+    parser.add_argument('--tmdb', action="store_true", help='Run Tile TMDB Post Processing')
+    parser.add_argument('--digi-noise', action="store_true", dest='digiNoise', help='Run Tile Digi Noise Post Processing')
+    parser.add_argument('--raw-chan-noise', action="store_true", dest='rawChanNoise', help='Run Tile Digi Noise Post Processing')
+    parser.add_argument('--interval', type=int, default=60, help='Interval (in seconds) to run Tile Monitoring Post Processing')
+    parser.add_argument('--noise-interval', type=int, default=300, dest='noiseInterval',
+                        help='Interval (in seconds) to run Tile Noise Monitoring Post Processing')
+
+    args = parser.parse_args()
+
+    if args.stateless:
+
+        server = 'Histogramming'
+        partition = os.getenv("TDAQ_PARTITION", "ATLAS")
+
+        dataPath = find_datafile('TileMonitoring')
+
+        def sigtermHandler(signal, frame):
+            print('Terminating postporcessing ...')
+            sys.exit(0)
+
+        signal.signal(signal.SIGTERM, sigtermHandler)
+
+        if args.tmdb:
+
+            inputPath = f'{partition};{server};TileMIG:TileGatherer'
+            outputPath = f'{partition};{server};TilePT-stateless-PP'
+
+            physConfigurations = []
+            if args.tmdb:
+                physConfigurations += [os.path.join(dataPath, 'TileTMDBPostProc.yaml')]
+
+            physPostProcess = (['histgrinder', inputPath, outputPath,
+                                 '--inmodule', 'DQOnlinePostprocessing.atlas_oh.OHInputModule',
+                                 '--outmodule', 'DQOnlinePostprocessing.atlas_oh.OHOutputModule',
+                                 '-c'] + physConfigurations)
+
+            subprocess.run(physPostProcess)
+
+        elif any([args.digiNoise, args.rawChanNoise]):
+
+            inputPath = f'{partition};{server};TilePT-stateless-noise-01'
+            outputPath = f'{partition};{server};TilePT-stateless-noise-PP'
+
+            noiseConfigurations = []
+            if args.digiNoise:
+                noiseConfigurations += [os.path.join(dataPath, 'TileDigiNoisePostProc.yaml')]
+            if args.rawChanNoise:
+                noiseConfigurations += [os.path.join(dataPath, 'TileRawChanNoisePostProc.yaml')]
+
+            noisePostProcess = (['histgrinder', inputPath, outputPath,
+                                 '--inmodule', 'DQOnlinePostprocessing.atlas_oh.OHInputModule',
+                                 '--outmodule', 'DQOnlinePostprocessing.atlas_oh.OHOutputModule',
+                                 '-c'] + noiseConfigurations)
+
+            subprocess.run(noisePostProcess)