diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/CMakeLists.txt b/TileCalorimeter/TileCalib/TileCalibBlobObjs/CMakeLists.txt
index abd78ab1797b0d481037510f33f2b465a6612d7b..277bec86c0e0cd829b0f107901ff05cbf7ad1427 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/CMakeLists.txt
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/CMakeLists.txt
@@ -5,9 +5,6 @@
 # Declare the package name:
 atlas_subdir( TileCalibBlobObjs )
 
-atlas_depends_on_subdirs( PRIVATE
-                          AtlasTest/TestTools )
-
 # External dependencies:
 find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess )
 find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
@@ -20,7 +17,7 @@ atlas_add_library( TileCalibBlobObjs
                    PUBLIC_HEADERS TileCalibBlobObjs
                    INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
                    PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${CORAL_LIBRARIES}
+                   LINK_LIBRARIES CxxUtils ${CORAL_LIBRARIES}
                    PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} )
 
 atlas_add_dictionary( TileCalibBlobObjsDict
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/ATLAS_CHECK_THREAD_SAFETY b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..5475dd5db21812f27da21a55f500c9f2f990ffe0
--- /dev/null
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+TileCalorimeter/TileCalib/TileCalibBlobObjs
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/Exception.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/Exception.h
index 5bca938e15543fe40a61511fe311d4609b98bdeb..eb48dee0534e08368e1e18df67d4e78f2c60ccff 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/Exception.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/Exception.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBBLOBOBJS_EXCEPTION_H
@@ -22,13 +22,14 @@ namespace TileCalib {
   class Exception : public std::exception {
   public:
     explicit Exception( const std::string& domain, const std::string& message)
-      : m_domain(domain), m_message(message){}
+      : m_domain(domain), m_message(message)
+    {
+      format();
+    }
     virtual ~Exception() throw() {}
 
     virtual const char* what() const throw(){
-      static std::string result;
-      result = m_domain + ": "+ m_message;
-      return result.c_str();
+      return m_result.c_str();
     }
     
     virtual const std::string& domain() const{
@@ -38,11 +39,18 @@ namespace TileCalib {
   protected:
     virtual void setMessage( const std::string& message ){
       m_message = message;
+      format();
     }
     
   private:
+    void format()
+    {
+      m_result = m_domain + ": "+ m_message;
+    }
+
     std::string m_domain;
     std::string m_message;
+    std::string m_result;
   };
 
 
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchPrbs.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchPrbs.h
index 8bf2eb7336bc4a1f4468f88a8f10cc2bf82f118f..4bd15e77f4ca4afabd8fcf45ad83f5504fede5da 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchPrbs.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchPrbs.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
 */
 
 #ifndef TILECALIBBLOBOBJS_TILEBCHPRBS_H
@@ -102,9 +102,7 @@ class TileBchPrbs
   
  private:
   /** @brief Initializes the problem description map*/
-  static void initPrbDesc();
-  /** @brief PROBLEM to description association. */
-  static std::map<Prb,std::string> m_prbNames;
+  static std::map<Prb,std::string> initPrbDesc();
 };
 
 #endif
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchStatus.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchStatus.h
index b61fe36d25e2511d1551f43b8e3419c081e08366..d6fa86171cc6a5b959440637720ff7a3c61409e9 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchStatus.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileBchStatus.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
 */
 
 #ifndef TILECALIBBLOBOBJS_TILEBCHSTATUS_H
@@ -11,8 +11,10 @@
 */
 
 #include "TileCalibBlobObjs/TileBchPrbs.h"
+#include "CxxUtils/checker_macros.h"
 #include <set>
 #include <string>
+#include <mutex>
 
 class TileBchStatus
 {
@@ -64,12 +66,43 @@ class TileBchStatus
  private:
   PrbSet m_prbSet;
   //=== reference sets
-  static PrbSet m_refBad;
-  static PrbSet m_refNoisy;
-  static PrbSet m_refNoGainL1;
-  static PrbSet m_refBadTiming;
-  static PrbSet m_refWrongBCID;
-  static PrbSet m_refTimingDmuBcOffset;
+  struct LockedPrbSet
+  {
+    size_t size() const
+    {
+      std::lock_guard lock (m_mutex);
+      return m_set.size();
+    }
+    void set (const PrbSet& s)
+    {
+      std::lock_guard lock (m_mutex);
+      m_set = s;
+    }
+    void set (PrbSet&& s)
+    {
+      std::lock_guard lock (m_mutex);
+      m_set = std::move(s);
+    }
+    operator TileBchStatus() const
+    {
+      std::lock_guard lock (m_mutex);
+      return TileBchStatus (m_set, true);
+    }
+    bool test (const PrbSet& s) const;
+
+  private:
+    PrbSet m_set;
+    mutable std::mutex m_mutex;
+  };
+
+  TileBchStatus (const PrbSet& s, bool) : m_prbSet (s) {}
+
+  static LockedPrbSet s_refBad ATLAS_THREAD_SAFE;
+  static LockedPrbSet s_refNoisy ATLAS_THREAD_SAFE;
+  static LockedPrbSet s_refNoGainL1 ATLAS_THREAD_SAFE;
+  static LockedPrbSet s_refBadTiming ATLAS_THREAD_SAFE;
+  static LockedPrbSet s_refWrongBCID ATLAS_THREAD_SAFE;
+  static LockedPrbSet s_refTimingDmuBcOffset ATLAS_THREAD_SAFE;
 };
 
 //
@@ -109,7 +142,7 @@ TileBchStatus::isAffected() const
 inline bool
 TileBchStatus::isBad() const
 {
-  return m_prbSet.size() ? (testFor(m_refBad).size() != 0) : false;
+  return m_prbSet.size() ? (s_refBad.test (m_prbSet)) : false;
 }
 
 //
@@ -117,7 +150,7 @@ TileBchStatus::isBad() const
 inline bool
 TileBchStatus::isNoisy() const
 {
-  return m_prbSet.size() ? (testFor(m_refNoisy).size() != 0) : false;
+  return m_prbSet.size() ? (s_refNoisy.test (m_prbSet)) : false;
 }
 
 //
@@ -141,7 +174,7 @@ TileBchStatus::isIgnoredInHlt() const
 inline bool
 TileBchStatus::isNoGainL1() const
 {
-  return m_prbSet.size() ? (testFor(m_refNoGainL1).size()!=0) : false;
+  return m_prbSet.size() ? (s_refNoGainL1.test (m_prbSet)) : false;
 }
 
 //
@@ -157,7 +190,7 @@ TileBchStatus::isHalfGainL1() const
 inline bool
 TileBchStatus::isBadTiming() const
 {
-  return m_prbSet.size() ? (testFor(m_refBadTiming).size() != 0) : false;
+  return m_prbSet.size() ? (s_refBadTiming.test (m_prbSet)) : false;
 }
 
 //
@@ -165,7 +198,7 @@ TileBchStatus::isBadTiming() const
 inline bool
 TileBchStatus::isTimingDmuBcOffset() const
 {
-  return m_prbSet.size() ? (testFor(m_refTimingDmuBcOffset).size() != 0) : false;
+  return m_prbSet.size() ? (s_refTimingDmuBcOffset.test (m_prbSet)) : false;
 }
 
 //
@@ -173,7 +206,7 @@ TileBchStatus::isTimingDmuBcOffset() const
 inline bool
 TileBchStatus::isWrongBCID() const
 {
-  return m_prbSet.size() ? (testFor(m_refWrongBCID).size() != 0) : false;
+  return m_prbSet.size() ? (s_refWrongBCID.test (m_prbSet)) : false;
 }
 
 #endif
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBase.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBase.h
index b7559e457253dbad30e10a51655684abf534d54a..7668d6c410851fcb1f5a0159231515d3503d3bc0 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBase.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBase.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBBLOBOBJS_TILECALIBDRAWERBASE_H
@@ -131,7 +131,8 @@ class TileCalibDrawerBase{
   //==================================================================
   /** @brief Returns start address of iEle-th basic unit. 
       @param iEle sequential basic unit number */
-  void* getAddress(unsigned int iEle) const;
+  const void* getAddress(unsigned int iEle) const;
+        void* getAddress(unsigned int iEle);
   
   /** @brief The header size in units of uint32_t. */
   static const unsigned int m_hdrSize32 = 5;
@@ -140,6 +141,9 @@ class TileCalibDrawerBase{
   /** @brief Ctor for const blob. */
   TileCalibDrawerBase(const coral::Blob& blob);
 
+  /** @brief Ctor for non-const blob. */
+  TileCalibDrawerBase(coral::Blob& blob);
+
   /** @brief (re-)creation of the referenced BLOB object.
       @param objType Object type
       @param objVersion Object version 
@@ -165,12 +169,15 @@ class TileCalibDrawerBase{
   void dumpHeader(std::ostream& stm) const; 
 
  private:
-  /** @brief Reference to the BLOB*/
-  coral::Blob*  m_blob;
+  /** @brief Non-const reference to the BLOB.
+             (Only present if we were created with a non-const blob.) */
+  coral::Blob*  m_blob_nc;
+  /** @brief Const reference to the BLOB (always there) */
+  const coral::Blob*  m_blob;
   /** @brief Cache blob starting address as uint_32t* */
-  uint32_t*     m_blobStart32;
+  const uint32_t*  m_blobStart32;
   /** @brief Cache blob starting address as uint_16t* */
-  uint16_t*     m_blobStart16;
+  const uint16_t*  m_blobStart16;
   /** @brief Cache blob size in units of uint32_t */
   uint64_t      m_blobSize32;
     /** @brief Is this TileCalibDrawer owner of the BLOB */
@@ -236,13 +243,25 @@ TileCalibDrawerBase::getCommentSizeUint32() const
 
 //
 //_________________________________________________________
-__attribute__((always_inline)) inline void* 
+__attribute__((always_inline)) inline const void* 
 TileCalibDrawerBase::getAddress(unsigned int iEle) const
 {
   if(iEle>=getNObjs()){ 
     throw TileCalib::IndexOutOfRange("TileCalibDrawerBase::getAddress", iEle, getNObjs());
   }
-  return static_cast<void*>( m_blobStart32 + m_hdrSize32 + getObjSizeUint32()*iEle );
+  return static_cast<const void*>( m_blobStart32 + m_hdrSize32 + getObjSizeUint32()*iEle );
+}
+
+//
+//_________________________________________________________
+__attribute__((always_inline)) inline void* 
+TileCalibDrawerBase::getAddress(unsigned int iEle)
+{
+  if(iEle>=getNObjs()){ 
+    throw TileCalib::IndexOutOfRange("TileCalibDrawerBase::getAddress", iEle, getNObjs());
+  }
+  uint32_t* blobStart32 = static_cast<uint32_t*>(m_blob_nc->startingAddress());
+  return static_cast<void*>( blobStart32 + m_hdrSize32 + getObjSizeUint32()*iEle );
 }
 
 //
@@ -251,8 +270,8 @@ __attribute__((always_inline)) inline uint64_t
 TileCalibDrawerBase::getTimeStamp() const 
 {
   if(!getCommentSizeUint32()) return 0;
-  return *(reinterpret_cast<uint64_t*>(m_blobStart32 + m_hdrSize32 +
-				       getNObjs()*getObjSizeUint32()));
+  return *(reinterpret_cast<const uint64_t*>(m_blobStart32 + m_hdrSize32 +
+                                             getNObjs()*getObjSizeUint32()));
 }
 
 #endif
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBch.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBch.h
index d6431bfe9dd62e16cea46a1abeaf283e7433fae2..befa67a9582d004e526df3cff8e6ad3832800f0f 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBch.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerBch.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBBLOBOBJS_TILECALIBDRAWERBCH_H
@@ -66,9 +66,10 @@ class TileCalibDrawerBch : public TileCalibDrawerDat<uint32_t>
 		      uint32_t& adcStatus, uint32_t& chnStatus) const;
   
  protected:
-  /** @brief Ctor. */
+  /** @brief Ctor (const). */
   TileCalibDrawerBch(const coral::Blob& blob);
-  
+  /** @brief Ctor (non-const). */
+  TileCalibDrawerBch(coral::Blob& blob);
 };
 
 //
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerDat.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerDat.h
index fb40c5f077a3686c3a37673430b3406d5ceab5cc..5817b3f821b74027e2d03a3022d07eb893ce68ae 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerDat.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerDat.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBBLOBOBJS_TILECALIBDRAWERDAT_H
@@ -84,9 +84,12 @@ class TileCalibDrawerDat : public TileCalibDrawerBase
   virtual void dump(std::ostream& stm) const;
   
  protected:
-  /** @brief Ctor.
+  /** @brief Ctor (const).
       Derived classes should set doTypeCheck=false and do their own check. */
   TileCalibDrawerDat(const coral::Blob& blob) : TileCalibDrawerBase(blob){}
+  /** @brief Ctor (non-const).
+      Derived classes should set doTypeCheck=false and do their own check. */
+  TileCalibDrawerDat(coral::Blob& blob) : TileCalibDrawerBase(blob){}
 
   /** @brief Returns a pointer to the first value for the specified channel & ADC. 
       @param channel The channel number; If channel number >= getNChans() 
@@ -94,7 +97,8 @@ class TileCalibDrawerDat : public TileCalibDrawerBase
                      if channel number > (maximum number of channels in drawer)
                      otherwise it is reset to 0 without warning (default policy)   
       @param adc The gain index; if >= getNGains() it is reset to 0 without warning (default policy) */
-  T* getAddress(unsigned int channel, unsigned int adc) const;
+  const T* getAddress(unsigned int channel, unsigned int adc) const;
+        T* getAddress(unsigned int channel, unsigned int adc);
 };
 
 //
@@ -186,8 +190,17 @@ TileCalibDrawerDat<T>::setData(unsigned int channel, unsigned int adc, const std
 
 //
 //______________________________________________________________
-template<class T> T* 
+template<class T> const T* 
 TileCalibDrawerDat<T>::getAddress(unsigned int channel, unsigned int adc) const
+{
+  unsigned int idx = channel*getNGains() + adc;
+  return static_cast<const T*>(TileCalibDrawerBase::getAddress(idx));
+}
+
+//
+//______________________________________________________________
+template<class T> T* 
+TileCalibDrawerDat<T>::getAddress(unsigned int channel, unsigned int adc)
 {
   unsigned int idx = channel*getNGains() + adc;
   return static_cast<T*>(TileCalibDrawerBase::getAddress(idx));
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerFlt.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerFlt.h
index 030eb815c60c76fea3fb576d4560c9f98d47726f..87351753b1ef6622198459e13a7353ce82899d29 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerFlt.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerFlt.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBBLOBOBJS_TILECALIBDRAWERFLT_H
@@ -88,8 +88,10 @@ class TileCalibDrawerFlt : public TileCalibDrawerDat<float>
 
 
  protected:
-  /** @brief Ctor. */
+  /** @brief Ctor (const). */
   TileCalibDrawerFlt(const coral::Blob& blob);
+  /** @brief Ctor (non-const). */
+  TileCalibDrawerFlt(coral::Blob& blob);
 };
 
 
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerOfc.h b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerOfc.h
index a99b5c383470f14ca325ff463ee6e1fb51def98f..ba4de032366f67eaa5e54a7570948ddeaf50cdb6 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerOfc.h
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/TileCalibBlobObjs/TileCalibDrawerOfc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TILECALIBDRAWEROFC_H
@@ -164,22 +164,32 @@ class TileCalibDrawerOfc : public TileCalibDrawerBase {
   void setPhases(unsigned int channel, unsigned int adc, const std::vector<float>& phases); 
   
  protected:
-  /** @brief Ctor. */
+  /** @brief Ctor (const). */
   TileCalibDrawerOfc(const coral::Blob& blob);
+  /** @brief Ctor (non0const). */
+  TileCalibDrawerOfc(coral::Blob& blob);
   
  private:
+  void initCheck();
+
   /** @brief Returns pointer to first data OFC for a given field, ADC & phase.
       @param field The field identifier
       @param channel The channel number
       @param adc The gain index
       @param phase The phase */
-  float* getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const;
+  const float* getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const;
+       float* getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase);
+
+  unsigned int getOfcStartOffset(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const;
 
   /** @brief Returns pointer to the requested phase value
       @param channel The channel number
       @param adc The gain index
       @param phaseIdx The phase index */
-  int32_t* getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
+  const int32_t* getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
+       int32_t* getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx);
+
+  unsigned int getPhaseStartOffset(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
 
   /** Returns the index for a given phase 
       @param channel The channel number
@@ -192,14 +202,14 @@ class TileCalibDrawerOfc : public TileCalibDrawerBase {
 //______________________________________________________________
 __attribute__((always_inline)) 
 inline uint32_t TileCalibDrawerOfc::getNSamples() const {
-  return *(static_cast<uint32_t*>(getAddress(0)));
+  return *(static_cast<const uint32_t*>(getAddress(0)));
 }
 
 //
 //______________________________________________________________
 __attribute__((always_inline)) 
 inline int32_t TileCalibDrawerOfc::getNPhases() const {
-  return *(static_cast<int32_t*>(getAddress(1)));
+  return *(static_cast<const int32_t*>(getAddress(1)));
 }
 
 //
@@ -208,9 +218,9 @@ __attribute__((always_inline))
 inline unsigned int TileCalibDrawerOfc::getPhaseNumber(unsigned int channel, unsigned int adc, float& phase) const {
 
   int db_phase = (int) std::round(phase * (1 / PHASE_PRECISION)); // Phases are stored as int(10*phase) in DB
-  int32_t* beg = getPhaseStartAddress(channel, adc, 0);
-  int32_t* end = beg + std::abs(getNPhases());
-  int32_t* pos = std::lower_bound(beg, end, db_phase);
+  const int32_t* beg = getPhaseStartAddress(channel, adc, 0);
+  const int32_t* end = beg + std::abs(getNPhases());
+  const int32_t* pos = std::lower_bound(beg, end, db_phase);
 
   if (pos == end || (*pos != db_phase && pos != beg && (*pos - db_phase) > (db_phase - *(pos - 1)))) {
     --pos;
@@ -255,7 +265,7 @@ inline void TileCalibDrawerOfc::fillOfc (unsigned int channel,unsigned int adc,
                                          , float* w_a, float* w_b, float* w_c, float* g, float* dg) const {
 
 
-  float* startAddress = getOfcStartAddress(TileCalibDrawerOfc::FieldA, channel, adc, phase);
+  const float* startAddress = getOfcStartAddress(TileCalibDrawerOfc::FieldA, channel, adc, phase);
   size_t allSamplesSize = getNSamples() * sizeof(float); 
   size_t fieldSize = getObjSizeUint32() * getNSamples();
 
@@ -287,8 +297,8 @@ inline void TileCalibDrawerOfc::setOfc(unsigned int field,unsigned int channel,
 //
 //______________________________________________________________
 __attribute__((always_inline)) 
-inline int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const {
-
+inline unsigned int TileCalibDrawerOfc::getPhaseStartOffset(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
+{
   if(phaseIdx >= static_cast<unsigned int>(std::abs(getNPhases()))){
     throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getPhaseStartAddress", phaseIdx, std::abs(getNPhases()));
   }
@@ -307,14 +317,30 @@ inline int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, u
   unsigned int offset = 2;
   unsigned int nPhases = std::abs(getNPhases());
   offset += channel * nPhases * getNGains() + adc * nPhases + phaseIdx;
-  return static_cast<int32_t*>(getAddress(offset));
+  return offset;
+}
+
+//
+//______________________________________________________________
+__attribute__((always_inline)) 
+inline const int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
+{
+  return static_cast<const int32_t*>(getAddress(getPhaseStartOffset(channel, adc, phaseIdx)));
 }
 
 //
 //______________________________________________________________
 __attribute__((always_inline)) 
-inline float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const {
+inline int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx)
+{
+  return static_cast<int32_t*>(getAddress(getPhaseStartOffset(channel, adc, phaseIdx)));
+}
 
+//
+//______________________________________________________________
+__attribute__((always_inline)) 
+inline unsigned int TileCalibDrawerOfc::getOfcStartOffset(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const
+{
   //=== check default policy
 
   if(channel >= getNChans()) {
@@ -362,7 +388,23 @@ inline float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigne
   unsigned int lChan   = lAdc * nGain;
   offset += channel * lChan + adc * lAdc + iPhase * lPhase + field * nSample;
   
-  return static_cast<float*>(getAddress(offset));
+  return offset;
+}
+
+//
+//______________________________________________________________
+__attribute__((always_inline)) 
+inline const float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const
+{
+  return static_cast<const float*>(getAddress(getOfcStartOffset(field, channel, adc, phase)));
+}
+
+//
+//______________________________________________________________
+__attribute__((always_inline)) 
+inline float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase)
+{
+  return static_cast<float*>(getAddress(getOfcStartOffset(field, channel, adc, phase)));
 }
 
 #endif
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchPrbs.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchPrbs.cxx
index ad4f05a5954c7fc9d3c9060e8f24d7793718919f..535b096cbbee334848f9d9589c3b92fb44be1cce 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchPrbs.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchPrbs.cxx
@@ -1,85 +1,85 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
 #include "TileCalibBlobObjs/TileBchPrbs.h"
 
-//________________________________________________________________
-std::map<TileBchPrbs::Prb,std::string> TileBchPrbs::m_prbNames;
-
 //
 //________________________________________________________________
 std::string 
 TileBchPrbs::getDescription(const Prb& prb)
 {
-  if(!m_prbNames.size()) { initPrbDesc(); }
-  std::map<Prb,std::string>::const_iterator iMap = m_prbNames.find(prb);
+  static const std::map<Prb,std::string> prbNames = initPrbDesc();
+  std::map<Prb,std::string>::const_iterator iMap = prbNames.find(prb);
   std::string desc("<no description available>");
-  if(iMap!=m_prbNames.end()){ desc=iMap->second; }
+  if(iMap!=prbNames.end()){ desc=iMap->second; }
   return desc;
 }
 
 //
 //________________________________________________________________
-void 
+std::map<TileBchPrbs::Prb,std::string>
 TileBchPrbs::initPrbDesc()
 {
-  m_prbNames[TileBchPrbs::Invalid                ] = "Invalid";
+  std::map<Prb,std::string> prbNames;
+  prbNames[TileBchPrbs::Invalid                ] = "Invalid";
 
   //=== adc
-  m_prbNames[TileBchPrbs::GeneralMaskAdc         ] = "ADC masked (unspecified)";
-  m_prbNames[TileBchPrbs::AdcDead                ] = "ADC dead";
-  m_prbNames[TileBchPrbs::StuckBit               ] = "Stuck bit";
-  m_prbNames[TileBchPrbs::SevereStuckBit         ] = "Severe stuck bit";
-  m_prbNames[TileBchPrbs::DataCorruption         ] = "Data corruption";
-  m_prbNames[TileBchPrbs::SevereDataCorruption   ] = "Severe data corruption";
-  m_prbNames[TileBchPrbs::VeryLargeHfNoise       ] = "Very large HF noise";
-  m_prbNames[TileBchPrbs::NoData                 ] = "No data";
-  m_prbNames[TileBchPrbs::WrongDspConfig         ] = "Wrong DSP configuration";
-  m_prbNames[TileBchPrbs::LargeHfNoise           ] = "Large HF noise";
-  m_prbNames[TileBchPrbs::CorrelatedNoise        ] = "Correlated noise";
-  m_prbNames[TileBchPrbs::LargeLfNoise           ] = "Large LF noise";
-  m_prbNames[TileBchPrbs::NoCis                  ] = "No CIS calibration";
-  m_prbNames[TileBchPrbs::BadCis                 ] = "Bad CIS calibration";
-  m_prbNames[TileBchPrbs::IgnoredByDQV           ] = "Ignored by DQV";
+  prbNames[TileBchPrbs::GeneralMaskAdc         ] = "ADC masked (unspecified)";
+  prbNames[TileBchPrbs::AdcDead                ] = "ADC dead";
+  prbNames[TileBchPrbs::StuckBit               ] = "Stuck bit";
+  prbNames[TileBchPrbs::SevereStuckBit         ] = "Severe stuck bit";
+  prbNames[TileBchPrbs::DataCorruption         ] = "Data corruption";
+  prbNames[TileBchPrbs::SevereDataCorruption   ] = "Severe data corruption";
+  prbNames[TileBchPrbs::VeryLargeHfNoise       ] = "Very large HF noise";
+  prbNames[TileBchPrbs::NoData                 ] = "No data";
+  prbNames[TileBchPrbs::WrongDspConfig         ] = "Wrong DSP configuration";
+  prbNames[TileBchPrbs::LargeHfNoise           ] = "Large HF noise";
+  prbNames[TileBchPrbs::CorrelatedNoise        ] = "Correlated noise";
+  prbNames[TileBchPrbs::LargeLfNoise           ] = "Large LF noise";
+  prbNames[TileBchPrbs::NoCis                  ] = "No CIS calibration";
+  prbNames[TileBchPrbs::BadCis                 ] = "Bad CIS calibration";
+  prbNames[TileBchPrbs::IgnoredByDQV           ] = "Ignored by DQV";
 
   //=== channel
-  m_prbNames[TileBchPrbs::GeneralMaskChannel     ] = "Channel masked (unspecified)";
-  m_prbNames[TileBchPrbs::NoPmt                  ] = "No PMT connected";
-  m_prbNames[TileBchPrbs::NoHV                   ] = "No HV";
-  m_prbNames[TileBchPrbs::WrongHV                ] = "Wrong HV";
-  m_prbNames[TileBchPrbs::NoLaser                ] = "No laser calibration";
-  m_prbNames[TileBchPrbs::BadLaser               ] = "Bad laser calibration";
-  m_prbNames[TileBchPrbs::NoCesium               ] = "No cesium calibration";
-  m_prbNames[TileBchPrbs::BadCesium              ] = "Bad cesium calibration";
-  m_prbNames[TileBchPrbs::NoTiming               ] = "No timing set in dskew";
-  m_prbNames[TileBchPrbs::BadTiming              ] = "Bad timing";
-  m_prbNames[TileBchPrbs::Emergency              ] = "Module in emergency mode";
-  m_prbNames[TileBchPrbs::HVReadoutPb            ] = "HV readout problem";
-  m_prbNames[TileBchPrbs::BrokenClearFibre       ] = "Broken clear fibre";
-  m_prbNames[TileBchPrbs::IgnoreCs               ] = "Ignore cesium";
-  m_prbNames[TileBchPrbs::UnstableCs             ] = "Unstable cesium";
-  m_prbNames[TileBchPrbs::WrongBCID              ] = "Wrong BCID";
-  m_prbNames[TileBchPrbs::TimingDmuBcOffset      ] = "Timing DMU BC offset";
-  m_prbNames[TileBchPrbs::BurntIntegrator        ] = "Burnt Integrator";
+  prbNames[TileBchPrbs::GeneralMaskChannel     ] = "Channel masked (unspecified)";
+  prbNames[TileBchPrbs::NoPmt                  ] = "No PMT connected";
+  prbNames[TileBchPrbs::NoHV                   ] = "No HV";
+  prbNames[TileBchPrbs::WrongHV                ] = "Wrong HV";
+  prbNames[TileBchPrbs::NoLaser                ] = "No laser calibration";
+  prbNames[TileBchPrbs::BadLaser               ] = "Bad laser calibration";
+  prbNames[TileBchPrbs::NoCesium               ] = "No cesium calibration";
+  prbNames[TileBchPrbs::BadCesium              ] = "Bad cesium calibration";
+  prbNames[TileBchPrbs::NoTiming               ] = "No timing set in dskew";
+  prbNames[TileBchPrbs::BadTiming              ] = "Bad timing";
+  prbNames[TileBchPrbs::Emergency              ] = "Module in emergency mode";
+  prbNames[TileBchPrbs::HVReadoutPb            ] = "HV readout problem";
+  prbNames[TileBchPrbs::BrokenClearFibre       ] = "Broken clear fibre";
+  prbNames[TileBchPrbs::IgnoreCs               ] = "Ignore cesium";
+  prbNames[TileBchPrbs::UnstableCs             ] = "Unstable cesium";
+  prbNames[TileBchPrbs::WrongBCID              ] = "Wrong BCID";
+  prbNames[TileBchPrbs::TimingDmuBcOffset      ] = "Timing DMU BC offset";
+  prbNames[TileBchPrbs::BurntIntegrator        ] = "Burnt Integrator";
 
   //=== DSP
-  m_prbNames[TileBchPrbs::IgnoredInDsp           ] = "Ignored in DSP";
-  m_prbNames[TileBchPrbs::IgnoredInHlt           ] = "Ignored in HLT";
+  prbNames[TileBchPrbs::IgnoredInDsp           ] = "Ignored in DSP";
+  prbNames[TileBchPrbs::IgnoredInHlt           ] = "Ignored in HLT";
   
   //=== Trigger
-  m_prbNames[TileBchPrbs::TrigGeneralMask        ] = "Channel masked for LV1 (unspecified)";
-  m_prbNames[TileBchPrbs::TrigNoGain             ] = "LV1 channel no gain";
-  m_prbNames[TileBchPrbs::TrigHalfGain           ] = "LV1 channel half gain";
-  m_prbNames[TileBchPrbs::TrigNoisy              ] = "LV1 channel noisy";
-  m_prbNames[TileBchPrbs::DisableForL1           ] = "Channel disabled for LV1";
+  prbNames[TileBchPrbs::TrigGeneralMask        ] = "Channel masked for LV1 (unspecified)";
+  prbNames[TileBchPrbs::TrigNoGain             ] = "LV1 channel no gain";
+  prbNames[TileBchPrbs::TrigHalfGain           ] = "LV1 channel half gain";
+  prbNames[TileBchPrbs::TrigNoisy              ] = "LV1 channel noisy";
+  prbNames[TileBchPrbs::DisableForL1           ] = "Channel disabled for LV1";
 
   //=== online channel
-  m_prbNames[TileBchPrbs::OnlineBadTiming        ] = "Online bad timing";
-  m_prbNames[TileBchPrbs::OnlineTimingDmuBcOffset] = "Online timing DMU BC offset";
-  m_prbNames[TileBchPrbs::OnlineWrongBCID        ] = "Online wrong BCID";
+  prbNames[TileBchPrbs::OnlineBadTiming        ] = "Online bad timing";
+  prbNames[TileBchPrbs::OnlineTimingDmuBcOffset] = "Online timing DMU BC offset";
+  prbNames[TileBchPrbs::OnlineWrongBCID        ] = "Online wrong BCID";
 
   //=== online adc
-  m_prbNames[TileBchPrbs::OnlineGeneralMaskAdc   ] = "Online ADC masked (unspecified)";
+  prbNames[TileBchPrbs::OnlineGeneralMaskAdc   ] = "Online ADC masked (unspecified)";
+
+  return prbNames;
 }
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchStatus.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchStatus.cxx
index e4dfd2127616b4a53a5c08ec20dfbf392bbeb767..5754c95535e060d6867ad8d4313e9f363bdd2544 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchStatus.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileBchStatus.cxx
@@ -1,23 +1,23 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TileCalibBlobObjs/TileBchStatus.h"
 #include <algorithm>
 
 //=== static memebers
-TileBchStatus::PrbSet TileBchStatus::m_refBad;
-TileBchStatus::PrbSet TileBchStatus::m_refNoisy;
-TileBchStatus::PrbSet TileBchStatus::m_refNoGainL1;
-TileBchStatus::PrbSet TileBchStatus::m_refBadTiming;
-TileBchStatus::PrbSet TileBchStatus::m_refWrongBCID;
-TileBchStatus::PrbSet TileBchStatus::m_refTimingDmuBcOffset;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refBad ATLAS_THREAD_SAFE;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refNoisy ATLAS_THREAD_SAFE;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refNoGainL1 ATLAS_THREAD_SAFE;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refBadTiming ATLAS_THREAD_SAFE;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refWrongBCID ATLAS_THREAD_SAFE;
+TileBchStatus::LockedPrbSet TileBchStatus::s_refTimingDmuBcOffset ATLAS_THREAD_SAFE;
 
 //
 //_________________________________________________________
 TileBchStatus::TileBchStatus()
 {
-  if(!m_refBad.size()) initClassifierDefinitions();
+  if(!s_refBad.size()) initClassifierDefinitions();
 }
 
 //
@@ -25,7 +25,7 @@ TileBchStatus::TileBchStatus()
 TileBchStatus::TileBchStatus(const PrbSet& prbSet) : 
   m_prbSet(prbSet)
 {
-  if(!m_refBad.size()) initClassifierDefinitions();
+  if(!s_refBad.size()) initClassifierDefinitions();
 }
 
 //
@@ -91,50 +91,62 @@ void
 TileBchStatus::initClassifierDefinitions()
 {
   //=== define which problems trigger a bad state
+  PrbSet refBad;
   //=== adc
-  m_refBad.insert(TileBchPrbs::GeneralMaskAdc);
-  m_refBad.insert(TileBchPrbs::AdcDead);
-  m_refBad.insert(TileBchPrbs::SevereStuckBit);
-  m_refBad.insert(TileBchPrbs::SevereDataCorruption);
-  m_refBad.insert(TileBchPrbs::VeryLargeHfNoise);
-  m_refBad.insert(TileBchPrbs::NoData);
-  m_refBad.insert(TileBchPrbs::WrongDspConfig);
+  refBad.insert(TileBchPrbs::GeneralMaskAdc);
+  refBad.insert(TileBchPrbs::AdcDead);
+  refBad.insert(TileBchPrbs::SevereStuckBit);
+  refBad.insert(TileBchPrbs::SevereDataCorruption);
+  refBad.insert(TileBchPrbs::VeryLargeHfNoise);
+  refBad.insert(TileBchPrbs::NoData);
+  refBad.insert(TileBchPrbs::WrongDspConfig);
   //=== channel
-  m_refBad.insert(TileBchPrbs::GeneralMaskChannel);
-  m_refBad.insert(TileBchPrbs::NoPmt);
-  m_refBad.insert(TileBchPrbs::NoHV);
-  m_refBad.insert(TileBchPrbs::WrongHV);
+  refBad.insert(TileBchPrbs::GeneralMaskChannel);
+  refBad.insert(TileBchPrbs::NoPmt);
+  refBad.insert(TileBchPrbs::NoHV);
+  refBad.insert(TileBchPrbs::WrongHV);
   //=== online (adc)
-  m_refBad.insert(TileBchPrbs::OnlineGeneralMaskAdc);
+  refBad.insert(TileBchPrbs::OnlineGeneralMaskAdc);
+  s_refBad.set (std::move (refBad));
   
+  PrbSet refNoisy;
   //=== define which problems trigger a noisy state
-  m_refNoisy.insert(TileBchPrbs::LargeHfNoise);
-  m_refNoisy.insert(TileBchPrbs::CorrelatedNoise);
-  m_refNoisy.insert(TileBchPrbs::LargeLfNoise);
+  refNoisy.insert(TileBchPrbs::LargeHfNoise);
+  refNoisy.insert(TileBchPrbs::CorrelatedNoise);
+  refNoisy.insert(TileBchPrbs::LargeLfNoise);
+  s_refNoisy.set (std::move (refNoisy));
 
+  PrbSet refNoGainL1;
   //=== define which problems trigger a NoGainL1 state
-  m_refNoGainL1.insert(TileBchPrbs::AdcDead);
-  m_refNoGainL1.insert(TileBchPrbs::NoPmt);
-  m_refNoGainL1.insert(TileBchPrbs::NoHV);
-  m_refNoGainL1.insert(TileBchPrbs::TrigGeneralMask);
-  m_refNoGainL1.insert(TileBchPrbs::TrigNoGain);
-  m_refNoGainL1.insert(TileBchPrbs::TrigNoisy);
-  m_refNoGainL1.insert(TileBchPrbs::DisableForL1);
+  refNoGainL1.insert(TileBchPrbs::AdcDead);
+  refNoGainL1.insert(TileBchPrbs::NoPmt);
+  refNoGainL1.insert(TileBchPrbs::NoHV);
+  refNoGainL1.insert(TileBchPrbs::TrigGeneralMask);
+  refNoGainL1.insert(TileBchPrbs::TrigNoGain);
+  refNoGainL1.insert(TileBchPrbs::TrigNoisy);
+  refNoGainL1.insert(TileBchPrbs::DisableForL1);
+  s_refNoGainL1.set (std::move (refNoGainL1));
 
+  PrbSet refBadTiming;
   //=== define which problems trigger a bad timing
-  m_refBadTiming.insert(TileBchPrbs::BadTiming);
+  refBadTiming.insert(TileBchPrbs::BadTiming);
   //=== online
-  m_refBadTiming.insert(TileBchPrbs::OnlineBadTiming);
+  refBadTiming.insert(TileBchPrbs::OnlineBadTiming);
+  s_refBadTiming.set (std::move (refBadTiming));
 
+  PrbSet refTimingDmuBcOffset;
   //=== define which problems trigger an affected timing
-  m_refTimingDmuBcOffset.insert(TileBchPrbs::TimingDmuBcOffset);
+  refTimingDmuBcOffset.insert(TileBchPrbs::TimingDmuBcOffset);
   //=== online
-  m_refTimingDmuBcOffset.insert(TileBchPrbs::OnlineTimingDmuBcOffset);
+  refTimingDmuBcOffset.insert(TileBchPrbs::OnlineTimingDmuBcOffset);
+  s_refTimingDmuBcOffset.set (std::move (refTimingDmuBcOffset));
 
+  PrbSet refWrongBCID;
   //=== define which problems trigger a wrong BCID
-  m_refWrongBCID.insert(TileBchPrbs::WrongBCID);
+  refWrongBCID.insert(TileBchPrbs::WrongBCID);
   //=== online
-  m_refWrongBCID.insert(TileBchPrbs::OnlineWrongBCID);
+  refWrongBCID.insert(TileBchPrbs::OnlineWrongBCID);
+  s_refWrongBCID.set (std::move (refWrongBCID));
 }
 
 //
@@ -142,7 +154,7 @@ TileBchStatus::initClassifierDefinitions()
 void 
 TileBchStatus::defineBad(const TileBchStatus& status)
 {
-  m_refBad = status.getPrbs();
+  s_refBad.set (status.getPrbs());
 }
 
 //
@@ -150,7 +162,7 @@ TileBchStatus::defineBad(const TileBchStatus& status)
 void 
 TileBchStatus::defineNoisy(const TileBchStatus& status)
 {
-  m_refNoisy = status.getPrbs();
+  s_refNoisy.set (status.getPrbs());
 }
 
 //
@@ -158,7 +170,7 @@ TileBchStatus::defineNoisy(const TileBchStatus& status)
 void 
 TileBchStatus::defineNoGainL1(const TileBchStatus& status)
 {
-  m_refNoGainL1 = status.getPrbs();
+  s_refNoGainL1.set (status.getPrbs());
 }
 
 //
@@ -166,7 +178,7 @@ TileBchStatus::defineNoGainL1(const TileBchStatus& status)
 void 
 TileBchStatus::defineBadTiming(const TileBchStatus& status)
 {
-  m_refBadTiming = status.getPrbs();
+  s_refBadTiming.set (status.getPrbs());
 }
 
 //
@@ -174,7 +186,7 @@ TileBchStatus::defineBadTiming(const TileBchStatus& status)
 void
 TileBchStatus::defineTimingDmuBcOffset(const TileBchStatus& status)
 {
-  m_refTimingDmuBcOffset = status.getPrbs();
+  s_refTimingDmuBcOffset.set (status.getPrbs());
 }
 
 //
@@ -182,7 +194,7 @@ TileBchStatus::defineTimingDmuBcOffset(const TileBchStatus& status)
 void
 TileBchStatus::defineWrongBCID(const TileBchStatus& status)
 {
-  m_refWrongBCID = status.getPrbs();
+  s_refWrongBCID.set (status.getPrbs());
 }
 
 //
@@ -190,7 +202,7 @@ TileBchStatus::defineWrongBCID(const TileBchStatus& status)
 TileBchStatus 
 TileBchStatus::getDefinitionBad()
 {
-  return TileBchStatus(m_refBad);
+  return s_refBad;
 }
 
 //
@@ -198,7 +210,7 @@ TileBchStatus::getDefinitionBad()
 TileBchStatus
 TileBchStatus::getDefinitionNoisy()
 {
-  return TileBchStatus(m_refNoisy);
+  return s_refNoisy;
 }
 
 //
@@ -206,7 +218,7 @@ TileBchStatus::getDefinitionNoisy()
 TileBchStatus
 TileBchStatus::getDefinitionNoGainL1()
 {
-  return TileBchStatus(m_refNoGainL1);
+  return s_refNoGainL1;
 }
 
 //
@@ -214,7 +226,7 @@ TileBchStatus::getDefinitionNoGainL1()
 TileBchStatus
 TileBchStatus::getDefinitionBadTiming()
 {
-  return TileBchStatus(m_refBadTiming);
+  return s_refBadTiming;
 }
 
 //
@@ -222,7 +234,7 @@ TileBchStatus::getDefinitionBadTiming()
 TileBchStatus
 TileBchStatus::getDefinitionTimingDmuBcOffset()
 {
-  return TileBchStatus(m_refTimingDmuBcOffset);
+  return s_refTimingDmuBcOffset;
 }
 
 //
@@ -230,7 +242,7 @@ TileBchStatus::getDefinitionTimingDmuBcOffset()
 TileBchStatus
 TileBchStatus::getDefinitionWrongBCID()
 {
-  return TileBchStatus(m_refWrongBCID);
+  return s_refWrongBCID;
 }
 
 //
@@ -255,3 +267,14 @@ TileBchStatus::getString() const
   } 
   return prbStr;
 }
+
+//
+//_________________________________________________________
+bool TileBchStatus::LockedPrbSet::test (const PrbSet& s) const
+{
+  std::lock_guard lock (m_mutex);
+  PrbSet overlapp;
+  std::insert_iterator<PrbSet> insItr(overlapp, overlapp.begin()); 
+  std::set_intersection(m_set.begin(),m_set.end(), s.begin(),  s.end(), insItr);
+  return !overlapp.empty();
+}
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBase.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBase.cxx
index 143b62f2c84f050f85ff4a6e4c007afa1a8e7680..a968e8516289c2ac220fc22589404dbbce058d27 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBase.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBase.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TileCalibBlobObjs/TileCalibDrawerBase.h"
@@ -10,9 +10,22 @@
 //
 //_____________________________________________________________
 TileCalibDrawerBase::TileCalibDrawerBase(const coral::Blob& blob) : 
-  m_blob(const_cast<coral::Blob*>(&blob)),
-  m_blobStart32(static_cast<uint32_t*>(m_blob->startingAddress())),
-  m_blobStart16(static_cast<uint16_t*>(m_blob->startingAddress())),
+  m_blob_nc(nullptr),
+  m_blob(&blob),
+  m_blobStart32(static_cast<const uint32_t*>(m_blob->startingAddress())),
+  m_blobStart16(static_cast<const uint16_t*>(m_blob->startingAddress())),
+  m_blobSize32(m_blob->size()/sizeof(uint32_t)),
+  m_isBlobOwner(false)
+{
+}
+
+//
+//_____________________________________________________________
+TileCalibDrawerBase::TileCalibDrawerBase(coral::Blob& blob) : 
+  m_blob_nc(&blob),
+  m_blob(&blob),
+  m_blobStart32(static_cast<const uint32_t*>(m_blob->startingAddress())),
+  m_blobStart16(static_cast<const uint16_t*>(m_blob->startingAddress())),
   m_blobSize32(m_blob->size()/sizeof(uint32_t)),
   m_isBlobOwner(false)
 {
@@ -29,9 +42,10 @@ TileCalibDrawerBase::~TileCalibDrawerBase()
 //
 //_____________________________________________________________
 TileCalibDrawerBase::TileCalibDrawerBase(const TileCalibDrawerBase& other) : 
-  m_blob(new coral::Blob(*other.m_blob)),
-  m_blobStart32(static_cast<uint32_t*>(m_blob->startingAddress())),
-  m_blobStart16(static_cast<uint16_t*>(m_blob->startingAddress())),
+  m_blob_nc(new coral::Blob(*other.m_blob)),
+  m_blob(m_blob_nc),
+  m_blobStart32(static_cast<const uint32_t*>(m_blob->startingAddress())),
+  m_blobStart16(static_cast<const uint16_t*>(m_blob->startingAddress())),
   m_blobSize32(m_blob->size()/sizeof(uint32_t)),
   m_isBlobOwner(true)
 {
@@ -44,6 +58,8 @@ TileCalibDrawerBase::operator=(const TileCalibDrawerBase& other)
 {
   //=== catch self-assignment
   if(&other == this) {return *this;}
+  if (m_isBlobOwner) delete m_blob;
+  m_blob_nc     = other.m_blob_nc;
   m_blob        = other.m_blob;
   m_blobStart32 = other.m_blobStart32;
   m_blobStart16 = other.m_blobStart16;
@@ -58,10 +74,10 @@ void
 TileCalibDrawerBase::clone(const TileCalibDrawerBase& other)
 {
   //=== copy content of other blob
-  *m_blob = *other.m_blob;
+  *m_blob_nc = *other.m_blob;
   //=== and reset cached attributes
-  m_blobStart32 = static_cast<uint32_t*>(m_blob->startingAddress());
-  m_blobStart16 = static_cast<uint16_t*>(m_blob->startingAddress());
+  m_blobStart32 = static_cast<const uint32_t*>(m_blob->startingAddress());
+  m_blobStart16 = static_cast<const uint16_t*>(m_blob->startingAddress());
   m_blobSize32  = m_blob->size()/sizeof(uint32_t);
 }
 
@@ -92,24 +108,27 @@ TileCalibDrawerBase::createBlob(uint16_t objType,
   
   //=== create blob
   uint32_t blobSizeInBytes = dataSizeByte+commentSizeChar;
-  m_blob->resize(blobSizeInBytes);
-  m_blobStart32 = static_cast<uint32_t*>(m_blob->startingAddress());
-  m_blobStart16 = static_cast<uint16_t*>(m_blob->startingAddress());
-  m_blobSize32  = m_blob->size()/sizeof(uint32_t);
+  m_blob_nc->resize(blobSizeInBytes);
+  uint32_t* blobStart32 = static_cast<uint32_t*>(m_blob_nc->startingAddress());
+  uint16_t* blobStart16 = static_cast<uint16_t*>(m_blob_nc->startingAddress());
+  m_blobSize32  = m_blob_nc->size()/sizeof(uint32_t);
+
+  m_blobStart32 = blobStart32;
+  m_blobStart16 = blobStart16;
 
   //=== fill header
-  m_blobStart16[0] = objType;
-  m_blobStart16[1] = objVersion;
-  m_blobStart32[1] = objSizeUint32;
-  m_blobStart32[2] = nObjs;
-  m_blobStart16[6] = nChans;
-  m_blobStart16[7] = nGains;
-  m_blobStart32[4] = commentSizeChar/sizeof(uint32_t);
+  blobStart16[0] = objType;
+  blobStart16[1] = objVersion;
+  blobStart32[1] = objSizeUint32;
+  blobStart32[2] = nObjs;
+  blobStart16[6] = nChans;
+  blobStart16[7] = nGains;
+  blobStart32[4] = commentSizeChar/sizeof(uint32_t);
   
   //==== fill comment fields
   if(commentSizeChar){
     if(!timeStamp) timeStamp = ::time(0);
-    uint64_t* pTimeStamp = reinterpret_cast<uint64_t*>(m_blobStart32+dataSizeByte/sizeof(uint32_t));
+    uint64_t* pTimeStamp = reinterpret_cast<uint64_t*>(blobStart32+dataSizeByte/sizeof(uint32_t));
     pTimeStamp[0] = timeStamp;
     char* pChar = reinterpret_cast<char*>(++pTimeStamp); 
     std::string::const_iterator iStr = author.begin();
@@ -128,9 +147,10 @@ std::string
 TileCalibDrawerBase::getAuthor() const
 {
   if(!getCommentSizeUint32()) return std::string("");
-  char* iBeg = reinterpret_cast<char*>(m_blobStart32 + m_hdrSize32     +
-				       getNObjs()*getObjSizeUint32()   +
-				       sizeof(uint64_t)/sizeof(uint32_t));
+  const char* iBeg =
+    reinterpret_cast<const char*>(m_blobStart32 + m_hdrSize32     +
+                                  getNObjs()*getObjSizeUint32()   +
+                                  sizeof(uint64_t)/sizeof(uint32_t));
   return std::string(iBeg);
 }
 
@@ -141,10 +161,11 @@ std::string
 TileCalibDrawerBase::getComment() const
 {
   if(!getCommentSizeUint32()) return std::string("");
-  char* iBeg = reinterpret_cast<char*>(m_blobStart32 + m_hdrSize32     +
-				       getNObjs()*getObjSizeUint32()   +
-				       sizeof(uint64_t)/sizeof(uint32_t));
-  char* iEnd = iBeg + getCommentSizeChar();
+  const char* iBeg =
+    reinterpret_cast<const char*>(m_blobStart32 + m_hdrSize32     +
+                                  getNObjs()*getObjSizeUint32()   +
+                                  sizeof(uint64_t)/sizeof(uint32_t));
+  const char* iEnd = iBeg + getCommentSizeChar();
   iBeg = std::find(iBeg,iEnd,0);
   return std::string(++iBeg);
 }
@@ -156,7 +177,8 @@ TileCalibDrawerBase::getDate() const
 {
   if(!getCommentSizeUint32()) return std::string("");
   ::time_t timeStamp = getTimeStamp();
-  char* iBeg = ::ctime(&timeStamp);
+  char buf[32];
+  char* iBeg = ::ctime_r(&timeStamp, buf);
   char* iEnd = iBeg;
   while(*iEnd!='\n'){++iEnd;}
   return std::string(iBeg,iEnd-iBeg);
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBch.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBch.cxx
index 2e877d3ecbea8e14114230978eb1cc7d2de96824..e5cd01dd99aa5c028170d8e267c839c067b6d2f0 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBch.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerBch.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TileCalibBlobObjs/TileCalibDrawerBch.h"
@@ -47,3 +47,16 @@ TileCalibDrawerBch::TileCalibDrawerBch(const coral::Blob& blob)
   }
 }
 
+//
+//_______________________________________________________________
+TileCalibDrawerBch::TileCalibDrawerBch(coral::Blob& blob) 
+  : TileCalibDrawerDat<uint32_t>(blob)
+{
+  //=== check for correct blob type
+  if(getBlobSize()){
+    if(getObjType() != getType()){
+      throw TileCalib::TypeConflict("TileCalibDrawerBch::Ctor",getObjType(),getType());
+    }
+  }
+}
+
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerFlt.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerFlt.cxx
index 532af9ec33b2cafeaf8116b58e9209f49c42a8a4..7383deaff493178b4beb0140569fb871fd59f47c 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerFlt.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerFlt.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TileCalibBlobObjs/TileCalibDrawerFlt.h"
@@ -47,6 +47,18 @@ TileCalibDrawerFlt::TileCalibDrawerFlt(const coral::Blob& blob) :
   }
 }
 
+//
+//_______________________________________________________________
+TileCalibDrawerFlt::TileCalibDrawerFlt(coral::Blob& blob) : 
+  TileCalibDrawerDat<float>(blob)
+{
+  if(getBlobSize()){
+    if(getObjType() != getType()){
+      throw TileCalib::TypeConflict("TileCalibDrawerFlt::Ctor",getObjType(),getType());
+    }
+  }
+}
+
 //
 //______________________________________________________________
 float 
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerOfc.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerOfc.cxx
index 6a6eff5518852bb305f0f6e1f93733affd81d892..0800db6b4843397a599df631f659e431518bbdf1 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerOfc.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/src/TileCalibDrawerOfc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TileCalibBlobObjs/TileCalibDrawerOfc.h"
@@ -41,6 +41,21 @@ const TileCalibDrawerOfc* TileCalibDrawerOfc::getInstance(const coral::Blob& blo
 //_______________________________________________________________
 TileCalibDrawerOfc::TileCalibDrawerOfc(const coral::Blob& blob)
   : TileCalibDrawerBase(blob)
+{
+  initCheck();
+}
+
+//
+//_______________________________________________________________
+TileCalibDrawerOfc::TileCalibDrawerOfc(coral::Blob& blob)
+  : TileCalibDrawerBase(blob)
+{
+  initCheck();
+}
+
+//
+//_______________________________________________________________
+void TileCalibDrawerOfc::initCheck()
 {
   if(getBlobSize()){
 
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerFlt_test.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerFlt_test.cxx
index 2ac95e8a1c0687ae8b06e2b3a3faecc52d445efc..681a89b118f42f99ee23688e9e0255c46685bc40 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerFlt_test.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerFlt_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #undef NDEBUG
@@ -14,6 +14,7 @@
 #include "CoralBase/AttributeListSpecification.h"
 
 #include "TestTools/FLOATassert.h"
+#include "CxxUtils/checker_macros.h"
 
 #include <algorithm>
 #include <cassert>
@@ -34,7 +35,7 @@ const std::vector<std::vector<float> > channel0data = {
 const std::vector<float> channel1data = {100, 200, 300, 1000, 2000, 3000};
 
 
-void testTileCalibDrawerFltV100() {
+void testTileCalibDrawerFltV100 ATLAS_NOT_THREAD_SAFE () {
 
   std::cout << "testTileCalibDrawerFltV100\n";
   
@@ -67,7 +68,7 @@ void testTileCalibDrawerFltV100() {
 }
 
 
-void testTileCalibDrawerFltV200() {
+void testTileCalibDrawerFltV200 ATLAS_NOT_THREAD_SAFE () {
 
   std::cout << "testTileCalibDrawerFltV200\n";
   
@@ -119,7 +120,7 @@ void testTileCalibDrawerFltV200() {
 
 
 
-int main() {
+int main ATLAS_NOT_THREAD_SAFE () {
 
 
   testTileCalibDrawerFltV100();
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerOfc_test.cxx b/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerOfc_test.cxx
index ee464824d6d4e85a298fb9b98e36f7eab9299014..f7d0b2a95ec7ad9b76c0010a5aa50b4e03c0ea1b 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerOfc_test.cxx
+++ b/TileCalorimeter/TileCalib/TileCalibBlobObjs/test/TileCalibDrawerOfc_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #undef NDEBUG
@@ -14,6 +14,7 @@
 #include "CoralBase/AttributeListSpecification.h"
 
 #include "TestTools/FLOATassert.h"
+#include "CxxUtils/checker_macros.h"
 
 #include <algorithm>
 #include <cassert>
@@ -31,7 +32,7 @@ static const int NGAINS(1);
 static const unsigned int NSAMPLES(1);
 
 
-void test1() {
+void test1 ATLAS_NOT_THREAD_SAFE () {
 
   std::cout << "test1\n";
   
@@ -176,7 +177,7 @@ int prepareReferenceFile () {
 }
 
 
-int main() {
+int main ATLAS_NOT_THREAD_SAFE () {
 
   //  prepareReferenceFile();