diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtCorFuncSetCollection.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtCorFuncSetCollection.h
index 0559025621393d924ff64e573fb4d92efa96008a..b2025f616055cf55d20645284b611248f9c3da88 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtCorFuncSetCollection.h
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtCorFuncSetCollection.h
@@ -25,4 +25,7 @@ It is a DataVector. It can be saved to storegate.
 typedef DataVector<MuonCalib::MdtCorFuncSet> MdtCorFuncSetCollection;
 CLASS_DEF(MdtCorFuncSetCollection , 1176811704 , 1 )
 
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF( MdtCorFuncSetCollection, 1338477494 );
+
 #endif
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtRtRelationCollection.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtRtRelationCollection.h
index 290a5de7260b8521a7aa79e8b4521114c82021a3..806acd06420d5ffa0f0af597aff956ae818035c9 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtRtRelationCollection.h
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtRtRelationCollection.h
@@ -25,4 +25,7 @@ It is a DataVector. It can be saved to storegate.
 typedef DataVector<MuonCalib::MdtRtRelation> MdtRtRelationCollection;
 CLASS_DEF(MdtRtRelationCollection, 1270996316, 1 )
 
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF( MdtRtRelationCollection, 1160701058 );
+
 #endif
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtTubeCalibContainerCollection.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtTubeCalibContainerCollection.h
index 10d2d60aceb48917612d46a2c1fd68b9ff6c63fe..0b18baef327174c981d5227f2e3209d6c084b2a9 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtTubeCalibContainerCollection.h
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibData/MdtCalibData/MdtTubeCalibContainerCollection.h
@@ -25,4 +25,7 @@ It is a DataVector. It can be saved to storegate.
 typedef DataVector<MuonCalib::MdtTubeCalibContainer> MdtTubeCalibContainerCollection;
 CLASS_DEF(MdtTubeCalibContainerCollection, 1221928754, 1 )
 
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF( MdtTubeCalibContainerCollection, 1164762092 );
+
 #endif
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbAlg.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..2773b29bddf83aba01b4cfa52cde947f431ae3a6
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbAlg.h
@@ -0,0 +1,138 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+   MdtCalibDbAlg reads raw condition data and writes derived condition data to the condition store
+*/
+
+#ifndef MDTCALIBDBCOOLSTRTOOL_MDTCALIBDBALG_H
+#define MDTCALIBDBCOOLSTRTOOL_MDTCALIBDBALG_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+#include "GaudiKernel/ICondSvc.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+
+//from MdtCalibDbCoolStrTool.h
+//removing obsolete ones
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "MdtCalibInterfaces/IMdtCalibDBTool.h"
+#include "MdtCalibData/MdtTubeCalibContainerCollection.h"
+#include "MdtCalibData/MdtRtRelationCollection.h"
+#include "MdtCalibData/MdtCorFuncSetCollection.h"
+#include "MuonCalibITools/IIdToFixedIdTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "CLHEP/Random/RandomEngine.h"
+
+#include "AthenaKernel/IAtRndmGenSvc.h"
+
+//c - c++
+#include "zlib.h"
+#include "vector"
+
+#include "MdtCalibSvc/MdtCalibrationRegionSvc.h"
+
+class MdtCalibrationRegionSvc;
+class Identifier; 
+class MdtIdHelper;
+class IIOVDbSvc;
+class MsgStream;
+class IAtRndmGenSvc;
+
+namespace MuonGM{
+  class MuonDetectorManager;
+}
+
+namespace coral	{
+  class Blob;
+}
+
+#include "MdtCalibData/RtResolutionLookUp.h"
+#include "MuonCalibMath/SamplePoint.h"
+
+class MdtCalibDbAlg: public AthAlgorithm {
+
+ public:
+
+  MdtCalibDbAlg (const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~MdtCalibDbAlg() = default;
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute() override;
+  
+ private:
+  
+  ServiceHandle<ICondSvc> m_condSvc;
+
+  //like MdtCalibDbCoolStrTool
+  //removing obsolete ones
+
+  MuonCalib::MdtTubeCalibContainer* buildMdtTubeCalibContainer(const Identifier &id);
+  
+  StatusCode loadRt();
+  StatusCode defaultRt(std::unique_ptr<MdtRtRelationCollection>& writeCdoRt);
+  StatusCode loadTube();
+  StatusCode defaultT0s(std::unique_ptr<MdtTubeCalibContainerCollection>& writeCdoTube);
+
+  const MdtIdHelper *m_mdtIdHelper;
+  const MuonGM::MuonDetectorManager *m_detMgr;
+  ToolHandle<MuonCalib::IIdToFixedIdTool> m_idToFixedIdTool;
+  ServiceHandle<MdtCalibrationRegionSvc> m_regionSvc;
+
+  std::string      m_rtFolder;
+  std::string      m_tubeFolder;
+
+  //like MdtCalibrationDbSvc
+  //for corData in loadRt
+  bool m_create_b_field_function;
+  bool m_createWireSagFunction;
+  bool m_createSlewingFunction;
+  void initialize_B_correction(MuonCalib::MdtCorFuncSet *funcSet, const MuonCalib::MdtRtRelation *rt);
+  void initializeSagCorrection(MuonCalib::MdtCorFuncSet *funcSet);
+
+  //if m_TimeSlewingCorrection is set to true then it is assumed that the
+  //time slewing correction is applied. If false not. If this flag does
+  //not match the bit in the creation parameters, the rt-relation and t0
+  //will be corrected.
+  //NOTE: This was a preliminary solution for 17.2. In principle each
+  //MdtDriftCircleOnTrackCreator could decide individually if it wants to
+  //have TS-correction. In the default reco-jobs however, this is
+  //configured by one muonRecFlag, that will be used to set this job-option.
+  
+  bool   m_TimeSlewingCorrection;
+  bool   m_UseMLRt;
+  std::vector<float> m_MeanCorrectionVsR;
+  float  m_TsCorrectionT0;
+  double m_defaultT0;
+  double m_t0Shift;
+  double m_t0Spread;
+  double m_rtShift;
+  double m_rtScale;
+  double m_prop_beta;
+  ServiceHandle<IAtRndmGenSvc> m_AtRndmGenSvc;
+  //TODO: This is the old, non thread-safe implementation of the random numbers service. It might be useful to use the new one (IAthRNGSvc).
+  CLHEP::HepRandomEngine *m_engine;
+
+  StringArrayProperty m_RTfileNames; //temporary!!!
+
+  //decompression buffer and length of buffer
+  uLongf m_buffer_length;
+  std::unique_ptr<Bytef> m_decompression_buffer;
+  
+  //wrapper function for the zlib uncompress, 
+  //that automatically creates or increases the buffer if needed.    
+  inline bool uncompressInMyBuffer(const coral::Blob &blob);
+  inline MuonCalib::RtResolutionLookUp* getRtResolutionInterpolation(const std::vector<MuonCalib::SamplePoint> &sample_points);
+  inline StatusCode extractString(std::string& input, std::string& output, std::string separator);  
+
+  SG::ReadCondHandleKey<CondAttrListCollection> m_readKeyRt;
+  SG::ReadCondHandleKey<CondAttrListCollection> m_readKeyTube;
+  SG::WriteCondHandleKey<MdtRtRelationCollection> m_writeKeyRt{this,"MdtRtRelationCollection","MdtRtRelationCollection","MDT RT relations"};
+  SG::WriteCondHandleKey<MdtTubeCalibContainerCollection> m_writeKeyTube{this,"MdtTubeCalibContainerCollection","MdtTubeCalibContainerCollection","MDT tube calib"};
+  SG::WriteCondHandleKey<MdtCorFuncSetCollection> m_writeKeyCor{this,"MdtCorFuncSetCollection","MdtCorFuncSetCollection","MDT cor Funcs"};
+   
+};
+
+#endif
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool.h
index f340ab04cb913f7ce5610b54909abcd480cb043f..acf0dea5ba370ec8034ca859b7d90ab7c8d1538a 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool.h
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool.h
@@ -17,6 +17,8 @@
 #include "zlib.h"
 #include "vector"
 
+#include "MdtCalibSvc/MdtCalibrationRegionSvc.h"
+
 class MdtCalibrationRegionSvc;
 class Identifier; 
 class MdtIdHelper;
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbAlg.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..522f62794110fd6f1108338df9303e7fb461beb4
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbAlg.cxx
@@ -0,0 +1,1106 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MdtCalibDbCoolStrTool/MdtCalibDbAlg.h"
+
+//from MdtCalibDbCoolStrTool.cxx
+
+#include "StoreGate/StoreGateSvc.h"
+#include "SGTools/TransientAddress.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeListSpecification.h"
+#include "CoralBase/Blob.h"
+#include "AthenaPoolUtilities/AthenaAttributeList.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+
+#include "Identifier/IdentifierHash.h"
+#include "MuonIdHelpers/MdtIdHelper.h"
+
+#include "MdtCalibData/CalibFunc.h"
+#include "MuonCalibStl/ToString.h"
+#include "MdtCalibUtils/RtDataFromFile.h"
+#include "PathResolver/PathResolver.h"
+#include "MdtCalibData/MdtCalibrationFactory.h"
+#include "MdtCalibData/IRtRelation.h"
+#include "MdtCalibData/IRtResolution.h"
+#include "MuonCalibMath/SamplePoint.h"
+#include "MuonCalibTools/IdToFixedIdTool.h"
+#include "MuonCalibIdentifier/MuonFixedId.h"
+#include "MuonCalibIdentifier/MdtCalibCreationFlags.h"
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "MdtCalibSvc/MdtCalibrationRegionSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+
+#include "MdtCalibData/MdtRtRelationCollection.h"
+#include "MdtCalibData/MdtTubeCalibContainerCollection.h"
+#include "MdtCalibData/RtFromPoints.h"
+#include "MdtCalibData/RtResolutionFromPoints.h"
+
+#include "MuonReadoutGeometry/MuonDetectorManager.h"
+#include "MuonReadoutGeometry/MdtReadoutElement.h"
+
+#include "AthenaKernel/IIOVDbSvc.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+#include "CLHEP/Random/RandGaussZiggurat.h"
+
+#include "TSpline.h"
+#include "TFile.h"
+
+//like MdtCalibrationDbSvc
+//for corData in loadRt
+
+#include "MdtCalibData/MdtCorFuncSetCollection.h"
+#include "MdtCalibData/MdtFullCalibData.h"
+#include "MdtCalibData/BFieldCorFunc.h"
+#include "MdtCalibData/WireSagCorFunc.h"
+#include "MdtCalibData/MdtSlewCorFuncHardcoded.h"
+#include "MdtCalibData/CalibFunc.h"
+
+//TODO: use smart pointers
+//TODO: avoid dynamic char array
+//TODO: check if temporary things can be removed
+
+#include "GaudiKernel/PhysicalConstants.h"
+
+MdtCalibDbAlg::MdtCalibDbAlg(const std::string& name, ISvcLocator* pSvcLocator) :
+  AthAlgorithm(name, pSvcLocator),
+  m_condSvc{"CondSvc", name},
+  m_idToFixedIdTool("MuonCalib::IdToFixedIdTool"),
+  m_regionSvc("MdtCalibrationRegionSvc", name),
+  m_rtFolder("/MDT/RTBLOB"),
+  m_tubeFolder("/MDT/T0BLOB"),
+  m_TimeSlewingCorrection(false),
+  m_UseMLRt(true),
+  m_TsCorrectionT0(0.),
+  m_defaultT0(40.),
+  m_t0Shift(0.),
+  m_t0Spread(0.),
+  m_rtShift(0.),
+  m_rtScale(1.),
+  m_prop_beta(1.0),
+  m_AtRndmGenSvc ("AtRndmGenSvc", name),
+  m_buffer_length(0),
+  m_decompression_buffer(nullptr),
+  m_readKeyRt("/MDT/RTBLOB"),
+  m_readKeyTube("/MDT/T0BLOB")
+{
+
+  //Db Folders
+  declareProperty("TubeFolder",m_tubeFolder,"DB folder containing the tube constants");
+  declareProperty("RtFolder",m_rtFolder,"DB folder containing the RT calibrations");
+  declareProperty("ReadKeyTube",m_readKeyTube);
+  declareProperty("ReadKeyRt",m_readKeyRt);
+  
+  //Properties to deform the t0 and rt relationship
+  declareProperty("T0Shift",m_t0Shift,"for simulation: common shift of all T0s, in ns");
+  declareProperty("T0Spread",m_t0Spread,"for simulation: sigma for random smeraing of T0s, in ns");
+  declareProperty("RTShift",m_rtShift,"for simulations: maximum RT distortion, in mm");
+  declareProperty("RTScale",m_rtScale,"for simulations: a muliplicitive scale to the drift r");
+
+  //is this the simplest way to initialize a list?
+  std::ostringstream myse;
+  std::vector<std::string> myord;
+  myse << "DC2_rt_default.dat";
+  myord.push_back(myse.str());
+
+  declareProperty("RT_InputFiles",m_RTfileNames=myord,"single input ascii file for default RT to be applied in absence of DB information");
+
+  //defaultT0, used for tubes not found in DB
+  declareProperty("defaultT0",m_defaultT0,"default T0 value to be used in absence of DB information");
+  declareProperty("TimeSlewingCorrection", m_TimeSlewingCorrection);
+  declareProperty("MeanCorrectionVsR", m_MeanCorrectionVsR);
+  declareProperty("UseMLRt", m_UseMLRt,"Enable use of ML-RTs from COOL");
+  declareProperty("PropagationSpeedBeta", m_prop_beta);
+
+  //like MdtCalibrationDbSvc
+  //for corData in loadRt
+  declareProperty("CreateBFieldFunctions", m_create_b_field_function = false,
+		  "If set to true, the B-field correction functions are initialized for each rt-relation that is loaded.");
+  declareProperty("CreateWireSagFunctions", m_createWireSagFunction = false,
+		  "If set to true, the wire sag correction functions are initialized for each rt-relation that is loaded.");
+  declareProperty("CreateSlewingFunctions", m_createSlewingFunction = false,
+		  "If set to true, the slewing correction functions are initialized for each rt-relation that is loaded.");
+
+}
+
+StatusCode MdtCalibDbAlg::initialize(){
+
+  ATH_MSG_DEBUG( "initialize " << name() );
+  ATH_CHECK(m_condSvc.retrieve());
+
+  //if timeslew correction vector m_MeanCorrectionVsR has non-zero size then set
+  //m_TsCorrectionT0=m_MeanCorrectionVsR[0] and subtract this each value in the vector.
+  if(m_MeanCorrectionVsR.size()) {
+    m_TsCorrectionT0 = m_MeanCorrectionVsR[0];
+    for(std::vector<float>::iterator it=m_MeanCorrectionVsR.begin(); it!=m_MeanCorrectionVsR.end(); it++) {
+      (*it) -= m_TsCorrectionT0;
+    }
+  }
+
+  ATH_CHECK( detStore()->retrieve(m_mdtIdHelper, "MDTIDHELPER" ) );
+  ATH_CHECK( detStore()->retrieve( m_detMgr ) );
+  ATH_CHECK( m_regionSvc.retrieve() );
+  ATH_CHECK( m_idToFixedIdTool.retrieve() );
+
+  // initialize MdtRtRelationCollection 
+  // if COOL RT folder is called /MDT/RTUNIQUE then only read one RT from COOL and use for all chambers
+  // Not sure this option has ever been used, perhaps could be used for simulated data.
+  // Job option RtFolder would need to be set to "/MDT/RTUNIQUE" to make this work.
+  if(m_rtFolder == "/MDT/RTUNIQUE") {
+    m_regionSvc->remapRtRegions("OneRt"); 
+  } else if( m_UseMLRt ) {
+    m_regionSvc->remapRtRegions("OnePerMultilayer");
+  } else {
+    m_regionSvc->remapRtRegions("OnePerChamber");
+  }
+  
+  //initiallize random number generator if doing t0 smearing (for robustness studies)
+  if( m_t0Spread != 0. ) {
+    ATH_CHECK( m_AtRndmGenSvc.retrieve() );
+    ATH_MSG_DEBUG( " initialize Random Number Service: running with t0 shift "
+                    << m_t0Shift << " spread " << m_t0Spread << " rt shift " << m_rtShift );
+      
+    // getting our random numbers stream
+    m_engine = m_AtRndmGenSvc->GetEngine("MDTCALIBDBALG");
+    //m_engine = m_AtRndmGenSvc->GetEngine("MDTCALIBDBASCIITOOL");
+    //if we need to reproduce something
+  }
+
+  if ( m_rtShift != 0. || m_rtScale != 1. || m_t0Shift != 0. || m_t0Spread != 0.) {
+    ATH_MSG_INFO( "************************************" << std::endl
+                   << " Running with Calibration Deformations! " << std::endl
+                   << " For performance studies only!" << std::endl
+                   << " **************************************" );
+    ATH_MSG_DEBUG( " rt scale " << m_rtScale << " t0 shift " 
+                    << m_t0Shift << " spread " << m_t0Spread << " rt shift " << m_rtShift );
+  }
+
+  ATH_CHECK(m_readKeyRt.initialize());
+  ATH_CHECK(m_readKeyTube.initialize());
+  ATH_CHECK(m_writeKeyRt.initialize());
+  ATH_CHECK(m_writeKeyTube.initialize());
+  ATH_CHECK(m_writeKeyCor.initialize());
+
+  if(m_condSvc->regHandle(this, m_writeKeyRt).isFailure()) {
+    ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKeyRt.fullKey() << " with CondSvc");
+    return StatusCode::FAILURE;
+  }
+  if(m_condSvc->regHandle(this, m_writeKeyTube).isFailure()) {
+    ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKeyTube.fullKey() << " with CondSvc");
+    return StatusCode::FAILURE;
+  }
+  if(m_condSvc->regHandle(this, m_writeKeyCor).isFailure()) {
+    ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKeyCor.fullKey() << " with CondSvc");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode MdtCalibDbAlg::execute(){
+  
+  ATH_MSG_DEBUG( "execute " << name() );  
+
+  if ( loadRt().isFailure() ) {
+    ATH_MSG_FATAL("loadRt().isFailure()");
+    return StatusCode::FAILURE;
+  }
+
+  if ( loadTube().isFailure() ) {
+    ATH_MSG_FATAL("loadTube().isFailure()");
+    return StatusCode::FAILURE;
+  }
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode MdtCalibDbAlg::defaultRt(std::unique_ptr<MdtRtRelationCollection>& writeCdoRt){
+  ATH_MSG_DEBUG( "defaultRt " << name() );
+
+  if ( writeCdoRt == nullptr ) {
+    ATH_MSG_ERROR("writeCdoRt == nullptr");
+    return StatusCode::FAILURE; 
+  }   
+
+  //Build the transient structure in StoreGate and load default RT function read from a text file
+  //In principle, a list of text files can be specified in the job options, and each text file
+  //may potentially contain multiple RT functions.  However, only the first valid RT function in
+  //the first text file is used as the default for all chambers.
+
+  writeCdoRt->resize(m_regionSvc->numberOfRegions());
+  ATH_MSG_DEBUG( "Created new MdtRtRelationCollection size " << writeCdoRt->size() );
+
+  // Check that an RT text file has been specified in job options
+  std::vector<std::string>::const_iterator it     = m_RTfileNames.value().begin();
+  std::vector<std::string>::const_iterator it_end = m_RTfileNames.value().end();
+  if (it == it_end ) {
+    ATH_MSG_FATAL( "No input RT file declared in jobOptions");
+    return StatusCode::FAILURE;
+  } else if (it_end-it>1) {
+    ATH_MSG_WARNING( "Only first RT file declared in jobOptions will be used");
+  }
+
+  // Open the Ascii file with the RT relations
+  std::string fileName = PathResolver::find_file(it->c_str(),"DATAPATH");
+  if(fileName.length() == 0) {
+    ATH_MSG_ERROR( "RT Ascii file \"" <<  it->c_str() << "\" not found" );
+  }
+  std::ifstream inputFile( fileName.c_str() );
+  if( !inputFile ) {
+    ATH_MSG_ERROR( "Unable to open RT Ascii file: " << fileName.c_str() );
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG( "Opened RT Ascii file: " <<  fileName.c_str() );
+  }
+
+  // Read the RTs from the text file
+  MuonCalib::RtDataFromFile rts;
+  rts.read(inputFile);
+  ATH_MSG_VERBOSE( "File contains " << rts.nRts() << " RT relations " );
+
+  // Loop over all RTs in the file (but the default file only has 1 RT)
+  // Use the first valid RT found in the file as the default for all chambers.
+  for(unsigned int n=0;n<rts.nRts();++n) {
+    std::unique_ptr<MuonCalib::RtDataFromFile::RtRelation> rt(rts.getRt(n));
+
+    const MuonCalib::RtDataFromFile::RtRelation::DataVec &times = rt->times();
+    const MuonCalib::RtDataFromFile::RtRelation::DataVec &radii = rt->radii();
+    const MuonCalib::RtDataFromFile::RtRelation::DataVec &reso  = rt->resolution();
+
+    // check if rt contains data, at least two points on the rt are required
+    if( times.size() < 2 ) {
+      ATH_MSG_ERROR( " defaultRt rt table has too few entries" );
+      continue;
+    }
+    // check if all tables have same size
+    if( times.size() != radii.size() || times.size() != reso.size() ) {
+      ATH_MSG_ERROR( "defaultRt rt table size mismatch " );
+      continue;
+    }
+    // check for negative time bins, i.e. decreasing time value with radius
+    double t_min    = times[0];
+    double bin_size = times[1]-t_min;
+    if( bin_size <= 0 ) {
+      ATH_MSG_ERROR( "defaultRt rt table negative binsize " );
+      continue;
+    }
+
+    // create a vector to hold the r values,
+    // we need two extra fields to store t_min and bin_size
+    MuonCalib::CalibFunc::ParVec rtPars;
+    rtPars.push_back( t_min );
+    rtPars.push_back( bin_size );
+
+    // copy r values into vector
+    rtPars.insert( rtPars.end(), radii.begin(), radii.end() );
+
+    ATH_MSG_DEBUG( "defaultRt new MuonCalib::IRtRelation" );
+
+    MuonCalib::CalibFunc::ParVec resoPars;
+    resoPars.push_back( t_min );
+    resoPars.push_back( bin_size );
+
+    // copy r values into vector
+    resoPars.insert( resoPars.end(), reso.begin(), reso.end() );
+
+    ATH_MSG_DEBUG( "defaultRt new MuonCalib::IRtResolution" );
+
+    // create RT and resolution "I" objects
+    MuonCalib::IRtRelation *rtRel = MuonCalib::MdtCalibrationFactory::createRtRelation( "RtRelationLookUp", rtPars );
+    if( !rtRel ) ATH_MSG_WARNING( "ERROR creating RtRelationLookUp " );
+
+    MuonCalib::IRtResolution *resoRel = MuonCalib::MdtCalibrationFactory::createRtResolution( "RtResolutionLookUp", resoPars );
+    if( !resoRel ) ATH_MSG_WARNING( "ERROR creating RtResolutionLookUp " );
+
+    // if either RT and resolution are not OK then delete both and try next RT in file
+    if( !resoRel || !rtRel ) {
+      if(resoRel) delete resoRel;
+      if(rtRel) delete rtRel;
+      continue;
+    }
+
+    //Since the same RT is loaded for all chambers you might be tempted to create it once
+    //and simply store the same pointer in writeCdoRt for all regions.
+    //However it seems that when StoreGate clears writeCdoRt (which will happen in LoadRt
+    //by detStore()->removeDataAndProxy) it will crash unless there are unique pointers/objects
+    //for rtRel, resoRel, and MdtRtRelation
+
+    //Loop over RT regions and store the default RT in each
+    for(unsigned int iregion=0; iregion<writeCdoRt->size(); iregion++) {
+      ATH_MSG_DEBUG( "Inserting default Rt for region "<<iregion);
+      // create RT and resolution "I" objects, again, so they can all be cleanly deleted later.
+      MuonCalib::IRtRelation* rtRelRegion = MuonCalib::MdtCalibrationFactory::createRtRelation( "RtRelationLookUp", rtPars );
+      MuonCalib::IRtResolution* resoRelRegion = MuonCalib::MdtCalibrationFactory::createRtResolution( "RtResolutionLookUp", resoPars );
+      (*writeCdoRt)[iregion] = new MuonCalib::MdtRtRelation( rtRelRegion, resoRelRegion, 0. );
+    }   //end loop over RT regions
+
+    //if VERBOSE enabled print out RT function
+    if( msgLvl(MSG::VERBOSE) ) {
+      int npoints = rtRel->nPar()-2;
+      ATH_MSG_VERBOSE( "defaultRt npoints from rtRel="<< npoints );
+      for( int ipt=0;ipt<npoints;++ipt ){
+	double t = t_min + ipt*bin_size;
+	ATH_MSG_VERBOSE(" "<<ipt<<" "<<t<<" "<< rtRel->radius(t)<<" "<< resoRel->resolution(t));
+      }
+    }
+
+    delete resoRel;
+    delete rtRel;
+
+    break; //only need the first good RT from the text file
+
+  } //end loop over RTs in file
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode MdtCalibDbAlg::loadRt(){
+  ATH_MSG_DEBUG( "loadRt " << name() );
+
+  SG::WriteCondHandle<MdtRtRelationCollection> writeHandleRt{m_writeKeyRt};
+  if ( writeHandleRt.isValid() ) {
+    ATH_MSG_DEBUG("CondHandle " << writeHandleRt.fullKey() << " is already valid.");
+    return StatusCode::SUCCESS; 
+  }
+  std::unique_ptr<MdtRtRelationCollection> writeCdoRt{std::make_unique<MdtRtRelationCollection>()};
+
+  SG::WriteCondHandle<MdtCorFuncSetCollection> writeHandleCor{m_writeKeyCor};
+  if ( writeHandleCor.isValid() ) {
+    ATH_MSG_DEBUG("CondHandle " << writeHandleCor.fullKey() << " is already valid.");
+    return StatusCode::SUCCESS;
+  }
+  std::unique_ptr<MdtCorFuncSetCollection> writeCdoCor{std::make_unique<MdtCorFuncSetCollection>()};
+
+  //like MdtCalibDbCoolStrTool::loadRt()
+  //m_rtData is writeCdoRt here
+  //atrc is readCdoRt here
+
+  //tr-relation creators
+  MuonCalib::RtFromPoints rt_fromPoints;
+
+  if ( defaultRt(writeCdoRt).isFailure() ){
+    ATH_MSG_FATAL("defaultRt(writeCdoRt).isFailure()");
+    return StatusCode::FAILURE;
+  }
+  
+  //Read Cond Handle  
+  SG::ReadCondHandle<CondAttrListCollection> readHandleRt{ m_readKeyRt };
+  const CondAttrListCollection* readCdoRt{*readHandleRt}; 
+  if ( readCdoRt==nullptr ) {
+    ATH_MSG_ERROR("readCdoRt==nullptr");
+    return StatusCode::FAILURE; 
+  }   
+  EventIDRange rangeRt;
+  if ( !readHandleRt.range(rangeRt) ) {
+    ATH_MSG_ERROR("Failed to retrieve validity range for " << readHandleRt.key());
+    return StatusCode::FAILURE;
+  }  
+  ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleRt.fullKey() << " readCdoRt->size()= " << readCdoRt->size());
+  ATH_MSG_INFO("Range of input is " << rangeRt);
+
+  // unpack the strings in the collection and update the writeCdoRt
+  CondAttrListCollection::const_iterator itr;
+  for (itr = readCdoRt->begin(); itr != readCdoRt->end(); ++itr) {
+    const coral::AttributeList &atr=itr->second;
+    bool rt_ts_applied = (atr["tech"].data<int>() & MuonCalib::TIME_SLEWING_CORRECTION_APPLIED);
+    std::string header="",payload="",trailer="";
+    // if BLOB data
+    if (atr["data"].specification().type() == typeid(coral::Blob)){
+      ATH_MSG_VERBOSE( "Data load is a blob. Uncompressing");
+      if(!uncompressInMyBuffer(atr["data"].data<coral::Blob>())) {
+	ATH_MSG_FATAL( "Cannot uncompress buffer" );
+	return StatusCode::FAILURE;
+      }
+      std::string istr(reinterpret_cast<char*>(m_decompression_buffer.get()));
+      ATH_CHECK( extractString(istr, header, "\n") );
+      ATH_CHECK( extractString(istr, payload, "\n") );
+      if( istr.size() ) ATH_CHECK( extractString(istr, trailer, "\n") );
+    } else {      // else CLOB data
+      std::string data;
+      data = *(static_cast<const std::string*>((atr["data"]).addressOfData()));
+      ATH_MSG_VERBOSE( "Data load is " << data );
+      // interpret as string stream
+      std::string istr(data.c_str());
+      ATH_CHECK( extractString(istr, header, " ") );
+      ATH_CHECK( extractString(istr, payload, " ") );
+      if( istr.size() ) ATH_CHECK( extractString(istr, trailer, " ") );
+    }
+    ATH_MSG_VERBOSE( "Read header:" << header << " payload:" << payload << " trailer:" << trailer );
+
+    // the header contains the muonfixedid rather than the hash
+    char *parameters = new char [header.size()+1];
+    strncpy(parameters, header.c_str(), header.size()+1);
+    parameters[header.size()]='\0';
+    unsigned int regionId, npoints(0);
+    Identifier  athenaId; 
+    char *pch = strtok(parameters," _,");
+    regionId = atoi(pch);
+    //Long ago the hash was put in the RT file header, but now (2016) 
+    //the muonfixedid of the chamber is in the header.  Hence the "if" below will always be true.    
+    //TODO: put this magic number in constatnt
+    if(regionId>2500) {
+      MuonCalib::MuonFixedId id(regionId);
+      athenaId = m_idToFixedIdTool->fixedIdToId(id);
+      // If using chamber RTs skip RTs for ML2 -- use ML1 RT for entire chamber
+      if( m_regionSvc->RegionType()==ONEPERCHAMBER && m_mdtIdHelper->multilayer(athenaId)==2 ) {
+        ATH_MSG_VERBOSE("MdtCalibDbAlg::loadRt Ignore ML2 RT for region "<<regionId<<" "<<
+			m_mdtIdHelper->stationNameString(m_mdtIdHelper->stationName(athenaId))<<"_"<<
+			m_mdtIdHelper->stationPhi(athenaId)<<"_"<<m_mdtIdHelper->stationEta(athenaId)<<
+			" ML"<<m_mdtIdHelper->multilayer(athenaId));  //TEMP
+	continue;
+      }
+      IdentifierHash hash;  //chamber hash
+      IdContext idCont = m_mdtIdHelper->module_context();
+      idCont = m_mdtIdHelper->module_context();
+      m_mdtIdHelper->get_hash( athenaId, hash, &idCont );
+      ATH_MSG_VERBOSE( "Fixed region Id "<<regionId<<" converted into athena Id "<<athenaId <<" and then into hash "<<hash);
+      regionId = hash;      //reset regionId to chamber hash
+    }
+    // extract npoints in RT function
+    pch = strtok (NULL, "_,");
+    npoints = atoi(pch);
+    delete [] parameters;
+    MuonCalib::CalibFunc::ParVec rtPars;
+    MuonCalib::CalibFunc::ParVec resoPars;
+
+    MuonCalib::SamplePoint tr_point, ts_point;  //pairs of numbers; tr = (time,radius); ts = (time,sigma)  [sigma=resolution]
+    std::vector<MuonCalib::SamplePoint> tr_points(0), ts_points(0);  //all the points in time,radius [RT] and time,sigma [resolution func]
+    float multilayer_tmax_diff(-9e9);
+
+    double innerTubeRadius = -9999.;
+    const MuonGM::MdtReadoutElement *detEl = m_detMgr->getMdtReadoutElement( m_mdtIdHelper->channelID(athenaId,1,1,1) );
+    if( !detEl ){
+      ATH_MSG_INFO( "Ignoring nonexistant station in calibration DB: " << m_mdtIdHelper->print_to_string(athenaId) );
+    } else {
+      innerTubeRadius = detEl->innerTubeRadius();
+    }
+
+    char *RTPar= new char [payload.size()+1];
+    strncpy(RTPar, payload.c_str(), payload.size()+1);
+    RTPar[payload.size()]='\0';   //terminate string (not sure this is really needed because payload.c_str() should be terminated in \0)
+    char *pch1 = strtok (RTPar,",");
+    unsigned int n=0;
+    //loop over RT function payload (triplets of radius,time,sigma(=resolution) )
+    for( int k=1; pch1!=NULL && n<=npoints; pch1=strtok(NULL,", "), k++ ) {
+      if(k==1) {    //radius point
+	float radius = atof(pch1);       
+	if( m_rtShift != 0. ) {
+	  float oldradius = radius;
+	  //TODO: What is this magic number
+	  float rshift = m_rtShift*1.87652e-2*radius*(radius-innerTubeRadius);
+	  radius = oldradius + rshift;
+	  ATH_MSG_DEBUG( "DEFORM RT: old radius " << oldradius << " new radius " 
+			  << radius << " shift " << rshift << " max shift " << m_rtShift );
+	}
+       
+	if( m_rtScale !=1. ) {
+	  radius = radius*m_rtScale;
+	  ATH_MSG_DEBUG( "DEFORM RT: old radius " << radius << " new radius " 
+			  << radius << " scale factor " << m_rtScale );
+	}
+       
+	tr_point.set_x2(radius);
+      } else if(k==2) {     //time
+	float time= atof(pch1);
+	tr_point.set_x1(time);
+	ts_point.set_x1(time);
+      } else if(k==3) {     //sigma or resolution
+	float sigma= atof(pch1);
+	ts_point.set_x2(sigma);
+	ts_point.set_error(1.0);
+	tr_point.set_error(1.0);
+	if(tr_point.x2()<-99) {    //if radius is < -99 then treat time as ML Tmax difference
+	  multilayer_tmax_diff = tr_point.x1();
+	} else if(n==0 || (tr_points[n-1].x1()<tr_point.x1() && tr_points[n-1].x2()<tr_point.x2())) {
+	  tr_points.push_back(tr_point);	       
+	  ts_points.push_back(ts_point);
+	  n++;  //count points in RT
+	}
+	k=0;
+      }
+    }   //end loop over RT function payload (triplets of radius,time,resolution)
+    delete [] RTPar;
+
+    //Must have at least 3 points to have a valid RT
+    if(ts_points.size()<3) {
+      ATH_MSG_FATAL( "Rt relation broken!");
+      ATH_MSG_FATAL( "file='"<<atr["file"].data<std::string>()<<"'");
+      ATH_MSG_FATAL( "header='"<<header<<"'");
+      return StatusCode::FAILURE;
+    }
+
+    if(rt_ts_applied != m_TimeSlewingCorrection) {
+      float sign(rt_ts_applied ? -1.0 : 1.0);
+      float slice_width = innerTubeRadius/static_cast<float>(m_MeanCorrectionVsR.size());
+      for(std::vector<MuonCalib::SamplePoint>::iterator it=tr_points.begin(); it!=tr_points.end(); it++) {
+	int slice_number=static_cast<int>(std::floor(it->x2()/slice_width));		
+	if (slice_number<0)
+	  slice_number=0;
+	if (slice_number >= static_cast<int>(m_MeanCorrectionVsR.size()))
+	  slice_number = static_cast<int>(m_MeanCorrectionVsR.size()) - 1;
+	it->set_x1(it->x1() + sign * m_MeanCorrectionVsR[slice_number]);	
+      }
+    }
+    
+    //Create resolution function from ts_points
+    MuonCalib::IRtResolution *reso = getRtResolutionInterpolation(ts_points);
+    if (msgLvl(MSG::DEBUG)) {
+      ATH_MSG_DEBUG( "Resolution points :");
+      for(std::vector<MuonCalib::SamplePoint>::const_iterator it=tr_points.begin(); it!=tr_points.end(); it++) {
+	ATH_MSG_DEBUG( it->x1()<<"|"<<it->x2()<<"|"<<it->error());
+      }
+	
+      ATH_MSG_DEBUG( "Resolution parameters :");
+      for(unsigned int i=0; i<reso->nPar(); i++) {
+	ATH_MSG_DEBUG(  i<<" "<<reso->par(i) );
+      }
+    }
+
+    //Create RT function from tr_points and load RT and resolution functions 
+    try {
+      MuonCalib::IRtRelation *rt = new MuonCalib::RtRelationLookUp(rt_fromPoints.getRtRelationLookUp(tr_points));
+      if( reso && rt ){
+	if(regionId>=writeCdoRt->size()) {
+	  delete reso; delete rt;
+	  ATH_MSG_WARNING( "Illegal regionId "<< regionId );
+	} else { 
+	  if (rt->par(1)==0.) {
+	    ATH_MSG_WARNING( "Bin size is 0");
+	    for(std::vector<MuonCalib::SamplePoint>::const_iterator it=tr_points.begin(); it!=tr_points.end(); it++)
+	      ATH_MSG_WARNING( it->x1() << " " <<it->x2() <<" "<< it->error() );
+	  }
+	  //Save ML difference if it is available
+	  if(multilayer_tmax_diff>-8e8) {
+	    rt->SetTmaxDiff(multilayer_tmax_diff);
+	  }
+	  //Store RT and resolution functions for this region
+	  if( m_regionSvc->RegionType() == ONERT ) {
+	    (*writeCdoRt)[0] = new MuonCalib::MdtRtRelation( rt, reso, 0.);
+	    break;   // only read one RT from COOL for ONERT option.
+	  // If doing ML2 RTs, and this is a ML2 RT function then add it to the end of writeCdoRt
+	  } else if( m_regionSvc->RegionType()==ONEPERMULTILAYER && m_mdtIdHelper->multilayer(athenaId)==2 ) {
+	    ATH_MSG_VERBOSE("MdtCalibDbAlg::loadRt Load ML2 RT for region "<<regionId<<" "<<
+			 m_mdtIdHelper->stationNameString(m_mdtIdHelper->stationName(athenaId))<<"_"<<
+			 m_mdtIdHelper->stationPhi(athenaId)<<"_"<<m_mdtIdHelper->stationEta(athenaId)<<
+			 " ML"<<m_mdtIdHelper->multilayer(athenaId));
+	    (*writeCdoRt).push_back(new MuonCalib::MdtRtRelation( rt, reso, 0.));
+	    IdentifierHash mlHash;
+	    m_mdtIdHelper->get_detectorElement_hash( athenaId, mlHash ); 
+	    m_regionSvc->setRegionHash(mlHash);
+	  } else {   //store RT for chamber or ML1 if doing ONEPERMULTILAYER
+	    (*writeCdoRt)[regionId] = new MuonCalib::MdtRtRelation( rt, reso, 0.);
+	    //TODO: add setter method to the container to check if you are not overwriting an existing pointer
+	  }
+	}      //end else regionId is OK
+      }        //end if reso && rt
+    }          //end try
+    //TODO: What kind of exceptions can you get here
+    catch (int i) {
+      ATH_MSG_FATAL( "Error in creating rt-relation!" );
+      ATH_MSG_FATAL( "npoints="<<tr_points.size());
+      ATH_MSG_FATAL( "Offending input: header=" << header );
+      ATH_MSG_FATAL( "Offending input: payload=" << payload );
+      return StatusCode::FAILURE;
+    }
+    
+  }//end loop over itr (strings read from COOL)
+  ATH_MSG_INFO("MdtCalibDbAlg::loadRt Read "<<m_regionSvc->numberOfRegions()<<"RTs from COOL");
+
+  //like MdtCalibrationDbSvc
+  //for corData in loadRt
+
+  //If all of the 3 cor flags were 0
+  //it returned success here in prvious Tool
+  //but here at least record default as an Alg
+  //and then check flags again in the DbSvc
+
+  writeCdoCor->resize(writeCdoRt->size());
+  ATH_MSG_DEBUG( "Initializing " << writeCdoCor->size() << " b-field functions" );
+  for (unsigned int i=0; i < writeCdoCor->size(); i++) {
+    (*writeCdoCor)[i] = new MuonCalib::MdtCorFuncSet();
+    if(m_create_b_field_function) initialize_B_correction((*writeCdoCor)[i], (*writeCdoRt)[i]);
+    if(m_createWireSagFunction)   initializeSagCorrection((*writeCdoCor)[i]);
+    if(m_createSlewingFunction)   (*writeCdoCor)[i]->setSlewing(new MuonCalib::MdtSlewCorFuncHardcoded(MuonCalib::CalibFunc::ParVec()));
+  }
+
+  //finally record writeCdo
+
+  if ( writeCdoRt->size()==0 ) {
+    ATH_MSG_WARNING("writeCdoRt->size()==0"); 
+    return StatusCode::FAILURE;
+  }
+  if (writeHandleRt.record(rangeRt, std::move(writeCdoRt)).isFailure()) {
+    ATH_MSG_FATAL("Could not record " << writeHandleRt.key()
+		  << " with EventRange " << rangeRt
+		  << " into Conditions Store");
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("recorded new " << writeHandleRt.key()
+	       << " with range " << rangeRt
+	       << " into Conditions Store");
+
+  if ( writeCdoCor->size()==0 ) {
+    ATH_MSG_WARNING("writeCdoCor->size()==0");
+    return StatusCode::FAILURE;
+  }
+  if (writeHandleCor.record(rangeRt, std::move(writeCdoCor)).isFailure()) {
+    ATH_MSG_FATAL("Could not record " << writeHandleCor.key()
+		  << " with EventRange " << rangeRt
+		  << " into Conditions Store");
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("recorded new " << writeHandleCor.key()
+	       << " with range " << rangeRt
+	       << " into Conditions Store");
+  
+  return StatusCode::SUCCESS;
+}
+
+
+// build the transient structure and load some defaults for T0s
+StatusCode MdtCalibDbAlg::defaultT0s(std::unique_ptr<MdtTubeCalibContainerCollection>& writeCdoTube) {
+
+  if ( writeCdoTube == nullptr ) {
+    ATH_MSG_ERROR("writeCdoTube == nullptr");
+    return StatusCode::FAILURE; 
+  }
+  
+  //like MdtCalibDbCoolStrTool::defaultT0s()
+  //m_tubeData is writeCdoTube here
+
+  writeCdoTube->resize( m_mdtIdHelper->module_hash_max() );
+  ATH_MSG_DEBUG( " Created new MdtTubeCalibContainerCollection size " << writeCdoTube->size() );
+
+  // Inverse of wire propagation speed
+  float inversePropSpeed = 1./(Gaudi::Units::c_light*m_prop_beta);
+
+  //loop over modules (MDT chambers) and create an MdtTubeContainer for each
+  MdtIdHelper::const_id_iterator it     = m_mdtIdHelper->module_begin();
+  MdtIdHelper::const_id_iterator it_end = m_mdtIdHelper->module_end();
+  for(; it!=it_end;++it ) {
+    MuonCalib::MdtTubeCalibContainer *tubes=0;
+    //create an MdtTubeContainer
+    tubes = buildMdtTubeCalibContainer(*it);
+
+    // is tubes ever 0?  how could that happen?
+    if(tubes) {
+      std::string rName=tubes->regionKey();
+      double t0 = m_defaultT0;
+
+      int nml=tubes->numMultilayers();
+      int nlayers=tubes->numLayers();
+      int ntubes=tubes->numTubes();
+      int size = nml*nlayers*ntubes;
+      ATH_MSG_VERBOSE( "Adding chamber " << m_mdtIdHelper->print_to_string(*it) );
+      ATH_MSG_VERBOSE( " size " << size << " ml " << nml << " l " << nlayers << " t " 
+		       << ntubes << " address " << tubes );
+      for( int ml=0;ml<nml;++ml ){
+	for( int l=0;l<nlayers;++l ){
+	  for( int t=0;t<ntubes;++t ){
+	    MuonCalib::MdtTubeCalibContainer::SingleTubeCalib data;
+	    data.t0 = t0;
+	    data.adcCal = 1.;
+	    data.inversePropSpeed = inversePropSpeed;
+	    tubes->setCalib( ml,l,t,data );
+	  }
+	}
+      }
+    }  //end loop over chambers (modules)
+    ATH_MSG_VERBOSE( " set t0's done " );
+    IdentifierHash hash;
+    IdContext idCont = m_mdtIdHelper->module_context();
+    m_mdtIdHelper->get_hash( *it, hash, &idCont );
+
+    if( hash < writeCdoTube->size() ){
+      (*writeCdoTube)[hash] = tubes;
+      ATH_MSG_VERBOSE( " adding tubes at " << hash << " current size " << writeCdoTube->size() );
+//write out string for chamberlist
+      if(tubes) {
+	int nml     = tubes->numMultilayers();
+	int nlayers = tubes->numLayers();
+	int ntubes  = tubes->numTubes();	
+	ATH_MSG_VERBOSE( "CHAMBERLIST: " << m_mdtIdHelper->stationNameString(m_mdtIdHelper->stationName(*it)) << " " << m_mdtIdHelper->stationEta(*it) << " " << m_mdtIdHelper->stationPhi(*it) << " " << nml*nlayers*ntubes << " " << nml << " " << nlayers << " " << ntubes << " dummy " << hash );
+      }
+    } else {
+      if(tubes) delete tubes;
+      ATH_MSG_WARNING( " HashId out of range " << hash << " max " << writeCdoTube->size() );
+    }
+  }
+  ATH_MSG_DEBUG( " Done defaultT0s " << writeCdoTube->size() );
+
+  return StatusCode::SUCCESS;
+}  //end MdtCalibDbAlg::defaultT0s
+
+
+StatusCode MdtCalibDbAlg::loadTube(){
+  ATH_MSG_DEBUG( "loadTube " << name() );
+
+  SG::WriteCondHandle<MdtTubeCalibContainerCollection> writeHandleTube{m_writeKeyTube};
+  if ( writeHandleTube.isValid() ) {
+    ATH_MSG_DEBUG("CondHandle " << writeHandleTube.fullKey() << " is already valid.");
+    return StatusCode::SUCCESS; 
+  }
+  std::unique_ptr<MdtTubeCalibContainerCollection> writeCdoTube{std::make_unique<MdtTubeCalibContainerCollection>()};
+
+  //like MdtCalibDbCoolStrTool::loadTube()
+  //m_tubeData is writeCdoTube here
+  //atrc is readCdoTube here
+
+  if ( defaultT0s(writeCdoTube).isFailure() ) {
+    ATH_MSG_FATAL("defaultT0s().isFailure()");
+    return StatusCode::FAILURE;
+  }
+  
+  //Read Cond Handle  
+  SG::ReadCondHandle<CondAttrListCollection> readHandleTube{ m_readKeyTube };
+  const CondAttrListCollection* readCdoTube{*readHandleTube}; 
+  if ( readCdoTube==nullptr ) {
+    ATH_MSG_ERROR("readCdoTube==nullptr");
+    return StatusCode::FAILURE; 
+  }   
+  EventIDRange rangeTube;
+  if ( !readHandleTube.range(rangeTube) ) {
+    ATH_MSG_ERROR("Failed to retrieve validity range for " << readHandleTube.key());
+    return StatusCode::FAILURE;
+  }  
+  ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleTube.fullKey() << " readCdoTube->size()= " << readCdoTube->size());
+  ATH_MSG_INFO("Range of input is " << rangeTube);
+  
+  // Inverse of wire propagation speed
+  float inversePropSpeed = 1./(Gaudi::Units::c_light*m_prop_beta);
+
+  // unpack the strings in the collection and update the 
+  // MdtTubeCalibContainers in TDS
+  CondAttrListCollection::const_iterator itr;
+  for (itr = readCdoTube->begin(); itr != readCdoTube->end(); ++itr) {
+    const coral::AttributeList &atr = itr->second;
+    std::string header="",payload="",trailer="";
+
+    bool t0_ts_applied = (atr["tech"].data<int>() & MuonCalib::TIME_SLEWING_CORRECTION_APPLIED);
+    // If BLOB data then uncompress
+    if (atr["data"].specification().type() == typeid(coral::Blob)) {
+      ATH_MSG_VERBOSE( "Data load is a blob. Uncompressing");
+      if(!uncompressInMyBuffer(atr["data"].data<coral::Blob>())) {
+	ATH_MSG_FATAL( "Cannot uncompress buffer" );
+	return StatusCode::FAILURE;
+      }
+      std::string istr(reinterpret_cast<char*>(m_decompression_buffer.get()));
+      ATH_CHECK( extractString(istr, header, "\n") );
+      ATH_CHECK( extractString(istr, payload, "\n") );
+      if( istr.size() ) ATH_CHECK( extractString(istr, trailer, "\n") );
+    } else {        //else is uncompressed CLOB (no longer used)
+      std::string data;
+      data = *(static_cast<const std::string*>((atr["data"]).addressOfData()));
+      ATH_MSG_VERBOSE( "Data load is " << data );
+
+      // interpret as string stream
+      std::string istr(data.c_str());
+      ATH_CHECK( extractString(istr, header, "\n") );
+      ATH_CHECK( extractString(istr, payload, "\n") );
+      if( istr.size() ) ATH_CHECK( extractString(istr, trailer, "\n") );
+    }
+    ATH_MSG_VERBOSE( "Read header:" << header << " payload:" << payload << " trailer:" << trailer );
+
+    // Extract info from the header line, chamber name, number of tubes.
+    int ieta=-99, iphi=-99, region=-99, ntubes=-99;
+    //    std::string rName;
+
+    // parameters for the MdtTubeContainer
+    // header filename,version,region,tubes
+    char *parameters = new char [header.size()+1];
+    strncpy(parameters, header.c_str(), header.size()+1);
+    parameters[header.size()] = '\0';      //terminate string
+    char *pch = strtok(parameters," _,");  //split using delimiters "_" and ","
+    std::string name(pch,2,3);             //extract 3-character station to "name" (e.g. BIL) 
+
+    // Split header line and extract phi, eta, region, ntubes
+    pch = strtok (NULL, "_,");
+    for( int i=1; pch!=NULL; pch=strtok(NULL,"_,"), i++ ) {
+      std::istringstream is(pch);
+      if(i==1) {
+	is >> iphi; 
+      } else if(i==2) {
+	is >> ieta; 
+      } else if(i==4) {
+	is >> region; 
+      } else if(i==5) {
+	is >> ntubes; 
+      }
+    }
+    delete [] parameters;
+
+    // find chamber ID
+    Identifier chId = m_mdtIdHelper->elementID(name,ieta,iphi);
+ 
+    MuonCalib::MdtTubeCalibContainer *tubes = NULL;
+
+    // get chamber hash
+    IdentifierHash hash;
+    IdContext idCont = m_mdtIdHelper->module_context();
+    m_mdtIdHelper->get_hash( chId , hash, &idCont );
+
+    if( msgLvl(MSG::VERBOSE) ) {
+      ATH_MSG_VERBOSE( "name of chamber is " << pch << " station name is " << name );
+      ATH_MSG_VERBOSE( "phi value is " << iphi );
+      ATH_MSG_VERBOSE( "eta value is " << ieta );
+      ATH_MSG_VERBOSE( "region value is " << region );
+      ATH_MSG_VERBOSE( "ntubes value is " << ntubes );
+      ATH_MSG_VERBOSE( "station name is " << name << " chamber ID  is " << chId );
+      ATH_MSG_VERBOSE( "corresponding hash is " << hash );
+    }
+    
+   //skip illegal stations.     
+    if (hash>=writeCdoTube->size()) {
+      ATH_MSG_INFO( "Illegal station (1)! (" << name << "," << iphi << "," << ieta << ")" );
+      continue;
+    }
+                                                                                
+    // retrieve the existing one (created by defaultt0() )
+    tubes = (*writeCdoTube)[hash];
+
+    if(tubes==NULL) {
+      ATH_MSG_INFO( "Illegal station (2)! (" << name << "," << iphi << "," << ieta << ")" );
+      continue;
+    }
+    
+    int nml       = tubes->numMultilayers();
+    int nlayers   = tubes->numLayers();
+    int ntubesLay = tubes->numTubes();
+    int size      = nml*nlayers*ntubesLay;
+
+    if(size!=ntubes) {
+      ATH_MSG_ERROR( "Pre-existing MdtTubeCalibContainer for chamber ID " <<chId<< " size does not match the one found in DB ");
+      return StatusCode::FAILURE;
+    }
+
+    //Extract T0, ADCcal, valid flag for each tube from payload.
+    MuonCalib::MdtTubeCalibContainer::SingleTubeCalib datatube;
+    char *TubePar= new char [payload.size()+1];
+    strncpy(TubePar, payload.c_str(), payload.size()+1);
+    TubePar[payload.size()]='\0';
+    
+    //Loop over payload 
+    char *pch1=strtok(TubePar,",");
+    int ml=1, l=1, t=1;
+    for( int k=1; pch1!=NULL; pch1=strtok(NULL,", "), k++) { 
+      if(k==1) {
+	double tzero = atof(pch1);
+	if( m_t0Shift != 0. ){
+	  tzero += m_t0Shift;
+	  ATH_MSG_VERBOSE( "T0 shift " << m_t0Shift << " t0 " << tzero 
+			   << " id " << ml << " " << l << " " << t );
+	}
+	if(m_t0Spread != 0. ){
+	  double sh = CLHEP::RandGaussZiggurat::shoot(m_engine,0.,m_t0Spread);
+	  tzero += sh;
+	  ATH_MSG_VERBOSE( "T0 spread " << sh << " t0 " << tzero 
+			   << " id " << ml << " " << l << " " << t );
+	}
+	if(!t0_ts_applied && m_TimeSlewingCorrection) {
+	  tzero += m_TsCorrectionT0;
+	}
+	if(t0_ts_applied && !m_TimeSlewingCorrection) {
+	  tzero -= m_TsCorrectionT0;
+	}
+	datatube.t0=tzero;
+      } else if(k==2) {
+	datatube.statusCode = atoi(pch1);
+      } else if(k==3) {
+        datatube.adcCal = atof(pch1);
+        datatube.inversePropSpeed = inversePropSpeed;
+        tubes->setCalib( ml-1,l-1,t-1,datatube);
+        ATH_MSG_VERBOSE( "Loading T0s "<<ml << " " << l << " " << t << " " << datatube.t0 );
+        t++; k=0;
+        if (t>ntubesLay) {
+          l++; 
+          t=1;
+        }
+        if (l>nlayers) {
+          ml++;
+          l=1;
+        }
+      }
+    }
+    delete [] TubePar;
+  }//end loop over readCdoTube
+
+  //finally record writeCdo
+
+  if ( writeCdoTube->size()==0 ) {
+    ATH_MSG_WARNING("writeCdoTube->size()==0"); 
+    return StatusCode::FAILURE;
+  }
+  if (writeHandleTube.record(rangeTube, std::move(writeCdoTube)).isFailure()) {
+    ATH_MSG_FATAL("Could not record " << writeHandleTube.key()
+		  << " with EventRange " << rangeTube
+		  << " into Conditions Store");
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("recorded new " << writeHandleTube.key()
+	       << " with range " << rangeTube
+	       << " into Conditions Store");
+
+  return StatusCode::SUCCESS;
+}
+
+
+// Build a MuonCalib::MdtTubeCalibContainer for a given Identifier
+MuonCalib::MdtTubeCalibContainer* MdtCalibDbAlg::buildMdtTubeCalibContainer(const Identifier &id) {    
+  MuonCalib::MdtTubeCalibContainer *tubes = 0;
+
+  const MuonGM::MdtReadoutElement *detEl = m_detMgr->getMdtReadoutElement( m_mdtIdHelper->channelID(id,1,1,1) );
+  const MuonGM::MdtReadoutElement *detEl2 = 0;
+  if (m_mdtIdHelper->numberOfMultilayers(id) == 2){
+    detEl2 = m_detMgr->getMdtReadoutElement(m_mdtIdHelper->channelID(id,2,1,1) );
+  } else {
+    ATH_MSG_VERBOSE( "A single multilayer for this station " << m_mdtIdHelper->stationNameString(m_mdtIdHelper->stationName(id))<<","<< m_mdtIdHelper->stationPhi(id) <<","<< m_mdtIdHelper->stationEta(id) );
+  }
+
+  ATH_MSG_VERBOSE( " new det el " << detEl );
+  
+  if( !detEl ){ 
+    ATH_MSG_INFO( "Ignoring nonexistant station in calibration DB: " << m_mdtIdHelper->print_to_string(id) );
+  } else {
+    int nml = 2;
+    if( !detEl2 ) nml = 1;
+    
+    int nlayers = detEl->getNLayers();
+    if( detEl2 && detEl2->getNLayers() > nlayers ){
+      ATH_MSG_DEBUG( "Second multilayer has more layers " << detEl2->getNLayers() << " then first " << nlayers );
+      nlayers = detEl2->getNLayers();
+    }
+
+    int ntubes = detEl->getNtubesperlayer();
+    if( detEl2 && detEl2->getNtubesperlayer() > ntubes ){
+      ATH_MSG_DEBUG( "Second multilayer has more tubes " << detEl2->getNtubesperlayer() << " then first " << ntubes );
+      ntubes = detEl2->getNtubesperlayer();
+    }
+
+    // build the region name in the format STATION_ETA_PHI
+    std::string rName;
+
+    int stName = m_mdtIdHelper->stationName(id);
+    int stPhi  = m_mdtIdHelper->stationPhi(id);
+    int stEta  = m_mdtIdHelper->stationEta(id);
+  
+    std::string separator("_");
+    MuonCalib::ToString ts;
+    rName = m_mdtIdHelper->stationNameString(stName);
+    rName += separator + ts( stPhi ) + separator + ts( stEta );
+    tubes = new MuonCalib::MdtTubeCalibContainer( rName,nml, nlayers, ntubes );
+  }
+
+  return tubes;
+}  //end MdtCalibDbAlg::buildMdtTubeCalibContainer
+
+inline bool MdtCalibDbAlg::uncompressInMyBuffer(const coral::Blob &blob) {
+  if (!m_decompression_buffer) {
+    m_buffer_length= 50000;
+    m_decompression_buffer.reset(new Bytef[m_buffer_length]);
+  }
+  uLongf actual_length;	
+  while(1) {
+    actual_length=m_buffer_length;
+    int res(uncompress(m_decompression_buffer.get(), &actual_length, reinterpret_cast<const Bytef *>(blob.startingAddress()), static_cast<uLongf>(blob.size())));
+    if (res == Z_OK) break;
+    //double buffer if it was not big enough
+    if( res == Z_BUF_ERROR) {
+      m_buffer_length*=2;
+      ATH_MSG_VERBOSE(  "Increasing buffer to " << m_buffer_length);
+      m_decompression_buffer.reset();
+      m_decompression_buffer.reset(new Bytef[m_buffer_length]);
+      continue;
+    }
+    //something else is wrong
+    return false;
+  }
+  //append 0 to terminate string, increase buffer if it is not big enough
+  if (actual_length >= m_buffer_length)	{
+    std::unique_ptr<Bytef> old_buffer(std::move(m_decompression_buffer));
+    size_t old_length=m_buffer_length;
+    m_buffer_length*=2;
+    m_decompression_buffer.reset(new Bytef[m_buffer_length]);
+    memcpy(m_decompression_buffer.get(), old_buffer.get(), old_length);
+    old_buffer.reset();
+  }
+  m_decompression_buffer.get()[actual_length]=0;
+  return true;
+}
+
+inline MuonCalib::RtResolutionLookUp* MdtCalibDbAlg::getRtResolutionInterpolation( const std::vector<MuonCalib::SamplePoint> &sample_points) {
+
+  ///////////////
+  // VARIABLES //
+  ///////////////
+  Double_t *x = new Double_t[sample_points.size()];
+  Double_t *y = new Double_t[sample_points.size()];
+	
+  for (unsigned int i=0; i<sample_points.size(); i++) {
+    x[i] = sample_points[i].x1();
+    y[i] = sample_points[i].x2();
+  }
+  TSpline3 sp("Rt Res Tmp", x, y, sample_points.size());
+  ///////////////////////////////////////////////////////////////////
+  // CREATE AN RtRelationLookUp OBJECT WITH THE CORRECT PARAMETERS //
+  ///////////////////////////////////////////////////////////////////
+  unsigned int nb_points(100);
+  std::vector<double> res_param(nb_points+2); // r-t parameters
+  Double_t bin_width=(x[sample_points.size() -1] - x[0]) / static_cast<Double_t>(nb_points);
+	
+  res_param[0] = x[0];
+  res_param[1] = bin_width;
+  for (unsigned int k=0; k<nb_points; k++) {
+    Double_t xx = x[0] + k*bin_width;
+    res_param[k+2] = sp.Eval(xx);
+    if (std::isnan(res_param[k+2])) {
+      TFile outf("kacke.root", "RECREATE");
+      sp.Write("kacke");
+      exit(99);
+    }
+  }
+  delete [] x;
+  delete [] y;
+  return new MuonCalib::RtResolutionLookUp(res_param);
+}
+
+inline StatusCode MdtCalibDbAlg::extractString(std::string &input, std::string &output, std::string separator) {
+  unsigned long int pos = 0;
+  std::string::size_type start = input.find_first_not_of(separator.c_str(),pos);
+  if(start == std::string::npos) {
+    ATH_MSG_ERROR("MdtCalibDbAlg::extractString: Cannot extract string in a proper way!");
+    return StatusCode::FAILURE;
+  }
+  std::string::size_type stop = input.find_first_of(separator.c_str(),start+1);
+  if (stop == std::string::npos) stop = input.size();
+  output = input.substr(start,stop-start);
+  input.erase(pos,stop-pos);
+
+  return StatusCode::SUCCESS;
+}
+
+
+//like MdtCalibrationDbSvc
+//for corData in loadRt
+void MdtCalibDbAlg::initialize_B_correction(MuonCalib::MdtCorFuncSet *funcSet,
+                                                  const MuonCalib::MdtRtRelation *rt_rel) {
+  if (rt_rel==NULL) {
+    funcSet->setBField(NULL);
+    return;
+  }
+  ATH_MSG_VERBOSE( "initialize_B_correction..." );
+  std::vector<double> corr_params(2);
+  corr_params[0] = 3080.0; // high voltage (not correct for sMDT which use 2730V!)
+  corr_params[1] = 0.11;   // epsilon parameter
+  funcSet->setBField(new MuonCalib::BFieldCorFunc(std::string("medium"), corr_params, rt_rel->rt()));
+}
+
+void MdtCalibDbAlg::initializeSagCorrection(MuonCalib::MdtCorFuncSet *funcSet) {
+  ATH_MSG_VERBOSE( "initializeSagCorrection..." );
+  std::vector<double> corr_params(0);
+  funcSet->wireSag(new MuonCalib::WireSagCorFunc(corr_params));
+}
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbCoolStrTool.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbCoolStrTool.cxx
index 6130ec417dae995140e62d9d329e2e6aaa3ad0b9..c3d066ab5e79602282680f67079e5c46a81a3ed9 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbCoolStrTool.cxx
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/MdtCalibDbCoolStrTool.cxx
@@ -161,18 +161,9 @@ StatusCode MdtCalibDbCoolStrTool::initialize() {
 
   ATH_CHECK( m_idToFixedIdTool.retrieve() );
 
-  ServiceHandle<MdtCalibrationDbSvc> dbSvc("MdtCalibrationDbSvc", name());
-  ATH_CHECK( dbSvc.retrieve() );
-  ATH_MSG_DEBUG( "Retrieved MdtCalibrationDbSvc" );
-
-  ATH_CHECK( detStore()->regFcn(&IMdtCalibDBTool::loadTube,
-				dynamic_cast<IMdtCalibDBTool*>(this),
-				&MdtCalibrationDbSvc::loadTube,
-				dynamic_cast<MdtCalibrationDbSvc*>(&*dbSvc)) );
-  ATH_CHECK( detStore()->regFcn(&IMdtCalibDBTool::loadRt,
-				dynamic_cast<IMdtCalibDBTool*>(this),
-				&MdtCalibrationDbSvc::loadRt,
-				dynamic_cast<MdtCalibrationDbSvc*>(&*dbSvc)) );
+  //In 2019 for the AthenaMT migration,
+  //old callback functions and member data cache were removed from MdtCalibrationDbSvc
+  //Please use MdtCalibDbAlg to provide derived data via the condition store
 
   // initialize MdtTubeCalibContainers 
   ATH_CHECK( defaultT0s() );
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/components/MdtCalibDbCoolStrTool_entries.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/components/MdtCalibDbCoolStrTool_entries.cxx
index ba05e576b4ac472cec277cf5c7e40244e160bce2..46b31ea7371e13c191bd7c744b666f59e6e43b51 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/components/MdtCalibDbCoolStrTool_entries.cxx
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibDbCoolStrTool/src/components/MdtCalibDbCoolStrTool_entries.cxx
@@ -1,6 +1,7 @@
 #include "MdtCalibDbCoolStrTool/MdtCalibDbCoolStrTool.h"
+#include "MdtCalibDbCoolStrTool/MdtCalibDbAlg.h"
 
 using namespace MuonCalib;
 
 DECLARE_COMPONENT( MdtCalibDbCoolStrTool )
-
+DECLARE_COMPONENT( MdtCalibDbAlg )
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbSvc.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbSvc.h
index 1056500b9735e14d7c592beb3fffa4288ac87bf2..eda24cb6df879fde4614ff703c80aa272780eb19 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbSvc.h
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbSvc.h
@@ -34,6 +34,8 @@ namespace MuonCalib{
   struct MdtFullCalibData;
 }
 
+#include "StoreGate/ReadCondHandleKey.h"
+
 /** handles the retreival of constants from the DB: it uses a Tool 
  * derived from MuonCalib::IMdtCalibDBTool to access different types of DB
  * (currently implemented ASCII files and COOL CLOBS)*/
@@ -55,16 +57,8 @@ public:
   /** initialization */
   virtual StatusCode initialize(void);
   /** finalization */
-  virtual StatusCode finalize(void);  
-    
-  /** to be called back to update the Collections : retrieve from database */
-  virtual StatusCode LoadCalibration(IOVSVC_CALLBACK_ARGS);
-  /** to be called back to update the Collections : retrieve RTs from database*/
-  virtual StatusCode loadRt(IOVSVC_CALLBACK_ARGS);
-  /** to be called back to update the Collections : 
-   * retrieve Tube inforsmation  from database */
-  virtual StatusCode loadTube(IOVSVC_CALLBACK_ARGS);
-    
+  virtual StatusCode finalize(void);
+
   /** Access to calibration constants per calibration region/chamber */
   MuonCalib::MdtFullCalibData getCalibration( const Identifier &id ) const; 
     
@@ -93,15 +87,6 @@ public:
   const MuonCalib::MdtCorFuncSet* getCorFunctions( const IdentifierHash &detElHash ) const;
     
 private:
-  /** Indexed with MdtRegionHash for rt relations*/
-  mutable MdtRtRelationCollection *m_rtData;
-    
-  /** Indexed with MdtChamberHash */
-  mutable MdtTubeCalibContainerCollection *m_tubeData;
-    
-  /** Indexed with MdtRegionHash for correction function regions */
-  mutable MdtCorFuncSetCollection *m_corData;
-
   /** handle to region service */
   ServiceHandle<MdtCalibrationRegionSvc> m_regionSvc;
     
@@ -118,16 +103,17 @@ private:
   ServiceHandle<StoreGateSvc> m_detStore;
 
   /** Properties: */
-  std::string m_tubeDataLocation;
-  std::string m_rtDataLocation;
-  std::string m_corDataLocation;
   bool m_create_b_field_function; //<! flag to switch on loading of B field correction
   bool m_createWireSagFunction;   //<! flag to switch on loading of wire sag correction
   bool m_createSlewingFunction;   //<! flag to switch on loading of slewing correction
 
   bool m_getTubeConstants; //<! flag to switch off loading of tube constants
   bool m_getCorrections;   //<! flag to switch off loading of correction function constants
-    
+
+  SG::ReadCondHandleKey<MdtRtRelationCollection> m_readKeyRt{this,"MdtRtRelationCollection","MdtRtRelationCollection","MDT RT relations"};
+  SG::ReadCondHandleKey<MdtTubeCalibContainerCollection> m_readKeyTube{this,"MdtTubeCalibContainerCollection","MdtTubeCalibContainerCollection","MDT tube calib"};
+  SG::ReadCondHandleKey<MdtCorFuncSetCollection> m_readKeyCor{this,"MdtCorFuncSetCollection","MdtCorFuncSetCollection","MDT cor Funcs"};
+
 };
 
 #endif // MDTCALIBSVC_MDTCALIBRATIONDBSVC_H
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbTool.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..5dafd8d48b0a58b84c5c83bd9c83c676369409be
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationDbTool.h
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MDTCALIBSVC_MDTCALIBRATIONDBTOOL_H
+#define MDTCALIBSVC_MDTCALIBRATIONDBTOOL_H
+
+#include "AthenaBaseComps/AthService.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/ToolHandle.h"  // for configurables
+#include "AthenaKernel/IOVSvcDefs.h"
+
+#include "MdtCalibData/MdtRtRelationCollection.h"
+#include "MdtCalibData/MdtTubeCalibContainerCollection.h"
+#include "MdtCalibData/MdtCorFuncSetCollection.h"
+
+#include "GaudiKernel/AlgTool.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+
+class MdtCalibrationRegionSvc;
+class MdtIdHelper;
+class Identifier;
+class IdentifierHash;
+
+namespace MuonCalib{
+  class IMdtCalibDBTool;
+  struct MdtFullCalibData;
+}
+
+#include "StoreGate/ReadCondHandleKey.h"
+
+/** handles the retreival of constants from the DB: it uses a Tool 
+ * derived from MuonCalib::IMdtCalibDBTool to access different types of DB
+ * (currently implemented ASCII files and COOL CLOBS)*/
+
+//TODO: Use public extends<AthAlgTool, IInterface> here. Then you can construct the base class using base_class.
+
+class MdtCalibrationDbTool : public AthAlgTool, virtual public IInterface {
+public:
+  /** constructor */
+  MdtCalibrationDbTool(const std::string& type, const std::string &name, const IInterface* parent);
+
+  /** destructor */
+  virtual ~MdtCalibrationDbTool();
+  /** IInterface implementation */
+  static const InterfaceID &interfaceID() {
+    static InterfaceID s_iID("MdtCalibrationDbTool", 1, 0);
+    return s_iID;
+  }
+    
+  /** initialization */
+  virtual StatusCode initialize();
+
+  /** Access to calibration constants per calibration region/chamber */
+  MuonCalib::MdtFullCalibData getCalibration( const Identifier &id ) const; 
+    
+  /** Access to RT calibration constants per calibration region/chamber directly using the hashes */
+  //  MuonCalib::MdtFullCalibData getCalibration( const IdentifierHash &chamberHash, const IdentifierHash &detElHash ) const;
+  MuonCalib::MdtFullCalibData getCalibration( const IdentifierHash &chamberHash, const IdentifierHash &mlhash ) const;
+    
+  /** Access to RT calibration constants per calibration region/chamber */
+  const MuonCalib::MdtRtRelation* getRtCalibration( const Identifier &id ) const;
+    
+  /** Access to calibration constants per calibration region/chamber by hash */
+  const MuonCalib::MdtRtRelation* getRtCalibration( const IdentifierHash &detElHash ) const;
+    
+  /** Access to Tube calibration constants per calibration region/chamber */
+  const MuonCalib::MdtTubeCalibContainer* getTubeCalibContainer( const Identifier &id ) const;
+    
+  /** Access to Tube calibration constants per calibration region/chamber by hash */
+  const MuonCalib::MdtTubeCalibContainer* getTubeCalibContainer( const IdentifierHash &chamberHash ) const;
+    
+  /** Access to corrections to calibration constants per calibration 
+   * region/chamber */
+  const MuonCalib::MdtCorFuncSet* getCorFunctions( const Identifier &id ) const;
+    
+  /** Access to corrections to calibration constants per calibration 
+   * region/chamber by hash */
+  const MuonCalib::MdtCorFuncSet* getCorFunctions( const IdentifierHash &detElHash ) const;
+    
+private:
+  /** handle to region service */
+  ServiceHandle<MdtCalibrationRegionSvc> m_regionSvc;
+    
+  /** Id Helper used to retrieve hashes from IDs */ 
+  const MdtIdHelper *m_mdtIdHelper;
+    
+  /** create the correction functions */
+  void initialize_B_correction(MuonCalib::MdtCorFuncSet *funcSet,
+			       const MuonCalib::MdtRtRelation *rt);
+  void initializeSagCorrection(MuonCalib::MdtCorFuncSet *funcSet);
+    
+  /** Tool handling the DB access */
+  ServiceHandle<StoreGateSvc> m_detStore;
+
+  /** Properties: */
+  bool m_create_b_field_function; //<! flag to switch on loading of B field correction
+  bool m_createWireSagFunction;   //<! flag to switch on loading of wire sag correction
+  bool m_createSlewingFunction;   //<! flag to switch on loading of slewing correction
+
+  bool m_getTubeConstants; //<! flag to switch off loading of tube constants
+  bool m_getCorrections;   //<! flag to switch off loading of correction function constants
+
+  SG::ReadCondHandleKey<MdtRtRelationCollection> m_readKeyRt{this,"MdtRtRelationCollection","MdtRtRelationCollection","MDT RT relations"};
+  SG::ReadCondHandleKey<MdtTubeCalibContainerCollection> m_readKeyTube{this,"MdtTubeCalibContainerCollection","MdtTubeCalibContainerCollection","MDT tube calib"};
+  SG::ReadCondHandleKey<MdtCorFuncSetCollection> m_readKeyCor{this,"MdtCorFuncSetCollection","MdtCorFuncSetCollection","MDT cor Funcs"};
+
+};
+
+#endif // MDTCALIBSVC_MDTCALIBRATIONDBTOOL_H
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationTool.h b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..57e264792c94317fb956b28fc055a789dc1e6242
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/MdtCalibSvc/MdtCalibrationTool.h
@@ -0,0 +1,121 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MDTCALIBSVC_MDTCALIBRATIONTOOL_H
+#define MDTCALIBSVC_MDTCALIBRATIONTOOL_H
+
+#include "AthenaBaseComps/AthService.h"
+#include "GaudiKernel/IInterface.h"
+#include "Identifier/Identifier.h"
+#include "MuonPrepRawData/MdtDriftCircleStatus.h"
+
+#include "GaudiKernel/AlgTool.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+
+class MdtCalibHit;
+class MdtCalibrationSvcInput;
+class MdtCalibrationSvcSettings;
+class MdtCalibrationDbTool;
+namespace MuonCalib {
+  class MdtRtRelation;
+}
+
+/**
+   @class MdtCalibrationTool
+   the Mdt Calib Service provides, on request, the drift radius and its 
+   error, computed applying the proper calibration, for any hit in Mdt chambers  
+   @author Martin Woudstra, Niels van Eldik
+*/
+
+//TODO: Use public extends<AthAlgTool, IInterface> here. Then you can construct the base class using base_class.
+
+class MdtCalibrationTool : virtual public IInterface, public AthAlgTool {
+public:
+  /** constructor */
+  MdtCalibrationTool(const std::string& type, const std::string &name, const IInterface* parent);
+
+  /** destructor */
+  virtual ~MdtCalibrationTool();
+
+  /** implements IInterface */
+  static const InterfaceID &interfaceID() {
+    static InterfaceID s_iID("MdtCalibrationTool", 1, 0);
+    return s_iID;
+  }
+
+  /** initialization */
+  virtual StatusCode initialize();
+
+  /** Convert the raw MDT time (+charge) into a drift radius + error.
+      It returns whether the conversion was successful.
+       
+      @param[in,out] hit Hit must have pointer set to the MdtDigit,
+      as well as the global hit position (including the position along the tube!)
+      @param[in] signedTracklength the track length from the 'triggerpoint' to the hit.
+      It is used for the time-of-flight correction.
+      This triggerpoint is the I.P. for ATLAS p-p collisions,
+      typically scintillators in test-beam and cosmic teststands,
+      and not clear yet what is it is for cosmics in ATLAS.
+      The sign is for determining the sign of the time-of-flight correction.
+      If a muon first passes the triggerpoint, and then the MDT tube, the sign
+      should be positive (the case for ATLAS p-p and H8 test-beam).
+      If a muon first passes the MDT tube, and then de triggerpoint, the sign
+      should be negative (typically the case for cosmic-ray teststands).
+      @param[in] triggerTime the time of the 'triggerpoint' in ns. This is the time (measured with
+      the same clock as the MDT TDC's) when the muon passed a known point in
+      space: the 'triggerpoint'. 
+      For ATLAS this is 0.0 since the TDC's are synchonised w.r.t. the bunch-crossings.
+      For H8 test-beam it is the trigger time, which is time when the muon passed
+      the trigger scintillators. For cosmic-ray teststands it is usually also the
+      time when the muon passed the trigger scintillators.
+      For cosmics in ATLAS it is not clear yet.
+      @param[in] resolFromRtrack indicates the method to provide the resolution as a function 
+      of the distance of the reconstructed track from the anode wire instead of the drift
+      radius
+  */
+  bool driftRadiusFromTime( MdtCalibHit &hit, double signedTrackLength, double triggerTime = 0.0, bool resolFromRtrack=false );
+
+  /** Convert the raw MDT time (+charge) into a drift radius + error.
+      It returns whether the conversion was successful.
+       
+  */
+  bool driftRadiusFromTime( MdtCalibHit &hit, const MdtCalibrationSvcInput &inputData, const MdtCalibrationSvcSettings &settings, bool resolFromRtrack=false  );
+
+  /** Convert the raw MDT time (+charge) into a drift radius + error.
+      It returns whether the conversion was successful.
+       
+  */
+  bool driftRadiusFromTime( MdtCalibHit &hit, const MdtCalibrationSvcInput &inputData, bool resolFromRtrack=false  );
+
+  /** TDC bin size. 25/32 ns for all MDT/sMDT, except BMG=0.2ns */
+  double tdcBinSize(const Identifier &id);
+
+  /** Convert the raw MDT times of two twin hits into a Twin position (coordinate along tube)
+      It returns whether the conversion was successful. */
+  bool twinPositionFromTwinHits( MdtCalibHit &hit, MdtCalibHit &twinhit, double signedTrackLength, double twinSignedTrackLength, bool &twinDigitIsPrompt, double triggerTime = 0.0 );
+   
+  /** Convert the raw MDT times of two twin hits into a Twin position (coordinate along tube)
+      It returns whether the conversion was successful. */
+  bool twinPositionFromTwinHits( MdtCalibHit &hit, MdtCalibHit &twinhit, const MdtCalibrationSvcInput &inputData, const MdtCalibrationSvcInput &twinInputData, const MdtCalibrationSvcSettings &settings, bool &twinDigitIsPrompt );
+   
+  /** Return status of drift time: in window, above/below window (with upper/lower bounds described by the settings) or invalid.
+      @return @c Muon::MdtDriftCircleStatus saying whether the drift time comes before, during or after the bounds of the drift time spectrum.
+      @param[in] driftTime is the drift time of the hit.
+      @param[in] rtRelation is used to obtain the upper and lower limits of the r(t) relation.
+      @param[in] settings define the extra window around the r(t) relationship bounds that is acceptable.
+  */
+  Muon::MdtDriftCircleStatus driftTimeStatus( double driftTime, const MuonCalib::MdtRtRelation *rtRelation, const MdtCalibrationSvcSettings &settings );
+   
+private:
+
+  /// please don't add any data members here!!
+  /// they should be added to Imp to keep the class free from data exposed to clients
+  class Imp;
+  Imp *m_imp;
+
+  ToolHandle<MdtCalibrationDbTool> m_dbTool;
+
+};
+
+#endif
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbSvc.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbSvc.cxx
index c9cf4d6ec2650bfa49608fec711d409088dfe0bc..4e746eeb8d4e1cbc6c46ee318233296a259f9c6a 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbSvc.cxx
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbSvc.cxx
@@ -26,14 +26,11 @@
 #include "MdtCalibData/CalibFunc.h"
 
 MdtCalibrationDbSvc::MdtCalibrationDbSvc(const std::string &n,ISvcLocator *sl)
-  : AthService(n,sl), m_rtData(0), m_tubeData(0), m_corData(0), 
+  : AthService(n,sl),
     m_regionSvc("MdtCalibrationRegionSvc", name()),
     m_mdtIdHelper(0),
     m_dbTool("MuonCalib::MdtCalibDbAsciiTool"),
-    m_detStore("StoreGateSvc/DetectorStore", name()),
-    m_tubeDataLocation("TubeKey"),
-    m_rtDataLocation("RtKey"),
-    m_corDataLocation("CorKey")
+    m_detStore("StoreGateSvc/DetectorStore", name())
 {
   declareProperty("DBTool", m_dbTool,
 		  "the Tool to be used to retrieve the constants");
@@ -87,85 +84,14 @@ StatusCode MdtCalibrationDbSvc::initialize() {
     return StatusCode::FAILURE;
   }
 
-  // register call backs requiring to be called after the Tool 
-  // will work for Ascii Tool only
-  // for real DB access the callback is registered with 2 functions 
-  // within the Tool
-  if(m_dbTool.type()=="MuonCalib::MdtCalibDbAsciiTool"){
-    const DataHandle<MdtTubeCalibContainerCollection> tubeData;
-    if(m_detStore->regFcn(&MdtCalibrationDbSvc::LoadCalibration,dynamic_cast<MdtCalibrationDbSvc*>(this),tubeData,m_tubeDataLocation).isFailure()){
-      ATH_MSG_ERROR("Failed to register call-back on tube data");
-      return StatusCode::FAILURE;
-    }
-    const DataHandle<MdtRtRelationCollection> rtData;
-    if(m_detStore->regFcn(&MdtCalibrationDbSvc::LoadCalibration,
-			  dynamic_cast<MdtCalibrationDbSvc*>(this),
-			  rtData,m_rtDataLocation).isFailure() ){
-      ATH_MSG_ERROR("Failed to register call-back on rt data");
-      return StatusCode::FAILURE;
-    }
-  }
+  ATH_CHECK(m_readKeyRt.initialize());
+  ATH_CHECK(m_readKeyTube.initialize());
+  ATH_CHECK(m_readKeyCor.initialize());
     
   return StatusCode::SUCCESS;
 }  //end MdtCalibrationDbSvc::initialize
 
-StatusCode MdtCalibrationDbSvc::LoadCalibration(IOVSVC_CALLBACK_ARGS_P(I,keys)) {
-  std::list<std::string>::const_iterator itr;
-  if( msgLvl(MSG::DEBUG) ) {
-    ATH_MSG_DEBUG( "LoadCalibration has been triggered for the following keys " );
-    for (itr=keys.begin(); itr!=keys.end(); ++itr) {
-      msg(MSG::DEBUG) << *itr << " I="<<I<<" ";
-    }
-    msg(MSG::DEBUG) << endmsg;
-  }
-  for (itr=keys.begin(); itr!=keys.end(); ++itr) {
-    msg(MSG::INFO) << *itr << " I="<<I<<" ";
-  }
-  msg(MSG::INFO) << endmsg;
-
-  for (itr=keys.begin(); itr!=keys.end(); ++itr) {
-    if(*itr==m_tubeDataLocation) {
-      if(loadTube(I,keys).isFailure()) return StatusCode::FAILURE;
-    }
-    if(*itr==m_rtDataLocation) {
-      if(loadRt(I,keys).isFailure()) return StatusCode::FAILURE;
-    }
-  }
-  return StatusCode::SUCCESS;
-}  //end MdtCalibrationDbSvc::LoadCalibration
-
-StatusCode MdtCalibrationDbSvc::loadTube(IOVSVC_CALLBACK_ARGS) { 
-  ATH_MSG_DEBUG( "In loadTube " );  
-  return m_detStore->retrieve(m_tubeData, m_tubeDataLocation);
-}
-
-StatusCode MdtCalibrationDbSvc::loadRt(IOVSVC_CALLBACK_ARGS) {
-  ATH_MSG_DEBUG( "In loadRt " );  
-
-  // Retrieve RT functions from StoreGate
-  if( m_detStore->retrieve(m_rtData, m_rtDataLocation).isFailure() ) return StatusCode::FAILURE;
-
-  // Check if doing corrections; return if not  
-  if( !m_createSlewingFunction && !m_createWireSagFunction && !m_create_b_field_function ) return StatusCode::SUCCESS;
-
-  //Delete old correction functions and create new ones
-  //The correction functions are made with the same regions as are used for RTs.
-  if( m_corData ) delete m_corData;
-  m_corData = new MdtCorFuncSetCollection();
-  m_corData->resize(m_rtData->size());
-  ATH_MSG_DEBUG( "Initializing " << m_corData->size() << " b-field functions" );
-  for (unsigned int i=0; i < m_corData->size(); i++) {
-    (*m_corData)[i] = new MuonCalib::MdtCorFuncSet();
-    if(m_create_b_field_function) initialize_B_correction((*m_corData)[i], (*m_rtData)[i]);
-    if(m_createWireSagFunction)   initializeSagCorrection((*m_corData)[i]);
-    if(m_createSlewingFunction)   (*m_corData)[i]->setSlewing(new MuonCalib::MdtSlewCorFuncHardcoded(MuonCalib::CalibFunc::ParVec()));
-  }
-
-  return StatusCode::SUCCESS;
-}  //end MdtCalibrationDbSvc::loadRt
-
 StatusCode MdtCalibrationDbSvc::finalize()  {
-  if( m_corData ) delete m_corData;
   return AthService::finalize();
 }
 
@@ -234,12 +160,20 @@ const MuonCalib::MdtTubeCalibContainer* MdtCalibrationDbSvc::getTubeCalibContain
 }
 
 const MuonCalib::MdtTubeCalibContainer* MdtCalibrationDbSvc::getTubeCalibContainer( const IdentifierHash &hash ) const {
-  if( !m_tubeData ) return 0;
-
-  // single tube calibrations are accessed per chamber 
-  if ( hash.is_valid() && hash < m_tubeData->size() ) { 
-    return (*m_tubeData)[ hash ]; 
+  if ( !hash.is_valid() ) {
+    ATH_MSG_WARNING( "cannot get tube, invalid hash"  );
+    return 0;
+  }
+  SG::ReadCondHandle<MdtTubeCalibContainerCollection> readHandleTube{ m_readKeyTube };
+  const MdtTubeCalibContainerCollection* readCdoTube{*readHandleTube};
+  if ( readCdoTube==nullptr ) {
+    ATH_MSG_ERROR("readCdoTube==nullptr");
+    return 0;
   }
+  if ( hash < readCdoTube->size() ) {
+    return (*readCdoTube)[ hash ];
+  }
+  ATH_MSG_WARNING( "cannot get tube, region hash out of range"  );
   return 0;
 }
 
@@ -258,22 +192,21 @@ const MuonCalib::MdtRtRelation* MdtCalibrationDbSvc::getRtCalibration( const Ide
 }
 
 const MuonCalib::MdtRtRelation* MdtCalibrationDbSvc::getRtCalibration( const IdentifierHash &hash ) const {
-  // check whether there are cached rt's
-  if( !m_rtData ) {
-    ATH_MSG_WARNING( "No rt-calibrations loaded"  );
+  if ( !hash.is_valid() ) {
+    ATH_MSG_WARNING( "cannot get rt, invalid hash"  );
     return 0;
   }
-  // check if hash is ok
-  if ( !hash.is_valid() ) {
-    ATH_MSG_WARNING( "cannot get rt, invalid hash"  ); 
+  SG::ReadCondHandle<MdtRtRelationCollection> readHandleRt{ m_readKeyRt };
+  const MdtRtRelationCollection* readCdoRt{*readHandleRt};
+  if ( readCdoRt==nullptr ) {
+    ATH_MSG_ERROR("readCdoRt==nullptr");
     return 0;
   }
-
   // Get the RT using the hash as an index
-  if( hash < m_rtData->size() ) { 
-    return (*m_rtData)[ hash ]; 
+  if( hash < readCdoRt->size() ) {
+    return (*readCdoRt)[ hash ];
   }
-  ATH_MSG_WARNING( "cannot get RT, region hash out of range"  ); 
+  ATH_MSG_WARNING( "cannot get RT, region hash out of range"  );
   return 0;
 }
 
@@ -292,17 +225,24 @@ const MuonCalib::MdtCorFuncSet* MdtCalibrationDbSvc::getCorFunctions( const Iden
 }
 
 const MuonCalib::MdtCorFuncSet* MdtCalibrationDbSvc::getCorFunctions( const IdentifierHash &hash ) const {
-  // check whether there are cached correction functions
-  if( !m_corData ) return 0;
-
-  // check if hash is ok
-  if ( !hash.is_valid() ) return 0;
-
-  // Get the correction functions using the hash as an index
-  if( hash < m_corData->size() ) { 
-    return (*m_corData)[ hash ]; 
+  if ( !hash.is_valid() ){
+    ATH_MSG_WARNING( "cannot get cor, invalid hash"  );
+    return 0;
   }
-
+  //in this case the loadRt() was intended to keep m_corData nullptr and getCorFunctions() returned 0 here so
+  if( !m_createSlewingFunction && !m_createWireSagFunction && !m_create_b_field_function ){
+    return 0;
+  }
+  SG::ReadCondHandle<MdtCorFuncSetCollection> readHandleCor{ m_readKeyCor };
+  const MdtCorFuncSetCollection* readCdoCor{*readHandleCor};
+  if ( readCdoCor==nullptr ) {
+    ATH_MSG_ERROR("readCdoCor==nullptr");
+    return 0;
+  }
+  if( hash < readCdoCor->size() ) {
+    return (*readCdoCor)[ hash ];
+  }
+  ATH_MSG_WARNING( "cannot get cor, region hash out of range"  );
   return 0;
 }
 
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbTool.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..de63c505c120dd04655da1120e094cf59bbd19d6
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationDbTool.cxx
@@ -0,0 +1,238 @@
+/*
+  Copyright (C) 2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+#include "StoreGate/StoreGateSvc.h"
+
+#include "Identifier/IdentifierHash.h"
+#include "MuonIdHelpers/MdtIdHelper.h"
+#include "MdtCalibSvc/MdtCalibrationRegionSvc.h"
+
+#include <string>
+
+#include "MdtCalibData/MdtFullCalibData.h"
+#include "MdtCalibData/BFieldCorFunc.h"
+#include "MdtCalibData/WireSagCorFunc.h"
+#include "MdtCalibData/MdtSlewCorFuncHardcoded.h"
+#include "MdtCalibData/CalibFunc.h"
+
+MdtCalibrationDbTool::MdtCalibrationDbTool(const std::string& type, const std::string &name, const IInterface* parent)
+  : AthAlgTool(type, name, parent),
+    m_regionSvc("MdtCalibrationRegionSvc", name),
+    m_mdtIdHelper(0),
+    m_detStore("StoreGateSvc/DetectorStore", name)
+{
+  declareProperty("AccessTubeConstants", m_getTubeConstants = true,
+		  "configure the Tool to retrieve the constants per tube (t0)");
+  declareProperty("AccessCorrections", m_getCorrections = true,
+		  "configure the Tool to retrieve the parameters of the correction functions");
+  declareProperty("CreateBFieldFunctions", m_create_b_field_function = false,
+		  "If set to true, the B-field correction functions are initialized for each rt-relation that is loaded.");
+  declareProperty("CreateWireSagFunctions", m_createWireSagFunction = false,
+		  "If set to true, the wire sag correction functions are initialized for each rt-relation that is loaded.");
+  declareProperty("CreateSlewingFunctions", m_createSlewingFunction = false, 
+		  "If set to true, the slewing correction functions are initialized for each rt-relation that is loaded.");
+}
+
+MdtCalibrationDbTool::~MdtCalibrationDbTool() {}
+
+StatusCode MdtCalibrationDbTool::initialize() {
+
+  if ( m_regionSvc.retrieve().isFailure() ) {
+    ATH_MSG_ERROR( "Failed to retrieve MdtCalibrationRegionSvc" );
+    return StatusCode::FAILURE;
+  }
+  
+  if ( m_detStore.retrieve().isFailure() ) {
+    ATH_MSG_FATAL( "Can't locate the DetectorStore" ); 
+    return StatusCode::FAILURE;
+  }
+
+  // initialize the MdtIdHelper
+  if (m_detStore->retrieve(m_mdtIdHelper, "MDTIDHELPER" ).isFailure()) {
+    ATH_MSG_ERROR( "Can't retrieve MdtIdHelper" );
+    return StatusCode::FAILURE;
+  }
+
+  ATH_CHECK(m_readKeyRt.initialize());
+  ATH_CHECK(m_readKeyTube.initialize());
+  ATH_CHECK(m_readKeyCor.initialize());
+
+  return StatusCode::SUCCESS;
+}  //end MdtCalibrationDbTool::initialize
+
+MuonCalib::MdtFullCalibData MdtCalibrationDbTool::getCalibration( const Identifier &idt ) const {
+
+  Identifier id = m_mdtIdHelper->elementID( idt );
+
+  IdentifierHash mlHash;     //hash for ML (needed when using ML-RT functions)
+  m_mdtIdHelper->get_detectorElement_hash( id, mlHash );   //hash for the ML 
+
+  IdentifierHash chamberHash;
+  IdContext idCont = m_mdtIdHelper->module_context();
+  m_mdtIdHelper->get_hash( id, chamberHash, &idCont );
+
+  return getCalibration( chamberHash, mlHash );
+}
+
+MuonCalib::MdtFullCalibData MdtCalibrationDbTool::getCalibration( const IdentifierHash &chamberHash, const IdentifierHash &mlHash ) const {
+  const MuonCalib::MdtRtRelation         *rt   = 0;
+  const MuonCalib::MdtTubeCalibContainer *tube = 0;
+  const MuonCalib::MdtCorFuncSet         *cor  = 0;
+  
+  IdentifierHash tubeHash = chamberHash;
+  IdentifierHash rtHash;
+  if( m_regionSvc->RegionType()==ONEPERMULTILAYER ) { //if using ML-RTs  
+    rtHash = m_regionSvc->getRegionHash(mlHash);
+  } else {
+    rtHash = m_regionSvc->getRegionHash(chamberHash);
+  }
+  IdentifierHash corHash  = rtHash;   //correction functions done in same regions as RTs
+
+  if( rtHash.is_valid() ) {
+    // find rt relation
+    rt = getRtCalibration( rtHash );
+    if ( !rt ) { 
+      ATH_MSG_WARNING( "No valid MdtRtRelation found " );
+    } 
+  } else {
+    ATH_MSG_WARNING( "--- INVALID RT HASH, cannot access rt calibration constants " );
+  }
+   
+  // find correction functions 
+  if( m_getCorrections && corHash.is_valid()) {
+    cor = getCorFunctions( corHash );
+  }
+
+  // find t0's
+  if( m_getTubeConstants && tubeHash.is_valid() ) {
+    tube = getTubeCalibContainer( tubeHash );
+    if( !tube ){
+      ATH_MSG_WARNING( "Not valid MdtTubeCalibContainer found " );
+    }
+  }
+  
+  return MuonCalib::MdtFullCalibData( cor, rt, tube );
+}
+
+const MuonCalib::MdtTubeCalibContainer* MdtCalibrationDbTool::getTubeCalibContainer( const Identifier &idt ) const {
+  Identifier id = m_mdtIdHelper->elementID( idt );
+
+  IdentifierHash hash;
+  IdContext idCont = m_mdtIdHelper->module_context();
+  m_mdtIdHelper->get_hash( id, hash, &idCont );
+  
+  return getTubeCalibContainer( hash );
+}
+
+const MuonCalib::MdtTubeCalibContainer* MdtCalibrationDbTool::getTubeCalibContainer( const IdentifierHash &hash ) const {
+  if ( !hash.is_valid() ) {
+    ATH_MSG_WARNING( "cannot get tube, invalid hash"  );
+    return 0;
+  }
+  SG::ReadCondHandle<MdtTubeCalibContainerCollection> readHandleTube{ m_readKeyTube };
+  const MdtTubeCalibContainerCollection* readCdoTube{*readHandleTube};
+  if ( readCdoTube==nullptr ) {
+    ATH_MSG_ERROR("readCdoTube==nullptr");
+    return 0;
+  }
+  if ( hash < readCdoTube->size() ) {
+    return (*readCdoTube)[ hash ];
+  }
+  ATH_MSG_WARNING( "cannot get tube, region hash out of range"  );
+  return 0;
+}
+
+const MuonCalib::MdtRtRelation* MdtCalibrationDbTool::getRtCalibration( const Identifier &idt ) const {
+  Identifier id = m_mdtIdHelper->elementID( idt );
+  IdentifierHash hash;
+
+  if( m_regionSvc->RegionType()==ONEPERMULTILAYER ) {
+    m_mdtIdHelper->get_detectorElement_hash( id, hash );   //hash for the ML 
+  } else {
+    IdContext idCont = m_mdtIdHelper->module_context();
+    m_mdtIdHelper->get_hash( id, hash, &idCont );          //hash for the chamber
+  }
+  hash = m_regionSvc->getRegionHash(hash);
+  return getRtCalibration( hash );
+}
+
+const MuonCalib::MdtRtRelation* MdtCalibrationDbTool::getRtCalibration( const IdentifierHash &hash ) const {
+  if ( !hash.is_valid() ) {
+    ATH_MSG_WARNING( "cannot get rt, invalid hash"  );
+    return 0;
+  }
+  SG::ReadCondHandle<MdtRtRelationCollection> readHandleRt{ m_readKeyRt };
+  const MdtRtRelationCollection* readCdoRt{*readHandleRt};
+  if ( readCdoRt==nullptr ) {
+    ATH_MSG_ERROR("readCdoRt==nullptr");
+    return 0;
+  }
+  // Get the RT using the hash as an index
+  if( hash < readCdoRt->size() ) {
+    return (*readCdoRt)[ hash ];
+  }
+  ATH_MSG_WARNING( "cannot get RT, region hash out of range"  );
+  return 0;
+}
+
+const MuonCalib::MdtCorFuncSet* MdtCalibrationDbTool::getCorFunctions( const Identifier &idt ) const {
+  Identifier id = m_mdtIdHelper->elementID( idt );
+  IdentifierHash hash;
+
+  if( m_regionSvc->RegionType()==ONEPERMULTILAYER ) {
+    m_mdtIdHelper->get_detectorElement_hash( id, hash );   //hash for the ML 
+  } else {
+    IdContext idCont = m_mdtIdHelper->module_context();
+    m_mdtIdHelper->get_hash( id, hash, &idCont );          //hash for the chamber
+  }
+  hash = m_regionSvc->getRegionHash(hash);
+  return getCorFunctions( hash );
+}
+
+const MuonCalib::MdtCorFuncSet* MdtCalibrationDbTool::getCorFunctions( const IdentifierHash &hash ) const {
+  if ( !hash.is_valid() ){
+    ATH_MSG_WARNING( "cannot get cor, invalid hash"  );
+    return 0;
+  }
+  //in this case the loadRt() was intended to keep m_corData nullptr and getCorFunctions() returned 0 here so
+  if( !m_createSlewingFunction && !m_createWireSagFunction && !m_create_b_field_function ){
+    return 0;
+  }
+  SG::ReadCondHandle<MdtCorFuncSetCollection> readHandleCor{ m_readKeyCor };
+  const MdtCorFuncSetCollection* readCdoCor{*readHandleCor};
+  if ( readCdoCor==nullptr ) {
+    ATH_MSG_ERROR("readCdoCor==nullptr");
+    return 0;
+  }
+  if( hash < readCdoCor->size() ) {
+    return (*readCdoCor)[ hash ];
+  }
+  ATH_MSG_WARNING( "cannot get cor, region hash out of range"  );
+  return 0;
+}
+
+void MdtCalibrationDbTool::initialize_B_correction(MuonCalib::MdtCorFuncSet *funcSet,
+                                                  const MuonCalib::MdtRtRelation *rt_rel) {
+  if (rt_rel==NULL) {
+    funcSet->setBField(NULL);
+    return;
+  }
+  ATH_MSG_VERBOSE( "initialize_B_correction..." );
+  std::vector<double> corr_params(2);
+  corr_params[0] = 3080.0; // high voltage (not correct for sMDT which use 2730V!)
+  corr_params[1] = 0.11;   // epsilon parameter
+  funcSet->setBField(new MuonCalib::BFieldCorFunc(std::string("medium"), corr_params, rt_rel->rt()));
+}
+
+void MdtCalibrationDbTool::initializeSagCorrection(MuonCalib::MdtCorFuncSet *funcSet) {
+  ATH_MSG_VERBOSE( "initializeSagCorrection..." );
+  std::vector<double> corr_params(0);
+  funcSet->wireSag(new MuonCalib::WireSagCorFunc(corr_params));
+}
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationTool.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1eab778b8cd63f5a99504a4497e5786472dc60b3
--- /dev/null
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/MdtCalibrationTool.cxx
@@ -0,0 +1,947 @@
+/*
+  Copyright (C) 2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+// std
+#include <fstream>
+#include <string>
+// other packages
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGateSvc.h"
+
+// this package
+#include "MuonCalibEvent/MdtCalibHit.h"
+
+#include "MuonIdHelpers/MdtIdHelper.h"
+#include "MuonReadoutGeometry/MuonDetectorManager.h"
+#include "MuonReadoutGeometry/MdtReadoutElement.h"
+
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+// this package
+#include "MdtCalibSvc/MdtCalibrationTool.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
+#include "MdtCalibSvc/MdtCalibrationSvcInput.h"
+#include "MdtCalibSvc/MdtCalibrationSvcSettings.h"
+
+#include "MdtCalibData/MdtFullCalibData.h"
+#include "MdtCalibData/MdtRtRelation.h"
+#include "MdtCalibData/MdtTubeCalibContainer.h"
+#include "MdtCalibData/MdtCorFuncSet.h"
+#include "MdtCalibData/IMdtBFieldCorFunc.h"
+#include "MdtCalibData/IMdtSlewCorFunc.h"
+#include "MdtCalibData/IMdtTempCorFunc.h"
+#include "MdtCalibData/IMdtBackgroundCorFunc.h"
+#include "MdtCalibData/IMdtWireSagCorFunc.h"
+#include "MdtCalibData/IRtRelation.h"
+#include "MdtCalibData/IRtResolution.h"
+#include "MdtCalibData/TrRelation.h"
+#include "MdtCalibData/RtScaleFunction.h"
+
+#include "MdtCalibInterfaces/IShiftMapTools.h"
+
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/PhysicalConstants.h"
+
+//
+// private helper functions
+//
+
+class MdtCalibrationTool::Imp {
+public:
+
+  Imp( std::string name );
+
+  const MuonGM::MdtReadoutElement* getGeometry( const Identifier &id ) {
+    assert( m_muonGeoManager );
+    return m_muonGeoManager->getMdtReadoutElement( id );
+  }
+
+  double applyCorrections( MdtCalibHit &hit,
+			   const MdtCalibrationSvcInput &input,
+			   const MdtCalibrationSvcSettings &settings,
+			   double adcCal,
+			   const MuonCalib::MdtCorFuncSet *corrections,
+			   const MuonCalib::IRtRelation *rt ) const;
+
+  const MuonGM::MuonDetectorManager *m_muonGeoManager;
+  const MdtIdHelper                 *m_mdtIdHelper;
+  MdtCalibrationSvcSettings          settings;
+
+  double m_inverseSpeedOfLight;      // in ns/mm
+  double m_inversePropagationSpeed;  // in ns/mm
+
+  MsgStream *m_log; //!< Pointer to MsgStream - MdtCalibrationTool now owns this
+  bool m_verbose;   //!< True if we should print MSG::VERBOSE messages
+  bool m_debug;     //!< True if we should print MSG::DEBUG messages
+
+  //handle of b-field service - job option
+  ServiceHandle<MagField::IMagFieldSvc> m_magFieldSvc;
+
+  /* T0 Shift Service -- Per-tube offsets of t0 value */
+  ServiceHandle<MuonCalib::IShiftMapTools> m_t0ShiftSvc;
+  /* TMax Shift Service -- Per-tube offsets of Tmax */
+  ServiceHandle<MuonCalib::IShiftMapTools> m_tMaxShiftSvc;
+
+  // tools should only be retrieved if they are used
+  bool m_doT0Shift;
+  bool m_doTMaxShift;
+
+  double m_unphysicalHitRadiusUpperBound;
+  double m_unphysicalHitRadiusLowerBound;
+  double m_resTwin;
+  bool m_BMGpresent;
+  int m_BMGid;
+
+};
+
+MdtCalibrationTool::Imp::Imp(std::string name) :
+  m_muonGeoManager(0),
+  m_mdtIdHelper(0),
+  m_inverseSpeedOfLight(1./Gaudi::Units::c_light),
+  m_inversePropagationSpeed(m_inverseSpeedOfLight/0.85),
+  m_log(0),
+  m_verbose(false),
+  m_debug(false),
+  m_magFieldSvc("AtlasFieldSvc", name),
+  m_t0ShiftSvc("MdtCalibrationT0ShiftSvc", name),
+  m_tMaxShiftSvc("MdtCalibrationTMaxShiftSvc", name),
+  m_doT0Shift(false),
+  m_doTMaxShift(false),
+  m_unphysicalHitRadiusUpperBound(-1.),
+  m_unphysicalHitRadiusLowerBound(-1.),
+  m_resTwin(-1.),
+  m_BMGpresent(false),
+  m_BMGid(-1)
+{}
+
+
+MdtCalibrationTool::MdtCalibrationTool(const std::string& type, const std::string &name, const IInterface* parent)
+  : AthAlgTool(type, name, parent),
+    m_dbTool("MdtCalibrationDbTool",this)
+{
+  //TODO: Use smart pointer
+  m_imp = new MdtCalibrationTool::Imp(name);
+  // settable properties
+  declareProperty("TimeWindowLowerBound",m_imp->settings.windowLowerBound );
+  declareProperty("TimeWindowUpperBound",m_imp->settings.windowUpperBound );
+  declareProperty("TimeWindowSetting",m_imp->settings.windowSetting );
+  declareProperty("DoTofCorrection",m_imp->settings.doTof );
+  declareProperty("DoPropagationCorrection",m_imp->settings.doProp );
+  declareProperty("DoTemperatureCorrection",m_imp->settings.doTemp );
+  declareProperty("DoMagneticFieldCorrection",m_imp->settings.doField );
+  declareProperty("DoWireSagCorrection",m_imp->settings.doWireSag );
+  declareProperty("DoSlewingCorrection",m_imp->settings.doSlew );
+  declareProperty("DoBackgroundCorrection",m_imp->settings.doBkg );
+  declareProperty("ResolutionTwinTube",   m_imp->m_resTwin = 1.05, "Twin Tube resolution");
+  declareProperty("MagFieldSvc", m_imp->m_magFieldSvc);
+  declareProperty("UpperBoundHitRadius", m_imp->m_unphysicalHitRadiusUpperBound = 20. );
+  declareProperty("LowerBoundHitRadius", m_imp->m_unphysicalHitRadiusLowerBound = 0. );
+  declareProperty("DoT0Shift", m_imp->m_doT0Shift = false );
+  declareProperty("DoTMaxShift", m_imp->m_doTMaxShift = false );
+  declareProperty("CalibrationDbTool",m_dbTool);
+}
+
+MdtCalibrationTool::~MdtCalibrationTool() {
+  delete m_imp;
+}
+
+StatusCode MdtCalibrationTool::initialize() {
+  ATH_MSG_DEBUG( "Initializing" );
+
+  m_imp->settings.initialize();
+  // initialize the MdtIdHelper
+  //TODO: Use detStore() directly
+  ServiceHandle<StoreGateSvc> detStore("StoreGateSvc/DetectorStore", name());
+  if ( detStore.retrieve().isFailure() ) {
+    ATH_MSG_FATAL( "Can't locate the DetectorStore" );
+    return StatusCode::FAILURE;
+  }
+
+  if ( detStore->retrieve(m_imp->m_mdtIdHelper, "MDTIDHELPER" ).isFailure() ) {
+    ATH_MSG_FATAL( "Can't retrieve MdtIdHelper" );
+    return StatusCode::FAILURE;
+  }
+  // assign BMG identifier
+  m_imp->m_BMGpresent = m_imp->m_mdtIdHelper->stationNameIndex("BMG") != -1;
+  if(m_imp->m_BMGpresent){
+    ATH_MSG_INFO("Processing configuration for layouts with BMG chambers.");
+    m_imp->m_BMGid = m_imp->m_mdtIdHelper->stationNameIndex("BMG");
+  }
+  // initialise MuonGeoModel access
+  if ( detStore->retrieve( m_imp->m_muonGeoManager ).isFailure() ) {
+    ATH_MSG_FATAL( "Can't retrieve MuonDetectorManager" );
+    return StatusCode::FAILURE;
+  }
+  if ( m_imp->m_magFieldSvc.retrieve().isFailure() ) {
+    ATH_MSG_FATAL( "Could not find MagFieldSvc" );
+    return StatusCode::FAILURE;
+  }
+
+  if (m_imp->m_doT0Shift) ATH_CHECK( m_imp->m_t0ShiftSvc.retrieve() );
+
+  if (m_imp->m_doTMaxShift) ATH_CHECK ( m_imp->m_tMaxShiftSvc.retrieve() );
+
+  m_imp->m_log = &msg();
+  m_imp->m_verbose = msgLvl(MSG::VERBOSE);
+  m_imp->m_debug = msgLvl(MSG::DEBUG);
+
+  ATH_MSG_DEBUG("Settings:");
+  ATH_MSG_DEBUG("  Time window: lower bound " << m_imp->settings.timeWindowLowerBound()
+	       << "   upper bound " << m_imp->settings.timeWindowUpperBound() );
+  if( m_imp->settings.doTofCorrection() )           ATH_MSG_DEBUG(" Using TOF ");
+  if( m_imp->settings.doPropCorrection() )          ATH_MSG_DEBUG(" Using Prop ");
+  if( m_imp->settings.doCorrections() )             ATH_MSG_DEBUG(" Using Cor ");
+  if( m_imp->settings.doTemperatureCorrection() )   ATH_MSG_DEBUG(" Using TempCor ");
+  if( m_imp->settings.doMagneticFieldCorrection() ) ATH_MSG_DEBUG(" Using MagCor ");
+  if( m_imp->settings.doWireSagCorrection() )       ATH_MSG_DEBUG(" Using WireSag ");
+  if( m_imp->settings.doSlewingCorrection() )       ATH_MSG_DEBUG(" Using Slew ");
+  if( m_imp->settings.doBackgroundCorrection() )    ATH_MSG_DEBUG(" Using BkgCor");
+
+  return StatusCode::SUCCESS;
+}  //end MdtCalibrationTool::initialize
+
+bool MdtCalibrationTool::driftRadiusFromTime( MdtCalibHit &hit,
+                                             double signedTrackLength,
+                                             double triggerTime,
+                                             bool resolFromRtrack ) {
+  MdtCalibrationSvcInput inputData;
+  inputData.tof = signedTrackLength*m_imp->m_inverseSpeedOfLight;
+  inputData.triggerOffset = triggerTime;
+  return driftRadiusFromTime( hit, inputData, m_imp->settings, resolFromRtrack );
+}
+
+bool MdtCalibrationTool::driftRadiusFromTime( MdtCalibHit &hit,
+                                             const MdtCalibrationSvcInput &inputData,
+                                             bool resolFromRtrack ) {
+  return driftRadiusFromTime( hit, inputData, m_imp->settings, resolFromRtrack );
+}
+
+bool MdtCalibrationTool::driftRadiusFromTime( MdtCalibHit &hit,
+                                             const MdtCalibrationSvcInput &inputData,
+                                             const MdtCalibrationSvcSettings &settings,
+                                             bool resolFromRtrack ) {
+
+  if( settings.timeWindowUpperBound() < 0. || settings.timeWindowLowerBound() < 0. ) {
+    // Should be an ERROR, but can't return StatusCode::FAILURE
+    ATH_MSG_WARNING( "Uninitialized settings object at " << &settings );
+    return false;
+  }
+
+  // Easiest MessageSvc implementation, not necessarily the best
+  if (msgLvl(MSG::VERBOSE)) {
+    msg(MSG::VERBOSE) << "Input: tof " << inputData.tof << " trigger offset " << inputData.triggerOffset;
+    if( inputData.pointOfClosestApproach ) msg(MSG::VERBOSE) << "  PointOfClosestApproach";
+    if( inputData.trackDirection )         msg(MSG::VERBOSE) << "  TrackDirection";
+    if( inputData.nominalWireSurface )     msg(MSG::VERBOSE) << "  Nom. WireSurface";
+    if( inputData.wireSurface )            msg(MSG::VERBOSE) << "  Sagged Wiresurface";
+    msg(MSG::VERBOSE) << endmsg;
+    msg(MSG::VERBOSE) << "Settings: window " << settings.timeWindowLowerBound() << "  " << settings.timeWindowUpperBound();
+    if( settings.doTof )     msg(MSG::VERBOSE) << " Tof";
+    if( settings.doProp )    msg(MSG::VERBOSE) << " Prop";
+    if( settings.doTemp )    msg(MSG::VERBOSE) << " Temp";
+    if( settings.doField )   msg(MSG::VERBOSE) << " Field";
+    if( settings.doWireSag ) msg(MSG::VERBOSE) << " WireSag";
+    if( settings.doSlew )    msg(MSG::VERBOSE) << " Slew";
+    if( settings.doBkg )     msg(MSG::VERBOSE) << " Bkg";
+    msg(MSG::VERBOSE) << endmsg;
+  }
+
+  const Identifier &id = hit.identify();
+
+  const MuonGM::MdtReadoutElement *geo = hit.geometry();
+
+  // set geometry pointer if not yet set
+  if ( !geo ) {
+    geo = m_imp->getGeometry( id );
+    if ( !geo ) return false;
+    hit.setGeometry( geo );
+  }
+
+  // get calibration constants from DbTool
+  MuonCalib::MdtFullCalibData data = m_dbTool->getCalibration( geo->collectionHash(),
+								     geo->detectorElementHash() );
+
+  // require at least the MdtRtRelation to be available
+  const MuonCalib::MdtRtRelation *rtRelation = data.rtRelation;
+  // Hardcoded MDT tube radius 14.6mm here - not correct for sMDT
+  // on the other hand it should be rare that a tube does not have an RT
+  if( !rtRelation ) {
+    ATH_MSG_WARNING( "no rtRelation found, cannot calibrate tube" );
+    hit.setDriftRadius( 0., 2*14.6/sqrt(12) ); // treat the tube as a 'strip' measurement
+    return false;
+  }
+  double t0(0.);
+  double inversePropSpeed = m_imp->m_inversePropagationSpeed;
+  double adcCal(1.);
+
+  // access t0 for the given tube
+  if ( data.tubeCalib ) {
+
+    const int ml    = m_imp->m_mdtIdHelper->multilayer(id)-1;
+    const int layer = m_imp->m_mdtIdHelper->tubeLayer(id)-1;
+    const int tube  = m_imp->m_mdtIdHelper->tube(id)-1;
+
+    if ( ml<0 || layer<0 || tube<0 ){
+      ATH_MSG_WARNING( "Oops negative index....." );
+      return false;
+    }
+
+    //TODO: Use ATH_MSG macro
+
+    // extract calibration constants for single tube
+    const MuonCalib::MdtTubeCalibContainer::SingleTubeCalib *singleTubeData =
+      data.tubeCalib->getCalib( ml, layer, tube );
+    if( singleTubeData ){
+      t0 = singleTubeData->t0;
+      inversePropSpeed = singleTubeData->inversePropSpeed;
+      adcCal = singleTubeData->adcCal;
+    } else {      
+      msg(MSG::WARNING) << "failed to access tubedata for "
+			<< ml << " " << layer << " " << tube
+			<< " using defaults.. " << endmsg;
+      if ( geo )
+	msg(MSG::WARNING) << "detel " << geo->getMultilayer()
+			  << " lay " << geo->getNLayers()
+			  << " tubes " << geo->getNtubesperlayer() << endmsg;
+      t0 =  800.;
+    }
+
+    // get t0 shift from tool (default: no shift, value is zero)
+    if (m_imp->m_doT0Shift) t0 += m_imp->m_t0ShiftSvc->getValue(id);
+  } else {
+    msg(MSG::WARNING) << "MdtTubeCalibContainer not found for "
+		      << m_imp->m_mdtIdHelper->print_to_string( id ) << endmsg;
+    ATH_MSG_WARNING( "Tube cannot be calibrated!!!" );
+    return false;
+  }
+
+  // correct for global t0 of rt-region
+  t0 += rtRelation->t0Global();
+  hit.setTubeT0(t0);
+  hit.setTubeAdcCal(adcCal);
+
+  // in order to have clean info in the ntuple set to 0 the
+  // corrections which are not used
+  /*    hit.setSlewingTime( 0 );
+	hit.setLorentzTime( 0 );
+	hit.setTemperatureTime( 0 );
+	hit.setWiresagTime( 0 );*/
+  // set propagation delay
+  double propTime(0.);
+  if ( settings.doProp ){
+    // set propagation delay w.r.t. centre of tube.
+    double distToRO = geo->distanceFromRO( hit.globalPointOfClosestApproach(), id );
+    hit.setDistanceToReadout( distToRO );
+    double propagationDistance = distToRO - geo->RODistanceFromTubeCentre( id );
+    propTime = propagationDistance * inversePropSpeed;
+  }
+  hit.setPropagationTime(propTime);
+
+  // set time-of-flight
+  double triggerTime = inputData.tof + inputData.triggerOffset;
+  hit.setTimeOfFlight( settings.doTof ? triggerTime : 0. );
+
+  // calculate drift time
+  double driftTime = hit.tdcCount() * tdcBinSize(id) - hit.timeOfFlight()
+                     - hit.tubeT0() - hit.propagationTime();
+  hit.setDriftTime( driftTime );
+
+  // apply corrections
+  double corTime(0.);
+  if ( settings.doCorrections() ) {
+    corTime = m_imp->applyCorrections( hit, inputData, settings,
+				       adcCal, data.corrections, rtRelation->rt());
+  }
+
+  // calculate drift radius + error
+  double r(0.);
+  double reso(1.);
+  double t = hit.driftTime();
+  double t_inrange = hit.driftTime();
+  bool calibOk = true;
+  Muon::MdtDriftCircleStatus timeStatus = driftTimeStatus(t, rtRelation, settings);
+  if( rtRelation->rt() ){
+
+    r = rtRelation->rt()->radius(t);
+
+    // apply tUpper gshift
+    if (m_imp->m_doTMaxShift) {
+      float tShift = m_imp->m_tMaxShiftSvc->getValue(id);
+      r = rtRelation->rt()->radius( t * (1 + tShift) );
+    }
+
+    // check whether drift times are within range, if not fix them to the min/max range
+    if ( t < rtRelation->rt()->tLower() ) {
+      t_inrange = rtRelation->rt()->tLower();
+      double rmin = rtRelation->rt()->radius( t_inrange );
+      double drdt = (rtRelation->rt()->radius( t_inrange + 30. ) - rmin)/30.;
+
+      // now check whether we are outside the time window
+      if ( timeStatus == Muon::MdtStatusBeforeSpectrum ) {
+	t = rtRelation->rt()->tLower() - settings.timeWindowLowerBound();
+	calibOk = false;
+      }
+
+      // if we get here we are outside the rt range but inside the window.
+      r = rmin + drdt*(t-t_inrange);
+      if( r < m_imp->m_unphysicalHitRadiusLowerBound ) r = m_imp->m_unphysicalHitRadiusLowerBound;
+    } else if( t > rtRelation->rt()->tUpper() ) {
+      t_inrange = rtRelation->rt()->tUpper();
+      double rmax = rtRelation->rt()->radius( t_inrange );
+      double drdt = (rmax - rtRelation->rt()->radius( t_inrange - 30. ))/30.;
+
+      // now check whether we are outside the time window
+      if ( timeStatus == Muon::MdtStatusAfterSpectrum ) {
+	t = rtRelation->rt()->tUpper() + settings.timeWindowUpperBound();
+	calibOk = false;
+      }
+
+      // if we get here we are outside the rt range but inside the window.
+      r = rmax + drdt*(t-t_inrange);
+    }
+  } else {
+    ATH_MSG_WARNING( "no rt found" );
+  }
+
+  if ( rtRelation->rtRes() ){
+    if (!resolFromRtrack) {
+      reso = rtRelation->rtRes()->resolution( t_inrange );
+    } else {
+      bool out_of_bound_flag;
+      reso = rtRelation->rtRes()->resolution(rtRelation->tr()->tFromR(fabs(hit.signedDistanceToTrack()),
+								      out_of_bound_flag) );
+    }
+  }else{
+    ATH_MSG_WARNING( "no rtRes found" );
+  }
+  hit.setDriftRadius( r, reso );
+
+  // summary
+  ATH_MSG_VERBOSE( "driftRadiusFromTime for tube " << m_imp->m_mdtIdHelper->print_to_string(id)
+		 << (calibOk ? " OK" : "FAILED") );
+  ATH_MSG_VERBOSE( " raw drift time " << hit.tdcCount() * tdcBinSize(id)
+		 << " TriggerOffset " << inputData.triggerOffset << endmsg
+		 << "Tof " << inputData.tof << " Propagation Delay "
+		 << hit.propagationTime() << " T0 " << hit.tubeT0()
+		 << " invProp " << inversePropSpeed << endmsg
+		 << "Drift time after corrections " << driftTime
+		 << " time cor " << corTime
+		 << " Drift radius " << hit.driftRadius()
+		 << " sigma " <<  hit.sigmaDriftRadius() );
+
+
+  return calibOk;
+}  //end MdtCalibrationTool::driftRadiusFromTime
+
+// + TWIN TUBES
+bool MdtCalibrationTool::twinPositionFromTwinHits( MdtCalibHit &hit,
+                                                  MdtCalibHit &secondHit,
+                                                  double signedTrackLength,
+                                                  double secondSignedTrackLength,
+                                                  bool &secondDigitIsPrompt,
+                                                  double triggerTime ){
+  MdtCalibrationSvcInput inputData;
+  inputData.tof = signedTrackLength*m_imp->m_inverseSpeedOfLight;
+  inputData.triggerOffset = triggerTime;
+
+  MdtCalibrationSvcInput secondInputData;
+  secondInputData.tof = secondSignedTrackLength*m_imp->m_inverseSpeedOfLight;
+  secondInputData.triggerOffset = triggerTime;
+  return twinPositionFromTwinHits( hit, secondHit, inputData,
+				   secondInputData, m_imp->settings, secondDigitIsPrompt );
+}
+
+bool MdtCalibrationTool::twinPositionFromTwinHits( MdtCalibHit &hit,
+                                                  MdtCalibHit &secondHit,
+                                                  const MdtCalibrationSvcInput &inputData,
+                                                  const MdtCalibrationSvcInput &secondInputData,
+                                                  const MdtCalibrationSvcSettings &settings,
+                                                  bool &secondDigitIsPrompt ) {
+
+  // 13/02/2009 A.Koutsman: after discussion with P.Kluit rebuilt this function to use the standard way
+  // of calibrating a MdtCalibHit with driftRadiusFromTime(...)
+
+  driftRadiusFromTime( hit, inputData, settings );
+  driftRadiusFromTime( secondHit, secondInputData, settings );
+
+  // get Identifier and MdtReadOutElement for twin tubes
+  const Identifier &id = hit.identify();
+  const Identifier &idSecond = secondHit.identify();
+  const MuonGM::MdtReadoutElement *geo = hit.geometry();
+  const MuonGM::MdtReadoutElement *geoSecond = secondHit.geometry();
+
+  // get 'raw' drifttimes of twin pair; we don't use timeofFlight or propagationTime cause they are irrelevant for twin coordinate
+  double driftTime = hit.tdcCount()*tdcBinSize(id) - hit.tubeT0();
+  double driftTimeSecond = secondHit.tdcCount()*tdcBinSize(idSecond) - secondHit.tubeT0();
+
+  if(!geo) {
+    ATH_MSG_WARNING( "Geometry not set for first hit" );
+    return false;
+  }
+  if(!geoSecond) {
+    ATH_MSG_WARNING( "Geometry not set for second hit" );
+    return false;
+  }
+  // get calibration constants from DbTool
+  MuonCalib::MdtFullCalibData data = m_dbTool->getCalibration( geo->collectionHash(), geo->detectorElementHash() );
+  MuonCalib::MdtFullCalibData dataSecond = m_dbTool->getCalibration( geoSecond->collectionHash(), geoSecond->detectorElementHash() );
+
+  double inversePropSpeed = m_imp->m_inversePropagationSpeed;
+  double inversePropSpeedSecond = m_imp->m_inversePropagationSpeed;
+
+  // access t0 for the give tube
+  if( data.tubeCalib ){
+
+    const int ml    = m_imp->m_mdtIdHelper->multilayer(id)-1;
+    const int layer = m_imp->m_mdtIdHelper->tubeLayer(id)-1;
+    const int tube  = m_imp->m_mdtIdHelper->tube(id)-1;
+
+    if( ml<0 || layer<0 || tube<0 ){
+      ATH_MSG_WARNING( "Oops negative index....." );
+      return false;
+    }
+
+    // extract calibration constants for single tube
+    const MuonCalib::MdtTubeCalibContainer::SingleTubeCalib *singleTubeData =
+      data.tubeCalib->getCalib( ml, layer, tube );
+    if ( singleTubeData ){
+      inversePropSpeed = singleTubeData->inversePropSpeed;
+    } else {
+      ATH_MSG_WARNING( "failed to access tubedata for "
+		       << ml << " " << layer << " " << tube
+		       << " using defaults.. " );
+      if ( geo )
+	ATH_MSG_WARNING( "detel "
+			 << geo->getMultilayer() << " lay " << geo->getNLayers()
+			 << " tubes " << geo->getNtubesperlayer() );
+    }
+  } else {
+    ATH_MSG_WARNING( "MdtTubeCalibContainer not found for "
+		     << m_imp->m_mdtIdHelper->print_to_string( id ) );
+    ATH_MSG_WARNING( "Tube cannot be calibrated!!!" );
+    return false;
+  }
+
+  // access t0 for the given second tube
+  if ( dataSecond.tubeCalib ){
+    const int mlSecond    = m_imp->m_mdtIdHelper->multilayer(idSecond)-1;
+    const int layerSecond = m_imp->m_mdtIdHelper->tubeLayer(idSecond)-1;
+    const int tubeSecond  = m_imp->m_mdtIdHelper->tube(idSecond)-1;
+
+    if( mlSecond<0 || layerSecond<0 || tubeSecond<0 ){
+      ATH_MSG_WARNING( "Oops negative index for second tube....." );
+      return false;
+    }
+
+    // extract calibration constants for single tube
+    const MuonCalib::MdtTubeCalibContainer::SingleTubeCalib *singleTubeDataSecond =
+      dataSecond.tubeCalib->getCalib( mlSecond, layerSecond, tubeSecond );
+    if ( singleTubeDataSecond ){
+      inversePropSpeedSecond = singleTubeDataSecond->inversePropSpeed;
+    } else {
+      ATH_MSG_WARNING( "failed to access (second) tubedata for " << mlSecond
+		       << " " << layerSecond << " " << tubeSecond
+		       << " using defaults.. " );
+      if ( geoSecond )
+	ATH_MSG_WARNING( "detel " << geoSecond->getMultilayer()
+			 << " lay " << geoSecond->getNLayers()
+			 << " tubes " << geoSecond->getNtubesperlayer() );
+    }
+  } else {
+    ATH_MSG_WARNING( "MdtTubeCalibContainer not found for "
+		     << m_imp->m_mdtIdHelper->print_to_string( idSecond ) );
+    ATH_MSG_WARNING( "Second tube cannot be calibrated!!!" );
+    return false;
+  }
+
+  // define twin position and error
+  double zTwin(0.);
+  double errZTwin(0.);
+  double twin_timedif(0.);
+
+  // find out which tube was the prompt
+  // (= actually hit by the muon; not hit by the muon = twinhit_)
+  // in the formula for z_hit_from_twin we take as convention that
+  // twindif = twin_time - prompt_time
+
+  Identifier prompthit_id = id;
+  const MuonGM::MdtReadoutElement *prompthit_geo = geo;
+  int prompthit_tdc = 0;
+  int twinhit_tdc = 0;
+  if ( driftTime < driftTimeSecond) {
+    twin_timedif = driftTimeSecond - driftTime;
+    //prompthit_tdc = hit.tdcCount(); prompthit_adc = adcCal;
+    //twinhit_tdc = secondHit.tdcCount(); twinhit_adc = adcCalSecond;
+    secondDigitIsPrompt = false;
+  } else if (driftTimeSecond <= driftTime){
+    prompthit_id = idSecond;
+    prompthit_geo = geoSecond;
+    twin_timedif = driftTime - driftTimeSecond;
+    //prompthit_tdc = secondHit.tdcCount(); prompthit_adc = adcCalSecond;
+    //twinhit_tdc = hit.tdcCount(); twinhit_adc = adcCal;
+    secondDigitIsPrompt = true;
+  }
+
+  // get tubelength and set HV-delay (~6ns)
+
+  double tubelength = prompthit_geo->tubeLength(prompthit_id);
+  double HVdelay = 6.;
+
+  // twin_timedif must be between min and max of possible time-difference
+  // between prompt and twin signals
+  // accounting for 3 std.dev. of twin time resolution
+  if ( twin_timedif < (HVdelay - 5.*m_imp->m_resTwin)
+       || twin_timedif > (tubelength*inversePropSpeed
+			  + tubelength*inversePropSpeedSecond
+			  + HVdelay + 5.*m_imp->m_resTwin)){
+    if ( m_imp->m_debug ) {
+      ATH_MSG_DEBUG( " TIME DIFFERENCE OF TWIN PAIR OUT OF RANGE("
+		     << (HVdelay - 5.*m_imp->m_resTwin)
+		     << "-"
+		     << (tubelength*inversePropSpeed
+			 + tubelength*inversePropSpeedSecond
+			 + HVdelay + 5.*m_imp->m_resTwin)
+		     << ")   time difference = "
+		     << twin_timedif );
+    }
+  }
+
+  // Make ONLY a twin PrepData if twin time difference is physical (within tubelength)
+  if (twin_timedif < (tubelength*inversePropSpeed
+		      + tubelength*inversePropSpeedSecond
+		      + HVdelay + 10.*m_imp->m_resTwin)){
+
+    //calculate local(!) z of the hit from twin tubes information
+
+    double z_hit_sign_from_twin = ( 1 / (inversePropSpeed *2.))
+      * (tubelength*inversePropSpeedSecond - twin_timedif + HVdelay) ;
+
+    // Put twin hit always inside acceptance
+    if (z_hit_sign_from_twin < -tubelength/2.) {
+      if ( m_imp->m_debug ) {
+	ATH_MSG_DEBUG( " TWIN HIT outside acceptance with time difference "
+		       <<  twin_timedif
+		       << " Z local hit " <<  z_hit_sign_from_twin
+		       << " Z local minimum " <<  -tubelength/2 );
+      }
+      z_hit_sign_from_twin = - tubelength/2.;
+    }
+    // do sign management just like in MdtDigitizationTool.cxx
+    double distRO = prompthit_geo->tubeFrame_localROPos(prompthit_id).z();
+    double sign(-1.);
+    if (distRO < 0.) sign = 1.;
+
+    double z_hit_geo_from_twin = sign*z_hit_sign_from_twin;
+
+    zTwin = z_hit_geo_from_twin;
+    errZTwin = m_imp->m_resTwin*inversePropSpeed;
+
+    if ( m_imp->m_verbose ){
+      ATH_MSG_VERBOSE( " TWIN TUBE "
+		     << " tube: " << m_imp->m_mdtIdHelper->print_to_string(id)
+		     << " twintube: " << m_imp->m_mdtIdHelper->print_to_string(idSecond)
+		     );
+      ATH_MSG_VERBOSE( " prompthit tdc = " << prompthit_tdc//*TDCbinsize
+		     << "  twinhit tdc = " << twinhit_tdc// *TDCbinsize
+		     << "  tube driftTime = " << driftTime
+		     << "  second tube driftTime = " << driftTimeSecond
+		     << " TWIN PAIR time difference = " << twin_timedif
+		     );
+      ATH_MSG_VERBOSE( " z_hit_sign_from_twin = " << z_hit_sign_from_twin
+		     << " z_hit_geo_from_twin = " << z_hit_geo_from_twin
+		     << " with sign = " << sign
+		     << "  distRO = " << distRO
+		     );
+    }
+
+  } // end  if(twin_timedif < (tubelength*inversePropSpeed + tubelength*inversePropSpeedSecond + HVdelay + 10.*m_imp->m_resTwin)){
+  else {
+
+    if ( m_imp->m_verbose ){
+      ATH_MSG_VERBOSE( " TIME DIFFERENCE OF TWIN PAIR UNPHYSICAL OUT OF RANGE("
+		     << (HVdelay - 5*m_imp->m_resTwin) << "-"
+		     << (2*tubelength*inversePropSpeed + HVdelay + 5*m_imp->m_resTwin)
+		     << ")   time difference = "
+		     << twin_timedif );
+    }
+    zTwin = 0.;
+    errZTwin = tubelength/2.;
+  }
+
+  hit.setLocXtwin( zTwin );
+  hit.setSigma2LocXtwin( errZTwin*errZTwin );
+  secondHit.setLocXtwin( zTwin );
+  secondHit.setSigma2LocXtwin( errZTwin*errZTwin );
+
+  return true;
+}  //end MdtCalibrationTool::twinPositionFromTwinHits
+
+double MdtCalibrationTool::tdcBinSize(const Identifier &id) {
+//BMG which uses HPTDC instead of AMT, and has 0.2ns TDC ticksize
+  //if( m_imp->m_mdtIdHelper->stationName(id) == 54 )  //BMG
+    //return 0.2;
+// Alternative method if you don't like hardcoding BMG stationName (54)
+ // don't do string comparisons!
+ //if( m_imp->m_mdtIdHelper->stationNameString( m_imp->m_mdtIdHelper->stationName(id) ) == "BMG" )
+  if( m_imp->m_mdtIdHelper->stationName(id) == m_imp->m_BMGid && m_imp->m_BMGpresent)
+    return 0.1953125; // 25/128
+  return 0.78125;  //25/32; exact number: (1000.0/40.079)/32.0
+}
+
+double MdtCalibrationTool::Imp::applyCorrections(MdtCalibHit &hit,
+                                                const MdtCalibrationSvcInput &inputData,
+						const MdtCalibrationSvcSettings &settings,
+						double /*adcCal*/,
+                                                const MuonCalib::MdtCorFuncSet *corrections, const MuonCalib::IRtRelation *rt) const {
+
+  double corTime(0.);
+  // apply corrections
+  if ( corrections ){
+
+    if (m_verbose) *m_log << MSG::VERBOSE << "There are correction functions." << endmsg;
+
+    // slewing corrections
+    if ( settings.doSlew && corrections->slewing() ){
+      double slew_time=corrections->slewing()->correction( hit.driftTime(), hit.adcCount());
+      corTime -=slew_time;
+      hit.setSlewingTime(slew_time);
+    }
+
+    if( settings.doField && corrections->bField()){
+      if( inputData.trackDirection && inputData.pointOfClosestApproach ) {
+        Amg::Transform3D gToStation = hit.geometry()->GlobalToAmdbLRSTransform();
+        double BGXYZ[3];
+	double xyz[3] = { (*inputData.pointOfClosestApproach)(0),
+			  (*inputData.pointOfClosestApproach)(1),
+			  (*inputData.pointOfClosestApproach)(2) };
+        m_magFieldSvc->getField(xyz, BGXYZ);
+	for (int i=0; i<3; i++) BGXYZ[i] *= 1000.; // convert kT to Tesla
+        Amg::Vector3D B_global(BGXYZ[0], BGXYZ[1], BGXYZ[2]);
+        Amg::Vector3D B_loc(gToStation.linear()*B_global);
+        double Bpar = B_loc.x();
+        Amg::Vector3D loc_dir(gToStation.linear()*(*(inputData.trackDirection)));
+        Amg::Vector3D dir(0.0, loc_dir.y(), loc_dir.z());
+        double Bper = B_loc.dot(dir.unit());
+        hit.setBFieldPerp(Bper);
+        hit.setBFieldPara(Bpar);
+        if( m_verbose ) *m_log << MSG::VERBOSE << "doing b-field correction" << endmsg;
+        if(hit.bFieldPara() != MdtCalibHit::kNoValue && hit.bFieldPerp() != MdtCalibHit::kNoValue) {
+	  hit.setLorentzTime(corrections->bField()->correction( hit.driftTime(), hit.bFieldPara(),  hit.bFieldPerp() ));
+	} else {
+	  hit.setLorentzTime(0);
+	}
+        corTime -= hit.lorentzTime();
+      }
+    }
+
+    // temperature corrections
+    // NOTE: Use this temporarily for ML dependent scaling.
+ /*   if ( settings.doTemp && corrections->temperature() ){
+      if(hit.temperature() != MdtCalibHit::kNoValue)
+        {
+          hit.setTemperatureTime(corrections->temperature()->correction( hit.driftTime(), hit.temperature()));
+        }
+      else
+        {
+          hit.setTemperatureTime(0);
+        }
+      corTime += hit.TemperatureTime();
+    }*/
+
+    // Scale RT function from Tmax difference
+    if( settings.doTemp && rt && rt->HasTmaxDiff()) {
+      float scle_time=MuonCalib::RtScaleFunction(hit.driftTime(), m_mdtIdHelper->multilayer(hit.identify())==2, *rt);
+      hit.setTemperatureTime(scle_time);
+      corTime-=scle_time;
+    } else {
+      hit.setTemperatureTime(0);
+    }
+
+    // background corrections
+    if ( settings.doBkg && corrections->background() ){
+      double bgLevel = 0.;
+      corTime += corrections->background()->correction( hit.driftTime(), bgLevel );
+    }
+
+    // wire sag corrections
+    // First some debug output
+    if (m_verbose) {
+      if ( settings.doWireSag ){
+	*m_log << MSG::VERBOSE << "settings.doWireSag == TRUE" << endmsg;
+      } else {
+	*m_log << MSG::VERBOSE << "settings.doWireSag == FALSE" << endmsg;
+      }
+      if ( corrections->wireSag() ){
+	*m_log << MSG::VERBOSE << "corrections->wireSag() == TRUE" << endmsg;
+      } else {
+	*m_log << MSG::VERBOSE << "corrections->wireSag() == FALSE" << endmsg;
+      }
+    }
+    // Wire sag corrections
+    if ( settings.doWireSag && corrections->wireSag() ){
+
+      if (m_verbose) {
+	*m_log << MSG::VERBOSE << "Performing Rt Corrections due to Wire Sag." << endmsg;
+
+	if (inputData.pointOfClosestApproach) {
+	  *m_log << MSG::VERBOSE << "Have a point of closest approach." << endmsg;
+	} else {
+	  *m_log << MSG::VERBOSE << "No point of closest approach!" << endmsg;
+	}
+	if (inputData.trackDirection) {
+	  *m_log << MSG::VERBOSE << "Have a track direction." << endmsg;
+	} else {
+	  *m_log << MSG::VERBOSE << "No track direction!" << endmsg;
+	}
+	if (inputData.nominalWireSurface) {
+	  *m_log << MSG::VERBOSE << "Have a nominal wire surface." << endmsg;
+	} else {
+	  *m_log << MSG::VERBOSE << "No nominal wire surface!" << endmsg;
+	}
+	if (inputData.wireSurface) {
+	  *m_log << MSG::VERBOSE << "Have a sagged wire surface." << endmsg;
+	} else {
+	  *m_log << MSG::VERBOSE << "No sagged wire surface!" << endmsg;
+	}
+      }
+
+      const Amg::Vector3D *pointOfClosestApproach = inputData.pointOfClosestApproach;
+      const Amg::Vector3D *trackDirection         = inputData.trackDirection;
+      const Trk::StraightLineSurface *nominalWireSurface = inputData.nominalWireSurface;
+      const Trk::StraightLineSurface *wireSurface = inputData.wireSurface;
+
+      // check whether all input data is there
+      if ( !pointOfClosestApproach || !trackDirection || !nominalWireSurface ){
+	*m_log << MSG::WARNING << " cannot perform wire sag correction: ";
+        if( !pointOfClosestApproach ) *m_log << " no pointOfClosestApproach ";
+        if( !trackDirection )         *m_log << " no trackDirection ";
+        if( !nominalWireSurface )     *m_log << " no nominalWireSurface ";
+        *m_log << endmsg;
+      } else {
+
+	if (m_verbose) {
+	  *m_log << MSG::VERBOSE << "All Necessary Wire Sag data available: " << endmsg;
+	  *m_log << MSG::VERBOSE << "  pCA = ("
+		 << pointOfClosestApproach->x() << ", "
+		 << pointOfClosestApproach->y() << ", "
+		 << pointOfClosestApproach->z() << ")" << endmsg;
+	}
+
+        // store pointer to sagged surface as we get ownership if we recalculate it
+        const Trk::StraightLineSurface *tempSaggedSurface = 0;
+
+        // if wire surface is missing, calculate sagged wire position
+        if ( !wireSurface ){
+          const Trk::SaggedLineSurface *nominalSurf = dynamic_cast<const Trk::SaggedLineSurface*>(nominalWireSurface);
+          if ( nominalSurf ){
+            // Local position for calculation of position along the tube,
+            // used for wire sag treatment
+            const Amg::Vector2D *tempLocOnWire = nominalSurf->Trk::Surface::globalToLocal(*pointOfClosestApproach,1000.);
+            if ( !tempLocOnWire ){
+              *m_log << MSG::WARNING << "globalToLocal failed! " << endmsg;
+            } else {
+              // sagged surface
+              wireSurface = nominalSurf->correctedSurface(*tempLocOnWire);
+              tempSaggedSurface = wireSurface;
+              delete tempLocOnWire;
+            }
+          } else {
+            *m_log << MSG::WARNING
+		   << "Nominal wire surface not a SaggedLineSurface,"
+		   << " cannot perform wire sag correction" << endmsg;
+          }
+        }
+
+        if ( !wireSurface ){
+          *m_log << MSG::WARNING
+		 << " cannot perform wire sag correction: no sagged wire surface "
+		 << endmsg;
+        } else {
+
+          // get to transformation matrix from global into the tube frame
+          Amg::Transform3D globalToTube = nominalWireSurface->transform().inverse();
+
+          // calculate the local position of the nominal and sagged wire
+          Amg::Vector3D locNominalPos(0.,0.,0.);
+          Amg::Vector3D locSaggedPos = globalToTube*wireSurface->center();
+          locSaggedPos[2] = 0.;
+
+          // calculate the local track direction
+          Amg::Vector3D locTrackDir = globalToTube.linear()*(*trackDirection);
+          locTrackDir[2] = 0.;
+          locTrackDir = locTrackDir.unit();
+
+          // check if point of closest approach has been calculated
+          // relative to nominal or sagged wire
+
+          Amg::Vector3D locApproachDir(pointOfClosestApproach->x(),
+				       pointOfClosestApproach->y(),
+				       pointOfClosestApproach->z());
+          double dotProd = locApproachDir.dot(locTrackDir);
+          double deltaY = 0.;
+          if (dotProd == 0){
+            // this means the closest approach was calculated
+            // from the nominal position
+            deltaY = pointOfClosestApproach->y() - nominalWireSurface->center().y();
+          } else {
+            // this means the closest approach was calculated
+            // from the sagged position
+            deltaY = pointOfClosestApproach->y() - wireSurface->center().y();
+          }
+
+          // sign of drift radius (for sag calculation) is +/- of track passes
+          // above/below wire
+
+          double signedDriftRadius = fabs(hit.driftRadius())*deltaY/fabs(deltaY);
+
+          // calculate the magnitude of the wire sag
+
+          double effectiveSag = nominalWireSurface->center().y()
+            - wireSurface->center().y();
+
+          // apply the correction
+
+          corTime += corrections->wireSag()->correction(signedDriftRadius, effectiveSag);
+
+        }
+        delete tempSaggedSurface;
+      }
+    }
+
+  }
+
+  hit.setDriftTime(hit.driftTime() + corTime);
+
+  return corTime;
+}  //end MdtCalibrationTool::Imp::applyCorrections
+
+Muon::MdtDriftCircleStatus MdtCalibrationTool::driftTimeStatus( double driftTime, const MuonCalib::MdtRtRelation *rtRelation, const MdtCalibrationSvcSettings &settings ) {
+  if( settings.timeWindowUpperBound() < 0. || settings.timeWindowLowerBound() < 0. ) {
+      ATH_MSG_WARNING( " Unphysical time window detected, both ranges should be positive: "
+		       << " lower bound " << settings.timeWindowLowerBound()
+		       << " upper bound " << settings.timeWindowUpperBound() );
+  }
+
+  if( rtRelation && rtRelation->rt() ) {
+    if( driftTime < rtRelation->rt()->tLower() - settings.timeWindowLowerBound() ) {
+      // Will this produce too much output from ROT creators?
+      if ( m_imp->m_verbose )
+	ATH_MSG_VERBOSE( " drift time outside time window "
+			 << driftTime << ". Mininum time = "
+			 << rtRelation->rt()->tLower() - settings.timeWindowLowerBound() );
+      return Muon::MdtStatusBeforeSpectrum;
+    } else if( driftTime > rtRelation->rt()->tUpper() + settings.timeWindowUpperBound()  ) {
+      if ( m_imp->m_verbose )
+	ATH_MSG_VERBOSE( " drift time outside time window "
+			 << driftTime << ". Maximum time  = "
+			 << rtRelation->rt()->tUpper() + settings.timeWindowUpperBound() );
+      return Muon::MdtStatusAfterSpectrum;
+    }
+  } else {
+    ATH_MSG_WARNING( "No valid rt relation supplied for driftTimeStatus method" );
+    return Muon::MdtStatusUnDefined;
+  }
+  return Muon::MdtStatusDriftTime;
+}  //end MdtCalibrationTool::driftTimeStatus
diff --git a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/components/MdtCalibSvc_entries.cxx b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/components/MdtCalibSvc_entries.cxx
index baf205b911faefcc067f56ca349e83e8633f09ba..6d7c4539f6b54df7dea3f2353bb70d7a80f6d2d8 100644
--- a/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/components/MdtCalibSvc_entries.cxx
+++ b/MuonSpectrometer/MuonCalib/MdtCalib/MdtCalibSvc/src/components/MdtCalibSvc_entries.cxx
@@ -1,12 +1,16 @@
 #include "MdtCalibSvc/MdtCalibrationSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
 #include "MdtCalibSvc/MdtCalibrationRegionSvc.h"
 #include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MdtCalibSvc/MdtCalibrationT0ShiftSvc.h"                                                                                                                                                     
 #include "MdtCalibSvc/MdtCalibrationTMaxShiftSvc.h"
 
 DECLARE_COMPONENT( MdtCalibrationSvc )
+DECLARE_COMPONENT( MdtCalibrationTool )
 DECLARE_COMPONENT( MdtCalibrationRegionSvc )
 DECLARE_COMPONENT( MdtCalibrationDbSvc )
+DECLARE_COMPONENT( MdtCalibrationDbTool )
 DECLARE_COMPONENT( MdtCalibrationT0ShiftSvc )
 DECLARE_COMPONENT( MdtCalibrationTMaxShiftSvc )
 
diff --git a/MuonSpectrometer/MuonCalib/MuonCalibPatRec/MuonCalibPatRec/MuonSegmentToCalibSegment.h b/MuonSpectrometer/MuonCalib/MuonCalibPatRec/MuonCalibPatRec/MuonSegmentToCalibSegment.h
index ea1e8f3237ce0c190b1e825f0e7495ca408613cb..57fd9885e5da8f35aebaba5c7c41f7a1f74ee2a2 100644
--- a/MuonSpectrometer/MuonCalib/MuonCalibPatRec/MuonCalibPatRec/MuonSegmentToCalibSegment.h
+++ b/MuonSpectrometer/MuonCalib/MuonCalibPatRec/MuonCalibPatRec/MuonSegmentToCalibSegment.h
@@ -16,7 +16,7 @@
 #include "MuonSegment/MuonSegment.h"
 #include "MuonCalibITools/IIdToFixedIdTool.h"
 #include "MuonRecToolInterfaces/IMuonPatternSegmentAssociationTool.h"
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
 
 class MdtIdHelper;
 class CscIdHelper;
@@ -105,7 +105,7 @@ output the muon calibration input.
     const TgcIdHelper*  m_tgcIdHelper;
 
     /** pointer to MdtCalibSvc */
-    ServiceHandle<MdtCalibrationSvc> m_calibSvc;
+    ToolHandle<MdtCalibrationTool> m_calibrationTool;
 
     /** IdentifierTool initialization */
     ToolHandle< Muon::IMuonPatternSegmentAssociationTool> m_assocTool;
diff --git a/MuonSpectrometer/MuonCalib/MuonCalibPatRec/src/MuonSegmentToCalibSegment.cxx b/MuonSpectrometer/MuonCalib/MuonCalibPatRec/src/MuonSegmentToCalibSegment.cxx
index 6d9d8e77cb683c36f7b01746e854ab2e7229550b..e64a8f44151618f9b51deaaa185c808178128af4 100644
--- a/MuonSpectrometer/MuonCalib/MuonCalibPatRec/src/MuonSegmentToCalibSegment.cxx
+++ b/MuonSpectrometer/MuonCalib/MuonCalibPatRec/src/MuonSegmentToCalibSegment.cxx
@@ -29,7 +29,7 @@ namespace Trk {
 }
 
 // mdt calibration
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
 #include "MdtCalibSvc/MdtCalibrationSvcSettings.h"
 #include "MdtCalibSvc/MdtCalibrationSvcInput.h"
 #include "MuonCalibEvent/MdtCalibHit.h"
@@ -65,7 +65,7 @@ namespace MuonCalib {
     m_cscIdHelper(NULL),
     m_rpcIdHelper(NULL),
     m_tgcIdHelper(NULL),
-    m_calibSvc("MdtCalibrationSvc", name),
+    m_calibrationTool("MdtCalibrationTool",this),
     m_assocTool("Muon::MuonPatternSegmentAssociationTool/MuonPatternSegmentAssociationTool"),
     m_idToFixedIdTool("MuonCalib::IdToFixedIdTool/MuonCalib_IdToFixedIdTool")
 
@@ -92,6 +92,8 @@ namespace MuonCalib {
     declareProperty("UpdateForT0Shift", m_updateForT0Shift = -1 );
     declareProperty("DoTOF", m_doTof = true );
     declareProperty("DoCosmicsTof", m_cosmics_tof=false);
+
+    declareProperty("CalibrationTool",m_calibrationTool);
   }
 
   // Initialize
@@ -135,8 +137,6 @@ namespace MuonCalib {
       m_tgcIdHelper = 0;
     }
 
-    ATH_CHECK( m_calibSvc.retrieve() );
-
     // Get the maximum number of segments each algorithm can
     // store in the ntuple
     MuonSegmentNtupleBranch segBranch;
@@ -761,7 +761,7 @@ namespace MuonCalib {
 	} else { 
 	  segment_with_multiple_t0s=true;
 	  // We may be in a new chamber, with a different fitted t0 
-	  m_calibSvc->driftRadiusFromTime( calibHit, input, settings ); 
+	  m_calibrationTool->driftRadiusFromTime( calibHit, input, settings );
 	  
 	  // Reset the value of the t0 shift 
 	  t0Shift = calibHit.driftTime() - mrot->driftTime(); 
@@ -776,7 +776,7 @@ namespace MuonCalib {
 
 	// Calculate drift radius from drift time using MdtCalibrationSvc
 	double oldDriftTime = calibHit.driftTime(); // 0 unless we shift t0
-	m_calibSvc->driftRadiusFromTime( calibHit, input, settings );
+	m_calibrationTool->driftRadiusFromTime( calibHit, input, settings );
 	
 	double timeDif = calibHit.driftTime() - mrot->driftTime();
 	
diff --git a/MuonSpectrometer/MuonCnv/MuonCnvExample/python/MuonCalibConfig.py b/MuonSpectrometer/MuonCnv/MuonCnvExample/python/MuonCalibConfig.py
index f887b3d422e0fcb2396782fd37ea81109b35f1a2..1a324779d82ce7c492b679ab1e99667dc2adff0b 100644
--- a/MuonSpectrometer/MuonCnv/MuonCnvExample/python/MuonCalibConfig.py
+++ b/MuonSpectrometer/MuonCnv/MuonCnvExample/python/MuonCalibConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 #--------------------------------------------------------------
 # JobOption fragments for Condition Database access
@@ -139,19 +139,70 @@ else:
 
 
 def setupMdtCondDB():
+
     global mdt_folder_name_appendix
     from IOVDbSvc.CondDB import conddb
 
     if mdtCalibFlags.mdtCalibrationSource()=="MDT":
-        conddb.addFolderSplitOnline("MDT", '/MDT/Onl/RT' + mdt_folder_name_appendix,'/MDT/RT' + mdt_folder_name_appendix)
-        conddb.addFolderSplitOnline("MDT", '/MDT/Onl/T0' + mdt_folder_name_appendix,'/MDT/T0' + mdt_folder_name_appendix)
+        conddb.addFolderSplitOnline("MDT", '/MDT/Onl/RT' + mdt_folder_name_appendix,'/MDT/RT' + mdt_folder_name_appendix, className='CondAttrListCollection')
+        conddb.addFolderSplitOnline("MDT", '/MDT/Onl/T0' + mdt_folder_name_appendix,'/MDT/T0' + mdt_folder_name_appendix, className='CondAttrListCollection')
     else:
         from AthenaCommon.AppMgr import ServiceMgr
         ServiceMgr.TagInfoMgr.ExtraTagValuePairs += ["MDTCalibrationSource", mdtCalibFlags.mdtCalibrationSource()]
         specialAddFolderSplitOnline(mdtCalibFlags.mdtCalibrationSource(), '/MDT/Onl/RT' + mdt_folder_name_appendix,'/MDT/RT' + mdt_folder_name_appendix)
         specialAddFolderSplitOnline(mdtCalibFlags.mdtCalibrationSource(), '/MDT/Onl/T0' + mdt_folder_name_appendix,'/MDT/T0' + mdt_folder_name_appendix)
+
+    from AthenaCommon.AlgSequence import AthSequencer
+    from MdtCalibDbCoolStrTool.MdtCalibDbCoolStrToolConf import MdtCalibDbAlg
+    condSequence = AthSequencer("AthCondSeq")
+    if not hasattr(condSequence,"MdtCalibDbAlg"):
+        condSequence += MdtCalibDbAlg("MdtCalibDbAlg")
+
+    if conddb.isOnline and not conddb.isMC:
+        MdtCalibDbAlg.TubeFolder = "/MDT/T0"
+        MdtCalibDbAlg.RtFolder = "/MDT/RT"
+        MdtCalibDbAlg.ReadKeyTube = "/MDT/T0"
+        MdtCalibDbAlg.ReadKeyRt = "/MDT/RT"
+    else:
+        MdtCalibDbAlg.TubeFolder = "/MDT/T0" + mdt_folder_name_appendix
+        MdtCalibDbAlg.RtFolder = "/MDT/RT" + mdt_folder_name_appendix
+        MdtCalibDbAlg.ReadKeyTube = "/MDT/T0" + mdt_folder_name_appendix
+        MdtCalibDbAlg.ReadKeyRt = "/MDT/RT" + mdt_folder_name_appendix
+    MdtCalibDbAlg.RT_InputFiles = ["Muon_RT_default.data"]
+    if globalflags.DataSource == 'data':
+        MdtCalibDbAlg.defaultT0 = 40
+    elif globalflags.DataSource == 'geant4':
+        MdtCalibDbAlg.defaultT0 = 799
+    MdtCalibDbAlg.UseMLRt = mdtCalibFlags.useMLRt()
+    MdtCalibDbAlg.TimeSlewingCorrection = mdtCalibFlags.correctMdtRtForTimeSlewing()
+    MdtCalibDbAlg.MeanCorrectionVsR = [ -5.45973, -4.57559, -3.71995, -3.45051, -3.4505, -3.4834, -3.59509, -3.74869, -3.92066, -4.10799, -4.35237, -4.61329, -4.84111, -5.14524 ]
+    MdtCalibDbAlg.PropagationSpeedBeta = mdtCalibFlags.mdtPropagationSpeedBeta()
+    # the same as MdtCalibrationDbTool
+    MdtCalibDbAlg.CreateBFieldFunctions = mdtCalibFlags.correctMdtRtForBField()
+    MdtCalibDbAlg.CreateWireSagFunctions = mdtCalibFlags.correctMdtRtWireSag()
+    MdtCalibDbAlg.CreateSlewingFunctions = mdtCalibFlags.correctMdtRtForTimeSlewing()
+
+    from MdtCalibSvc.MdtCalibSvcConf import MdtCalibrationTool
+    MdtCalibrationTool.DoSlewingCorrection = mdtCalibFlags.correctMdtRtForTimeSlewing()
+    MdtCalibrationTool.DoTemperatureCorrection = mdtCalibFlags.applyRtScaling()
+    MdtCalibrationTool.DoWireSagCorrection = mdtCalibFlags.correctMdtRtWireSag()
+    if beamFlags.beamType() == 'collisions':
+        MdtCalibrationTool.DoTofCorrection = True
+        if globalflags.DataSource() == 'geant4':
+            MdtCalibrationTool.TimeWindowSetting = mdtCalibWindowNumber('Collision_G4')
+        elif globalflags.DataSource() == 'data':
+            MdtCalibrationTool.TimeWindowSetting = mdtCalibWindowNumber('Collision_G4')
+    else: # cosmics or single beam
+        MdtCalibrationTool.DoTofCorrection = False
+
+    from MdtCalibSvc.MdtCalibSvcConf import MdtCalibrationDbTool
+    MdtCalibrationDbTool.CreateBFieldFunctions = mdtCalibFlags.correctMdtRtForBField()
+    MdtCalibrationDbTool.CreateWireSagFunctions = mdtCalibFlags.correctMdtRtWireSag()
+    MdtCalibrationDbTool.CreateSlewingFunctions = mdtCalibFlags.correctMdtRtForTimeSlewing()
+
 # end of function setupMdtCondDB()
 
+
 def MdtCalibDbTool(name="MdtCalibDbTool",**kwargs):
     # setup COOL folders
     global mdt_folder_name_appendix
@@ -187,8 +238,7 @@ def MdtCalibrationSvc(name="MdtCalibrationSvc",**kwargs):
     from AthenaCommon.CfgGetter import getService
     getService("MdtCalibrationDbSvc")
     kwargs.setdefault( "DoSlewingCorrection",  mdtCalibFlags.correctMdtRtForTimeSlewing() )
-
-# Hack to use DoTemperatureCorrection for applyRtScaling; but applyRtScaling should not be used anyway, since MLRT can be used
+    # Hack to use DoTemperatureCorrection for applyRtScaling; but applyRtScaling should not be used anyway, since MLRT can be used
     kwargs.setdefault( "DoTemperatureCorrection", mdtCalibFlags.applyRtScaling() )
     kwargs.setdefault( "DoWireSagCorrection",  mdtCalibFlags.correctMdtRtWireSag() )
     if beamFlags.beamType() == 'collisions':
@@ -199,9 +249,7 @@ def MdtCalibrationSvc(name="MdtCalibrationSvc",**kwargs):
         elif globalflags.DataSource() == 'data':
             # for collisions cut away hits that are far outside of the MDT time window
             kwargs.setdefault( "TimeWindowSetting", mdtCalibWindowNumber('Collision_G4') )
-
     else: # cosmics or single beam
         kwargs.setdefault("DoTofCorrection",False)
-
     return CfgMgr.MdtCalibrationSvc(name,**kwargs)
 
diff --git a/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.cxx b/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.cxx
index 08e0993f4336913a2fad84469bb53d63aec03d65..53f151b856ec12c9a3e153132d60423d0b1811ea 100644
--- a/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.cxx
@@ -17,7 +17,7 @@
 #include "MdtRDO_Decoder.h"
 
 #include "MuonCalibEvent/MdtCalibHit.h"
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
 #include "MdtCalibSvc/MdtCalibrationSvcSettings.h"
 #include "MdtCalibSvc/MdtCalibrationSvcInput.h"
 
@@ -36,7 +36,7 @@ Muon::MdtRdoToPrepDataTool::MdtRdoToPrepDataTool(const std::string& t,
   AthAlgTool(t,n,p),
   m_muonMgr(0),
   m_mdtHelper(0),
-  m_calibrationSvc(0),
+  m_calibrationTool("MdtCalibrationTool",this),
   m_mdtCalibSvcSettings(new MdtCalibrationSvcSettings() ),
   m_calibHit( 0 ),
   m_invSpeed(1./299.792458),
@@ -72,6 +72,8 @@ Muon::MdtRdoToPrepDataTool::MdtRdoToPrepDataTool(const std::string& t,
   // DataHandle
   declareProperty("RDOContainer",	m_rdoContainerKey = std::string("MDTCSM"),"MdtCsmContainer to retrieve");
   declareProperty("OutputCollection",	m_mdtPrepDataContainerKey = std::string("MDT_DriftCircles"),"Muon::MdtPrepDataContainer to record");
+
+  declareProperty("CalibrationTool",m_calibrationTool);
 }
 
 
@@ -86,13 +88,14 @@ StatusCode Muon::MdtRdoToPrepDataTool::initialize()
     ATH_MSG_FATAL(" Cannot retrieve MuonDetectorManager ");
     return StatusCode::FAILURE;
   }
-  
-  // get MDT Calibration service
-  if (!serviceLocator()->service("MdtCalibrationSvc", m_calibrationSvc).isSuccess() || 0 == m_calibrationSvc) {
-    ATH_MSG_ERROR(" Could not initialize MDT Calibration service Service");
-    return StatusCode::FAILURE;
+
+  StatusCode sc = m_calibrationTool.retrieve();
+  if ( sc.isFailure() ){
+    ATH_MSG_ERROR( "Could not retrieve MdtCalibrationTool"  );
+  } else {
+    ATH_MSG_VERBOSE("MdtCalibrationTool retrieved with statusCode = "<<sc<<" pointer = "<<m_calibrationTool );
   }
-  
+
   /// create an empty MDT PrepData container for filling
   m_mdtHelper = m_muonMgr->mdtIdHelper();
 
@@ -1316,7 +1319,7 @@ MdtDriftCircleStatus MdtRdoToPrepDataTool::getMdtDriftRadius(const MdtDigit * di
     // MdtCalibHit calib_hit( channelId, digit->tdc(), digit->adc(), measured_position, descriptor );
     m_calibHit->setGlobalPointOfClosestApproach(position);
 
-    bool drift_ok = m_calibrationSvc->driftRadiusFromTime(*m_calibHit,inputData,*m_mdtCalibSvcSettings,false);
+    bool drift_ok = m_calibrationTool->driftRadiusFromTime(*m_calibHit,inputData,*m_mdtCalibSvcSettings,false);
     if (!drift_ok) {
       if( m_calibHit->driftTime() < 0. ) return MdtStatusBeforeSpectrum;
       else                             return MdtStatusAfterSpectrum;
@@ -1414,8 +1417,7 @@ MdtDriftCircleStatus MdtRdoToPrepDataTool::getMdtTwinPosition(const MdtDigit * d
     // calculate and calibrate radius for both hits and calculate twin position
     second_calib_hit.setGlobalPointOfClosestApproach(second_measured_position);
 
-
-    bool second_ok = m_calibrationSvc->twinPositionFromTwinHits(calib_hit, second_calib_hit, signedTrackLength, second_signedTrackLength, secondHitIsPrompt);
+    bool second_ok = m_calibrationTool->twinPositionFromTwinHits(calib_hit, second_calib_hit, signedTrackLength, second_signedTrackLength, secondHitIsPrompt);
     if (!second_ok){
       if( calib_hit.driftTime() < 0. || second_calib_hit.driftTime() < 0. ) return MdtStatusBeforeSpectrum;
       else                             return MdtStatusAfterSpectrum;
diff --git a/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.h b/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.h
index f4d999ae47acf15107fb2408070444dc5ef1a440..8feb61ae40dd7ab560b2b2d2630b45e65dbe13a8 100644
--- a/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.h
+++ b/MuonSpectrometer/MuonCnv/MuonMDT_CnvTools/src/MdtRdoToPrepDataTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -26,13 +26,12 @@ class AtlasDetectorID;
 class Identifier;
 class MdtIdHelper;
 class MdtDigit;
-class MdtCalibrationSvc;
+class MdtCalibrationTool;
 class MdtCalibrationSvcSettings;
 class MdtCalibHit;
 //class MdtRDO_Decoder;
 class MdtCsm;
 class StoreGateSvc;
-//class MdtCalibrationDbSvc; //TWIN TUBES
 
 
 namespace MuonGM
@@ -122,7 +121,7 @@ namespace Muon
     const MdtIdHelper * m_mdtHelper;
         
     /// MDT calibration service
-    MdtCalibrationSvc* m_calibrationSvc;
+    ToolHandle<MdtCalibrationTool> m_calibrationTool;
     MdtCalibrationSvcSettings* m_mdtCalibSvcSettings; 
     MdtCalibHit* m_calibHit;
     double m_invSpeed;
@@ -157,7 +156,6 @@ namespace Muon
     bool   m_use1DPrepDataTwin;
     bool   m_twinCorrectSlewing;
     bool   m_discardSecondaryHitTwin;
-    //  const MdtCalibrationDbSvc* m_dbSvc;
     int m_twin_chamber[2][3][36];
     int m_secondaryHit_twin_chamber[2][3][36];
     // - TWIN TUBE
diff --git a/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/MuonRdoToPrepData/MdtRdoToMdtPrepData.h b/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/MuonRdoToPrepData/MdtRdoToMdtPrepData.h
index 932c0194a60dab04100cbd8c134f550cf1dad464..798ba717d6ac1d88ef885bc17b12aecd49c2d4fe 100755
--- a/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/MuonRdoToPrepData/MdtRdoToMdtPrepData.h
+++ b/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/MuonRdoToPrepData/MdtRdoToMdtPrepData.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MDTRDOTOMDTPREPDATA_H
@@ -16,7 +16,6 @@
 
 class MdtIdHelper;
 class MdtDigit;
-class MdtCalibrationSvc;
 class MDTcablingSvc;
 
 ////////////////////////////////////////////////////////////////////////////////////////
diff --git a/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/src/MdtRdoToMdtPrepData.cxx b/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/src/MdtRdoToMdtPrepData.cxx
index 65526b8143348dfd1069ceec10692d127c26fc14..b345c25bcf4f060ee84e9060630b5b6f0ea9401b 100755
--- a/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/src/MdtRdoToMdtPrepData.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonRdoToPrepData/src/MdtRdoToMdtPrepData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 /// Author: Davide Costanzo
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
index 8cff38eb2c7b869b83600c421a161221afc5c16e..025ff006536ceeb5e190477b4a2e650063b1ed47 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
@@ -74,7 +74,7 @@ class PileUpMergeSvc;
 class MdtIdHelper;
 class MdtHitIdHelper;
 
-class MdtCalibrationDbSvc;
+class MdtCalibrationDbTool;
 
 // Digitization class for MDT hits
 /*
@@ -250,7 +250,7 @@ protected:
 
   ServiceHandle <IAthRNGSvc> m_rndmSvc{this, "RndmSvc", "AthRNGSvc", ""};      // Random number service
 
-  ServiceHandle<MdtCalibrationDbSvc> m_calibDbSvc;
+  ToolHandle<MdtCalibrationDbTool> m_calibrationDbTool;
   ServiceHandle<IMDTConditionsSvc> m_pSummarySvc;
   bool m_t0_from_DB ;
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/RT_Relation_DB_DigiTool.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/RT_Relation_DB_DigiTool.h
index 5021f574c833fa7a874ed6c6837e2322dbc4b0ad..ba33696978e0fed9b1985bdf9551211477bbc31b 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/RT_Relation_DB_DigiTool.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/RT_Relation_DB_DigiTool.h
@@ -20,7 +20,7 @@ Adopted from RT_Relation_DigiTool
 #include "MdtCalibData/IRtResolution.h"
 
 #include "MdtCalibData/MdtRtRelation.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MdtCalibData/MdtFullCalibData.h"
 
 #include "CLHEP/Random/RandFlat.h"
@@ -58,7 +58,8 @@ class RT_Relation_DB_DigiTool : public AthAlgTool, virtual public IMDT_Digitizat
     const MuonGM::MuonDetectorManager* m_muonGeoMgr;
     
   protected:
-    ServiceHandle<MdtCalibrationDbSvc> m_calibDbSvc;
+    ToolHandle<MdtCalibrationDbTool> m_calibrationDbTool;
+
 };
 
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator.h
index b0bfc7421caea23b6339fc2b835e5150a713f9e5..8e836bccf906f4e1e99f9caa635a8903167a6325 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator.h
@@ -36,7 +36,6 @@ to the third digit of decimal number of the  pdgid.
 
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/MdtTubeCalibContainer.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
 
 #include "TrkDetDescrUtils/GeometryStatics.h"
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator_PileUp.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator_PileUp.h
index ff192b4fd3ad47688a933cf418eb47811189732e..37c9826a52eed60d53b1d61894cab26331a79587 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator_PileUp.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/chargeCalculator_PileUp.h
@@ -37,7 +37,6 @@ to the third digit of decimal number of the  pdgid.
 
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/MdtTubeCalibContainer.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
 
 #include "TrkDetDescrUtils/GeometryStatics.h"
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma.h
index f91f4bdecf88652ff1fca1c9a99d399cadfd7775..95305a0553653cb7a7eb131042ab2dfa53b223a0 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma.h
@@ -31,7 +31,6 @@ Function particleGamma returns the value of gamma factor for Qball particle.
 
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/MdtTubeCalibContainer.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
 
 #include "TrkDetDescrUtils/GeometryStatics.h"
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma_PileUp.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma_PileUp.h
index debb11203a2abc4c9f3215ef8f109a98d5833d4c..c657f72607dcf3a3e0dc2800504944ebf4cf75d2 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma_PileUp.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/particleGamma_PileUp.h
@@ -31,7 +31,6 @@ Function particleGamma returns the value of gamma factor for Qball particle.
 
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/MdtTubeCalibContainer.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
 
 #include "TrkDetDescrUtils/GeometryStatics.h"
 
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
index 34e4e35795a074a4c7e49e9717c8e79a22cbd95d..bdfc79a9df4b90fd6f73916d6655f032feaff6a9 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
@@ -60,7 +60,7 @@
 //Calibration Service
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/MdtTubeCalibContainer.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 
 MdtDigitizationTool::MdtDigitizationTool(const std::string& type,const std::string& name,const IInterface* pIID)
   : PileUpToolBase(type, name, pIID)
@@ -74,12 +74,12 @@ MdtDigitizationTool::MdtDigitizationTool(const std::string& type,const std::stri
   , m_BMGid(-1)
   , m_mergeSvc(0)
   , m_inputObjectName("")
-  , m_calibDbSvc("MdtCalibrationDbSvc", name) 
+  , m_calibrationDbTool("MdtCalibrationDbTool",this)
   , m_pSummarySvc("MDTCondSummarySvc", name)
 {
   declareProperty("DigitizationTool",    m_digiTool,                          "Tool which handle the digitization process");
   //Conditions Database
-  declareProperty("MdtCalibrationDbSvc", m_calibDbSvc);
+  declareProperty("CalibrationDbTool", m_calibrationDbTool);
   declareProperty("MDTCondSummarySvc",   m_pSummarySvc);
   declareProperty("UseDeadChamberSvc",   m_UseDeadChamberSvc   =  false );
   declareProperty("GetT0FromBD",         m_t0_from_DB          =  false );
@@ -120,6 +120,7 @@ MdtDigitizationTool::MdtDigitizationTool(const std::string& type,const std::stri
   declareProperty("UseOffSet2",          m_useOffSet2          =  true);
   //Truth
   declareProperty("IncludePileUpTruth",  m_includePileUpTruth  =  true, "Include pile-up truth info");
+  declareProperty("ParticleBarcodeVeto", m_vetoThisBarcode     =  crazyParticleBarcode, "Barcode of particle to ignore");
 }
 
 
@@ -132,7 +133,7 @@ StatusCode MdtDigitizationTool::initialize() {
   ATH_MSG_INFO ( "Configuration  MdtDigitizationTool" );
   ATH_MSG_INFO ( "RndmSvc                " << m_rndmSvc             );
   ATH_MSG_INFO ( "DigitizationTool       " << m_digiTool            );
-  ATH_MSG_INFO ( "MdtCalibrationDbSvc    " << m_calibDbSvc          );
+  ATH_MSG_INFO ( "MdtCalibrationDbTool    " << m_calibrationDbTool  );
   ATH_MSG_INFO ( "MDTCondSummarySvc      " << m_pSummarySvc         );
   ATH_MSG_INFO ( "UseDeadChamberSvc      " << m_UseDeadChamberSvc   );
   if (!m_UseDeadChamberSvc) ATH_MSG_INFO ( "MaskedStations         " << m_maskedStations      );
@@ -226,15 +227,7 @@ StatusCode MdtDigitizationTool::initialize() {
   m_inv_c_light = 1./(CLHEP::c_light);
   
   ATH_CHECK(m_rndmSvc.retrieve());
-  
-  // Get pointer to MdtCalibrationDbSvc and cache it :
-  if ( m_t0_from_DB ){
-    if ( !m_calibDbSvc.retrieve().isSuccess() ) {
-      ATH_MSG_FATAL("Unable to retrieve pointer to MdtCalibrationDbSvc");
-      return StatusCode::FAILURE;
-    }
-  }
-  
+
   //Gather masked stations
   for (unsigned int i=0;i<m_maskedStations.size();i++) {
     std::string mask=m_maskedStations[i];
@@ -941,10 +934,10 @@ bool MdtDigitizationTool::createDigits(MdtDigitContainer* digitContainer, MuonSi
       insideMask = false;
     }
     if( insideMatch || insideMask ) {
-      // get calibration constants from DbSvc
+      // get calibration constants from DbTool
       double t0 = m_offsetTDC;
       if ( m_t0_from_DB ) {
-	MuonCalib::MdtFullCalibData data = m_calibDbSvc->getCalibration( geo->collectionHash(), geo->detectorElementHash() ); 
+	MuonCalib::MdtFullCalibData data = m_calibrationDbTool->getCalibration( geo->collectionHash(), geo->detectorElementHash() );
 	if ( data.tubeCalib ) {
 	  int ml    = m_idHelper->multilayer(idDigit)-1;
 	  int layer = m_idHelper->tubeLayer(idDigit)-1;
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/RT_Relation_DB_DigiTool.cxx b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/RT_Relation_DB_DigiTool.cxx
index 181b93c133aaaff9650b0d10da6a7cb6238de43e..f9838b4987c1fafb4e5c3d997423aab7b2d4b29d 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/RT_Relation_DB_DigiTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/RT_Relation_DB_DigiTool.cxx
@@ -19,11 +19,11 @@ RT_Relation_DB_DigiTool::RT_Relation_DB_DigiTool( const std::string& type, const
 : AthAlgTool(type,name,parent)
 , m_maxRadius(0)
 , m_muonGeoMgr(0)
-, m_calibDbSvc("MdtCalibrationDbSvc", name)
+, m_calibrationDbTool("MdtCalibrationDbTool",this)
 {
   declareInterface<IMDT_DigitizationTool>(this);
   declareProperty("EffectiveRadius",  m_effRadius = 14.4275);
-  declareProperty("MdtCalibrationDbSvc", m_calibDbSvc);
+  declareProperty("CalibrationDbTool",m_calibrationDbTool);
 }
 
 
@@ -56,12 +56,6 @@ StatusCode RT_Relation_DB_DigiTool::initialize()
     }
   }
   
-  if ( !m_calibDbSvc.retrieve().isSuccess() )
-  {
-    ATH_MSG_FATAL("Unable to retrieve pointer to MdtCalibrationDbSvc");
-    return StatusCode::FAILURE;
-  }
-  
   initializeTube();
   
   return StatusCode::SUCCESS;
@@ -100,7 +94,7 @@ bool RT_Relation_DB_DigiTool::initializeTube()
 double RT_Relation_DB_DigiTool::getDriftTime(double r,Identifier DigitId,CLHEP::HepRandomEngine *rndmEngine) const
 {
   //Get RT relation from DB
-  const MuonCalib::MdtRtRelation *data = m_calibDbSvc->getRtCalibration( DigitId );
+  const MuonCalib::MdtRtRelation *data = m_calibrationDbTool->getRtCalibration( DigitId );
   
   double time        = 0.0;
   double t           = 0.0;
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator.h b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator.h
index 48ac14b1f951e46d35f6ca140d0a4796ac043c05..8145b52328aaca0825ee1799b5f277ecab86bca2 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -30,8 +30,8 @@
 
 class Identifier;
 class MdtIdHelper;
-class MdtCalibrationSvc;
-class MdtCalibrationDbSvc;
+class MdtCalibrationTool;
+class MdtCalibrationDbTool;
 class MdtCalibrationSvcSettings;
 class MdtCalibrationSvcInput;
 class MsgStream;
@@ -196,8 +196,8 @@ namespace Muon {
       double muonErrorStrategy(const MuonDriftCircleErrorStrategy* myStrategy, double sigmaR, const Identifier& id) const;
       
       ToolHandle<Muon::MuonIdHelperTool>   m_idHelper;
-      ServiceHandle<MdtCalibrationSvc>     m_mdtCalibSvc;
-      ServiceHandle<MdtCalibrationDbSvc>   m_mdtCalibDbSvc;
+      ToolHandle<MdtCalibrationTool> m_mdtCalibrationTool;
+      ToolHandle<MdtCalibrationDbTool> m_mdtCalibrationDbTool;
       ToolHandle<IMuonTofTool>             m_tofTool; //!<Time of flight tool (handle tof if not coming from IP)
 
       // Configuration variables
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/src/MdtDriftCircleOnTrackCreator.cxx b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/src/MdtDriftCircleOnTrackCreator.cxx
index 22ef2b8d54c04b85d86f84fbc798e374109cff51..e6454c62aeb5003eb63981356b312a340e53688c 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/src/MdtDriftCircleOnTrackCreator.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MdtDriftCircleOnTrackCreator/src/MdtDriftCircleOnTrackCreator.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 ////////////////////////////////////////////////////////////////////
@@ -17,8 +17,8 @@
 #include "MuonIdHelpers/MuonIdHelperTool.h"
 
 #include "MuonIdHelpers/MdtIdHelper.h"
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MdtCalibSvc/MdtCalibrationSvcSettings.h"
 #include "MdtCalibSvc/MdtCalibrationSvcInput.h"
 #include "MdtCalibData/MdtRtRelation.h"
@@ -42,16 +42,15 @@
 #include "Identifier/IdentifierHash.h"
 #include <boost/assign/std/vector.hpp>
 
-Muon::MdtDriftCircleOnTrackCreator::MdtDriftCircleOnTrackCreator
-(const std::string& ty,const std::string& na,const IInterface* pa)
+Muon::MdtDriftCircleOnTrackCreator::MdtDriftCircleOnTrackCreator(const std::string& ty,const std::string& na,const IInterface* pa)
   : AthAlgTool(ty,na,pa),
-  m_idHelper("Muon::MuonIdHelperTool/MuonIdHelperTool"),
-  m_mdtCalibSvc("MdtCalibrationSvc", na),
-  m_mdtCalibDbSvc("MdtCalibrationDbSvc", na),
-  m_tofTool(""),
-  m_invSpeed(1./299.792458),
-  m_mdtCalibSvcSettings( 0 ),
-  m_errorStrategy(Muon::MuonDriftCircleErrorStrategyInput())
+    m_idHelper("Muon::MuonIdHelperTool/MuonIdHelperTool"),
+    m_mdtCalibrationTool("MdtCalibrationTool", this),
+    m_mdtCalibrationDbTool("MdtCalibrationDbTool", this),
+    m_tofTool(""),
+    m_invSpeed(1./299.792458),
+    m_mdtCalibSvcSettings( 0 ),
+    m_errorStrategy(Muon::MuonDriftCircleErrorStrategyInput())
 {
   // create calibration service settings 
   m_mdtCalibSvcSettings = new MdtCalibrationSvcSettings();
@@ -95,6 +94,9 @@ Muon::MdtDriftCircleOnTrackCreator::MdtDriftCircleOnTrackCreator
   declareProperty("DoSegmentErrors",m_doSegments=true , "Use error strategy for segments");
   declareProperty("UseLooseErrors",m_looseErrors=false , "Use error strategy for MC");
   declareProperty("IsMC",m_isMC=false);
+
+  declareProperty("CalibrationTool",m_mdtCalibrationTool);
+  declareProperty("CalibrationDbTool",m_mdtCalibrationDbTool);
 }
 
 
@@ -157,15 +159,7 @@ StatusCode Muon::MdtDriftCircleOnTrackCreator::initialize()
   ATH_MSG_VERBOSE( "A correction is made if set to true: do_MDT = " << m_doMdt ); 
   
   ATH_CHECK( m_idHelper.retrieve() );
-  
-  if (m_doMdt) {
-    ATH_CHECK( m_mdtCalibSvc.retrieve() );
-    // Get pointer to MdtCalibrationDbSvc and cache it :
-    ATH_CHECK( m_mdtCalibDbSvc.retrieve() );
-  } else {
-    ATH_MSG_WARNING( " tool is configured such that MDT_DCs are only copied!" );
-  }
-  
+
   if( m_timeCorrectionType == COSMICS_TOF ){
     if( m_tofTool.empty() ) ATH_MSG_DEBUG("no TOF tool, TOF will be calculated directly from T0 shift provided");
     else ATH_CHECK(m_tofTool.retrieve());
@@ -422,7 +416,7 @@ Muon::MdtDriftCircleOnTrackCreator::getLocalMeasurement(const MdtPrepData& DC,
     }
     
     // call the calibration service providing the time when the particle passed the tube
-    ok = m_mdtCalibSvc->driftRadiusFromTime( *calibHit, inputData, *m_mdtCalibSvcSettings );
+    ok = m_mdtCalibrationTool->driftRadiusFromTime( *calibHit, inputData, *m_mdtCalibSvcSettings );
     
     driftTime = calibHit->driftTime();
     radius    = calibHit->driftRadius();  // copy new values
@@ -527,7 +521,7 @@ double Muon::MdtDriftCircleOnTrackCreator::getErrorFromRt(const Muon::MdtDriftCi
   double t = DCT.driftTime();
   const MuonGM::MdtReadoutElement* detEl = DCT.detectorElement();
 
-  MuonCalib::MdtFullCalibData data = m_mdtCalibDbSvc->getCalibration( detEl->collectionHash(), detEl->detectorElementHash() ); 
+  MuonCalib::MdtFullCalibData data = m_mdtCalibrationDbTool->getCalibration( detEl->collectionHash(), detEl->detectorElementHash() );
   const MuonCalib::MdtRtRelation* rtRelation = data.rtRelation;
   if( !rtRelation ){
     ATH_MSG_WARNING("no calibration found for tube " << m_idHelper->toString(DCT.identify()));
@@ -674,7 +668,7 @@ Muon::MdtDriftCircleStatus Muon::MdtDriftCircleOnTrackCreator::driftCircleStatus
   }
   
   // access rt relation
-  MuonCalib::MdtFullCalibData data = m_mdtCalibDbSvc->getCalibration( detEl->collectionHash(), detEl->detectorElementHash() ); 
+  MuonCalib::MdtFullCalibData data = m_mdtCalibrationDbTool->getCalibration( detEl->collectionHash(), detEl->detectorElementHash() );
   const MuonCalib::MdtRtRelation* rtRelation = data.rtRelation;
   if( !rtRelation ){
     ATH_MSG_WARNING("no calibration found for tube " << m_idHelper->toString(DCT.identify()));
@@ -683,7 +677,7 @@ Muon::MdtDriftCircleStatus Muon::MdtDriftCircleOnTrackCreator::driftCircleStatus
   
   // check whether drift time is within range, if not fix them to the min/max range
   double t = DCT.driftTime();
-  return m_mdtCalibSvc->driftTimeStatus(t, rtRelation, *m_mdtCalibSvcSettings); 
+  return m_mdtCalibrationTool->driftTimeStatus(t, rtRelation, *m_mdtCalibSvcSettings);
 }
 
 double Muon::MdtDriftCircleOnTrackCreator::parametrisedSigma( double r ) const {
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.cxx b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.cxx
index 26979e2461b78e33c6fc5851093a5dae4df51ee3..a1865acba3be6893d19c2fbe5d627e283c69e847 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.h b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.h
index 7e1f06253f358b9c5d6b8324ba561dfcfdf96d9e..fdc3a0b41158140be26dce8a35be311adaa612c0 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonCompetingClustersOnTrackCreator/src/MuonCompetingClustersOnTrackCreator.h
@@ -24,7 +24,6 @@
 
 class Identifier;
 class MdtIdHelper;
-class MdtCalibrationSvc;
 
 namespace MuonGM {
   class MuonDetectorManager;
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCalibConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCalibConfig.py
index 147891dc81b4787bb5b9d2286a0444df2363405f..c09b3925ad1f2aa89ae7ab2e3d3d504d13129f1c 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCalibConfig.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCalibConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 import os
 
@@ -66,7 +66,8 @@ def getMuonSegmentToCalibSegment():
         MuonSegmentToCalibSegment.SegmentAuthors = [ 4,8 ] 
         MuonSegmentToCalibSegment.ReadSegments = True # rather than SegmentCombinations
 
-        getService("MdtCalibrationSvc")
+        from MuonCnvExample import MuonCalibConfig
+        MuonCalibConfig.setupMdtCondDB()
 
         # finally add it to topSequence
         topSequence += MuonSegmentToCalibSegment
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
index 96ac9fc9084dd56560e6bb215ac2e82ac3a5a879..4949f80c539b5824f921fc4559af429ffbd05594 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 from AthenaCommon.Include import include
 
@@ -8,7 +8,7 @@ source = globalflags.DataSource()
 
 from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.AppMgr import ToolSvc
-from AthenaCommon.CfgGetter import getService
+from AthenaCommon.CfgGetter import getService,getPrivateTool
 from RecExConfig.RecAlgsFlags import recAlgs
 
 
@@ -36,11 +36,12 @@ def RpcPrepDataProviderTool(name="RpcPrepDataProviderTool",**kwargs):
 
 
 def MdtPrepDataProviderTool(name="MdtPrepDataProviderTool", **kwargs):
-  global source,include,getService
+  global source,include,getService,getPrivateTool
 
   # setup dependencies which are not yet in C++
   import MuonCnvExample.MuonCablingConfig
-  getService("MdtCalibrationSvc")
+  from MuonCnvExample import MuonCalibConfig
+  MuonCalibConfig.setupMdtCondDB()
   include("AmdcAth/AmdcAth_jobOptions.py")
   
   if source == 'data':
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
index a869ef53d83d248034c983396f50177a4bfe6a02..b3bfd3888edc7bea02e31e84c669822da3969e10 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 # MDT Calibration tools/services are defined in MuonCnvExample/python/MuonCalibConfig.py
 # For backwards compatibility, they are instantiated here, but this whole module
@@ -6,7 +6,7 @@
 from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s", __name__)
 
-from AthenaCommon.CfgGetter import getPublicTool,getService
+from AthenaCommon.CfgGetter import getPublicTool,getService,getPrivateTool,getAlgorithm
 from MuonRecFlags import muonRecFlags
 muonRecFlags.setDefaults()
 
@@ -14,7 +14,5 @@ if muonRecFlags.doCSCs():
     CscCalibTool = getPublicTool("CscCalibTool")
 
 if muonRecFlags.doMDTs():
-    MdtDbTool     = getPublicTool("MdtCalibDbTool")
-    MdtCalibDbSvc = getService("MdtCalibrationDbSvc")
-    MdtCalibSvc   = getService("MdtCalibrationSvc")
-
+    from MuonCnvExample import MuonCalibConfig
+    MuonCalibConfig.setupMdtCondDB()
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
index 27c0e32e054565a3c1d66040bed06b39aa9a1cad..b092a846db45f09d1cdfd73823d044bfc8334ff4 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
@@ -74,8 +74,8 @@ def CscBroadClusterOnTrackCreator(name="CscBroadClusterOnTrackCreator",**kwargs)
 
 def MdtDriftCircleOnTrackCreator(name="MdtDriftCircleOnTrackCreator",**kwargs):
     # setup dependencies missing in C++. TODO: fix in C++
-    getService("MdtCalibrationSvc")
-    getService("MdtCalibrationDbSvc")
+    from MuonCnvExample import MuonCalibConfig
+    MuonCalibConfig.setupMdtCondDB()
     
     kwargs.setdefault("DoMagneticFieldCorrection", mdtCalibFlags.correctMdtRtForBField())
     kwargs.setdefault("DoWireSag", muonRecFlags.useWireSagCorrections())
@@ -340,7 +340,8 @@ def MuonSegmentMomentum(name="MuonSegmentMomentum",**kwargs):
 
 def MdtSegmentT0Fitter(name="MdtSegmentT0Fitter",**kwargs):
     # setup dependencies missing in C++. TODO: fix in C++
-    getService("MdtCalibrationDbSvc")
+    from MuonCnvExample import MuonCalibConfig
+    MuonCalibConfig.setupMdtCondDB()
     return CfgMgr.TrkDriftCircleMath__MdtSegmentT0Fitter(name,**kwargs)
 
 def MdtMathSegmentFinder(name="MdtMathSegmentFinder",extraFlags=None,**kwargs):
diff --git a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/MdtSegmentT0Fitter/MdtSegmentT0Fitter.h b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/MdtSegmentT0Fitter/MdtSegmentT0Fitter.h
index 5bf9bb2efd0637090f9f0bd5e5e13312f3228e58..e2415f4c1f1f88e14a1e84ec71fc64a05a4b3b92 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/MdtSegmentT0Fitter/MdtSegmentT0Fitter.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/MdtSegmentT0Fitter/MdtSegmentT0Fitter.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // Fitting for in situ calibration of segments
@@ -13,12 +13,12 @@
 #include "TrkDriftCircleMath/DCSLFitter.h"
 #include "MuonSegmentMakerInterfaces/IDCSLFitProvider.h"
 
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 
 #include <vector>
 
 class IIdToFixedIdTool;
-class MdtCalibrationDbSvc;
+class MdtCalibrationDbTool;
 class TMinuit;
 
 namespace TrkDriftCircleMath {
@@ -43,9 +43,8 @@ namespace TrkDriftCircleMath {
 		  bool m_dumpNoFit; // debug - print hit info where fit doesn't run		
 
       bool m_useInternalRT; // whether to use an internal RT function or the one from Calibration Service
-		  ServiceHandle<MdtCalibrationDbSvc> m_calibDbSvc;
-      // MdtCalibrationDbSvc* m_calibDbSvc;
-      
+      ToolHandle<MdtCalibrationDbTool> m_calibrationDbTool;
+
       int m_minHits; // minimum number of selected hits for t0 fit. Otherwise use default
 
       bool m_constrainShifts; // whether to constrain t0 shifts to a 50 ns window
diff --git a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx
index 347c1a87fd5c092ab9e37b9876df0f7b4b4f7940..b1115d91dfb32ba5946d56b9140c33bcaeafc9e6 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/MsgStream.h"
@@ -7,13 +7,11 @@
 #include "MdtSegmentT0Fitter/MdtSegmentT0Fitter.h"
 
 #include "MuonIdHelpers/MdtIdHelper.h"
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
 #include "MdtCalibSvc/MdtCalibrationSvcSettings.h"
-//#include "MdtCalibSvc/MdtCalibrationSvcInput.h"
 #include "MuonReadoutGeometry/MdtReadoutElement.h"
 #include "MuonReadoutGeometry/MuonDetectorManager.h"
 
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MuonCalibTools/IdToFixedIdTool.h"
 #include "MdtCalibData/IRtRelation.h"
 #include "MdtCalibData/IRtResolution.h"
@@ -64,7 +62,7 @@ namespace TrkDriftCircleMath {
   MdtSegmentT0Fitter::MdtSegmentT0Fitter(const std::string& ty,const std::string& na,const IInterface* pa)
   : AthAlgTool(ty,na,pa),
     DCSLFitter(), 
-    m_calibDbSvc("MdtCalibrationDbSvc", na),
+    m_calibrationDbTool("MdtCalibrationDbTool",this),
     m_ntotalCalls(0),
     m_npassedNHits(0),
     m_npassedSelectionConsistency(0),
@@ -83,6 +81,7 @@ namespace TrkDriftCircleMath {
     declareProperty("RejectWeakTopologies",  m_rejectWeakTopologies = true);
     declareProperty("RescaleErrors",m_scaleErrors = true );
     declareProperty("PropagateErrors",m_propagateErrors = true );
+    declareProperty("CalibrationDbTool",m_calibrationDbTool);
   }
   
   
@@ -94,11 +93,7 @@ namespace TrkDriftCircleMath {
     use_hardcoded = m_useInternalRT;
     use_shift_constraint = m_constrainShifts;
     constrainT0Error = m_constrainT0Error;
-//		count = 0;
-    
-        
-    // Get pointer to MdtCalibrationDbSvc and cache it :
-    ATH_CHECK ( m_calibDbSvc.retrieve() );
+    //count = 0;
 
     TMinuit* oldMinuit = gMinuit;
     m_minuit = new TMinuit(3);
@@ -394,7 +389,7 @@ namespace TrkDriftCircleMath {
 	dcs_new.push_back( dc_new );
         if( selection[i] == 0 ){
           double t = ds->rot()->driftTime();
-          const MuonCalib::MdtRtRelation *rtInfo = m_calibDbSvc->getRtCalibration(ds->rot()->identify());
+          const MuonCalib::MdtRtRelation *rtInfo = m_calibrationDbTool->getRtCalibration(ds->rot()->identify());
           double tUp = rtInfo->rt()->tUpper();
           double tLow = rtInfo->rt()->tLower();
           if(t<tLow) chi2p += (t-tLow)*(t-tLow)*0.1;
@@ -456,7 +451,7 @@ namespace TrkDriftCircleMath {
           return false;
         }
         Identifier id = roto->identify();
-        const MuonCalib::MdtRtRelation *rtInfo = m_calibDbSvc->getRtCalibration(id);
+        const MuonCalib::MdtRtRelation *rtInfo = m_calibrationDbTool->getRtCalibration(id);
         rtpointers[ii] = rtInfo->rt();
         t[ii] = roto->driftTime();
 
@@ -655,7 +650,7 @@ namespace TrkDriftCircleMath {
 	dcs_new.push_back( dc_new );
         if( selection[i] == 0 ){
           double t = ds->rot()->driftTime();
-          const MuonCalib::MdtRtRelation *rtInfo = m_calibDbSvc->getRtCalibration(ds->rot()->identify());
+          const MuonCalib::MdtRtRelation *rtInfo = m_calibrationDbTool->getRtCalibration(ds->rot()->identify());
           double tUp = rtInfo->rt()->tUpper();
           double tLow = rtInfo->rt()->tLower();
           if(t<tLow) chi2p += (t-tLow)*(t-tLow)*0.1;
diff --git a/Reconstruction/MuonIdentification/MuGirlStau/MuGirlStau/StauTool.h b/Reconstruction/MuonIdentification/MuGirlStau/MuGirlStau/StauTool.h
index 826faadc2491e2d30fcc0c02f4a64b3ff1464a24..a63bc979f2b0127d7deb01f81ff025bf6fe3bfb1 100644
--- a/Reconstruction/MuonIdentification/MuGirlStau/MuGirlStau/StauTool.h
+++ b/Reconstruction/MuonIdentification/MuGirlStau/MuGirlStau/StauTool.h
@@ -57,7 +57,7 @@ class IMdtDriftCircleOnTrackCreator;
 class IMuonSegmentMaker;
 class MuonSegment;
 }
-class MdtCalibrationDbSvc;
+class MdtCalibrationDbTool;
 
 namespace Rec
 {
@@ -224,10 +224,9 @@ public:
     {
         return m_caloCellAssociationTool;
     }
-
-    const ServiceHandle<MdtCalibrationDbSvc>& mdtCalibrationDbSvc()
+    const ToolHandle<MdtCalibrationDbTool>& mdtCalibrationDbTool()
     {
-        return m_pMdtCalibDbSvc;
+      return m_calibrationDbTool;
     }
     double idP() const
     {
@@ -422,8 +421,8 @@ private:
     ToolHandle<IStauBetaTofTool> m_pTofTool;
     ToolHandle<MuGirlNS::IGlobalFitTool> m_pGlobalFitTool;
     ToolHandle<Rec::IParticleCaloCellAssociationTool> m_caloCellAssociationTool; //!< Tool to make the step-wise extrapolation
+    ToolHandle<MdtCalibrationDbTool> m_calibrationDbTool;
 
-    ServiceHandle<MdtCalibrationDbSvc> m_pMdtCalibDbSvc;
     ServiceHandle<IAtRndmGenSvc> m_randSvc;
     std::string m_randStreamName;
 
diff --git a/Reconstruction/MuonIdentification/MuGirlStau/src/StauMDTT.cxx b/Reconstruction/MuonIdentification/MuGirlStau/src/StauMDTT.cxx
index fe679f04b0e92b5133cde50a1531e6dafe21a17a..d163f84eec8cf3b4ea11a45b90acac8aecdf2a6a 100644
--- a/Reconstruction/MuonIdentification/MuGirlStau/src/StauMDTT.cxx
+++ b/Reconstruction/MuonIdentification/MuGirlStau/src/StauMDTT.cxx
@@ -9,7 +9,7 @@
 #include "MuGirlStau/StauTool.h"
 #include "MuGirlStau/IStauBetaTofTool.h"
 #include "TrkTrack/Track.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MuonRIO_OnTrack/MdtDriftCircleOnTrack.h"
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/TrRelation.h"
@@ -30,7 +30,7 @@ StauMDTT::MDTT::MDTT(StauTool* pStau, MsgStream&, const Muon::MdtDriftCircleOnTr
     driftRadius = mdcot->driftRadius();
     driftTime = mdcot->driftTime();
     auto detEl = mdcot->detectorElement();
-    auto data = pStau->mdtCalibrationDbSvc()->getCalibration(detEl->collectionHash(),
+    auto data = pStau->mdtCalibrationDbTool()->getCalibration(detEl->collectionHash(),
             detEl->detectorElementHash());
     auto rtRelation = data.rtRelation;
     bool out_of_bound_flag = false;
diff --git a/Reconstruction/MuonIdentification/MuGirlStau/src/StauTool.cxx b/Reconstruction/MuonIdentification/MuGirlStau/src/StauTool.cxx
index 7205b5b8238a21d198c2372304d72465f0f5e252..ea72f227b545ce68a77ef37f82b9f304bacf9a63 100644
--- a/Reconstruction/MuonIdentification/MuGirlStau/src/StauTool.cxx
+++ b/Reconstruction/MuonIdentification/MuGirlStau/src/StauTool.cxx
@@ -33,7 +33,7 @@
 
 #include "EventInfo/TagInfo.h"
 #include "EventInfoMgt/ITagInfoMgr.h"
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "TFile.h"
 
 namespace MuGirlNS
@@ -50,7 +50,7 @@ StauTool::StauTool(const std::string& t, const std::string& n, const IInterface*
                 m_pMdtDriftCircleCreator("Muon::MdtDriftCircleOnTrackCreator"), m_pTofTool("MuGirlNS::StauBetaTofTool"),
                 m_pGlobalFitTool("MuGirlNS::GlobalFitTool", 0),    // make this a public tool
                 m_caloCellAssociationTool("Rec::ParticleCaloCellAssociationTool/ParticleCaloCellAssociationTool"),
-                m_pMdtCalibDbSvc("MdtCalibrationDbSvc", n),
+                m_calibrationDbTool("MdtCalibrationDbTool", this),
                 m_randSvc ("AtRanluxGenSvc", n),
                 m_pMuonMgr(NULL), m_lowerBetaLimit(0.2),
                 m_upperBetaLimit(1.5), m_betaTolerance(0.001), m_gfBetaTolerance(0.001), m_minBeta(0.1), m_maxBeta(1.5),
@@ -69,7 +69,7 @@ StauTool::StauTool(const std::string& t, const std::string& n, const IInterface*
     declareProperty("StauBetaTofTool", m_pTofTool);
     declareProperty("StauGlobalFitTool", m_pGlobalFitTool);
     declareProperty("ParticleCaloCellAssociationTool", m_caloCellAssociationTool);
-    declareProperty("MdtCalibrationDbSvc", m_pMdtCalibDbSvc);
+    declareProperty("MdtCalibrationDbTool", m_calibrationDbTool);
     declareProperty("RandSvc", m_randSvc);
 
     //  other properties
@@ -120,7 +120,6 @@ StatusCode StauTool::initialize()
     ATH_CHECK( m_pTofTool.retrieve() );
     ATH_CHECK( m_pGlobalFitTool.retrieve() );
 //    if (!m_caloCellAssociationTool.empty()) ATH_CHECK(m_caloCellAssociationTool.retrieve());
-    ATH_CHECK( m_pMdtCalibDbSvc.retrieve() );
     ATH_CHECK( m_randSvc.retrieve() );
     ATH_CHECK( m_caloCellAssociationTool.retrieve() );
     /** initialize MuonDetectorManager */
diff --git a/Reconstruction/MuonIdentification/MuonCombinedRecExample/share/MuonCombinedRec_myTopOptions.py b/Reconstruction/MuonIdentification/MuonCombinedRecExample/share/MuonCombinedRec_myTopOptions.py
index 127c0386c320c70219320d682519d7f80a7e5a5a..1445305ce6619e89a462f0a6427176d880ec3e19 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedRecExample/share/MuonCombinedRec_myTopOptions.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedRecExample/share/MuonCombinedRec_myTopOptions.py
@@ -277,7 +277,7 @@ muonCombinedRecFlags.doMuonSegmentTagger = True
 #muonCombinedRecFlags.doxAOD = True
 muonCombinedRecFlags.doAOD = False
 muonCombinedRecFlags.doCaloTrkMuId = True
-muonCombinedRecFlags.doMuGirlLowBeta = False
+muonCombinedRecFlags.doMuGirlLowBeta = True
 
 muonRecFlags.doCreateClusters = False 
 muonRecFlags.prdToxAOD = False
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
index e45f25325dd69304699b667f9143d6e5501556f5..255d96c3085e79dc31dd7b2e137d73deecc45d7a 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
@@ -36,7 +36,7 @@
 #include "EventPrimitives/EventPrimitivesHelpers.h"
 #include "xAODTruth/TruthParticleContainer.h"
 
-#include "MdtCalibSvc/MdtCalibrationDbSvc.h"
+#include "MdtCalibSvc/MdtCalibrationDbTool.h"
 #include "MdtCalibData/MdtFullCalibData.h"
 #include "MdtCalibData/TrRelation.h"
 #include "MdtCalibData/IRtRelation.h"
@@ -74,8 +74,7 @@ namespace MuonCombined {
     m_stauTofTool("MuGirlNS::StauBetaTofTool/StauBetaTofTool"),
     m_insideOutRecoTool("MuonCombined::MuonInsideOutRecoTool/MuonInsideOutRecoTool"),
     m_updator("Trk::KalmanUpdator/KalmanUpdator"),
-    m_mdtCalibrationDbSvc("MdtCalibrationDbSvc", name)
-
+    m_calibrationDbTool("MdtCalibrationDbTool", this)
   {
     declareInterface<IMuonCombinedInDetExtensionTool>(this);
 
@@ -96,7 +95,7 @@ namespace MuonCombined {
     declareProperty("MuonTofTool",m_stauTofTool);
     declareProperty("Updator", m_updator );
     declareProperty("MuonInsideOutRecoTool", m_insideOutRecoTool );
-    declareProperty("MdtCalibrationDbSvc", m_mdtCalibrationDbSvc );
+    declareProperty("MdtCalibrationDbTool", m_calibrationDbTool );
     declareProperty("DoSummary", m_doSummary = false );
     declareProperty("ConsideredPDGs", m_pdgsToBeConsidered );
     declareProperty("UseTruthMatching", m_useTruthMatching = false );
@@ -140,7 +139,7 @@ namespace MuonCombined {
     ATH_CHECK(m_stauTofTool.retrieve());
     ATH_CHECK(m_insideOutRecoTool.retrieve());
     ATH_CHECK(m_updator.retrieve());
-    ATH_CHECK(m_mdtCalibrationDbSvc.retrieve());
+    ATH_CHECK(m_calibrationDbTool.retrieve());
     
     if( m_doTruth ){
       // add pdgs from jobO to set
@@ -483,7 +482,7 @@ namespace MuonCombined {
           float locR = pars->parameters()[Trk::locR];
           float errR = pars->covariance() ? Amg::error(*pars->covariance(),Trk::locR) : 0.3;
           auto detEl = mdt->detectorElement();
-          auto data = m_mdtCalibrationDbSvc->getCalibration(detEl->collectionHash(),detEl->detectorElementHash());
+          auto data = m_calibrationDbTool->getCalibration(detEl->collectionHash(),detEl->detectorElementHash());
           auto rtRelation = data.rtRelation;
           bool out_of_bound_flag = false;
           float drdt = rtRelation->rt()->driftvelocity(driftTime);
@@ -764,7 +763,7 @@ namespace MuonCombined {
         float locR = rline;
         float errR = dc.errorTrack();
         auto detEl = mdt->detectorElement();
-        auto data = m_mdtCalibrationDbSvc->getCalibration(detEl->collectionHash(),detEl->detectorElementHash());
+        auto data = m_calibrationDbTool->getCalibration(detEl->collectionHash(),detEl->detectorElementHash());
         auto rtRelation = data.rtRelation;
         bool out_of_bound_flag = false;
         float drdt = rtRelation->rt()->driftvelocity(driftTime);
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
index 3a21a32599abea1b5b11f52e18c165e7a387177c..76e7b67ed6b2ec8756e110475560d643a05d1334 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MUON_MUONSTAURECOTOOL_H
@@ -42,7 +42,7 @@ namespace Muon {
   class IMuonPRDSelectionTool;
   class RpcClusterOnTrack;
 }
-class MdtCalibrationDbSvc;
+class MdtCalibrationDbTool;
 
 namespace Rec {
   class ICombinedMuonTrackBuilder;
@@ -250,7 +250,7 @@ namespace MuonCombined {
     ToolHandle<MuGirlNS::IStauBetaTofTool>           m_stauTofTool;
     ToolHandle<MuonCombined::MuonInsideOutRecoTool>  m_insideOutRecoTool;
     ToolHandle<Trk::IUpdator>                        m_updator;
-    ServiceHandle<MdtCalibrationDbSvc>               m_mdtCalibrationDbSvc;
+    ToolHandle<MdtCalibrationDbTool> m_calibrationDbTool;
     Muon::MuonSectorMapping                          m_muonSectorMapping;
 
     struct TruthMatchingCounters {
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MdtRegionDefiner.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MdtRegionDefiner.h
index 8cb3808add2ddfb51e0e05606dcb7ae065f2ac74..88fec6721fb0d12c32f5fe356c6928b92cde8bc8 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MdtRegionDefiner.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MdtRegionDefiner.h
@@ -9,8 +9,6 @@
 
 #include "AthenaBaseComps/AthAlgTool.h"
 
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
-
 #include "TrigT1Interfaces/RecMuonRoI.h"
 
 #include "TrigL2MuonSA/TgcFit.h"
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastPatternFinder.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastPatternFinder.h
index ff71562f43cf1d33a120429db26383fd9cc91c1c..4dae2f67ec476db20082ea38c32a4b5ac6215cbc 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastPatternFinder.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastPatternFinder.h
@@ -9,7 +9,7 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GeoPrimitives/GeoPrimitives.h"
 
-#include "MdtCalibSvc/MdtCalibrationSvc.h"
+#include "MdtCalibSvc/MdtCalibrationTool.h"
 
 #include "TrigL2MuonSA/MuonRoad.h"
 #include "TrigL2MuonSA/MdtData.h"
@@ -68,7 +68,7 @@ class MuFastPatternFinder: public AthAlgTool
 
    private:
       // MDT calibration service
-      ServiceHandle<MdtCalibrationSvc> m_mdtCalibrationSvc;
+      ToolHandle<MdtCalibrationTool> m_mdtCalibrationTool;
 
       // Id helper
       const MdtIdHelper* m_mdtIdHelper;
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
index 509367f343ef4516fcf482dd6a6e229f1b640640..134d20247fa2da7bce5456144a44b0ed86333651 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
@@ -31,9 +31,10 @@ TrigL2MuonSA::MuFastPatternFinder::MuFastPatternFinder(const std::string& type,
 						     const std::string& name,
 						     const IInterface*  parent): 
    AthAlgTool(type,name,parent),
-   m_mdtCalibrationSvc( "MdtCalibrationSvc", name )
+   m_mdtCalibrationTool("MdtCalibrationTool",this)
 {
    declareInterface<TrigL2MuonSA::MuFastPatternFinder>(this);
+   declareProperty("CalibrationTool",m_mdtCalibrationTool);
 }
 
 // --------------------------------------------------------------------------------
@@ -64,10 +65,6 @@ StatusCode TrigL2MuonSA::MuFastPatternFinder::initialize()
    ATH_MSG_DEBUG("Retrieved GeoModel from DetectorStore."); 
    m_mdtIdHelper = muonMgr->mdtIdHelper();                                                   
 
-   // Locate MDT calibration service
-   ATH_CHECK( m_mdtCalibrationSvc.retrieve() );
-   
-   // 
    return StatusCode::SUCCESS; 
 }
 
@@ -76,10 +73,6 @@ StatusCode TrigL2MuonSA::MuFastPatternFinder::initialize()
 
 void TrigL2MuonSA::MuFastPatternFinder::doMdtCalibration(TrigL2MuonSA::MdtHitData& mdtHit, double track_phi, double phi0, bool isEndcap)
 {
-   // if was error in getting servce,
-   if( ! m_mdtCalibrationSvc ) return;
-
-   // 
    int StationName  = mdtHit.name;
    int StationEta   = mdtHit.StationEta;
    int StationPhi   = mdtHit.StationPhi;
@@ -127,7 +120,7 @@ void TrigL2MuonSA::MuFastPatternFinder::doMdtCalibration(TrigL2MuonSA::MdtHitDat
    ATH_MSG_DEBUG("... MDT hit position X/Y/Z/track_phi/Multilayer/Layer/Tube="
 		 << X << "/" << Y << "/" << Z << "/" << track_phi << "/" << Multilayer << "/" << Layer << "/" << Tube);
 
-   m_mdtCalibrationSvc->driftRadiusFromTime( calHit, point.mag() );
+   m_mdtCalibrationTool->driftRadiusFromTime( calHit, point.mag() );
    double driftSpace = calHit.driftRadius();
    double driftSigma = calHit.sigmaDriftRadius();