diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
index 87150e0c552cf97a02eefa15ff912eeaa433ff3f..91d82bc2fc97e07e11e66318354ab2591d17902b 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
+++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
@@ -10,6 +10,7 @@
 #include <string>
 #include <iostream>
 #include <cassert>
+#include <atomic>
 #include <stdint.h>
 
 // Gaudi includes
@@ -53,6 +54,35 @@ class TileCellBuilder;
 class TileL2Builder;
 class TileHid2RESrcID;
 
+namespace TileROD_Helper {
+
+
+// Helper to find the Tile container type corresponding to a container.
+template <class COLLECTION>
+struct ContainerForCollection {};
+
+template <>
+struct ContainerForCollection<TileBeamElemCollection>
+{
+  typedef TileBeamElemContainer type;
+};
+
+template <>
+struct ContainerForCollection<TileDigitsCollection>
+{
+  typedef TileDigitsContainer type;
+};
+
+template <>
+struct ContainerForCollection<TileRawChannelCollection>
+{
+  typedef TileRawChannelContainer type;
+};
+
+
+} // namespace TileROD_Helper
+
+
 /**
  *
  * @class TileROD_Decoder
@@ -113,7 +143,9 @@ class TileROD_Decoder: public AthAlgTool {
     /** This method calls the unpacking methods to decode the ROD data and fills
      the TileDigitsContainer and/or the TileRawChannelContainer
      */
-    void fillCollection(const ROBData * rob, COLLECTION& v);
+    void fillCollection(const ROBData * rob,
+                        COLLECTION& v,
+                        typename TileROD_Helper::ContainerForCollection<COLLECTION>::type* container = nullptr);
     uint32_t fillCollectionHLT(const ROBData * rob, TileCellCollection & v,
                                D0CellsHLT& d0cells);
     void fillCollectionL2(const ROBData * rob, TileL2Container & v);
@@ -140,8 +172,6 @@ class TileROD_Decoder: public AthAlgTool {
 
     void mergeD0cellsHLT (const D0CellsHLT& d0cells, TileCellCollection&);
 
-    // Set Pointer to container with raw channels
-    inline void PtrRChContainer(TileRawChannelContainer * container) { m_container = container; }
     void loadRw2Pmt(const int section, const std::vector<int>& vec) {
       for (unsigned int i = 0; i < vec.size(); ++i) {
         //	std::cout << vec[i] << std::endl;
@@ -149,6 +179,7 @@ class TileROD_Decoder: public AthAlgTool {
       }
     }
 
+    // Error reporting
     void printErrorCounter(bool printIfNoError);
     int getErrorCounter();
 
@@ -417,24 +448,28 @@ class TileROD_Decoder: public AthAlgTool {
                           DigitsMetaData_t& digitsMetaData,
                           RawChannelMetaData_t& rawchannelMetaData,
                           const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel,
-        TileBeamElemCollection& v) const;
+                          TileBeamElemCollection& v,
+                          TileBeamElemContainer* container) const;
     inline void make_copy(uint32_t bsflags,
                           TileFragHash::TYPE rChType,
                           TileRawChannelUnit::UNIT rChUnit,
                           DigitsMetaData_t& digitsMetaData,
                           RawChannelMetaData_t& rawchannelMetaData,
                           const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel,
-        TileDigitsCollection& v) const;
+                          TileDigitsCollection& v,
+                          TileDigitsContainer* container) const;
     inline void make_copy(uint32_t bsflags,
                           TileFragHash::TYPE rChType,
                           TileRawChannelUnit::UNIT rChUnit,
                           DigitsMetaData_t& digitsMetaData,
                           RawChannelMetaData_t& rawchannelMetaData,
                           const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel,
-        TileRawChannelCollection& v) const;
+                          TileRawChannelCollection& v,
+                          TileRawChannelContainer* container) const;
 
     uint32_t make_copyHLT(bool of2,
                           TileRawChannelUnit::UNIT rChUnit,
+                          bool correctAmplitude,
                           pFRwChVec & pChannel, TileCellCollection& v, const uint16_t DQuality,
                           D0CellsHLT& d0cells);
 
@@ -520,9 +555,6 @@ class TileROD_Decoder: public AthAlgTool {
 
     bool m_of2Default;
 
-    // TileRawChannelContainer
-    TileRawChannelContainer * m_container;
-
     bool m_maskBadDigits;
     // Pointer to a MBTS cell collection
     TileCellCollection* m_MBTS;
@@ -538,9 +570,8 @@ class TileROD_Decoder: public AthAlgTool {
     TileL2Builder* m_L2Builder;
     std::string m_TileDefaultL2Builder;
 
-    int m_WarningCounter;
-    int m_ErrorCounter;
-    bool m_correctAmplitude;
+    mutable std::atomic<int> m_WarningCounter;
+    mutable std::atomic<int> m_ErrorCounter;
 
     TileHid2RESrcID * m_hid2re;
     TileHid2RESrcID * m_hid2reHLT;
@@ -574,7 +605,7 @@ class TileROD_Decoder: public AthAlgTool {
         max_allowed_size = 0;
       if (size < 3 && size > 0) {
         if (rob->rod_source_id() > 0x50ffff) error |= 0x10000; // indicate error in frag size, but ignore error in laser ROD
-        if (m_WarningCounter < (m_maxWarningPrint--)) {
+        if (m_WarningCounter++ < m_maxWarningPrint) {
           ATH_MSG_WARNING("ROB " << MSG::hex << rob->source_id()
               << " ROD " << rob->rod_source_id() << MSG::dec
               << " has unexpected data size: " << size << " - assuming zero size " );
@@ -582,7 +613,7 @@ class TileROD_Decoder: public AthAlgTool {
         return 0;
       } else if (rob->rod_header_size_word() >= rob->rod_fragment_size_word()) {
         if (rob->rod_source_id() > 0x50ffff) error |= 0x10000; // indicate error in frag size, but ignore error in laser ROD
-        if (m_WarningCounter < (m_maxWarningPrint--)) {
+        if (m_WarningCounter++ < m_maxWarningPrint) {
           ATH_MSG_WARNING("ROB " << MSG::hex << rob->source_id()
               << " ROD " << rob->rod_source_id() << MSG::dec
               << " has unexpected header size: " << rob->rod_header_size_word()
@@ -655,7 +686,9 @@ void TileROD_Decoder::make_copy(uint32_t /*bsflags*/,
                                 DigitsMetaData_t& digitsMetaData,
                                 RawChannelMetaData_t& /*rawchannelMetaData*/,
                                 const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel,
-    TileDigitsCollection & v) const {
+                                TileDigitsCollection & v,
+                                TileDigitsContainer* /*container*/) const
+{
   copy_vec(pDigits, v); // Digits stored
 
   if (pChannel.size() > 0) { // RawChannels deleted
@@ -705,15 +738,16 @@ void TileROD_Decoder::make_copy(uint32_t bsflags,
                                 DigitsMetaData_t& /*digitsMetaData*/,
                                 RawChannelMetaData_t& rawchannelMetaData,
                                 const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel,
-    TileRawChannelCollection & v) const {
+                                TileRawChannelCollection & v,
+                                TileRawChannelContainer* container) const {
   if (pChannel.size() > 0) { // take available raw channels
                              // and store in collection
-    if (m_container) {
+    if (container) {
       ATH_MSG_VERBOSE( "RawChannel unit is " << rChUnit
                       << "  - setting unit in TileRawChannelContainer " );
-      m_container->set_unit(rChUnit);
-      m_container->set_type(rChType);
-      m_container->set_bsflags(bsflags);
+      container->set_unit(rChUnit);
+      container->set_type(rChType);
+      container->set_bsflags(bsflags);
     } else {
       ATH_MSG_ERROR( "Can't set unit=" << rChUnit << " in TileRawChannelContainer" );
     }
@@ -788,8 +822,10 @@ void TileROD_Decoder::make_copy(uint32_t /*bsflags*/,
                                 TileRawChannelUnit::UNIT /*rChUnit*/,
                                 DigitsMetaData_t& /*digitsMetaData*/,
                                 RawChannelMetaData_t& /*rawchannelMetaData*/,
-                                const ROBData * /* rob */, pDigiVec & pDigits
-    , pRwChVec & pChannel, TileBeamElemCollection &) const {
+                                const ROBData * /* rob */, pDigiVec & pDigits,
+                                pRwChVec & pChannel, TileBeamElemCollection &,
+                                TileBeamElemContainer* /*container*/) const
+{
   // do nothing
   delete_vec(pDigits);
   delete_vec(pChannel);
@@ -835,7 +871,10 @@ void TileROD_Decoder::make_copy(const ROBData * /* rob */, pBeamVec & pBeam,
  from a BLOCK of integers
  */
 template<class COLLECTION>
-void TileROD_Decoder::fillCollection(const ROBData * rob, COLLECTION & v) {
+void TileROD_Decoder::fillCollection(const ROBData * rob,
+                                     COLLECTION & v,
+                                     typename TileROD_Helper::ContainerForCollection<COLLECTION>::type* container /*= nullptr*/)
+{
   //
   // get info from ROD header
   //
@@ -1098,7 +1137,7 @@ void TileROD_Decoder::fillCollection(const ROBData * rob, COLLECTION & v) {
     } // end of all frags
 
     make_copy(bsflags, rChType, rChUnit, digitsMetaData, rawchannelMetaData,
-              rob, pDigits, pChannel, v);
+              rob, pDigits, pChannel, v, container);
   }
 
   return;
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
index b53400efa7625766b225dd605ba52318215b0379..549197768eeb1922eaa21090094784c1ed257558 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
@@ -67,13 +67,11 @@ TileROD_Decoder::TileROD_Decoder(const std::string& type, const std::string& nam
   declareProperty("AllowedTimeMax", m_allowedTimeMax =  50.); // set amp to zero if time is above allowed time max
   declareProperty("fullTileMode", m_fullTileRODs); // run from which to take the cabling (for the moment, either 320000 - full 2017 mode - or 0 - 2016 mode)
 
-  m_correctAmplitude = false;
   updateAmpThreshold(15.);
   m_timeMinThresh = -25;
   m_timeMaxThresh = 25;
-  
+
   m_of2Default = true;
-  m_container = 0;
   m_MBTS = NULL;
   m_cell2Double.reserve(23); // Maximum number of cells in a drawer
   m_WarningCounter = 0;
@@ -3288,6 +3286,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
     }
   }
   bool of2 = m_of2Default;
+  bool correctAmplitude = false;
   TileRawChannelUnit::UNIT rChUnit = TileRawChannelUnit::ADCcounts;
   uint16_t DQuality = 0x0;
   bool fragFound = false;
@@ -3332,13 +3331,13 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
         case 2:
           fragFound = true;
           DQfragMissing = false;
-          m_correctAmplitude = false;
+          correctAmplitude = false;
           unpack_frag2HLT(version, sizeOverhead, p, m_pRwChVec);
           break;
         case 3:
           fragFound = true;
           DQfragMissing = false;
-          m_correctAmplitude = false;
+          correctAmplitude = false;
           unpack_frag3HLT(version, sizeOverhead, p, m_pRwChVec);
           break;
         case 4:
@@ -3352,13 +3351,13 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
               
               of2 = ((idAndType & 0x4000000) != 0);
               int nIter = (idAndType & 0x3000000) >> 24;
-              m_correctAmplitude = (!nIter); // automatic detection of nIter
+              correctAmplitude = (!nIter); // automatic detection of nIter
               rChUnit = (TileRawChannelUnit::UNIT) (unit + TileRawChannelUnit::OnlineOffset); // Online units in real data
               
             } else { // simulated data
               
               DQfragMissing = false;
-              m_correctAmplitude = false;
+              correctAmplitude = false;
               rChUnit = (TileRawChannelUnit::UNIT) (unit); // Offline units in simulated data
             }
             
@@ -3372,7 +3371,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
             int unit = (idAndType & 0xC0000000) >> 30;
             
             of2 = ((idAndType & 0x4000000) != 0);
-            m_correctAmplitude = true; // fragment 5 will appear only if there is no iterations, so correction required
+            correctAmplitude = true; // fragment 5 will appear only if there is no iterations, so correction required
             rChUnit = (TileRawChannelUnit::UNIT) (unit + TileRawChannelUnit::OnlineOffset);
             
             unpack_frag5HLT(version, sizeOverhead, unit, p, m_pRwChVec);
@@ -3399,7 +3398,8 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
   
   if (fragFound) {
     if (masked_drawer) DQuality = 0x0;
-    error |= make_copyHLT(of2, rChUnit, m_pRwChVec, v, DQuality, d0cells);
+    error |= make_copyHLT(of2, rChUnit, correctAmplitude,
+                          m_pRwChVec, v, DQuality, d0cells);
   } else if (!masked_drawer) error |= 0x20000;
   
   return error;
@@ -3407,6 +3407,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect
 
 uint32_t TileROD_Decoder::make_copyHLT(bool of2,
                                        TileRawChannelUnit::UNIT rChUnit,
+                                       bool correctAmplitude,
                                        pFRwChVec & pChannel, TileCellCollection & v,
                                        const uint16_t DQuality,
                                        D0CellsHLT& d0cells) {
@@ -3476,7 +3477,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2,
                                                  TileRawChannelUnit::MegaElectronVolts);
         }
         // parabolic correction for good but slightly out-of-time signals
-        if (m_correctAmplitude) {
+        if (correctAmplitude) {
           if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
             ener = 0.0F;
             time = 0.0F;
@@ -3533,7 +3534,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2,
                                                    TileRawChannelUnit::MegaElectronVolts);
           }
           // parabolic correction for good but slightly out-of-time signals
-          if (m_correctAmplitude) {
+          if (correctAmplitude) {
             if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
               ener = 0.0F;
               time = 0.0F;
@@ -3590,7 +3591,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2,
                                                    rChUnit, TileRawChannelUnit::PicoCoulombs);
           }
           // parabolic correction for good but slightly out-of-time signals
-          if (m_correctAmplitude) {
+          if (correctAmplitude) {
             if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
               ener = 0.0F;
               time = 0.0F;
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx
index 9606fec1e4d97cf879198d4785d53f9d6e9ed83f..9b22d6beb86e4a80b203b66fa0b1e84cc015ace1 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx
@@ -80,7 +80,6 @@ StatusCode TileRawChannelContByteStreamCnv::initialize() {
   unit = TileRawChannelUnit::ADCcounts;
   m_containers[0] = new TileRawChannelContainer(true, type, unit); 
   m_containers[0]->addRef(); // make sure it's not deleted at the end of event
-  m_decoder->PtrRChContainer( m_containers[0] );
 
   type = TileFragHash::MF;
   unit = TileRawChannelUnit::ADCcounts;
@@ -147,7 +146,7 @@ StatusCode TileRawChannelContByteStreamCnv::createObj(IOpaqueAddress* pAddr, Dat
         if (isTMDB) {// reid for TMDB 0x5x010x
 	  m_decoder->fillCollection_TileMuRcv_RawChannel(robf[0], *rawChannelCollection);
         } else {
-          m_decoder->fillCollection(robf[0], *rawChannelCollection);
+          m_decoder->fillCollection(robf[0], *rawChannelCollection, m_containers[icnt]);
         }
       } else {
         rawChannelCollection->setFragGlobalCRC(TileROD_Decoder::NO_ROB);
diff --git a/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx b/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx
index 276a313e66160d9bb5034f65a1b3ef28a5c8e9e6..3f928b283108b30861e25632d2140d60d39a9907 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx
@@ -148,8 +148,7 @@ void test1 (TileROD_Decoder* decoder)
   {
     TileRawChannelContainer cont;
     TileRawChannelCollection coll (256);
-    decoder->PtrRChContainer (&cont);
-    decoder->fillCollection (&data01.rob(), coll);
+    decoder->fillCollection (&data01.rob(), coll, &cont);
     std::cout << "TileRawChannelCollection: " << coll.size() << " "
               << cont.get_unit() << " "
               << cont.get_type() << " "