From f3e4877a763d81925562e18a15a8037d0d9649bf Mon Sep 17 00:00:00 2001
From: Valerio Ippolito <valerio.ippolito@cern.ch>
Date: Tue, 17 Jun 2014 07:38:38 +0200
Subject: [PATCH] removed BFieldStand dependency/support (BFieldAth-01-08-08)

---
 .../BFieldAth/BFieldAth/IMagFieldAthenaSvc.h  |   28 +
 .../BFieldAth/BFieldAth/MagFieldAthena.h      |   17 +
 .../BFieldAth/BFieldAth/MagFieldSvcWrapper.h  |   36 +
 MagneticField/BFieldAth/cmt/requirements      |   26 +
 .../BFieldAth/share/BFieldAth_jobOptions.py   |    6 +
 MagneticField/BFieldAth/share/EmptyBfield.py  |   74 ++
 MagneticField/BFieldAth/share/bfield.py       |   21 +
 .../BFieldAth/src/MagFieldAthenaSvc.cxx       | 1065 +++++++++++++++++
 .../BFieldAth/src/MagFieldAthenaSvc.h         |  150 +++
 .../BFieldAth/src/MagFieldSvcWrapper.cxx      |   64 +
 .../components/MagFieldAthenaSvc_entries.cxx  |    9 +
 .../src/components/MagFieldAthenaSvc_load.cxx |    4 +
 12 files changed, 1500 insertions(+)
 create mode 100644 MagneticField/BFieldAth/BFieldAth/IMagFieldAthenaSvc.h
 create mode 100755 MagneticField/BFieldAth/BFieldAth/MagFieldAthena.h
 create mode 100644 MagneticField/BFieldAth/BFieldAth/MagFieldSvcWrapper.h
 create mode 100755 MagneticField/BFieldAth/cmt/requirements
 create mode 100755 MagneticField/BFieldAth/share/BFieldAth_jobOptions.py
 create mode 100644 MagneticField/BFieldAth/share/EmptyBfield.py
 create mode 100755 MagneticField/BFieldAth/share/bfield.py
 create mode 100755 MagneticField/BFieldAth/src/MagFieldAthenaSvc.cxx
 create mode 100755 MagneticField/BFieldAth/src/MagFieldAthenaSvc.h
 create mode 100644 MagneticField/BFieldAth/src/MagFieldSvcWrapper.cxx
 create mode 100755 MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_entries.cxx
 create mode 100755 MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_load.cxx

diff --git a/MagneticField/BFieldAth/BFieldAth/IMagFieldAthenaSvc.h b/MagneticField/BFieldAth/BFieldAth/IMagFieldAthenaSvc.h
new file mode 100644
index 00000000000..2200e4acece
--- /dev/null
+++ b/MagneticField/BFieldAth/BFieldAth/IMagFieldAthenaSvc.h
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef IMAGFIELDATHENASVC
+#define IMAGFIELDATHENASVC
+
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/StatusCode.h"
+#include "AthenaKernel/IOVSvcDefs.h" 
+#include "BFieldAth/MagFieldAthena.h"
+
+static const InterfaceID IID_IMagFieldAthenaSvc(1001, 1, 0);
+
+class IMagFieldAthenaSvc : virtual public IInterface {
+  public:
+  static const InterfaceID& interfaceID() { return IID_IMagFieldAthenaSvc; }
+  virtual MagFieldAthena* GetMagFieldAthena() = 0;
+  // retrieve through COOL callback - to be used in client callback method
+  virtual MagFieldAthena* GetUpdatedMagFieldAthena() = 0;
+  // check if field was really updated in callback, to be used in clients
+  virtual bool WasFieldUpdated() = 0;
+
+  virtual StatusCode initGeoModel(IOVSVC_CALLBACK_ARGS) = 0;
+  virtual StatusCode updateField(IOVSVC_CALLBACK_ARGS)  = 0;
+
+};
+#endif
diff --git a/MagneticField/BFieldAth/BFieldAth/MagFieldAthena.h b/MagneticField/BFieldAth/BFieldAth/MagFieldAthena.h
new file mode 100755
index 00000000000..00764b37409
--- /dev/null
+++ b/MagneticField/BFieldAth/BFieldAth/MagFieldAthena.h
@@ -0,0 +1,17 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//
+//  Author :  Saclay Muon Software Group SaMuSoG
+//  Date   :  18/05/00
+//
+// MagFieldAthena is a class providing Magnetic Field in Athena
+//
+#ifndef MAGFIELDATHENA
+#define MAGFIELDATHENA
+#include <sstream>
+#include "BFieldCore/AbstractMagneticField.h"
+#define MagFieldAthena AbstractMagneticField
+
+#endif
diff --git a/MagneticField/BFieldAth/BFieldAth/MagFieldSvcWrapper.h b/MagneticField/BFieldAth/BFieldAth/MagFieldSvcWrapper.h
new file mode 100644
index 00000000000..8a146709090
--- /dev/null
+++ b/MagneticField/BFieldAth/BFieldAth/MagFieldSvcWrapper.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MAGFIELDSVCWRAPPER_h
+#define MAGFIELDSVCWRAPPER_h
+#include "BFieldCore/AbstractMagneticField.h"
+	
+namespace MagField {
+  class IMagFieldSvc;
+}
+
+class MagFieldSvcWrapper: public AbstractMagneticField {
+ public:
+  // Constructor
+  MagFieldSvcWrapper( MagField::IMagFieldSvc& service );
+  // Destructor
+  virtual ~MagFieldSvcWrapper() {}
+ public:
+  // XYZ in cm => BXYZ in Tesla (Gradient Telsa/cm)
+  virtual void field_tesla_cm(float* XYZ,float* BXYZ);
+  virtual void fieldGradient_tesla_cm(float* XYZ,float* BXYZ);
+  // XYZ in mm => BXYZ in KiloGauss (G4) (Gradient kiloGauss/cm)
+  virtual void field_XYZ_in_mm(float* XYZ,float* BXYZ);
+  virtual void fieldGradient_XYZ_in_mm(float* XYZ,float* BXYZ);
+  // set Tilts extern parameters of b-field axis dx,dy,dz,dtheta,dphi,dpsi
+  void setSolenoidTilts( float* Dxyz_i, double theta, double phi, double psi );
+  // Where am I with respect to the Magnetic Field calculation
+  virtual void whereAmI(float* XYZ, int &iz); 
+  virtual const char * whereAmI(float* XYZ); 
+
+ private:
+  MagField::IMagFieldSvc* m_service;
+
+};
+#endif
diff --git a/MagneticField/BFieldAth/cmt/requirements b/MagneticField/BFieldAth/cmt/requirements
new file mode 100755
index 00000000000..98d9e51f406
--- /dev/null
+++ b/MagneticField/BFieldAth/cmt/requirements
@@ -0,0 +1,26 @@
+package BFieldAth
+#
+author  Marc Virchaux <virchaux@hep.saclay.cea.fr>
+#
+public
+use  AtlasPolicy                AtlasPolicy-*                   
+use  AthenaKernel               AthenaKernel-*                  Control
+use  GaudiInterface             GaudiInterface-*                External
+use  BFieldCore                 BFieldCore-*                    MagneticField
+##################################################
+private
+use  AthenaPoolUtilities        AthenaPoolUtilities-*           Database/AthenaPOOL
+use  AtlasCORAL                 AtlasCORAL-*                    External
+#use  BFieldStand                BFieldStand-*                   MagneticField
+use  GeoModelInterfaces         GeoModelInterfaces-*            DetectorDescription/GeoModel
+use  PathResolver               PathResolver-*                  Tools
+use  RDBAccessSvc               RDBAccessSvc-*                  Database/AthenaPOOL
+use  StoreGate                  StoreGate-*                     Control
+use  MagFieldInterfaces         *            MagneticField
+#
+public
+library BFieldAth *.F *.cxx components/*.cxx
+apply_pattern component_library 
+apply_pattern declare_joboptions files="*.txt *.py"
+
+
diff --git a/MagneticField/BFieldAth/share/BFieldAth_jobOptions.py b/MagneticField/BFieldAth/share/BFieldAth_jobOptions.py
new file mode 100755
index 00000000000..f137c87ec80
--- /dev/null
+++ b/MagneticField/BFieldAth/share/BFieldAth_jobOptions.py
@@ -0,0 +1,6 @@
+from AthenaCommon.Logging import logging
+logging.getLogger().error("BFieldAth/BFieldAth_jobOptions.py is OBSOLETE as the package is being DISCONTINUED")
+logging.getLogger().error("please use import MagFieldServices.SetupField instead")
+logging.getLogger().error("package BField will be removed from the release on June 13th, 2014")
+
+raise RuntimeError('protectedInclude(\'BFieldAth/BFieldAth_jobOptions.py\') is OBSOLETE, use instead: import MagFieldServices.SetupField')
diff --git a/MagneticField/BFieldAth/share/EmptyBfield.py b/MagneticField/BFieldAth/share/EmptyBfield.py
new file mode 100644
index 00000000000..921ccc92bcf
--- /dev/null
+++ b/MagneticField/BFieldAth/share/EmptyBfield.py
@@ -0,0 +1,74 @@
+AllAlgs = False # if false, all algorithms are switched off by defaults 
+#DetDescrVersion = 'ATLAS-CSC-01-00-00'
+#DetDescrVersion = 'ATLAS-CSC-01-01-00'
+#DetDescrVersion = "ATLAS-CSC-01-02-00"
+#DetDescrVersion = "ATLAS-CSC-02-01-00"
+#DetDescrVersion = "ATLAS-CSC-02-00-00"
+#DetDescrVersion = "ATLAS-CommNF-05-00-00"
+#DetDescrVersion = "ATLAS-GEO-00-00-00"
+#DetDescrVersion = "ATLAS-GEO-01-00-00"
+#DetDescrVersion = "ATLAS-GEO-02-00-00"
+#DetDescrVersion = "ATLAS-GEO-02-00-00"
+#DetDescrVersion = "ATLAS-GEO-03-00-00"
+#DetDescrVersion = "ATLAS-GEO-04-00-00"
+#DetDescrVersion = "ATLAS-TEST"
+DetDescrVersion = "ATLAS-GEO-08-00-00"
+#DetDescrVersion = "ATLAS-GEONTF-05-00-00"
+
+#
+doWriteESD=False # uncomment if do not write ESD
+doWriteAOD=False # uncomment if do not write AOD
+doAOD=False # uncomment if do not run AOD making algorithms
+doWriteTAG=False # uncomment if do not write TAG
+#
+doMissingET=False
+#
+doMoore=False
+doMuonIDStandAlone=False
+doMuonIDCombined=False
+doMuGirl=False
+doStaco=False
+doMuTag=False
+#
+doCBNT=False
+doTrigger = False # for example do not run trigger simulation
+doESD=False # uncomment if do not run ESD making algorithms
+doWriteESD=False # uncomment if do not write ESD
+doAOD=False # uncomment if do not run AOD making algorithms
+doWriteAOD=False # uncomment if do not write AOD
+doWriteTAG=False # uncomment if do not write TAG
+# DetFlags modifications are best set here (uncomment RecExCommon_flags first)
+include ("RecExCommon/RecExCommon_flags.py")
+# switch off ID, calo, or muons
+DetFlags.ID_setOff()
+DetFlags.Calo_setOff()
+DetFlags.Muon_setOff()
+
+PoolRDOInput=["/afs/cern.ch/atlas/project/muon/data/csc12/misal1_csc11.005145.PythiaZmumu.digit.RDO.v12003101_tid003501._00001.pool.root.1"]
+
+# main jobOption
+include ("RecExCommon/RecExCommon_topOptions.py")
+
+#--------------------------------------------------------------
+# MagField
+#  Ignore la diff entre tag simu et Tag reco
+#GeoModelSvc.IgnoreTagDifference = True
+ServiceMgr.GeoModelSvc.IgnoreTagDifference = True
+
+#--------------------------------------------------------------
+# BFieldAth
+#--------------------------------------------------------------
+include( "BFieldAth/BFieldAth_jobOptions.py" )
+###MagFieldAthenaSvc.NameOfTheSource = "BYPYTH"  
+###MagFieldAthenaSvc.dx = 0.001  
+###MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas05_test2_10250Amp.data" ;
+###MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas05_test2_NoSolenoid.data" ;
+###MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas04_test1_WithNoToroid_OnlySolAndIron.data" ;
+###MagFieldAthenaSvc.SetupCOOL=True
+###MagFieldAthenaSvc.NameOfTheSource = "COOL"  
+#-----------------------------------------------------------------
+# use DCS only if not running online
+ServiceMgr.MagFieldAthenaSvc.NameOfTheSource='COOL'
+from BFValidation.BFValidationConf import FastField
+topSequence += FastField( "MyFastField" )
+
diff --git a/MagneticField/BFieldAth/share/bfield.py b/MagneticField/BFieldAth/share/bfield.py
new file mode 100755
index 00000000000..77964ccb255
--- /dev/null
+++ b/MagneticField/BFieldAth/share/bfield.py
@@ -0,0 +1,21 @@
+#--------------------------------------------------------------
+# BFieldAth
+#
+if not 'MuonLayout' in dir():
+    # default value
+    MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas02.data"
+else:
+    if ( MuonLayout == "P03-DC2" or MuonLayout == "P03-DC1" ):
+        MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas02.data"
+    else:
+        if (MuonLayout == "Q02_initial" or MuonLayout == "Q02") :
+#           MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas03_test.data"
+            MagFieldAthenaSvc.NameOfTheBfieldFile = "bmagatlas03_test2.data"
+        else:
+            if (MuonLayout == "CTB2004" ):
+                print " WARNING magnetic field map for testbeam !!!! "
+                MagFieldAthenaSvc.NameOfTheBfieldFile = "mbps1-all-id-800-mbps2-muons-800.data"
+            else:
+                raise RuntimeError, 'ERROR : Unknown  MuonLayout allowed values are \nP03-DC1\nP03-DC2\nQ02_initial\nQ02\nCTB2004'
+
+print "Selecting B field map ",MagFieldAthenaSvc.NameOfTheBfieldFile
diff --git a/MagneticField/BFieldAth/src/MagFieldAthenaSvc.cxx b/MagneticField/BFieldAth/src/MagFieldAthenaSvc.cxx
new file mode 100755
index 00000000000..511634e4397
--- /dev/null
+++ b/MagneticField/BFieldAth/src/MagFieldAthenaSvc.cxx
@@ -0,0 +1,1065 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MagFieldAthenaSvc.h"
+#include "BFieldAth/MagFieldSvcWrapper.h"
+#include "GaudiKernel/SvcFactory.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/PropertyMgr.h"
+#include "PathResolver/PathResolver.h"
+
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h" 
+#include "StoreGate/StoreGateSvc.h"
+
+#include "AthenaPoolUtilities/AthenaAttributeList.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+
+#include "BFieldCore/MagFieldAccess.h"
+//#include "BFieldStand/MagFieldStand.h"
+//#include "BFieldStand/MagFieldFactory.h"
+//#include "BFieldStand/MagFieldStandXX.h"
+//#include "BFieldStand/MFSXXNoTilt.h"
+//#include "BFieldStand/noBfield.h"
+//#include "BFieldStand/MagFieldStandH8.h"
+//#include "BFieldStand/MagFieldStandH8Sym.h"
+#include "BFieldCore/MagFieldParam.h" 
+// Exception handling for non-existing fields in the database
+#include <stdexcept>
+#include "CoralBase/AttributeListException.h"
+
+// Standard Constructor
+MagFieldAthenaSvc::MagFieldAthenaSvc(const std::string& name,ISvcLocator* svc):
+  Service(name,svc),
+  geoModel(0),
+  par_onlineSolCur(0.),par_onlineTorCur(0.),
+  par_setupcool(false),par_usedcs(false),
+  par_scaletolerance(1.E-3),par_zerotolerance(1.0),par_currenttolerance(5.),
+  par_maptolerance(0.01),par_crashmap(false),
+  m_coolBFieldMap("/GLOBAL/BField/Map"),
+  m_coolCurrents("/EXT/DCS/MAGNETS/SENSORDATA"),
+  m_refSolCur(7730.),m_refTorCur(20400.),
+  m_gotcooldata(false),m_coolupdated(false),
+  m_getbad(0),m_getgood(0),m_getcoolbad(0),m_getcoolgood(0),
+  m_fieldService("MagField::AtlasFieldSvc/AtlasFieldSvc",name) {
+  //
+  p_MagFieldAthena                = 0       ;
+  //  std::cout << " before create param in constructor MagfieldAthSvc " << std::endl;
+  semiAnSol                       = 99999   ;
+  m_alreadyReadFile               = ""      ;
+  par_param.m_NameOfTheFile       = ""      ;
+  par_param.m_NameOfTheSource     = "ORACLE";
+  par_param.m_NoField             = ""      ;
+  par_param.m_SolenoidField       = ""      ;
+  par_param.calcul                = false   ;
+  //  Declare Properties
+  declareProperty("NameOfTheBfieldFile", par_param.m_NameOfTheFile)  ;
+  declareProperty("NameOfTheSource",     par_param.m_NameOfTheSource);
+  declareProperty("SolenoidField",       par_param.m_SolenoidField);
+  declareProperty("NOFIELD",             par_param.m_NoField);
+  declareProperty("Calcul",              par_param.calcul);
+  /*
+   * Temporary properties until we can read the "online" current from COOL.
+   * These are set by the HLT framework *before* BeginRun is fired (by reading
+   * the real-time currents directly from DCS). Only used if NameOfTheSource=="COOL_HLT"
+   */  
+  declareProperty("onlineSolCur",par_onlineSolCur,"Solenoid current for online running");
+  declareProperty("onlineTorCur",par_onlineTorCur,"Toroid current for online running");
+    
+  declareProperty("noTiltNoShift", par_param.noTiltNoShift);
+  declareProperty("InfosChain"   , par_param.m_InfosChain);
+  declareProperty("itf"    , par_param.m_itf);
+  declareProperty("dx"     , par_param.m_dx) ;
+  declareProperty("dy"     , par_param.m_dy) ;
+  declareProperty("dz"     , par_param.m_dz) ;
+  declareProperty("dphi"   , par_param.m_dphi)    ;
+  declareProperty("dtheta" , par_param.m_dtheta)  ;
+  declareProperty("dpsi"   , par_param.m_dpsi)    ;
+  // Solenoid displacements
+  declareProperty("dxsol"     , par_param.m_dxsol) ;
+  declareProperty("dysol"     , par_param.m_dysol) ;
+  declareProperty("dzsol"     , par_param.m_dzsol) ;
+  declareProperty("dphisol"   , par_param.m_dphisol)    ;
+  declareProperty("dthetasol" , par_param.m_dthetasol)  ;
+  declareProperty("dpsisol"   , par_param.m_dpsisol)    ;
+  // COOL stuff
+  declareProperty("SetupCOOL",par_setupcool);
+  declareProperty("UseDCS",par_usedcs);
+  declareProperty("ScaleTolerance",par_scaletolerance);
+  declareProperty("ZeroTolerance",par_zerotolerance);
+  declareProperty("CurrentTolerance",par_currenttolerance);
+  declareProperty("MapTolerance",par_maptolerance);
+  declareProperty("CrashMap",par_crashmap);
+  //
+  //  Test H8 only  
+  declareProperty("H8dx1"  , par_param.m_h8dx1) ;// mpbs1 displacement
+  declareProperty("H8dy1"  , par_param.m_h8dy1) ;
+  declareProperty("H8dz1"  , par_param.m_h8dz1) ;
+  declareProperty("H8dx2"  , par_param.m_h8dx2) ;// mpbl displacement
+  declareProperty("H8dy2"  , par_param.m_h8dy2) ;
+  declareProperty("H8dz2"  , par_param.m_h8dz2) ;
+  declareProperty("H8dx3"  , par_param.m_h8dx3) ;// mpbs2 displacement
+  declareProperty("H8dy3"  , par_param.m_h8dy3) ;
+  declareProperty("H8dz3"  , par_param.m_h8dz3) ;
+
+  declareProperty("UseIMagFieldSvc"  , m_useFieldService = true ) ;
+  // par_param.printParam();
+  // std::cout << " End constructor MagfieldAthSvc " << std::endl;
+  // std::cout << " ************************** " << std::endl;
+  //
+  alreadyReadFile = false;
+}
+ 
+//*Standard Destructor
+MagFieldAthenaSvc::~MagFieldAthenaSvc(){}
+
+void MagFieldAthenaSvc::getTagOracle (StatusCode &Sc) {
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "***********************************************" << endreq;
+  log << MSG::INFO << "* Retrieving Magnetic Field from DD DataBase! *" << endreq;
+  log << MSG::INFO << "***********************************************" << endreq;
+  //
+  // Get GeoModelSvc and RDBAccessSvc in order to get the bfield options from the database
+  IRDBAccessSvc * accessSvc;
+  Sc = service("RDBAccessSvc",accessSvc);
+  if (!Sc.isSuccess()) {
+    log << MSG::ERROR << "Unable to get RDBAccessSvc." << endreq;
+    //   return Sc;
+  }
+  accessSvc->connect();
+  //
+  // Check for NoField from Oracle
+  std::string bfTagName = geoModel->magFieldVersion();
+  if(bfTagName.find("NOFIELD")!=std::string::npos){
+    m_param.m_NoField = "NOFIELD";
+  } else{  
+    getBfieldFileName (geoModel, accessSvc);
+    getBfieldDisplacements (geoModel, accessSvc);
+    getCurrent (geoModel, accessSvc);
+  }
+  log <<  MSG::INFO << "bfTagName: " << bfTagName;
+  if(geoModel->magFieldVersion()==geoModel->magFieldVersionOverride())
+    log << " ! Overrides " << accessSvc->getChildTag("MagneticField",geoModel->atlasVersion(),"ATLAS");
+  log << endreq;
+
+  //if(bfTagName.find("CSC-01-01-00")!=std::string::npos || bfTagName.find("CSC-01-02-00")!=std::string::npos ){
+  if((geoModel->atlasVersion().find("CSC-01-01-00")!=std::string::npos || 
+     geoModel->atlasVersion().find("CSC-01-02-00")!=std::string::npos) && geoModel->magFieldVersionOverride().empty() ){
+    m_param.m_itf=1;
+    log <<  MSG::INFO << "ATTENTION Tilt is wrong but bfield is coherent with simulation: " << geoModel->atlasVersion() << endreq;
+    log <<  MSG::INFO << "itf       : " << m_param.m_itf << endreq;
+  } else {
+    log <<  MSG::INFO << "ATTENTION : " << geoModel->atlasVersion() << endreq;
+    log <<  MSG::INFO << "itf       : " << m_param.m_itf << endreq;
+  }
+  accessSvc->disconnect();
+}
+
+void MagFieldAthenaSvc::getTagOracle2 (StatusCode &Sc) {
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "INFOSBMAG from Oracle old mecansime < release 16...!" << endreq;
+  IRDBAccessSvc * accessSvc;
+  Sc = service("RDBAccessSvc",accessSvc);
+  if (!Sc.isSuccess()) {
+    log << MSG::ERROR << "Unable to get RDBAccessSvc." << endreq;
+    //   return Sc;
+  }
+  accessSvc->connect();
+  std::string bfTagName = geoModel->magFieldVersion();
+  getBfieldFileName2 (geoModel, accessSvc);
+  accessSvc->disconnect();
+}
+
+void MagFieldAthenaSvc::getBfieldFileName(const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc){
+  MsgStream log(messageService(), name());
+  log <<  MSG::INFO << "Using Atlas Geometry version tag: " << geoModel->atlasVersion() << endreq;
+  if(geoModel->magFieldVersionOverride()!="")
+    log <<  MSG::INFO << "Default MagneticField tag overriden by " << geoModel->magFieldVersionOverride() << endreq;
+  const IRDBRecordset *bfieldOptionsSet = accessSvc->getRecordset("MagneticFieldOptions",
+								  geoModel->magFieldVersion(),"MagneticField");
+//   const IRDBRecordset *bfieldOptionsSet = accessSvc->getRecordset("MagneticFieldOptions","MagneticFieldOptions-05");
+  if (bfieldOptionsSet->size()==0){
+    log << MSG::FATAL << "bfieldOptionsSet->size() is 0" << endreq;
+    //return StatusCode::FAILURE;
+  }
+  const IRDBRecord *bfieldOptions =  (*bfieldOptionsSet)[0];
+  m_param.m_NameOfTheFile    = bfieldOptions->getString("FILENAME");
+  log <<  MSG::INFO << "Using Atlas Geometry version tag: " << m_param.m_NameOfTheFile << endreq;
+
+
+  try
+  {
+    if(bfieldOptions->isFieldNull("SOLENOID_FILE")){
+      semiAnSol = 0;
+      log <<  MSG::INFO << "****************************************************" <<  endreq;
+      log <<  MSG::INFO << "* No Solenoid Map available for this tag           *" <<  endreq;
+      log <<  MSG::INFO << "* We use ATLM Solenoid semi-Analytical Calculation *" <<  endreq;
+      log <<  MSG::INFO << "****************************************************" <<  endreq;
+      log <<  MSG::INFO << "* semiAnSol =   "<< semiAnSol  <<  endreq;
+    }else{
+      m_param.m_SolenoidField  = bfieldOptions->getString("SOLENOID_FILE");
+      log <<  MSG::INFO << "Solenoid Map available for this tag is: " << m_param.m_SolenoidField <<  endreq;
+    }
+
+    if(bfieldOptions->isFieldNull("INFOSBMAG")){
+      m_param.m_InfosChain = 0;
+      log <<  MSG::INFO << "InfosBMAG From Oracle, Old chain NO CHANGE: "<< m_param.m_InfosChain  <<  endreq;
+    }else{
+      m_param.m_InfosChain  = bfieldOptions->getInt("INFOSBMAG");
+      log <<  MSG::INFO << "InfosBMAG From Oracle, New chain Correction: " << m_param.m_InfosChain <<  endreq;
+    }
+
+  }
+  catch(std::runtime_error& ex)
+  {
+    log << MSG::DEBUG << "Exception caught. " << ex.what() << endreq;
+    log << MSG::INFO << "No Solenoid Map available for this tag " <<  endreq;
+  }
+}
+void MagFieldAthenaSvc::getBfieldFileName2(const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc){
+  MsgStream log(messageService(), name());
+  const IRDBRecordset *bfieldOptionsSet = accessSvc->getRecordset("MagneticFieldOptions",
+								  geoModel->magFieldVersion(),"MagneticField");
+  if (bfieldOptionsSet->size()==0){
+    log << MSG::FATAL << "bfieldOptionsSet->size() is 0" << endreq;
+    //return StatusCode::FAILURE;
+  }
+  const IRDBRecord *bfieldOptions =  (*bfieldOptionsSet)[0];
+  try
+  {
+    if(bfieldOptions->isFieldNull("INFOSBMAG")){
+      m_param.m_InfosChain = 0;
+      log <<  MSG::INFO << "Old chain NO CHANGE (2):  "<< m_param.m_InfosChain  <<  endreq;
+    }else{
+      m_param.m_InfosChain  = bfieldOptions->getInt("INFOSBMAG");
+      log <<  MSG::INFO << "New chain Correction (2): " << m_param.m_InfosChain <<  endreq;
+    }
+  }
+  catch(std::runtime_error& ex)
+  {
+    log << MSG::DEBUG << "Exception caught. " << ex.what() << endreq;
+  }
+}
+
+void MagFieldAthenaSvc::getBfieldDisplacements(const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc){
+  //
+  //* Tilts & shifts for the full map
+  //* new way to get BFieldDisplacements
+  MsgStream log(messageService(), name());
+  const IRDBRecordset *bfieldDisplacementsSet = accessSvc->getRecordset("BFieldDisplacements",
+									geoModel->magFieldVersion(),"MagneticField");
+  if(bfieldDisplacementsSet->size()==0){
+    log << MSG::DEBUG << "bfieldDisplacementsSet->size() is 0, trying the default set" << endreq;
+    bfieldDisplacementsSet = accessSvc->getRecordset("BFieldDisplacements","BFieldDisplacements-01");
+    if(bfieldDisplacementsSet->size()==0){
+      log << MSG::FATAL << "bfieldDisplacementsSet->size() is 0"<< endreq;
+      //return StatusCode::FAILURE;
+    }
+  }
+  std::string tag = accessSvc->getChildTag("BFieldDisplacements", geoModel->magFieldVersion(),"MagneticField"); 
+  log << MSG::INFO << "BFieldDisplacements   tag = "<< tag << endreq;
+  if(tag == "BFieldDisplacements-01" || tag == "BFieldDisplacements-03" || tag == ""){
+    m_param.noTiltNoShift = 1;
+    log << MSG::INFO << "NO Shifts & NO Tilts For the Global map: tag = "<< tag << endreq;
+  }else{
+    m_param.noTiltNoShift = 0;
+    log << MSG::INFO << "   Shifts &    Tilts: tag = "<< tag << endreq;
+  }
+  
+  for(size_t index = 0; index < bfieldDisplacementsSet->size(); index++){
+    const IRDBRecord *bfieldDisplacements =  (*bfieldDisplacementsSet)[index];
+    if(bfieldDisplacements->isFieldNull("FIELDNAME")){
+      log << MSG::INFO << " Only Global displacement: BFieldDisplacements Global Map" << endreq;
+      m_param.m_dx        = bfieldDisplacements->getDouble("DX");
+      m_param.m_dy        = bfieldDisplacements->getDouble("DY");
+      m_param.m_dz        = bfieldDisplacements->getDouble("DZ");
+      m_param.m_dtheta    = bfieldDisplacements->getDouble("DALPHA");
+      m_param.m_dphi      = bfieldDisplacements->getDouble("DBETA");
+      m_param.m_dpsi      = bfieldDisplacements->getDouble("DGAMMA");
+    }else{
+      std::string aaa = bfieldDisplacements->getString("FIELDNAME");
+      if( aaa == "GlobalMap"){
+	log << MSG::INFO << "BFieldDisplacements Global Map" << endreq;
+	m_param.m_dx        = bfieldDisplacements->getDouble("DX");
+	m_param.m_dy        = bfieldDisplacements->getDouble("DY");
+	m_param.m_dz        = bfieldDisplacements->getDouble("DZ");
+	m_param.m_dtheta    = bfieldDisplacements->getDouble("DALPHA");
+	m_param.m_dphi      = bfieldDisplacements->getDouble("DBETA");
+	m_param.m_dpsi      = bfieldDisplacements->getDouble("DGAMMA");
+      }else if( aaa == "SolenoidMap"){
+	log << MSG::INFO << "BFieldDisplacements For Solenoid " << endreq;
+	m_param.m_dxsol     = bfieldDisplacements->getDouble("DX");
+	m_param.m_dysol     = bfieldDisplacements->getDouble("DY");
+	m_param.m_dzsol     = bfieldDisplacements->getDouble("DZ");
+	m_param.m_dthetasol = bfieldDisplacements->getDouble("DALPHA");
+	m_param.m_dphisol   = bfieldDisplacements->getDouble("DBETA");
+	m_param.m_dpsisol   = bfieldDisplacements->getDouble("DGAMMA");
+      }
+    }
+    log << MSG::INFO << "BFieldDisplacements printParam() " << endreq;
+    std::ostringstream outperso;
+    m_param.printParam(outperso);
+    log << MSG::INFO << outperso.str() << endreq;
+  }
+}
+
+// Get Current for Toroids and Solenoid from oracle (mainly for the simulation)
+void MagFieldAthenaSvc::getCurrent(const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc){
+  MsgStream log(messageService(), name());
+  const IRDBRecordset *bfieldScaleSet = accessSvc->getRecordset("MagneticFieldOptions",geoModel->magFieldVersion(),"MagneticField");
+  log << MSG::INFO << "Using Atlas Geometry version tag: " << geoModel->atlasVersion() << endreq;
+  if(geoModel->magFieldVersionOverride()!="")
+    log <<  MSG::INFO << "Default MagneticField tag overriden by " << geoModel->magFieldVersionOverride() << endreq;
+  if (bfieldScaleSet->size()==0) log << MSG::FATAL << "bfieldScaleSet->size() is 0" << endreq;
+  const IRDBRecord *bfieldScale = (*bfieldScaleSet)[0];
+  if (bfieldScale->isFieldNull("SOL_CURRENT")) {
+    m_param.m_SolCur=0.;
+  } else {
+    m_param.m_SolCur = bfieldScale->getDouble("SOL_CURRENT");
+  }
+  log << MSG::INFO << "Using Atlas Geometry the b-field current for the solenoid is " << m_param.m_SolCur    << " amps " << endreq;
+  log << MSG::INFO << "                                        the nominal value is " << m_param.m_SolCurNom << " amps " << endreq;
+  if (bfieldScale->isFieldNull("TOROIDS_CURRENT")) {
+    m_param.m_TorCur=0.;
+  } else {
+    m_param.m_TorCur = bfieldScale->getDouble("TOROIDS_CURRENT");
+  }
+  log << MSG::INFO << "Using Atlas Geometry the b-field current for the toroids is  " << m_param.m_TorCur    << " amps " << endreq;
+  log << MSG::INFO << "                                        the nominal value is " << m_param.m_TorCurNom << " amps " << endreq;
+  if(m_param.m_TorCur != 0 || m_param.m_SolCur != 0) m_param.doScale = true;
+}
+
+//
+//*Service initialisation
+StatusCode MagFieldAthenaSvc::initialize() {
+  //
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "in initialize()" << endreq;
+  //
+  StatusCode Sc = Service::initialize();
+  if (Sc.isFailure()) return StatusCode::FAILURE;
+
+  // get detector store
+  if (StatusCode::SUCCESS!=service("DetectorStore", p_detStore )) {
+    log << MSG::FATAL << "Cannot get detector store" << endreq;
+    return StatusCode::FAILURE;
+  }
+  // get the parameters from the joboption buffer
+  m_param=par_param;
+
+  // book COOL callback if needed
+  if (par_setupcool || m_param.m_NameOfTheSource == "COOL") {
+    if (StatusCode::SUCCESS==p_detStore->regFcn(
+     &IMagFieldAthenaSvc::updateField,dynamic_cast<IMagFieldAthenaSvc *>(this),
+     h_coolBFieldMap,m_coolBFieldMap)) {
+      log << MSG::INFO << "Booked callback for " << m_coolBFieldMap << endreq;
+    } else {
+      log << MSG::FATAL << "Could not book callback for " << m_coolBFieldMap
+	  << endreq;
+      return StatusCode::FAILURE;
+    }
+    if (par_usedcs) {
+      // boook callback for BField current DCS data
+      if (StatusCode::SUCCESS==p_detStore->regFcn(
+          &IMagFieldAthenaSvc::updateField,
+          dynamic_cast<IMagFieldAthenaSvc*>(this),
+          h_coolCurrents,m_coolCurrents)) {
+	log << MSG::INFO << "Booked callback for " << m_coolCurrents << endreq;
+      } else {
+	log << MSG::FATAL << "Could not book callback for " << m_coolCurrents
+	    << endreq;
+	return StatusCode::FAILURE;
+      }
+    }
+  }
+
+  if (m_param.m_NameOfTheSource == "ORACLE") { 
+    log << MSG::INFO << " Magnetic Field information from ORACLE " << endreq;
+    //
+    Sc = service ("GeoModelSvc",geoModel);
+    if (Sc.isFailure()) {
+      log << MSG::ERROR << "Unable to get GeoModelSvc." << endreq;
+      return Sc;
+    }
+    //
+    //*Dummy parameters for the callback
+    int par1 = 0;
+    std::list<std::string> par2;
+
+    if(geoModel->geoInitialized())
+      //*GeoModelSvc is configured by job options
+      return initGeoModel(par1,par2);
+    else
+      {
+	//*GeoModelSvc is configured automatically
+	//*Register MagFieldAthenaSvc::initGeoModel() as a callback function on DetStore
+	//*to be called after IGeoModelSvc::align()
+	Sc =  p_detStore->regFcn(&IGeoModelSvc::align,geoModel,
+				&MagFieldAthenaSvc::initGeoModel,this);
+	//
+	if (Sc.isFailure()) 
+	  log << MSG::ERROR << "Cannot register geoInit function "  << endreq;
+	else
+	  log << MSG::DEBUG << "Registered geoInit callback  " << endreq;
+
+	return Sc;
+      }
+
+  } else if (m_param.m_NameOfTheSource == "BYPYTH") { 
+    log << MSG::WARNING << "********************************************************" << endreq;
+    log << MSG::WARNING << "* Magnetic Field information from CUSTOM configuration.*" << endreq;
+    log << MSG::WARNING << "********************************************************" << endreq;
+    log << MSG::WARNING << " NEW Param from CUSTOM configuration.                   " << endreq;
+    semiAnSol = 0;
+    std::ostringstream outperso;
+    m_param.printParam(outperso);
+    log << MSG::INFO << outperso.str() << endreq;
+    m_coolupdated=true;
+    return initMagField();
+  } else if (m_param.m_NameOfTheSource == "COOL") {
+    par_setupcool=true;
+    log << MSG::INFO << "Magnetic Field information from COOL" << endreq;
+    return StatusCode::SUCCESS;
+  } else if (m_param.m_NameOfTheSource == "COOL_HLT") {
+    par_setupcool=true;
+    log << MSG::INFO << "Magnetic Field information from COOL and/or HLT (for online running)" << endreq;
+    return StatusCode::SUCCESS;
+  }
+  else {
+    log << MSG::FATAL << "Selected source " << m_param.m_NameOfTheSource  << " unknown "<< endreq;
+    log <<  MSG::INFO << "InfosChain      " << m_param.m_InfosChain  <<  endreq;
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode MagFieldAthenaSvc::initGeoModel(IOVSVC_CALLBACK_ARGS)
+{
+  
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "in initGeoModel()" << endreq;
+  StatusCode Sc;
+  //
+  //*Get correct information from the Geometry DB
+  getTagOracle (Sc);
+  //*Proceed with the rest of MagField initialization
+  m_coolupdated=true;
+  return initMagField();
+}
+  
+
+StatusCode MagFieldAthenaSvc::initMagField(){
+
+
+  //
+  //*Do the actual MagField initialization here
+
+  MsgStream log(messageService(), name());
+  //  log << MSG::INFO << "in initMagField()" << endreq;
+  //
+  //   Hack to get bz2 or unzip file   //
+  //   trick to test the hack...      //
+  //   fileName = "/afs/cern.ch/user/c/chevalie/afsmag/Map/AtlasFull/bmagatlas_09_fullAsym20400.data.bz2";
+  std::string fileName    = PathResolver::find_file(m_param.m_NameOfTheFile,"DATAPATH");
+  std::string fileNameSol = PathResolver::find_file(m_param.m_SolenoidField,"DATAPATH");
+  std::string fileNameUnzip;
+  log << MSG::INFO << "Selected source  : " << m_param.m_NameOfTheSource  << endreq;
+  log << MSG::INFO << "Input Bfield file: " << m_param.m_NameOfTheFile    << endreq;
+  if(fileName.empty()) {
+    fileNameUnzip = m_param.m_NameOfTheFile.substr( 0,  m_param.m_NameOfTheFile.size() - 4 );
+    log << MSG::INFO << "fileName empty, build fileNameUnzip: " << fileNameUnzip << endreq;
+    fileNameUnzip = PathResolver::find_file(fileNameUnzip,"DATAPATH");
+    log << MSG::INFO << "fileNameUnzip:                       " << fileNameUnzip << endreq;
+  }
+  
+  if (fileName.find(".bz2")!=std::string::npos) {
+    if(!fileNameUnzip.empty()) {
+      fileName = fileNameUnzip;
+      log << MSG::INFO << "MagField file unzipped found: " << fileName  << endreq;
+    } else {
+      log << MSG::INFO << "MagField file zipped found: " << fileName  << endreq;
+    }
+  } else if(!fileNameUnzip.empty()) {
+    fileName = fileNameUnzip;
+    log << MSG::INFO << "NO fileName zipped!! Only UnZipped file New Map: " << fileName  << endreq;
+  } else if(!fileName.empty()) {
+    log << MSG::INFO << "NO fileName zipped!! Only UnZipped file Old Map: " << fileName  << endreq;
+  } else if(m_param.m_NoField == "NOFIELD") {
+    log << MSG::INFO << "NO Magnetic Field COOL!!! " << m_param.m_NoField  << endreq;
+    log << MSG::INFO << "NO Magnetic Field current Toroid   " << par_onlineTorCur << endreq;
+    log << MSG::INFO << "NO Magnetic Field current Solenoid " << par_onlineSolCur << endreq;
+  } else {
+    log << MSG::FATAL << "Cannot locate MagField " << fileName << " from ${DATAPATH}"  << endreq;
+    return StatusCode::FAILURE;
+  }
+  //   Hack end   //
+  log << MSG::INFO << "fileName:          " << fileName << endreq;
+  log << MSG::INFO << "fileNameSol:       " << fileNameSol << endreq;
+  log << MSG::INFO << "fileNameUnzip:     " << fileNameUnzip << endreq;
+  //*Get correct information from the Geometry DB
+  StatusCode Sc;
+  Sc = service ("GeoModelSvc",geoModel);
+  if (Sc.isFailure()) {
+    log << MSG::ERROR << "Unable to get GeoModelSvc." << endreq;
+    return Sc;
+  }
+  if(m_param.m_NameOfTheFile=="bmagatlas05_test2.data"){
+    log << MSG::INFO << "Old map get InfosBmag " << endreq;
+    getTagOracle2 (Sc);
+  }
+  //
+  if(m_param.m_NoField == "NOFIELD"){
+    log << MSG::INFO << "No Magnetic Field Oracle Tag :  "<< m_param.m_NoField << endreq;
+    log << MSG::INFO << "*******************************" << endreq;
+    log << MSG::INFO << "*    No Magnetic Field       * " << endreq;
+    log << MSG::INFO << "*    No Magnetic Field       * " << endreq;
+    log << MSG::INFO << "*    No Magnetic Field       * " << endreq;
+    log << MSG::INFO << "*    No Magnetic Field       * " << endreq;
+    log << MSG::INFO << "*    No Magnetic Field       * " << endreq;
+    log << MSG::INFO << "*******************************" << endreq;
+  }else{
+    if (fileName == ""){
+      log << MSG::FATAL  << "Cannot locate " << m_param.m_NameOfTheFile << " from ${DATAPATH}"  << endreq;
+      return StatusCode::FAILURE;
+    } else {
+      log << MSG::INFO << "Global Shifts and Tilts for Magnetic Field:" << endreq;
+      int sommeParTilt;
+      sommeParTilt = m_param.m_dx +  m_param.m_dy + m_param.m_dz + m_param.m_dtheta + m_param.m_dphi + m_param.m_dpsi;
+      if(sommeParTilt == 0){ 
+	log << MSG::INFO << "No shift & No Tilts for the Global Mag Field Map             "<< sommeParTilt << endreq;
+      } else { 
+	log << MSG::INFO << "Shift &/or Tilts for the Global Mag Field Map                "<< sommeParTilt << endreq;
+	log << MSG::INFO << "Dx "<< m_param.m_dx << endreq;
+	log << MSG::INFO << "Dy "<< m_param.m_dy << endreq;
+	log << MSG::INFO << "Dz "<< m_param.m_dz << endreq;
+	log << MSG::INFO << "Da "<< m_param.m_dtheta << endreq;
+	log << MSG::INFO << "Db "<< m_param.m_dphi<< endreq;
+	log << MSG::INFO << "Dc "<< m_param.m_dpsi<< endreq;
+      }
+    }
+    if (fileNameSol == "" && semiAnSol != 0) {
+      log << MSG::FATAL << "Cannot locate " <<  m_param.m_SolenoidField << " from ${DATAPATH}" << endreq;
+      return StatusCode::FAILURE;
+    } else {
+      m_param.m_SolenoidField = fileNameSol;
+      log << MSG::INFO << "Fitted Solenoid Map used: " << m_param.m_SolenoidField  << endreq;
+      log << MSG::INFO << "Shifts and Tilts for Solenoid Map:" << endreq;
+      log << MSG::INFO << "Dxsol "<< m_param.m_dxsol << endreq;
+      log << MSG::INFO << "Dysol "<< m_param.m_dysol << endreq;
+      log << MSG::INFO << "Dzsol "<< m_param.m_dzsol << endreq;
+      log << MSG::INFO << "Dasol "<< m_param.m_dthetasol << endreq;
+      log << MSG::INFO << "Dbsol "<< m_param.m_dphisol<< endreq;
+      log << MSG::INFO << "Dcsol "<< m_param.m_dpsisol<< endreq;
+    }
+    //* if Map already open
+    if(m_param.m_NameOfTheFile == m_alreadyReadFile){
+      log << MSG::INFO << " Toroid map already open  "<< m_alreadyReadFile << endreq;
+      alreadyReadFile = false;
+    } else {
+      alreadyReadFile = true;
+      m_alreadyReadFile = m_param.m_NameOfTheFile;
+      log << MSG::INFO << " Toroid map first call    "<< m_alreadyReadFile << endreq;
+    };  
+  }
+  if( m_useFieldService ){
+
+    
+    if( m_fieldService.retrieve().isFailure() ) {
+      log << MSG::FATAL << "Cannot get " << m_fieldService << endreq;
+      return StatusCode::FAILURE;
+    }
+    
+    p_MagFieldAthena = new MagFieldSvcWrapper( *&*m_fieldService );
+
+  } else {
+    log << MSG::FATAL << "Support for old field service is DISCONTINUED" << endreq;
+    log << MSG::FATAL << "Please switch to the new MagFieldServices or set UseIMagFieldSvc (now " << m_useFieldService << ") to true" << endreq;
+    return StatusCode::FAILURE;
+  }
+//}else if(m_param.m_NoField == "NOFIELD") {
+//  log << MSG::INFO << " m_param.m_NoField  "<< m_param.m_NoField  << endreq; 
+//  p_MagFieldAthena = MagFieldFactory::instantiateMagneticField (fileName, &m_param);
+//}else if(alreadyReadFile) {
+//  //  m_param=par_param;
+//  m_param.m_NoField = par_param.m_NoField;
+//  m_param.calcul    = par_param.calcul;
+//  log << MSG::INFO << " alreadyReadFile    "<< alreadyReadFile << endreq; 
+//  log << MSG::INFO << " m_param.m_NoField  "<< m_param.m_NoField  << endreq; 
+//  log << MSG::INFO << " m_param.calcul     "<< m_param.calcul  << endreq; 
+//  p_MagFieldAthena = MagFieldFactory::instantiateMagneticField (fileName, &m_param);
+//} 
+//if (!p_MagFieldAthena) {
+//  log << MSG::FATAL<< "DTB does not correspond to known Type ??? " << endreq;
+//  return StatusCode::FAILURE;
+//}
+  p_MagFieldAthena->setAllToroidOn(false);
+  p_MagFieldAthena->setFieldStatusOn(false);  
+  if(p_MagFieldAthena->getToroidBarrelOn() &&
+     p_MagFieldAthena->getToroidECTAOn()   &&
+     p_MagFieldAthena->getToroidECTCOn() ){
+     p_MagFieldAthena->setAllToroidOn(true);
+  }
+  if(p_MagFieldAthena->getAllToroidOn() &&  
+     p_MagFieldAthena->getSolenoidOn() ){
+     p_MagFieldAthena->setFieldStatusOn(true);  
+  }    
+//  std::ostringstream outperso;
+//  m_param.printParam(outperso);
+//  log << MSG::INFO << outperso.str() << endreq;
+  log << MSG::INFO << m_param.outFactory << endreq;
+  //
+  log << MSG::INFO << "*** Magnetic Field Status *** " << endreq;
+  log << MSG::INFO << "*    ToroidBarrelOn()        * " <<  p_MagFieldAthena->getToroidBarrelOn() << endreq ;
+  log << MSG::INFO << "*    ToroidECTAOn()          * " <<  p_MagFieldAthena->getToroidECTAOn()   << endreq ;
+  log << MSG::INFO << "*    ToroidECTCOn()          * " <<  p_MagFieldAthena->getToroidECTCOn()   << endreq ;
+  log << MSG::INFO << "*    AllToroidOn()           * " <<  p_MagFieldAthena->getAllToroidOn()    << endreq ;
+  log << MSG::INFO << "*    SolenoidOn()            * " <<  p_MagFieldAthena->getSolenoidOn()     << endreq ;
+  log << MSG::INFO << "*    FieldStatusOn()         * " <<  p_MagFieldAthena->getFieldStatusOn()  << endreq ;
+  log << MSG::INFO << "*******************************" << endreq;
+  //
+  return StatusCode::SUCCESS;
+}
+ 
+//*Service finalisation
+StatusCode MagFieldAthenaSvc::finalize()    {
+  //
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "in finalize()" << endreq;
+  log << MSG::INFO << "Retrieves through getMagFieldAthena() [init, event] ["
+      << m_getbad << "," << m_getgood << "]" << endreq;
+  log << MSG::INFO << "Retrieves through getUpdatedMagFieldAthena() [init, event] ["
+      << m_getcoolbad << "," << m_getcoolgood << "]" << endreq;
+  //
+  //*Reset p_MagFieldAthena
+  delete p_MagFieldAthena ;
+  p_MagFieldAthena = 0;
+  return Service::finalize();
+}
+
+StatusCode MagFieldAthenaSvc::queryInterface( const InterfaceID& riid, void** ppvInterface ) { 
+  if ( IID_IMagFieldAthenaSvc == riid )    {
+    *ppvInterface = (IMagFieldAthenaSvc*)this;
+  }
+  else  {
+    return Service::queryInterface(riid, ppvInterface);
+  }
+  return StatusCode::SUCCESS;
+}
+ 
+MagFieldAthena* MagFieldAthenaSvc::GetMagFieldAthena() {
+  // count retrievals before and after the COOL setup has been done
+  if (m_gotcooldata) {
+    ++m_getgood;
+  } else {
+    ++m_getbad;
+  }
+  // if COOL is in use, throw exception as this method should not be called
+  if (m_param.m_NameOfTheSource=="COOL") {
+    MsgStream log(messageService(), name());
+    log << MSG::FATAL << "GetMagFieldAthena called when magnetic field is read from COOL - please use GetUpdatedMagFieldAthena instead" << endreq;
+    throw GaudiException("GetMagFieldAthena called when magnetic field read from COOL","MagFieldAthenaSvc",StatusCode::FAILURE);
+  }
+  return p_MagFieldAthena;
+}
+
+MagFieldAthena* MagFieldAthenaSvc::GetUpdatedMagFieldAthena() {
+  // return the pointer to the magnetic field retrieved after COOL callback
+  // to be called in client callbacks attached to MagFieldAthenaSvc::updateField  // count how many times this is called before/after callback done
+  if (m_gotcooldata) {
+    ++m_getcoolgood;
+    return p_MagFieldAthena;
+  } else {
+    ++m_getcoolbad;
+    return 0;
+  }
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "GetUpdatedMagFieldAthena" << endreq;
+}
+
+bool MagFieldAthenaSvc::WasFieldUpdated() {
+  return m_coolupdated;
+}
+
+// callback function called when COOL Bfield data (map, currents) changes
+StatusCode MagFieldAthenaSvc::updateField(IOVSVC_CALLBACK_ARGS_P(/*I*/,
+								 keys)) {
+  // callback function when COOL field information changes
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "COOL callback updateField called for " << 
+    keys.size() << " folders" << endreq;
+  m_coolupdated=true;
+
+  // first determine what has changed
+  bool newmap=false;
+  bool newcur=false;
+  for (std::list<std::string>::const_iterator ktr=keys.begin();ktr!=keys.end();
+       ++ktr) {
+    if (*ktr==m_coolBFieldMap) newmap=true;
+    if (*ktr==m_coolCurrents) newcur=true;
+  }
+  float solcur=0.;
+  float torcur=0.;
+  if (m_param.m_NameOfTheSource=="COOL_HLT") {
+    // obtain currents from HLT parameters
+    solcur=par_onlineSolCur;
+    torcur=par_onlineTorCur;
+  } else if (par_usedcs) {
+    // if DCS callback enabled, get parameters from DCS
+    log << MSG::DEBUG << "Process magnetic field currents from COOL, size "
+	  << h_coolCurrents->size() << endreq;
+    bool gotsol=false;
+    bool gottor=false;
+    for (CondAttrListCollection::const_iterator itr=h_coolCurrents->begin();
+	     itr!=h_coolCurrents->end();++itr) {
+      const coral::AttributeList& cpar=itr->second;
+      if (itr->first==1) {
+        // channel 1 is solenoid current
+        solcur=cpar["value"].data<float>();
+	gotsol=true;
+      } else if (itr->first==3) {
+        // channel 3 is toroid current
+        torcur=cpar["value"].data<float>();
+	gottor=true;
+      }
+    }
+    if (!gotsol || !gottor) {
+      log << MSG::ERROR << "Missing DCS field information: solenoid " <<
+	gotsol << " toroid " << gottor << endreq;
+      return StatusCode::FAILURE;
+    }
+  } else {
+    // fixed current parameters corresponding to hardwired values
+    solcur=m_refSolCur;
+    torcur=m_refTorCur;
+  }
+  log << MSG::INFO << "Obtained currents - Solenoid: " << solcur << 
+    " amps, Toriod: " << torcur << " amps" << endreq;
+
+  // create param object to retrieve configuration from COOL
+  MagFieldParam param;
+  // transfer the parameter type from the one currently in use
+  param.m_NameOfTheSource=m_param.m_NameOfTheSource;
+
+  // obtain the best configuration from COOL
+  // (including currents from HLT if appropriate)
+  if (StatusCode::SUCCESS!=chooseParamFromCOOL(solcur,torcur,param)) {
+    log << MSG::FATAL << "Cannot setup BField parameters from COOL" << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  // check if the change in currents is significant
+  float delsol=param.m_SolCur-m_param.m_SolCur;
+  float deltor=param.m_TorCur-m_param.m_TorCur;
+  if (fabs(delsol)<par_currenttolerance && fabs(deltor)<par_currenttolerance) {
+    // only print if map has not changed to avoid spurious warning
+    if (!newmap) log << MSG::INFO << 
+      "Difference between previous and new currents too small (solenoid "
+        << delsol << ", toriod " << deltor << ")" << endreq;
+    newcur=false;
+  }
+
+  // decide whether to use the new parameters and (re)init the field
+  if (param.m_NameOfTheSource=="COOL" || 
+       param.m_NameOfTheSource=="COOL_HLT") {
+    if (newmap || newcur) {
+      // initialise field with new parameters
+      m_param=param;
+      if (m_param.m_SolenoidField!="") {
+	semiAnSol=99999;
+      } else {
+	semiAnSol=0;
+      }
+      if (StatusCode::SUCCESS==initMagField()) {
+	m_gotcooldata=true;
+	log << MSG::INFO << "Initialised field from " << 
+	  param.m_NameOfTheSource << endreq;
+      } else {
+	log << MSG::ERROR << "Failed to initialise field from " << 
+	  param.m_NameOfTheSource << endreq; 
+	return StatusCode::FAILURE;
+      }
+    } else {
+      // no change of parameters
+      log << MSG::INFO << 
+	"Field update skipped as no significant difference in parameters" <<
+	endreq;
+      m_coolupdated=false;
+    }
+  } else {
+    // not using COOL or COOL_HLT - just compare the COOL parameters with
+    // what is already in use - check for consistency
+    // MagFieldParams does not define an equality operator, just check the
+    // most important paramters explicitly
+    if (!checkTol(m_param.m_dx,param.m_dx) || 
+	!checkTol(m_param.m_dy,param.m_dy) ||
+	!checkTol(m_param.m_dz,param.m_dz) ||
+	!checkTol(m_param.m_dpsi,param.m_dpsi) ||
+	!checkTol(m_param.m_dphi,param.m_dphi) ||
+	!checkTol(m_param.m_dtheta,param.m_dtheta) ||
+      	((!checkTol(m_param.m_dxsol,param.m_dxsol) ||
+      	  !checkTol(m_param.m_dysol,param.m_dysol) ||
+      	  !checkTol(m_param.m_dzsol,param.m_dzsol) ||
+      	  !checkTol(m_param.m_dpsisol,param.m_dpsisol) ||
+      	  !checkTol(m_param.m_dphisol,param.m_dphisol) ||
+      	  !checkTol(m_param.m_dthetasol,param.m_dthetasol)) &&
+	 m_param.m_SolenoidField!="" && param.m_SolenoidField!="") ||
+	m_param.m_NoField!=param.m_NoField ||
+	(m_param.m_NoField=="" &&
+         (m_param.m_NameOfTheFile!=param.m_NameOfTheFile ||
+          m_param.m_SolenoidField!=param.m_SolenoidField ||
+        (m_param.noTiltNoShift!=param.noTiltNoShift && 
+	 m_param.noTiltNoShift!=9999) ||
+	  m_param.doScale!=param.doScale))) {
+      log << MSG::WARNING << "Oracle and COOL parameters DISAGREE!" 
+	  << endreq;
+      // dump out the parameters to see which is different
+      std::ostringstream outperso;
+      log << MSG::INFO << "Parameters read from COOL" << endreq;
+      m_param.printParam(outperso);
+      log << MSG::INFO << outperso.str() << endreq;
+      log << MSG::INFO << "Field filenames: " << param.m_NameOfTheFile << " : "
+	<< param.m_SolenoidField << endreq;
+      log << MSG::INFO << "doScale " << param.doScale << endreq;
+      log << MSG::INFO << "NoField: " << param.m_NoField << endreq;
+      log << MSG::INFO << "CF parameters from Oracle" << endreq;
+    } else {
+      log << MSG::INFO << "Oracle and COOL parameters agree" << endreq;
+    }
+    m_gotcooldata=true;
+  }
+  return StatusCode::SUCCESS;
+}
+
+
+bool MagFieldAthenaSvc::checkTol(const double xo,const double xc) {
+  // check values from Oracle and COOL consistent (or Oracle=9999. and COOL=0)
+  double tol=1.E-3;
+  if (fabs(xo-xc)<tol) return true;
+  if (fabs(xo-9999.)<tol && fabs(xc)<tol) return true;
+  return false;
+}
+
+std::string MagFieldAthenaSvc::decodePath(const std::string& path) {
+  // decode a path name stored in the COOL /GLOBAL/BField/Map folder into 
+  // something ready for PathResolver
+  // only plain file: prefix for now, foresee to add GUID lookup later
+  if (path.substr(0,5)=="file:") {
+    return path.substr(5);
+  } else {
+    // if not recognised, return empty string
+    return "";
+  }
+}
+
+StatusCode MagFieldAthenaSvc::chooseParamFromCOOL(const float reqSolCur,
+				  const float reqTorCur,
+				  MagFieldParam& param) {
+  // choose the best parameters from COOL /GLOBAL/BField/Map folder
+  // given the input currents (which come from COOL or params in HLT case)
+  MsgStream log(messageService(), name());
+
+  // set currents to zero if below tolerance
+  float rSolCur,rTorCur;
+  bool solOff=false;
+  bool torOff=false;
+  if (fabs(reqSolCur)>par_zerotolerance) {
+    rSolCur=reqSolCur;
+  } else {
+   log << MSG::INFO << "Solenoid current only " << reqSolCur 
+		    << " assume zero" << endreq;
+    rSolCur=0.;
+    solOff=true;
+  }
+  if (fabs(reqTorCur)>par_zerotolerance) {
+    rTorCur=reqTorCur;
+  } else {
+   log << MSG::INFO << "Toroid current only " << reqTorCur  
+		    << " assume zero" << endreq;
+    rTorCur=0.;
+    torOff=true;
+  }
+  log << MSG::DEBUG << "Magnet settings: solenoid ON? " << !solOff << 
+    " toroid ON? " << !torOff << endreq;
+
+  // loop over all the available B-field configurations to choose the one
+  // closest to the actual currents being used
+  // step through from 1 in units of 2 (global+solenoid field)
+  CondAttrListCollection::const_iterator itr1,itr2;
+  // first find the number of field slots defined
+  unsigned int nfield=0;
+  itr2=h_coolBFieldMap->end();
+  for (itr1=h_coolBFieldMap->begin();itr1!=itr2;++itr1)
+    if ((itr1->first)>nfield) nfield=itr1->first;
+  unsigned int ibest=0;
+  float bestdist=1.E9;
+  // skip the check if only 1 configuration (nfield=1/2) available
+  if (nfield>0 && nfield<=2) {
+    ibest=1;
+    bestdist=0.;
+    log << MSG::DEBUG << "Only " << nfield << 
+      " sets of configuration data available - take dataslot 1" << endreq;
+  } else {
+    for (unsigned int ifield=1;ifield<=nfield;ifield+=2) {
+      itr1=h_coolBFieldMap->chanAttrListPair(ifield);
+      if (itr1!=h_coolBFieldMap->end()) {
+        const coral::AttributeList& bp1=itr1->second;
+        float torCur=bp1["Current"].data<float>();
+        float solCur=0.;
+        itr2=h_coolBFieldMap->chanAttrListPair(ifield+1);
+        if (itr2!=h_coolBFieldMap->end()) {
+          const coral::AttributeList& bp2=itr2->second;
+          solCur=bp2["Current"].data<float>();
+	}
+	// only consider configurations which have right magnets on/off
+	if (!((solOff && fabs(solCur)>par_zerotolerance) ||
+	      (torOff && fabs(torCur)>par_zerotolerance)) &&
+	    !((!solOff && fabs(solCur)<par_zerotolerance) ||
+	      (!torOff && fabs(torCur)<par_zerotolerance))) {
+	  // evaluate this one based on normalised difference from req currents
+          float dist=fabsf(torCur-rTorCur)/m_refTorCur+
+	             fabsf(solCur-rSolCur)/m_refSolCur;
+          log << MSG::DEBUG << "Field choice index " << ifield << 
+	    " has score " << dist << endreq;
+          if (dist<bestdist) {
+           // new best fieldmap match
+           bestdist=dist;
+           ibest=ifield;
+	  }
+	} else {
+	  log << MSG::DEBUG << "Field choice index " << ifield << 
+	    " has wrong magnet on/off configuration" << endreq;
+	}
+      }
+    }
+  }
+  // check something acceptable was found
+  if (ibest==0) {
+    log << MSG::ERROR << "Did not find any " << m_coolBFieldMap << 
+      " parameters - cannot load field" << endreq;
+    return StatusCode::FAILURE;
+  }
+  if (bestdist>par_maptolerance) {
+    log << MSG::WARNING << "No available field map has close enough currents ("
+	<< bestdist << "," << par_maptolerance << ")" << endreq;
+    if (par_crashmap) {
+      log << MSG::FATAL << "CrashMap enabled - will not setup field" << endreq;
+      return StatusCode::FAILURE;
+    }
+  }
+
+  // now have chosen the best field configuration, set it up in params obj
+  itr1=h_coolBFieldMap->chanAttrListPair(ibest);
+  const coral::AttributeList& bfieldpar=itr1->second;
+  const std::string& ftype=bfieldpar["FieldType"].data<std::string>();
+  log << MSG::INFO << "Chosen BFieldMap dataslot 1 of type: " << ftype << 
+    " from index " << ibest << endreq;
+  bool noTiltNoShift=true;
+  float tol=1.E-4; // tolerance on tilt/shift to be considered non-zero
+  if (ftype=="NOFIELD" || ftype=="OptNOFIELD") {
+    param.m_NoField="NOFIELD";
+    param.m_NameOfTheFile="";
+    param.m_SolenoidField="";
+  } else if (ftype=="GlobalMap" || ftype=="OptGlobalMap") {
+    param.m_dx=bfieldpar["dx"].data<float>();
+    param.m_dy=bfieldpar["dy"].data<float>();
+    param.m_dz=bfieldpar["dz"].data<float>();
+    param.m_dphi=bfieldpar["dphi"].data<float>();
+    param.m_dtheta=bfieldpar["dtheta"].data<float>();
+    param.m_dpsi=bfieldpar["dpsi"].data<float>();
+    if (fabsf(param.m_dx)>tol || fabsf(param.m_dy)>tol ||
+		fabsf(param.m_dz)>tol || fabsf(param.m_dphi)>tol ||
+		fabsf(param.m_dtheta>tol) || fabsf(param.m_dpsi)>tol)
+      noTiltNoShift=false;
+    param.m_NameOfTheFile=
+      decodePath(bfieldpar["FieldFileName"].data<std::string>());
+    param.m_TorCurNom=bfieldpar["Current"].data<float>();
+    param.m_TorCur=rTorCur;
+    log << MSG::INFO << "param.m_TorCurNom from COOL:  " << param.m_TorCurNom << endreq;
+    log << MSG::INFO << "param.m_TorCur    from COOL:  " << param.m_TorCur << endreq;
+    //  Add info and semiAnSol = 0 to be coherent with ORACLE
+    semiAnSol = 0;
+    // check the InfosBMap exists
+    int infosbmag=0;
+    try {
+      infosbmag=bfieldpar["BMAGINFO"].data<int>();
+      log << MSG::INFO << "Found InfosBMag from COOL of " << infosbmag << endreq;
+    }
+    catch (coral::AttributeListException& e) {
+      log << MSG::INFO << "No InfosBMag available, assume -1" << endreq;
+      infosbmag=-1;
+    }
+  } else {
+    log << MSG::ERROR << "Unrecognised field type in position 1: " <<
+      ftype << endreq;
+    return StatusCode::FAILURE;
+  }
+  // now deal with a solenoid field map, if present
+  itr2=h_coolBFieldMap->chanAttrListPair(ibest+1);
+  if (itr2!=h_coolBFieldMap->end()) {
+    const coral::AttributeList& bfieldpar2=itr2->second;
+    const std::string& ftype2=bfieldpar2["FieldType"].data<std::string>();
+    log << MSG::INFO << "Chosen BFieldMap dataslot 2 of type: " << ftype2 << 
+      " from index " << ibest+1 << endreq;
+    if (ftype2=="SolenoidMap" || ftype2=="OptSolenoidMap") {
+      param.m_dxsol=bfieldpar2["dx"].data<float>();
+      param.m_dysol=bfieldpar2["dy"].data<float>();
+      param.m_dzsol=bfieldpar2["dz"].data<float>();
+      param.m_dphisol=bfieldpar2["dphi"].data<float>();
+      param.m_dthetasol=bfieldpar2["dtheta"].data<float>();
+      param.m_dpsisol=bfieldpar2["dpsi"].data<float>();
+      if (fabsf(param.m_dxsol)>tol || fabsf(param.m_dysol)>tol ||
+        fabsf(param.m_dzsol)>tol || fabsf(param.m_dphisol)>tol ||
+        fabsf(param.m_dthetasol>tol) || fabsf(param.m_dpsisol)>tol)
+        noTiltNoShift=false;
+    // solenoid field is stored as resolved path (!)
+      param.m_SolenoidField=PathResolver::find_file(decodePath(
+        bfieldpar2["FieldFileName"].data<std::string>()),"DATAPATH");
+      param.m_SolCurNom=bfieldpar2["Current"].data<float>();
+      param.m_SolCur=rSolCur;
+    } else {
+      log << MSG::ERROR << "Unrecognised field type in position 2: " <<
+	ftype2 << endreq;
+      return StatusCode::FAILURE;
+    }
+  }
+
+  // set the tilt/shift flag according to the parameters retrieved
+  if (ftype!="NOFIELD" && ftype!="OptNOFIELD")
+    param.noTiltNoShift=(noTiltNoShift ? 1 : 0);
+  //
+  //            !!!!  Temporary 29/10/10 start !!!!
+  //   std::string str2 ("20400");
+  // size_t found;
+  // found=param.m_NameOfTheFile.find(str2);
+  // if (found!=std::string::npos){
+  //   log << MSG::INFO << "first '20400' found at: " << int(found) << endreq;
+  //   param.m_TorCurNom = 20400.0;
+  // }
+  // log << MSG::INFO << "param.m_TorCurNon: " << param.m_TorCurNom << endreq;
+  //            !!!!  Temporary 29/10/10 end   !!!!
+  //
+  // check if the field map needs to be scaled
+  param.doScale=
+    ( (param.m_SolCurNom!=0. && 
+       (fabs(param.m_SolCur/param.m_SolCurNom-1.)>par_scaletolerance)) ||
+      (param.m_TorCurNom!=0. && 
+       (fabs(param.m_TorCur/param.m_TorCurNom-1.)>par_scaletolerance)) );
+  if (param.doScale) {
+    // avoid problem when only solenoid is on, and we scale toriod from a 
+    // reference current of zero - in this case set cur/ref to 20500A to avoid
+    // NaN in toriod scaling (instead becomes 20500/20500, avoiding scaling)
+    if (torOff && !solOff && param.m_TorCurNom==0.) {
+      param.m_TorCurNom=m_refTorCur;
+      param.m_TorCur=m_refTorCur;
+    }
+    log << MSG::INFO << "COOL Rescale magnetic fields: Solenoid current "
+      << param.m_SolCur << " amps vs " << param.m_SolCurNom << endreq;
+    log << MSG::INFO << "COOL Rescale magnetic fields: Toroid current " << param.m_TorCur << " amps vs "
+	<< param.m_TorCurNom << " nominal" << endreq;
+  }
+  log << MSG::INFO << "chooseParamFromCOOL" << endreq;
+  return StatusCode::SUCCESS;
+}
+
diff --git a/MagneticField/BFieldAth/src/MagFieldAthenaSvc.h b/MagneticField/BFieldAth/src/MagFieldAthenaSvc.h
new file mode 100755
index 00000000000..9cf143cd690
--- /dev/null
+++ b/MagneticField/BFieldAth/src/MagFieldAthenaSvc.h
@@ -0,0 +1,150 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MAGFIELDATHENASVC
+#define MAGFIELDATHENASVC
+
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "StoreGate/StoreGateSvc.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#include "BFieldCore/MagFieldParam.h" 
+#include "BFieldAth/MagFieldAthena.h"
+#include "BFieldAth/IMagFieldAthenaSvc.h"
+
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+template <class TYPE> class SvcFactory;
+class IGeoModelSvc;
+class IRDBAccessSvc;
+class CondAttrListCollection;
+
+class MagFieldAthenaSvc : public Service , virtual public IMagFieldAthenaSvc {
+
+public:
+///////////////////////////////////
+
+  static const InterfaceID& interfaceID() { return IID_IMagFieldAthenaSvc; }
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface );
+
+  MagFieldAthena* GetMagFieldAthena();
+  // retrieve through COOL callback - to be used in client callback method
+  MagFieldAthena* GetUpdatedMagFieldAthena();
+  // check if field was really updated in callback, to be used in clients
+  bool WasFieldUpdated();
+
+  // Vakho: This method does mag field initialization. It gets called in two
+  //        different ways:
+  //        1. When GeoModelSvc is configured from job options, then initGeoModel
+  //           is called at initialization phase
+  //        2. When GeoModelSvc is configured automaticaly from TagInfo, then
+  //           initGeoModelSvc is registered as callback and is called after GeoModelSvc
+  //           initialization has been done
+  StatusCode initGeoModel(IOVSVC_CALLBACK_ARGS);
+  StatusCode initGeoModel2(IOVSVC_CALLBACK_ARGS);
+  StatusCode updateField(IOVSVC_CALLBACK_ARGS);
+
+  /// templated function for registering a callback
+  template <typename T1>
+  StatusCode regFcn( StatusCode (T1::*fcn)(IOVSVC_CALLBACK_ARGS),
+		      const T1* obj);
+
+  friend class SvcFactory<MagFieldAthenaSvc>;
+
+///////////////////////////////////
+protected:
+  // Standard Constructor
+  MagFieldAthenaSvc(const std::string& name, ISvcLocator* svc);
+
+  // Standard Destructor
+  virtual ~MagFieldAthenaSvc();
+
+///////////////////////////////////
+private:
+
+// private functions
+
+//  get stuff to run
+    void getTagOracle (StatusCode &Sc);
+    void getTagOracle2 (StatusCode &Sc);
+    void getBfieldFileName (const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc);
+    void getBfieldFileName2(const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc);
+    void getBfieldDisplacements (const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc);
+    void getCurrent (const IGeoModelSvc * geoModel, IRDBAccessSvc * accessSvc);
+    bool isThatFileExists( const std::string & );
+    // Vakho: This method performs actuall initialization of the Magnetic field based
+    //        on m_param values
+    const IGeoModelSvc* geoModel;
+    StatusCode initMagField();
+
+    bool checkTol(const double xo, const double xc);
+    std::string decodePath(const std::string& path);
+    StatusCode chooseParamFromCOOL(const float reqSolCur,const float reqTorCur,
+				   MagFieldParam& param);
+
+    // job option parameters
+    MagFieldParam par_param; // managed by PropertySvc
+    std::string m_alreadyReadFile;
+
+    // currents set by HLT framework for online running
+    double par_onlineSolCur;
+    double par_onlineTorCur;
+    bool par_setupcool;  // flag to setup COOL callback infrastructure
+    bool par_usedcs;     // include DCS currents when using COOL
+    float par_scaletolerance; // minimum fractional deviation to scale field
+    float par_zerotolerance; // current below which considered zero (amps)
+    float par_currenttolerance; // absolute change in currents which 
+                                // triggers field update (amps)
+    float par_maptolerance; // maximum acceptable deviation (fractional, S+T)
+                            // between map and real currents to accept map
+    bool par_crashmap; // crash (return FATAL) if acceptable deviation exceeded
+                       // otherwise just print WARNING
+    // fixed parameters
+    const std::string m_coolBFieldMap;
+    const std::string m_coolCurrents;
+    const float m_refSolCur; // refsolenoid and toriod currents for norml
+    const float m_refTorCur;
+
+    // internal variables
+    StoreGateSvc* p_detStore;
+    MagFieldAthena* p_MagFieldAthena; // pointer to BField itself
+    // Datahandles for the conditions data objects
+    const DataHandle<CondAttrListCollection> h_coolBFieldMap;
+    const DataHandle<CondAttrListCollection> h_coolCurrents;
+
+    MagFieldParam m_param; // parameters in use for actual field
+    bool alreadyReadFile; 
+    int semiAnSol;
+
+    bool m_gotcooldata;      // COOL-based field retrieve has been done
+    bool m_coolupdated;      // Last callback actually updated the field
+
+    // counters to count number of retrievals of MagFieldAthena through
+    // old and new interfaces, at initialize and in event loop
+    int m_getbad; // counter number of bad retrievals at initialise, old int
+    int m_getgood; // counter number of good retrieves, old interface
+    int m_getcoolbad; // counter number of bad retrieves with COOL
+    int m_getcoolgood; // counter number of good retrives with COOL
+
+    bool m_useFieldService;
+    ServiceHandle<MagField::IMagFieldSvc> m_fieldService;
+};
+
+template <typename T>
+StatusCode MagFieldAthenaSvc::regFcn(
+     StatusCode (T::*fcn)(IOVSVC_CALLBACK_ARGS),const T* obj) {
+  return p_detStore->regFcn(&MagFieldAthenaSvc::updateField,this,fcn,obj);
+}
+
+
+#endif
+
diff --git a/MagneticField/BFieldAth/src/MagFieldSvcWrapper.cxx b/MagneticField/BFieldAth/src/MagFieldSvcWrapper.cxx
new file mode 100644
index 00000000000..7796f213314
--- /dev/null
+++ b/MagneticField/BFieldAth/src/MagFieldSvcWrapper.cxx
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BFieldAth/MagFieldSvcWrapper.h"
+
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+// Constructor
+MagFieldSvcWrapper::MagFieldSvcWrapper( MagField::IMagFieldSvc& service )
+  : m_service(&service)
+{
+  // copy magnet status from the underlying service
+  setSolenoidOn( m_service->solenoidOn() );
+  setToroidBarrelOn( m_service->toroidOn() );
+  setToroidECTAOn( m_service->toroidOn() );
+  setToroidECTCOn( m_service->toroidOn() );
+  setAllToroidOn( m_service->toroidOn() );
+  setFieldStatusOn( m_service->solenoidOn() && m_service->toroidOn() );
+}
+
+// XYZ[3] in cm -> BXYZ[3] in T
+void MagFieldSvcWrapper::field_tesla_cm(float* XYZ,float* BXYZ) {
+  double xyz[3];
+  for( int i=0;i<3;++i ) xyz[i] = 10.*XYZ[i]; // cm -> mm
+  double bxyz[3];
+  m_service->getField(xyz, bxyz); // mm -> kT
+  for( int i=0;i<3;++i ) BXYZ[i] = 1000.*bxyz[i]; // kT -> T
+}
+
+// XYZ[3] in cm -> BXYZ[12] in T and T/cm
+void MagFieldSvcWrapper::fieldGradient_tesla_cm(float* XYZ,float* BXYZ) {
+  double xyz[3];
+  for( int i=0;i<3;++i ) xyz[i] = 10.*XYZ[i]; // cm -> mm
+  double bxyz[3];
+  double deriv[9];
+  m_service->getField(xyz, bxyz, deriv); // mm -> kT and kT/mm
+  for( int i=0;i<3;++i ) BXYZ[i] = 1000.*bxyz[i]; // kT -> T
+  for( int i=0;i<9;++i ) BXYZ[i+3] = 10000.*deriv[i]; // kT/mm -> T/cm
+}
+
+// XYZ[3] in mm -> BXYZ[3] in kG
+void MagFieldSvcWrapper::field_XYZ_in_mm(float* XYZ,float* BXYZ) {
+  double xyz[3];
+  for( int i=0;i<3;++i ) xyz[i] = XYZ[i]; // mm -> mm
+  double bxyz[3];
+  m_service->getField(xyz, bxyz); // mm -> kT
+  for( int i=0;i<3;++i ) BXYZ[i] = 10000.*bxyz[i]; // kT -> kG
+}
+
+// XYZ[3] in mm -> BXYZ[12] in kG and kG/mm
+void MagFieldSvcWrapper::fieldGradient_XYZ_in_mm(float* XYZ,float* BXYZ) {
+  double xyz[3];
+  for( int i=0;i<3;++i ) xyz[i] = XYZ[i]; // mm -> mm
+  double bxyz[3];
+  double deriv[9];
+  m_service->getField(xyz, bxyz, deriv); // mm -> kT and kT/mm
+  for( int i=0;i<3;++i ) BXYZ[i] = 10000.*bxyz[i]; // kT -> kG
+  for( int i=0;i<9;++i ) BXYZ[i+3] = 10000.*deriv[i]; // kT/mm -> kG/mm
+}
+
+void MagFieldSvcWrapper::whereAmI(float* /*XYZ*/, int& /*iz*/ ){}
+
+const char* MagFieldSvcWrapper::whereAmI(float* /*XYZ*/) { return "here"; }
diff --git a/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_entries.cxx b/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_entries.cxx
new file mode 100755
index 00000000000..9dc1c9be3d2
--- /dev/null
+++ b/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_entries.cxx
@@ -0,0 +1,9 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+#include "../MagFieldAthenaSvc.h"
+
+DECLARE_SERVICE_FACTORY( MagFieldAthenaSvc )
+ 
+DECLARE_FACTORY_ENTRIES(BFieldAth) {
+    DECLARE_SERVICE( MagFieldAthenaSvc )
+}
+ 
diff --git a/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_load.cxx b/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_load.cxx
new file mode 100755
index 00000000000..8409c00f8af
--- /dev/null
+++ b/MagneticField/BFieldAth/src/components/MagFieldAthenaSvc_load.cxx
@@ -0,0 +1,4 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+ 
+LOAD_FACTORY_ENTRIES(BFieldAth)
+ 
-- 
GitLab