diff --git a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx
index 0c1ff8f57b6d1b44c1a6cedf473889198d117a83..78ebac94f0f85bc8dba0a12c237e74b7145d9347 100644
--- a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx
+++ b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //***************************************************************************************
@@ -22,6 +22,7 @@
 //     10.dec.2013 ready for submission in svn
 //     16.jan.2014 fixed coverity errors
 //     06.oct.2015 including the barrel cells 
+//     21.jun.2020 MC pileup overlay
 //
 //  BUGS:
 // 
@@ -56,6 +57,11 @@
 #include <CLHEP/Random/Randomize.h>
 #include <CLHEP/Units/SystemOfUnits.h>
 
+
+// pileup
+#include "PileUpTools/PileUpMergeSvc.h"
+
+
 using CLHEP::RandGaussQ;
 using CLHEP::RandFlat;
 using CLHEP::MeV;
@@ -78,9 +84,9 @@ TilePulseForTileMuonReceiver::TilePulseForTileMuonReceiver(std::string name, ISv
   , m_nBinsPerX(0)
   , m_binTime0(0)
   , m_timeStep(0.0)
-  , m_run2(true)
+  , m_mergeSvc(nullptr)
+  , m_runPeriod(0)
 {
-
 }
 
 // destructor
@@ -96,10 +102,9 @@ StatusCode TilePulseForTileMuonReceiver::initialize() {
   //
   ATH_CHECK( m_cablingSvc.retrieve() );
   m_cablingService = m_cablingSvc->cablingService();
-
-  if (! m_cablingService->isRun2Cabling() ) {
+  m_runPeriod = m_cablingService->runPeriod();
+  if ( m_runPeriod == 0) {
     ATH_MSG_INFO("TilePulseForTileMuonReceiver should not be used for RUN1 simulations");
-    m_run2 = false;
     return StatusCode::SUCCESS;
   } else {
     ATH_MSG_INFO("Initializing TilePulseForTileMuonReceiver");
@@ -163,9 +168,28 @@ StatusCode TilePulseForTileMuonReceiver::initialize() {
     m_tileBadChanTool.disable();
   }
 
-  ATH_CHECK( m_hitContainerKey.initialize(m_run2) );
-  ATH_CHECK( m_muRcvDigitsContainerKey.initialize(m_run2) );
-  ATH_CHECK( m_muRcvRawChannelContainerKey.initialize(m_run2) );
+  ATH_MSG_INFO( "Integer digits: \t" << ((m_integerDigits)?"true":"false"));
+  ATH_MSG_INFO( "Tile Pedestal: \t" << ((m_tilePedestal)?"true":"false"));
+  ATH_MSG_INFO( "Tile Noise: \t" << ((m_tileNoise)?"true":"false"));
+  ATH_MSG_INFO( "Event Overlay: \t" << ((m_rndmEvtOverlay)?"true":"false"));
+  ATH_MSG_INFO( "Masking Channels: \t" << ((m_maskBadChannels)?"true":"false"));
+  ATH_MSG_INFO( "Pulse shapes from COOL: \t" << ((m_useCoolPulseShapes)?"true":"false"));
+
+  ATH_CHECK( m_hitContainerKey.initialize(true) );
+  ATH_CHECK( m_muRcvDigitsContainerKey.initialize(true) );
+  ATH_CHECK( m_muRcvRawChannelContainerKey.initialize(true) );
+
+  m_inputDigitContainerName = m_inputDigitContainerKey.key();
+  ATH_CHECK( m_inputDigitContainerKey.initialize(!m_onlyUseContainerName && m_rndmEvtOverlay) );
+
+  if (m_rndmEvtOverlay) {
+    ATH_MSG_INFO( "Pileup and/or noise added by overlaying digits of random events");
+    // locate the PileUpMergeSvc and initialize our local ptr
+    if (m_onlyUseContainerName) {
+      ATH_CHECK( service("PileUpMergeSvc", m_mergeSvc) );
+      ATH_MSG_INFO( "PileUpMergeSvc successfully initialized");
+    }
+  }
 
   ATH_MSG_VERBOSE("TilePulseForTileMuonReceiver initialization completed");
   return StatusCode::SUCCESS;
@@ -173,18 +197,16 @@ StatusCode TilePulseForTileMuonReceiver::initialize() {
 
 // execute
 //
-
 StatusCode TilePulseForTileMuonReceiver::execute() {
 
-  if (m_run2) {
-    ATH_MSG_VERBOSE( "ATT: RUN2 settings TilePulseForTileMuonReceiver will run now" );
-    ATH_MSG_DEBUG( "Executing TilePulseForTileMuonReceiver" );
-  } else {
+  if (m_runPeriod==0)  {
     ATH_MSG_VERBOSE( "ATT: RUN1 settings TilePulseForTileMuonReceiver will end now" );
     return StatusCode::SUCCESS;
+  } else {
+    ATH_MSG_DEBUG( "Executing TilePulseForTileMuonReceiver" );
   }
 
-  // Conversion from TMDB channel number to channel number in a drawer: EB (0-3) LB(0-13)
+  // Conversion from TMDB channel number to channel number in a drawer: EB (0-3) LB (0-8)
   // Including the cells used in the "The potential of using the ATLAS Tile calorimeter in Phase-II for the
   // Level-0 muon trigger" (ATL-COM-TILECAL-2015-007.pdf): ALL D-layer + BC-8.
   //
@@ -197,8 +219,10 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
   // Set to maximum possible index 
 #if (nEBchan > nLBchan)
   double pDigitSamplesArray[nEBchan][7];
+  double pDigitSamplesRndmArray[nEBchan][7];
 #else
   double pDigitSamplesArray[nLBchan][7];
+  double pDigitSamplesRndmArray[nLBchan][7];
 #endif
 
   // PULSE
@@ -222,7 +246,6 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
   double muRcv_Ped;
   double muRcv_Calib;
   double muRcv_Max;
-  // double muRcv_Thresh;
 
   // Get hit container from TES
   //
@@ -249,12 +272,69 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
                                                                                    SG::VIEW_ELEMENTS);
   ATH_CHECK( muRcvRawChannelContainer->status() );
 
+  // Prepare container for MC Overlay procedure
+  //
+  TileDigitsContainer::const_iterator collItrRndm;
+  TileDigitsContainer::const_iterator lastCollRndm;
+  std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
+
+  if (m_rndmEvtOverlay) {
+
+    ATH_MSG_DEBUG("Prepare background container for MC Overlay procedure");
+
+    backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(true,
+                                                                            TileFragHash::Digitizer,
+                                                                            TileRawChannelUnit::ADCcounts);
+    ATH_CHECK( backgroundDigitContainer->status() );
+
+    if (m_onlyUseContainerName) {
+      typedef PileUpMergeSvc::TimedList<TileDigitsContainer>::type TimedDigitContList;
+      TimedDigitContList digitContList;
+      ATH_CHECK( m_mergeSvc->retrieveSubEvtsData(m_inputDigitContainerName, digitContList));
+      ATH_MSG_DEBUG( "TileDigitsCnt successfully retrieved ");
+
+      if (digitContList.size() == 0) {
+        ATH_MSG_WARNING( "No overlay done ... ");
+        return StatusCode::SUCCESS;
+      }
+
+      TimedDigitContList::iterator iTzeroDigitCont(digitContList.begin());
+      for (const auto* digitCollection : *(iTzeroDigitCont->second)) {
+        for (const auto* digit : *digitCollection) {
+          auto pDigits = std::make_unique<TileDigits>(*digit);
+          ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
+        }
+      }
+    } else {
+      SG::ReadHandle<TileDigitsContainer> tileDigitsContainerHandle(m_inputDigitContainerKey);
+      if (tileDigitsContainerHandle.isValid()) {
+        for (const auto* digitCollection : *tileDigitsContainerHandle) {
+          for (const auto* digit : *digitCollection) {
+            auto pDigits = std::make_unique<TileDigits>(*digit);
+            ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
+          }
+	}
+      } else {
+	ATH_MSG_ERROR("ReadHandle to Background Digits is invalid.");
+        return StatusCode::FAILURE;
+      }
+    }
+
+    collItrRndm = backgroundDigitContainer->begin();
+    lastCollRndm = backgroundDigitContainer->end();
+  }
 
   // Vector of digits to set into the container
   //
   std::vector<float> digitsBuffer(m_nSamples);
 
+  // Vector(s) for MC Overlay procedure
+  //
+  std::vector<float> digitsBuffer_rndm(m_nSamples);
+  std::vector<bool> good_bkg( 9 , false );
+
   // Prepare RNG service
+  //
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_randomStreamName);
   rngWrapper->setSeed( m_randomStreamName, Gaudi::Hive::currentContext() );
 
@@ -290,10 +370,69 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
     //
     m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
 
+    // **************************************************************
+    //
+    // Prepare buffer for MC Overlay procedure: pileup digits
+    //
+
+    memset(pDigitSamplesRndmArray, 0, sizeof(pDigitSamplesRndmArray));
+
+    if (m_rndmEvtOverlay && collItrRndm != lastCollRndm) {
+
+      const TileDigitsCollection *bkgDigitCollection(*collItrRndm);
+
+      if (hitCollection->identify() != bkgDigitCollection->identify()) {
+        ATH_MSG_ERROR ( "Frag IDs for hit collection and digits overlay collection do not match "
+                  << MSG::hex << hitCollection->identify() << " != " << bkgDigitCollection->identify()
+                  << MSG::dec );
+        return StatusCode::FAILURE;
+      }
+
+      ATH_MSG_DEBUG("Prepare buffer (digitsBuffer_rndm) for MC Overlay procdure: pileup digits");
+
+      for (const auto* bkgDigit : *bkgDigitCollection) {
+        bool good_channel = true;
+        /* Get digit HWIdentifier (= adc_id) */
+        HWIdentifier adc_id_rndm = (*bkgDigit).adc_HWID();
+        int channel = m_tileHWID->channel(adc_id_rndm);
+        ATH_MSG_VERBOSE ( "check channels from adc id in rndm container (TMDB channel): "<< channel );
+        /* Get digits */
+        digitsBuffer_rndm = (*bkgDigit).samples();
+        /* Get number of sample and compare with nSamples */
+        int nsamp_rndm = digitsBuffer_rndm.size();
+        if (nsamp_rndm != m_nSamples) {
+          digitsBuffer_rndm.resize(m_nSamples);
+          if (nsamp_rndm>0) {
+            for (int js=nsamp_rndm; js<m_nSamples; ++js) {
+              digitsBuffer_rndm[js] = digitsBuffer_rndm[js-1];
+            }
+          }
+        }
+        /* Fill the background digits array for the current channel and set a flag if any digit is NULL */
+        for (int j=0; j< m_nSamples;j++) {
+          pDigitSamplesRndmArray[channel][j] = digitsBuffer_rndm[j];
+          // If any digit is 0 something should be wrong so flag it in order to use during overlay the standard
+	  // path to fill the expected background level for that channel
+          if (pDigitSamplesRndmArray[channel][j]==0) good_channel = false;
+        }
+        good_bkg[channel] = good_channel;
+
+        if (msgLvl(MSG::VERBOSE)){
+            msg(MSG::VERBOSE) << " Digits from pileup background " << channel << " " << ros << " " << drawer << " " << m_tileHWID->to_string(adc_id_rndm)<<" | ";
+            for (int j=0; j< (int) digitsBuffer_rndm.size(); j++) msg(MSG::VERBOSE) << digitsBuffer_rndm[j] <<" | ";
+            msg(MSG::VERBOSE) << "---> | ";
+            for (int j=0; j< (int) digitsBuffer_rndm.size(); j++) msg(MSG::VERBOSE) << pDigitSamplesRndmArray[channel][j] << " | ";
+            msg(MSG::VERBOSE) << endmsg;
+        }
+      }
+      ++collItrRndm; // skip to next digi collection
+    }
+
     //////////////////////////////////////////////////////////////////////////////
     // (a.1) Iterate over all hits in a collection : access 'channel'
     //
-    if ( hitCollection->empty() ) ATH_MSG_DEBUG("-- No hits in this drawer! Filling channels with noise and pedestal. --");
+
+    if ( hitCollection->empty() ) ATH_MSG_DEBUG("-- No hits in this drawer! Filling channels with either noise and pedestal or MC pileup overlay. --");
 
     for (const TileHit* tile_hit : *hitCollection) {
 
@@ -305,10 +444,9 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
       // 
       int tower = m_tileID->tower(pmt_id);
       int sample = m_tileID->sample(pmt_id);
-      if ( ! ((sample == TileID::SAMP_D) || (sample == TileID::SAMP_BC && tower == 7)) )
-        continue;
+      if ( ! ((sample == TileID::SAMP_D) || (sample == TileID::SAMP_BC && tower == 7)) ) continue;
 
-      ATH_MSG_VERBOSE("(B.00) ++ Iterate over all the D layer channels with hits for TMDB");
+      ATH_MSG_VERBOSE("(B.00) ++ Iterate over all the D layer channels with hits");
 
       // In COOL database data will be organized acoording to TMDB channel (TMDBchan): 0..n with n=5 in EB and n=8 in LB 
       int TMDBchan;
@@ -316,35 +454,37 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
       int TILEchan;
 
       if (eb_ros) {
-        // cells D5, D6 and then D4 at the end
-        if (m_tileID->side(pmt_id) > 0)
-          TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
-        else
-          TMDBchan =     m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
-	TILEchan=EBchan[TMDBchan];
+         // cells D5, D6 and then D4 at the end
+         if (m_tileID->side(pmt_id) > 0)
+            TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
+         else
+            TMDBchan =     m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
+
+	 TILEchan=EBchan[TMDBchan];
       } else {
         // Barrel (extension for HL-LHC)
         if (tower == 0) {
-          TMDBchan = 0; // cell D0, channel 0 always
+           TMDBchan = 0; // cell D0, channel 0 always
         } else {
           // cells D1. D2, D3 and BC8
           if (m_tileID->side(pmt_id) > 0)
-            TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
+             TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
           else
-            TMDBchan =     m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
+             TMDBchan =     m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
         }
+
 	TILEchan=LBchan[TMDBchan];
       }
 
       double* pDigitSamples = pDigitSamplesArray[TMDBchan];
 
       if (msgLvl(MSG::VERBOSE)){
-        HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, TMDBchan, TileID::LOWGAIN);
+         HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, TMDBchan, TileID::LOWGAIN);
 
-        ATH_MSG_VERBOSE( "(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<" "<<TILEchan<< "=?"
+         ATH_MSG_VERBOSE( "(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<" "<<TILEchan<< "=?"
                          << m_tileHWID->channel(m_cablingService->s2h_channel_id(pmt_id))
                          << " For reference get TMDB adc_id: " << m_tileHWID->to_string(adc_id)  );
-        ATH_MSG_VERBOSE( "(B.02) New hit in ROS/DRAWER/PMT "<<ros<<"/"<<drawer<<"/"<<TMDBchan<<" ("<<TILEchan<<")"
+         ATH_MSG_VERBOSE( "(B.02) New hit in ROS/DRAWER/PMT "<<ros<<"/"<<drawer<<"/"<<TMDBchan<<" ("<<TILEchan<<")"
                          << " pmt_id "<< m_tileID->to_string(pmt_id,-1)
                          << " adc_id "<< m_tileHWID->to_string(adc_id)  );
       }
@@ -366,16 +506,13 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
 
       for (int ihit = 0; ihit < n_hits; ++ihit) {
 
-        ATH_MSG_VERBOSE("(C.00) ++ Iterating over the hits of channel " << TILEchan  <<": hit #" << ihit);
+        ATH_MSG_VERBOSE("(C.00) ++ Iterating over the hits of channel " << TILEchan <<": hit " << ihit <<"/"<< n_hits);
 
         double e_hit = tile_hit->energy(ihit); // [MeV] energy deposited in scintillator
-        double e_pmt = e_hit * hit_calib;       // [MeV] true cell energy
+        double e_pmt = e_hit * hit_calib;      // [MeV] true cell energy
 
         ATH_MSG_VERBOSE("(C.01) Energy in scintillator [MeV]: " << e_hit << " true cell energy [MeV]: " << e_pmt);
 
-        // Need to pass the negative of t_hit, this is because the trigger returns the amplitude
-        // at a given phase whereas the t_hit returns it from t=0 when the hit took place
-        //
         double t_hit = tile_hit->time(ihit);
 
         ATH_MSG_VERBOSE("(C.02.01) Phase " << t_hit);
@@ -432,68 +569,67 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
         } // END if (m_useCoolPulseShapes)
       } // END loop over sub-HITS
 
-      ATH_MSG_VERBOSE("(C.04)   ENDED Loop over hits");
-      ATH_MSG_DEBUG("   Number of hits " << n_hits
-                    << " channel " << m_tileHWID->to_string(drawer_id,-2) << "/" << TMDBchan << "<-->" << TILEchan
-                    << " digitized pulse [MeV] "<< pDigitSamples[0]
+      ATH_MSG_VERBOSE("++ ENDED Loop over hits for a channel");
+      ATH_MSG_DEBUG("(C.04) Went over " << n_hits << " hits for channel"
+                    << m_tileHWID->to_string(drawer_id,-2) << "/" << TMDBchan << " (" << TILEchan << ")"
+                    << " digits [MeV] "<< pDigitSamples[0]
                     << "/" << pDigitSamples[1]
                     << "/" << pDigitSamples[2]
                     << "/" << pDigitSamples[3]
                     << "/" << pDigitSamples[4]
                     << "/" << pDigitSamples[5]
                     << "/" << pDigitSamples[6]);
-
+      ATH_MSG_VERBOSE("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
     } // END loop over a HIT collection
 
-    /////////////////////////////////////////////////////////////////////////
-    // (a.3) The pulse has a shape and a amplitude in MeV now it is converted 
-    //       into ADC counts and add the NOISE and the PEDESTAL
+    ATH_MSG_VERBOSE("++ END loop over a HIT collection");
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    // (a.3) The pulse has a shape and a amplitude in MeV now it is converted into ADC
+    //       counts and either add NOISE and PEDESTAL or the OVERLAY digits
+    //
     //       PEDESTAL [ADC counts] and NOISE [ADC counts] as stored in Tile 
-    //       Conditions (for NOW are fixed values LATER from COOL)
+    //       Conditions (FIXED values but also flag for collection from COOL)
+    //
     //       Keep containers for each module (each partition) the same size 
-    //       between events
+    //       between events i.e. ALL channels are filled even with ZERO energy
     //
+
+    ATH_MSG_VERBOSE("++ START filling of channels with background either noise+pedestal or overlay");
+
     for (int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) {
 
       double* pDigitSamples=pDigitSamplesArray[TMDBchan];
       int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
 
       HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, TMDBchan, TileID::LOWGAIN); 
-      
-      ATH_MSG_DEBUG( "(D.00) ++ Add noise and pedestal in "
+
+      ATH_MSG_DEBUG( "(D.)        Going now to channel " << " TMDBchan: "   << TMDBchan << " TILEchan: " << TILEchan);
+      ATH_MSG_DEBUG( "(D.00)      Add noise and pedestal in "
                        << " TMDBchan: "   << TMDBchan << " TILEchan: " << TILEchan
                        << " ROS: "        << ros
                        << " drawer: "     << drawer
                        << " drawer idx: " << drawerIdx
                        << " drawer_id: "  << m_tileHWID->to_string(drawer_id,-2)
 		       << " channel: "    << m_tileHWID->to_string(adc_id,-1));
-
-      // Different for each channel_id might be the case in the future (now a const. in TileInfoLoader.cxx)
-      //
-      muRcv_NoiseSigma = m_tileInfo->MuRcvNoiseSigma(adc_id); // [adc]
-      // muRcv_Thresh = m_tileInfo->MuRcvThresh(adc_id);      // [adc] ... not used
-      muRcv_Ped   = m_tileInfo->MuRcvPed(adc_id);             // [adc]
-      muRcv_Calib = m_tileInfo->MuRcvCalib(adc_id);           // pCb->[adc]
-      muRcv_Max   = m_tileInfo->MuRcvMax(adc_id);             // [adc]
-
-      ATH_MSG_VERBOSE( "(D.01)   Tile Muon Receiver parameters:"
-                      << " sig " << muRcv_NoiseSigma
-                      << " noi " << muRcv_NoiseSigma
-                      << " ped " << muRcv_Ped
-                      << " cal " << muRcv_Calib
-                      << " max " << muRcv_Max);
-
       // adc/pCb / MeV/pCb = adc/MeV
       //
+      muRcv_Max   = m_tileInfo->MuRcvMax(adc_id);             // [adc]
+      muRcv_Calib = m_tileInfo->MuRcvCalib(adc_id);           // pCb->[adc]
       double mev2ADC_factor = muRcv_Calib / m_tileToolEmscale->channelCalib(drawerIdx,TILEchan,TileID::LOWGAIN, 1.
-                                                                            , TileRawChannelUnit::PicoCoulombs
-                                                                            , TileRawChannelUnit::MegaElectronVolts);
-
-      // Generate an array to randomize the noise for each digit
-      //
-      RandGaussQ::shootArray(*rngWrapper, m_nSamples, Rndm, 0.0, 1.0);
-
-      ATH_MSG_VERBOSE( "(D.02)   Pulse digits [MeV]:"
+                                                                      , TileRawChannelUnit::PicoCoulombs
+                                                                      , TileRawChannelUnit::MegaElectronVolts);
+      ATH_MSG_VERBOSE( "(D.01)   Channel: "<<ros<<'/'<<drawer<<'/'<< TMDBchan
+                << " adc/pCb: "<< muRcv_Calib
+                << " Mev/pCb: "<< m_tileToolEmscale->channelCalib( drawerIdx,
+                                                                   TILEchan,
+                                                                   TileID::LOWGAIN,
+                                                                   1.,
+                                                                   TileRawChannelUnit::PicoCoulombs,
+                                                                   TileRawChannelUnit::MegaElectronVolts)
+                << " final calibration factor adc/MeV: "<< mev2ADC_factor);
+
+      ATH_MSG_VERBOSE( "(D.02)      Pulse digits [MeV]:"
                        << " " << pDigitSamples[0]
                        << " " << pDigitSamples[1]
                        << " " << pDigitSamples[2]
@@ -503,107 +639,151 @@ StatusCode TilePulseForTileMuonReceiver::execute() {
                        << " " << pDigitSamples[6]
                        << " [All ZERO if there is no hit in channel.] ");
 
-      ATH_MSG_VERBOSE( "(D.02.00)   Channel: "<<ros<<'/'<<drawer<<'/'<< TMDBchan
-                      << " adc/pCb: "<< muRcv_Calib
-                      << " Mev/pCb: "<< m_tileToolEmscale->channelCalib( drawerIdx, 
-                                                                         TILEchan, 
-                                                                         TileID::LOWGAIN, 
-                                                                         1., 
-                                                                         TileRawChannelUnit::PicoCoulombs, 
-                                                                         TileRawChannelUnit::MegaElectronVolts)
-                      << " final calibration factor adc/MeV: "<< mev2ADC_factor);
-
-      // Collecting pedestal from the database
-      //
-      if (m_tilePedestal) {
-        pedSim = m_tileToolNoiseSample->getPed(idhash, TMDBchan, TileID::LOWGAIN);
-        // As in TileDigitsMaker bug fix for wrong ped value in DB
-	//
-        if (pedSim == 0.0) pedSim = 30.;
+      if ( good_bkg[TMDBchan] ) {
+        // Collecting digits for MC Overlay procedure from overlay container
+        // IF good digits ere collected (no ZEROS <> good_bkg[TMDBchan]==true) then add the background to the simulated digits
+        // ELSE bad digits (any ZEROS <> good_bkg[TMDBchan]==false) then follow the standard path adding muRcv_Ped and muRvc_NoiseSigma
+
+        ATH_MSG_DEBUG("++ Adding to signal digits -- The MC PILE-UP OVERLAY digits " << m_rndmEvtOverlay << " " << m_integerDigits);
+
+        for (int js = 0; js < m_nSamples; ++js) {
+          // Signal
+          //
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<") sample "<< js+1 <<" E_{Signal} [adc]: "<< pDigitSamples[js] * mev2ADC_factor <<" -- Overlay");
+          digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
+          // Pileup
+          //
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<") sample "<< js+1 <<" E_{PileUp} [adc]: "<< pDigitSamplesRndmArray[TMDBchan][js] <<" -- Overlay");
+          digitsBuffer[js] += pDigitSamplesRndmArray[TMDBchan][js];
+          // Simulated pulse above allowed maximum
+          //
+          if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
+          // Rounding the ADC counts
+	  //
+          if (m_integerDigits) digitsBuffer[js] = round(digitsBuffer[js]);
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<") sample "<< js+1 <<" calibration [adc/MeV] "<< mev2ADC_factor <<"-> E_{Signal+PileUp} [adc]: "<< digitsBuffer[js] <<" -- Overlay");
+        }
       } else {
-        pedSim = muRcv_Ped;
-      }
-      // Collecting noise from the database
-      //
-      if (m_tileNoise) {
-        RandFlat::shootArray(*rngWrapper, 1, Rndm_dG, 0.0, 1.0);
-        sigma_Hfn1 = m_tileToolNoiseSample->getHfn1(idhash, TMDBchan, TileID::LOWGAIN);
-        sigma_Hfn2 = m_tileToolNoiseSample->getHfn2(idhash, TMDBchan, TileID::LOWGAIN);
-        if (sigma_Hfn1 > 0 || sigma_Hfn2) {
-          sigma_Norm = sigma_Hfn1 / (sigma_Hfn1 + sigma_Hfn2 * m_tileToolNoiseSample->getHfnNorm(idhash, TMDBchan, TileID::LOWGAIN));
+        if (m_rndmEvtOverlay) ATH_MSG_INFO("At least one digit is zero in background file using the stadart path to fill pedestal and noise in digits");
+        // Different for each channel_id might be the case in the future (now a const. in TileInfoLoader.cxx)
+        //
+        muRcv_NoiseSigma = m_tileInfo->MuRcvNoiseSigma(adc_id); // [adc]
+        muRcv_Ped   = m_tileInfo->MuRcvPed(adc_id);             // [adc]
+
+        ATH_MSG_VERBOSE( "(D.03)      Tile Muon Receiver parameters:"
+                 << " noi " << muRcv_NoiseSigma
+                 << " ped " << muRcv_Ped
+                 << " cal " << muRcv_Calib
+                 << " max " << muRcv_Max);
+
+        // Collecting digits for standard procedure NO OVERLAY: pedestal+noise
+        // ADD digitsBuffer[m_nSamples] WITH Ped and Noise from COOLDB/ATHENA
+        //
+        ATH_MSG_DEBUG("++ Adding to signal digits -- The PEDESTAL + NOISE digits "<< m_tilePedestal <<" "<< m_tileNoise << " " << m_integerDigits);
+        // Collecting pedestal from the database
+        //
+        if (m_tilePedestal) {
+          pedSim = m_tileToolNoiseSample->getPed(idhash, TMDBchan, TileID::LOWGAIN);
+          // As in TileDigitsMaker bug fix for wrong ped value in DB
+          //
+          if (pedSim == 0.0) pedSim = 30.;
         } else {
-          sigma_Hfn1 = m_tileToolNoiseSample->getHfn(idhash, TMDBchan, TileID::LOWGAIN);
-          sigma_Norm = 1.;
+          pedSim = muRcv_Ped;
         }
-        if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
-        else sigmaSim = sigma_Hfn2;
-      } else {
-        sigmaSim = muRcv_NoiseSigma;
-      }
-      // Loop over samples and either use noise and ped from db or user location (TileInfoLoader.cxx)
-      //
-      for (int js = 0; js < m_nSamples; ++js) {
-        ATH_MSG_VERBOSE( "(D.02.0"<< js <<")   sample "<< js <<" E [MeV]: "<< pDigitSamples[js]);
-        digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
-        ATH_MSG_VERBOSE( "(D.02.0"<< js <<")   sample "<< js <<" calibration Mev->adc "<< mev2ADC_factor <<"-> E [adc]: "<< digitsBuffer[js]);
-        // Pedestal (amp)
-	//
-        digitsBuffer[js] += pedSim;
-        ATH_MSG_VERBOSE( "(D.02.0"<< js <<")   sample "<< js <<" adding pedestal "<< pedSim <<"-> E [adc]: "<< digitsBuffer[js]);
-        // Noise (rms)
-	//
-        digitsBuffer[js] += sigmaSim * Rndm[js];
-        ATH_MSG_VERBOSE( "(D.02.0"<< js <<")   sample "<< js <<" adding noise "<< sigmaSim * Rndm[js] <<"-> E [adc]: "<< digitsBuffer[js]);
-        // Simulated pulse above allowed maximum
+        // Collecting noise from the database
         //
-        if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
-        // Rounding the ADC counts
+        if (m_tileNoise) {
+          // Generate an array to randomize the noise for each digit
+          //
+          RandGaussQ::shootArray(*rngWrapper, m_nSamples, Rndm, 0.0, 1.0);
+          RandFlat::shootArray(*rngWrapper, 1, Rndm_dG, 0.0, 1.0);
+          sigma_Hfn1 = m_tileToolNoiseSample->getHfn1(idhash, TMDBchan, TileID::LOWGAIN);
+          sigma_Hfn2 = m_tileToolNoiseSample->getHfn2(idhash, TMDBchan, TileID::LOWGAIN);
+          if (sigma_Hfn1 > 0 || sigma_Hfn2) {
+            sigma_Norm = sigma_Hfn1 / (sigma_Hfn1 + sigma_Hfn2 * m_tileToolNoiseSample->getHfnNorm(idhash, TMDBchan, TileID::LOWGAIN));
+          } else {
+            sigma_Hfn1 = m_tileToolNoiseSample->getHfn(idhash, TMDBchan, TileID::LOWGAIN);
+            sigma_Norm = 1.;
+          }
+          if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
+          else sigmaSim = sigma_Hfn2;
+        } else {
+          sigmaSim = muRcv_NoiseSigma;
+        }
+        // Loop over samples and either use noise and ped from db or user location (TileInfoLoader.cxx)
         //
-        if (m_integerDigits) digitsBuffer[js] = round(digitsBuffer[js]);
+        for (int js = 0; js < m_nSamples; ++js) {
+          // Signal
+          //
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<")   sample "<< js+1 <<" E [MeV]: "<< pDigitSamples[js]);
+          digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<")   sample "<< js+1 <<" calibration [adc/MeV] "<< mev2ADC_factor <<"-> E [adc]: "<< digitsBuffer[js]);
+          // Pedestal (amp)
+          //
+          digitsBuffer[js] += pedSim;
+          ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<")   sample "<< js+1 <<" adding pedestal "<< pedSim <<"-> E [adc]: "<< digitsBuffer[js]);
+          // Noise (rms)
+          //
+          if (m_tileNoise) {
+            digitsBuffer[js] += sigmaSim * Rndm[js];
+            ATH_MSG_VERBOSE( "(D.02.0"<< js+1 <<")   sample "<< js+1 <<" adding noise "<< sigmaSim * Rndm[js] <<"-> E [adc]: "<< digitsBuffer[js]);
+          }
+          // Simulated pulse above allowed maximum
+          //
+          if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
+          // Rounding the ADC counts
+          //
+          if (m_integerDigits) digitsBuffer[js] = round(digitsBuffer[js]);
+        }
       }
+
       // If channel is good, create TileDigits object and store in container.
       //
       bool chanIsBad = false;
+
       if (m_maskBadChannels) {
         TileBchStatus status = m_tileBadChanTool->getAdcStatus(drawerIdx, TILEchan, TileID::LOWGAIN);
         chanIsBad = status.isBad();
       }
+
       if (chanIsBad) {
         for (int js = 0; js < m_nSamples; ++js) {
-          digitsBuffer[js] = 255;// in TMDB we have 8-bit ADCs
+           digitsBuffer[js] = 255;// in TMDB we have 8-bit ADCs
         }
         ATH_MSG_VERBOSE( "(D.03)   Masking Channel: "<< ros << '/' << drawer << '/' << TILEchan <<" ("<< TMDBchan <<") LowGain" );
       } else {
-        ATH_MSG_VERBOSE( "(D.03)   Good Channel: "<< ros << '/' << drawer << '/' << TILEchan <<" ("<< TMDBchan <<") LowGain" );
+        ATH_MSG_VERBOSE( "(D.03)   Good Channel   : "<< ros << '/' << drawer << '/' << TILEchan <<" ("<< TMDBchan <<") LowGain" );
       }
-      ATH_MSG_VERBOSE( "(D.04)   Changed to TMDB adc_id: " << m_tileHWID->to_string(adc_id) 
-                       << " and create a TileDigits object and set it into a container." );
+
+      ATH_MSG_VERBOSE( "++ Changed to TMDB adc_id: " << m_tileHWID->to_string(adc_id) << " and save a TileDigits object into a container." );
       std::unique_ptr<TileDigits> muonReceiverDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
-      ATH_MSG_VERBOSE( "(D.05)   Create a TileRawChannelObject object and set it into a container " );
+      ATH_MSG_VERBOSE( "++ Create a TileRawChannelObject object and set it into a container " );
       TileRawChannel* muRcvRawChannel = m_MuRcvBuildTool->rawChannel(muonReceiverDigits.get());
       ATH_CHECK( muRcvDigitsContainer->push_back(std::move(muonReceiverDigits)) );
       ATH_CHECK( muRcvRawChannelContainer->push_back(muRcvRawChannel) );
       if (msgLvl(MSG::DEBUG)){
-        ATH_MSG_DEBUG( " Channel " << m_tileHWID->to_string(adc_id,-1) 
-                       << " Digitized pulse [ADC] "<< digitsBuffer[0]
-                       << "/" << digitsBuffer[1]
-                       << "/" << digitsBuffer[2]
-                       << "/" << digitsBuffer[3]
-                       << "/" << digitsBuffer[4]
-                       << "/" << digitsBuffer[5]
-                       << "/" << digitsBuffer[6]  );
-        ATH_MSG_DEBUG( " Raw channel reconstruction Ch: "<< m_tileHWID->to_string(adc_id,-1)
-                       <<" E [ADC]: "<< muRcvRawChannel->amplitude()
-                       <<" Time [ns]: "<< muRcvRawChannel->time()
-                       <<" Qf: "<< muRcvRawChannel->quality()  );
+        ATH_MSG_DEBUG( "++ Channel " << m_tileHWID->to_string(adc_id,-1)
+                     << " Digitized pulse [ADC] "<< digitsBuffer[0]
+                     << "/" << digitsBuffer[1]
+                     << "/" << digitsBuffer[2]
+                     << "/" << digitsBuffer[3]
+                     << "/" << digitsBuffer[4]
+                     << "/" << digitsBuffer[5]
+                     << "/" << digitsBuffer[6]  );
+        ATH_MSG_DEBUG( "++ Raw channel reconstruction Ch: "<< m_tileHWID->to_string(adc_id,-1)
+                     <<" E [ADC]: "<< muRcvRawChannel->amplitude()
+                     <<" Time [ns]: "<< muRcvRawChannel->time()
+                     <<" Qf: "<< muRcvRawChannel->quality()  );
       }
     }
   } // END loop over all HIT collections in container
   if (msgLvl(MSG::VERBOSE)) muRcvDigitsContainer->print();
-  // (b) Register the digits container in the TES
+
+  /////////////////////////////////////////////////////////////////////////
+  // (a.4) Register the digits container in the TES
   //
-  ATH_MSG_VERBOSE ( "(A.05)   Send to event store all collected objects " );
 
+  ATH_MSG_VERBOSE ( "(A.05)   Send to event store all collected objects " );
 
   SG::WriteHandle<TileDigitsContainer> muRcvDigitsCnt(m_muRcvDigitsContainerKey);
   ATH_CHECK( muRcvDigitsCnt.record(std::move(muRcvDigitsContainer)) );
diff --git a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.h b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.h
index d46d58126d0dad749992bc8f36e49c71d9a9ff56..b7672882d6beb6b4bb86e74e361a192554938ec2 100644
--- a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.h
+++ b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //****************************************************************************
@@ -24,9 +24,10 @@
 //    UseCoolPedestal                 "Pedestal from database (default=false)"
 //    RndmSvc                         "Random Number Service used in TilePulseForTileMuonReceiver" 
 //    TileRawChannelBuilderMF         "The tool by default is the Matched Filter"
+//    UseRndmEvtOverlay               "Pileup and/or noise added by overlaying rando events (default=false)"
 //
 // BUGS:
-//  
+//
 // History:
 //  
 //  
@@ -55,6 +56,8 @@
 #include "GaudiKernel/ToolHandle.h"
 #include "GaudiKernel/ServiceHandle.h"
 
+#include "CLHEP/Random/RandomEngine.h"
+
 class IAthRNGSvc;
 class PileUpMergeSvc;
 class HWIdentifier;
@@ -83,6 +86,9 @@ class TilePulseForTileMuonReceiver: public AthAlgorithm {
 
   private:
 
+    SG::ReadHandleKey<TileDigitsContainer> m_inputDigitContainerKey{this, "InputTileDigitContainer","",""};
+    std::string m_inputDigitContainerName{""};
+
     SG::ReadHandleKey<TileHitContainer> m_hitContainerKey{this,
         "TileHitContainer","TileHitCnt", "Input Tile hit container key"};
 
@@ -123,13 +129,15 @@ class TilePulseForTileMuonReceiver: public AthAlgorithm {
     Gaudi::Property<bool> m_useCoolPulseShapes{this, "UseCoolPulseShapes", false, "Pulse shapes from database (default=false)"};
     Gaudi::Property<bool> m_tileNoise{this, "UseCoolNoise", false, "Noise from database (default=false)"};
     Gaudi::Property<bool> m_tilePedestal{this, "UseCoolPedestal", false, "Pedestal from database (default=false)"};
+    Gaudi::Property<bool> m_rndmEvtOverlay{this, "RndmEvtOverlay", false, "Pileup and/or noise added by overlaying random events (default=false)"};
+    Gaudi::Property<bool> m_onlyUseContainerName{this, "OnlyUseContainerName", true, "Don't use the ReadHandleKey directly. Just extract the container name from it."};
 
     const TileID* m_tileID;
     const TileHWID* m_tileHWID;
     const TileInfo* m_tileInfo;
     const TileCablingService* m_cablingService; //!< TileCabling instance
 
-    int m_nSamples;          //!< Number of time slices for each channel
+    int m_nSamples;       //!< Number of time slices for each channel
     int m_iTrig;          //!< Index of the triggering time slice
     int m_adcMax;         //!< ADC saturation value
     double m_tileThresh;  //!< Actual threshold value
@@ -141,12 +149,12 @@ class TilePulseForTileMuonReceiver: public AthAlgorithm {
     int m_binTime0;     //!< Index of time=0 bin for pulse shape
     double m_timeStep;  //!< Time step in pulse shape: 25.0 / nBinsPerX
 
+    PileUpMergeSvc* m_mergeSvc;         //!< Pointer to PileUpMergeService
     // vector container for the pulse shape
     //
     std::vector<double> m_shapeMuonReceiver;//!< Muon receiver pulse shape
 
-    
-    bool m_run2;
+    int m_runPeriod;
 };
 
 #endif
diff --git a/Tools/PROCTools/python/RunTier0TestsTools.py b/Tools/PROCTools/python/RunTier0TestsTools.py
index dbd129d34e99c6360267b2882bd284c43f9f8ad9..04e9076c566e00b7b07519b90a3cbae305cadeca 100644
--- a/Tools/PROCTools/python/RunTier0TestsTools.py
+++ b/Tools/PROCTools/python/RunTier0TestsTools.py
@@ -31,7 +31,7 @@ ciRefFileMap = {
                 # OverlayTier0Test_required-test
                 'overlay-d1498-21.0'   : 'v2',
                 'overlay-d1498-22.0'   : 'v38',
-                'overlay-d1592-22.0'   : 'v5',
+                'overlay-d1592-22.0'   : 'v6',
                 'overlay-bkg-21.0'     : 'v1',
                 'overlay-bkg-22.0'     : 'v4',
                 'dataoverlay-d1590-22.0' : 'v8',