From f39cbb39a36ec2d2ac55a5774c3fea5ca892924b Mon Sep 17 00:00:00 2001
From: Dave Casper <dcasper@uci.edu>
Date: Wed, 6 Feb 2019 16:28:15 -0800
Subject: [PATCH] Reimplement AtlasDetDescr package for FASER

---
 .../DetDescrCnvSvc/CMakeLists.txt             |   27 +
 .../DetDescrCnvSvc/DetDescrAddress.h          |   64 +
 .../DetDescrCnvSvc/DetDescrCnvSvc.h           |  119 ++
 .../DetDescrCnvSvc/DetDescrConverter.h        |   63 +
 .../DetDescrCnvSvc/IDetDescrCnvSvc.h          |   46 +
 .../DetDescrCnvSvc/python/DetStoreConfig.py   |   36 +
 .../DetDescrCnvSvc/python/__init__.py         |    2 +
 .../DetDescrCnvSvc/share/DetStore.py          |   25 +
 .../share/DetStore_joboptions.py              |   25 +
 .../DetDescrCnvSvc/src/DetDescrAddress.cxx    |   63 +
 .../DetDescrCnvSvc/src/DetDescrCnvSvc.cxx     |  216 ++++
 .../DetDescrCnvSvc/src/DetDescrConverter.cxx  |  145 +++
 .../src/components/DetDescrCnvSvc_entries.cxx |    4 +
 .../FaserDetDescr/CMakeLists.txt              |   34 +
 .../FaserDetDescr/FaserDetDescrDict.h         |   19 +
 .../FaserDetDescr/FaserDetTechnology.h        |   52 +
 .../FaserDetDescr/FaserDetectorID.h           |  470 +++++++
 .../FaserDetDescr/FaserDetDescr/FaserRegion.h |   42 +
 .../FaserDetDescr/FaserRegionHelper.h         |   35 +
 .../FaserDetDescr/FaserDetDescr/selection.xml |    4 +
 .../FaserDetDescr/doc/packagedoc.h            |   25 +
 .../FaserDetDescr/src/FaserDetectorID.cxx     | 1134 +++++++++++++++++
 .../src/FaserDetectorIDHelper.cxx             |  185 +++
 .../FaserDetDescr/src/FaserDetectorIDHelper.h |   94 ++
 .../FaserDetDescr/src/FaserRegionHelper.cxx   |   28 +
 25 files changed, 2957 insertions(+)
 create mode 100644 DetectorDescription/DetDescrCnvSvc/CMakeLists.txt
 create mode 100644 DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrAddress.h
 create mode 100644 DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrCnvSvc.h
 create mode 100644 DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrConverter.h
 create mode 100644 DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/IDetDescrCnvSvc.h
 create mode 100644 DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
 create mode 100644 DetectorDescription/DetDescrCnvSvc/python/__init__.py
 create mode 100644 DetectorDescription/DetDescrCnvSvc/share/DetStore.py
 create mode 100644 DetectorDescription/DetDescrCnvSvc/share/DetStore_joboptions.py
 create mode 100644 DetectorDescription/DetDescrCnvSvc/src/DetDescrAddress.cxx
 create mode 100644 DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
 create mode 100644 DetectorDescription/DetDescrCnvSvc/src/DetDescrConverter.cxx
 create mode 100644 DetectorDescription/DetDescrCnvSvc/src/components/DetDescrCnvSvc_entries.cxx
 create mode 100644 DetectorDescription/FaserDetDescr/CMakeLists.txt
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetDescrDict.h
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegion.h
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegionHelper.h
 create mode 100644 DetectorDescription/FaserDetDescr/FaserDetDescr/selection.xml
 create mode 100644 DetectorDescription/FaserDetDescr/doc/packagedoc.h
 create mode 100644 DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
 create mode 100644 DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx
 create mode 100644 DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h
 create mode 100644 DetectorDescription/FaserDetDescr/src/FaserRegionHelper.cxx

diff --git a/DetectorDescription/DetDescrCnvSvc/CMakeLists.txt b/DetectorDescription/DetDescrCnvSvc/CMakeLists.txt
new file mode 100644
index 00000000..4c554ff2
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/CMakeLists.txt
@@ -0,0 +1,27 @@
+################################################################################
+# Package: DetDescrCnvSvc
+################################################################################
+
+# Declare the package name:
+atlas_subdir( DetDescrCnvSvc )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          GaudiKernel
+                          PRIVATE
+                          Control/StoreGate )
+
+# Component(s) in the package:
+atlas_add_library( DetDescrCnvSvcLib
+                   src/*.cxx
+                   PUBLIC_HEADERS DetDescrCnvSvc
+                   LINK_LIBRARIES GaudiKernel StoreGateLib SGtests )
+
+atlas_add_component( DetDescrCnvSvc
+                     src/components/*.cxx
+                     LINK_LIBRARIES GaudiKernel StoreGateLib SGtests DetDescrCnvSvcLib )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+atlas_install_joboptions( share/*.py )
+
diff --git a/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrAddress.h b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrAddress.h
new file mode 100644
index 00000000..a2fb9587
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrAddress.h
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//====================================================================
+//	DetDescrAddress.h
+//--------------------------------------------------------------------
+//
+//	Package    : DetDescrCnvSvc 
+//
+//  Description:     Definition of detector description address class
+//                   This class for the moment has just the
+//                   funtionality of a GenericAddress. It provides the
+//                   conversion service type but nothing more. It thus
+//                   just holds the clid and the class name. It is
+//                   created for later expansion.
+//	Author     : RD Schaffer
+//====================================================================
+#ifndef DETDESCRCNVSVC_DETDESCRADDRESS_H
+#define DETDESCRCNVSVC_DETDESCRADDRESS_H
+
+// C/C++ include files
+#include <string>
+
+// Framework include files
+#include "GaudiKernel/Kernel.h"
+#include "GaudiKernel/GenericAddress.h"
+#include "GaudiKernel/StatusCode.h"
+
+extern long DetDescr_StorageType;
+
+class DetDescrAddress   : public GenericAddress   {
+public:
+
+
+    /// Standard Destructor
+    virtual ~DetDescrAddress() {}; //doesn't own event
+
+    /// Standard Constructor
+    DetDescrAddress(const CLID& clid, const std::string& fname,
+		    const std::string& cname );
+
+    DetDescrAddress(const CLID& clid ) ;
+
+    const std::string& payload() const;
+
+    /// write technology-specific part of address to string  
+    StatusCode  toString(std::string& refString) const;
+
+    /// initialize technology-specific part of IOA from stringifiedIOA
+    StatusCode  fromString(const std::string& stringifiedIOA);
+
+
+private:
+
+    std::string  m_payload;
+
+};
+#endif 
+
+
+
+
+
diff --git a/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrCnvSvc.h b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrCnvSvc.h
new file mode 100644
index 00000000..23582c8b
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrCnvSvc.h
@@ -0,0 +1,119 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef DETDESCRCNVSVC_DETDESCRCNVSVC_H
+#define DETDESCRCNVSVC_DETDESCRCNVSVC_H
+
+#include "GaudiKernel/ConversionSvc.h"
+
+// Forward declarations
+template <class TYPE> class SvcFactory;
+
+class IOpaqueAddress;
+class StatusCode;
+class ActiveStoreSvc;
+class StoreGateSvc;
+//  namespace SG {
+//    class TransientAddress;
+//  }
+
+//  class DetDescrCnvSvc : 
+//      public ConversionSvc,
+//      public virtual IAddressProvider {
+
+class DetDescrCnvSvc : public ConversionSvc	{
+    /// Allow the factory class access to the constructor
+    friend class SvcFactory<DetDescrCnvSvc>;
+public:
+
+    /// Initialize the service.
+    virtual StatusCode initialize();
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface);
+
+    /// Add new address to the Detector Store
+    virtual StatusCode addToDetStore(const CLID& clid, const std::string& name) const;
+
+    /// Basic create address
+    virtual StatusCode createAddress( long svc_type,
+				      const CLID& clid,
+				      const std::string* par, 
+				      const unsigned long* ip,
+				      IOpaqueAddress*& refpAddress);
+
+    /// Create address from string form
+    virtual StatusCode createAddress( long svc_type, 
+				      const CLID& clid, 
+				      const std::string& refAddress,
+				      IOpaqueAddress*& refpAddress);
+
+    /// Convert address to string form
+    virtual StatusCode convertAddress( const IOpaqueAddress* pAddress,
+				       std::string& refAddress);
+    
+    /// Provide access to Detector Store
+    StoreGateSvc * 	detStore() const;
+  
+//      /// AddressProvider interface
+//      typedef IAddressProvider::tadList tadList;
+//      typedef IAddressProvider::tadListIterator tadListIterator;
+  
+//      /// get all addresses that the provider wants to preload in SG
+//      /// maps before the event loop
+//      virtual StatusCode preLoadAddresses( StoreID::type storeID,
+//  					 tadList& list );
+    
+//      /// get all new addresses from Provider for this Event.
+//      virtual StatusCode loadAddresses( StoreID::type storeID,
+//  				      tadList& list );
+      
+//      /// update a transient Address
+//      virtual StatusCode updateAddress( SG::TransientAddress* tad );
+
+
+    /**@name: Object implementation     */
+    //@{
+    /// Standard Constructor
+    DetDescrCnvSvc(const std::string& name, ISvcLocator* svc);
+
+    /// Standard Destructor
+    virtual ~DetDescrCnvSvc();
+
+
+private:
+
+    StatusCode fillTDSRefs(); 
+
+//      SG::TransientAddress* loadAddress(const CLID& clid, 
+//  				      const std::string& key);
+
+    void initTDSItems(); 
+
+    StoreGateSvc *			m_detStore;
+    StringArrayProperty			m_detMgrs;
+    StringArrayProperty			m_detNodes;
+    BooleanProperty 			m_decodeIdDict;
+    BooleanProperty 			m_idDictFromRDB;
+    StringProperty			m_idDictName;
+    StringProperty			m_idDictGlobalTag;
+    StringProperty			m_idDictFASERName;
+    StringProperty			m_idDictScintName;
+    // StringProperty			m_idDictInDetName;
+    // StringProperty			m_fullAtlasNeighborsName;
+    BooleanProperty 			m_fromRoot;
+    BooleanProperty 			m_fromNova;
+    BooleanProperty 			m_detElemsfromDetNodes;
+    BooleanProperty 			m_compact_ids_only;
+    BooleanProperty 			m_do_checks;
+    BooleanProperty 			m_do_neighbours;
+};
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrConverter.h b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrConverter.h
new file mode 100644
index 00000000..d272d08e
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/DetDescrConverter.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Detector description conversion service package
+ -----------------------------------------------
+ ***************************************************************************/
+
+//<doc><file>	$Id: DetDescrConverter.h,v 1.6 2008-12-14 02:24:44 ssnyder Exp $
+//<version>	$Name: not supported by cvs2svn $
+
+#ifndef DETDESCRCNVSVC_DETDESCRCONVERTER_H
+# define DETDESCRCNVSVC_DETDESCRCONVERTER_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "GaudiKernel/Converter.h"
+
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+class DetDescrCnvSvc;
+class DetDescrAddress;
+class DataObject;
+class StoreGateSvc;
+
+// Abstract factory to create the converter
+template <class TYPE> class CnvFactory;
+
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+class DetDescrConverter: public Converter {
+
+public:
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj) = 0;
+    virtual StatusCode fillObjRefs(IOpaqueAddress* pAddr, DataObject* pObj);
+    virtual StatusCode createRep(DataObject* pObj, IOpaqueAddress*& pAddr);
+    virtual StatusCode fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj);
+
+    /// Storage type for all DetDescrConverters
+    static long storageType();
+
+protected:
+
+    DetDescrConverter(const CLID& myCLID, ISvcLocator* svcloc);
+//      StatusCode addToDetStore(const CLID& clid, const std::string& name) const;
+
+    /// Provide access to Detector Store
+    StoreGateSvc * 	detStore() const;
+    
+
+private:
+    DetDescrCnvSvc* 	m_cnvSvc;
+    //const CLID       	m_CLID;
+};
+
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+#endif // DETDESCRCNVSVC_DETDESCRCONVERTER_H
diff --git a/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/IDetDescrCnvSvc.h b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/IDetDescrCnvSvc.h
new file mode 100644
index 00000000..a93ba30c
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/DetDescrCnvSvc/IDetDescrCnvSvc.h
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Detector description conversion service package
+ -----------------------------------------------
+ ***************************************************************************/
+
+//<doc><file>	$Id: IDetDescrCnvSvc.h,v 1.1 2002-07-10 13:44:41 schaffer Exp $
+//<version>	$Name: not supported by cvs2svn $
+
+#ifndef DETDESCRCNVSVC_IDETDESCRCNVSVC_H
+# define DETDESCRCNVSVC_IDETDESCRCNVSVC_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/IConversionSvc.h"
+#include "GaudiKernel/StatusCode.h"
+#include <string>
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+static const InterfaceID IID_IDetDescrCnvSvc(340,0,0) ;
+
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+class IDetDescrCnvSvc : virtual public IConversionSvc
+{
+
+public:
+    
+    virtual StatusCode addToDetStore(const CLID& clid, std::string& name) = 0;
+
+};
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+#endif // DETDESCRCNVSVC_IDETDESCRCNVSVC_H
+
diff --git a/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py b/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
new file mode 100644
index 00000000..dfd14b6e
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+#
+# Joboptions for bootstrapping the loading of the DetectorStore with
+# the DetDescrCnvSvc
+#
+
+def _setupDetStoreConfig():
+    from AthenaCommon.AppMgr import theApp
+    from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+
+    # first, make sure we create a DetectorStore
+    import AthenaCommon.AtlasUnixStandardJob
+    #theApp.CreateSvc += [ svcMgr.DetectorStore.getFullName() ]
+
+    # now configure the Detector Description converter service
+    from DetDescrCnvSvc.DetDescrCnvSvcConf import DetDescrCnvSvc
+    # Create DetDescrCnvSvc and add to SvcMgr
+    # Specify primary Identifier dictionary to be used
+    svcMgr += DetDescrCnvSvc(IdDictName = "IdDictParser/FASER_IDS.xml")
+
+    #theApp.CreateSvc += [ svcMgr.DetDescrCnvSvc.getFullName() ]
+    svcMgr.EventPersistencySvc.CnvServices += [ "DetDescrCnvSvc" ]
+
+    # Always include the IdDict jobOptions
+    from AthenaCommon.Include import include
+    include( "IdDictDetDescrCnv/IdDictDetDescrCnv_joboptions.py" )
+
+    pass
+
+# run this function at module's load
+_setupDetStoreConfig()
+
+# avoid running this method multiple times
+del _setupDetStoreConfig
+
diff --git a/DetectorDescription/DetDescrCnvSvc/python/__init__.py b/DetectorDescription/DetDescrCnvSvc/python/__init__.py
new file mode 100644
index 00000000..74583d36
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/python/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
diff --git a/DetectorDescription/DetDescrCnvSvc/share/DetStore.py b/DetectorDescription/DetDescrCnvSvc/share/DetStore.py
new file mode 100644
index 00000000..3a839701
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/share/DetStore.py
@@ -0,0 +1,25 @@
+#
+# Joboptions for bootstrapping the loading of the DetectorStore with
+# the DetDescrCnvSvc
+#
+
+# Adds and instantiates the DetDescrCnvSvc service. It is assumed that
+# a view of the application manager is available as 'theApp'
+
+
+from AthenaCommon.AppMgr import theApp
+theApp.Dlls   += [ 'DetDescrCnvSvc' ]
+theApp.ExtSvc += [ 'DetDescrCnvSvc' ]
+
+# Create service and add to list of conversion services
+#
+#  NOTE: the following does not yet work for the detector store
+# theApp.ExtSvc += { "DetPersistencySvc/DetectorPersistencySvc", 
+#  		      "DetDescrCnvSvc" };
+#DetectorPersistencySvc.CnvServices += { "DetDescrCnvSvc" };
+DetDescrCnvSvc = Service( "DetDescrCnvSvc" )
+EventPersistencySvc.CnvServices = [ "DetDescrCnvSvc" ]
+
+# Specify primary Identifier dictionary to be used
+DetDescrCnvSvc.IdDictName = "IdDictParser/FASER_IDS.xml";
+
diff --git a/DetectorDescription/DetDescrCnvSvc/share/DetStore_joboptions.py b/DetectorDescription/DetDescrCnvSvc/share/DetStore_joboptions.py
new file mode 100644
index 00000000..172eac07
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/share/DetStore_joboptions.py
@@ -0,0 +1,25 @@
+#
+# Joboptions for bootstrapping the loading of the DetectorStore with
+# the DetDescrCnvSvc
+#
+# DLLs 
+theApp.Dlls += [ "DetDescrCnvSvc" ]
+
+# Must create the service
+theApp.CreateSvc += [ "DetDescrCnvSvc" ]
+
+# Set DetDescrCnvSvc to be a proxy/address provider
+#ProxyProviderSvc.ProviderNames += { "DetDescrCnvSvc" };
+EventPersistencySvc = Service( "EventPersistencySvc" )
+EventPersistencySvc.CnvServices += [ "DetDescrCnvSvc" ]
+
+# Specify primary Identifier dictionary to be used
+DetDescrCnvSvc = Service( "DetDescrCnvSvc" )
+DetDescrCnvSvc.IdDictName = "IdDictParser/FASER_IDS.xml"
+
+# Specify the tag to be used
+# DetDescrCnvSvc.IdDictGlobalTag = "initial_layout"
+
+# Always include the IdDict jobOptions
+include( "IdDictDetDescrCnv/IdDictDetDescrCnv_joboptions.py" )
+
diff --git a/DetectorDescription/DetDescrCnvSvc/src/DetDescrAddress.cxx b/DetectorDescription/DetDescrCnvSvc/src/DetDescrAddress.cxx
new file mode 100644
index 00000000..bbff6ef7
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/src/DetDescrAddress.cxx
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//====================================================================
+//	DetDescrAddress implementation
+//--------------------------------------------------------------------
+//
+//	Package    : DetDescrCnvSvc
+//
+//  Description:     Detector description address implementation
+//
+//	Author     : RD Schaffer
+//      created    : June 2002
+//  History    :
+//====================================================================
+
+//own 
+#include "DetDescrCnvSvc/DetDescrAddress.h"
+
+// Framework include files
+#include "GaudiKernel/GenericAddress.h"
+#include "GaudiKernel/MsgStream.h"
+
+// Externals
+extern long DetDescr_StorageType;
+
+
+/// Standard Constructor
+DetDescrAddress::DetDescrAddress(const CLID& clid, 
+const std::string& fname , const std::string& cname)
+ : GenericAddress(DetDescr_StorageType, clid,fname,cname)
+{
+}
+
+DetDescrAddress::DetDescrAddress(const CLID& clid) 
+  : GenericAddress(DetDescr_StorageType, clid,"","")
+{
+
+}
+
+const std::string& 
+DetDescrAddress::payload() const
+{
+    return m_payload;
+}
+
+StatusCode 
+DetDescrAddress::toString(std::string& refString) const
+{
+    refString += m_payload;
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+
+StatusCode
+DetDescrAddress::fromString(const std::string& stringifiedIOA)
+{
+    m_payload = stringifiedIOA;
+    return StatusCode::SUCCESS;
+}
+
diff --git a/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
new file mode 100644
index 00000000..a8d224a0
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
@@ -0,0 +1,216 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Include files
+#include "DetDescrCnvSvc/DetDescrCnvSvc.h"
+#include "DetDescrCnvSvc/IDetDescrCnvSvc.h"
+//#include "AthenaServices/AthenaConversionSvc.h"
+#include "DetDescrCnvSvc/DetDescrAddress.h"
+
+
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IConversionSvc.h"
+#include "GaudiKernel/IConverter.h"
+#include "GaudiKernel/IDataSelector.h"
+#include "GaudiKernel/IOpaqueAddress.h"
+
+#include "StoreGate/StoreGate.h"
+//  #include "SGTools/TransientAddress.h"
+
+//External definitions
+long DetDescr_StorageType=0x44;
+
+//-------------------------------------------------------------------------
+
+/// Standard constructor
+DetDescrCnvSvc::DetDescrCnvSvc(const std::string& name, ISvcLocator* svc)
+        :
+        ConversionSvc( name, svc, DetDescr_StorageType),
+        m_detStore(0),
+        m_decodeIdDict(true),
+        m_idDictFromRDB(false),
+        m_fromRoot(false),
+        m_fromNova(false),
+        m_detElemsfromDetNodes(false),
+        m_compact_ids_only(false),
+        m_do_checks(false),
+        m_do_neighbours(true)
+{
+    declareProperty("DetectorManagers",            m_detMgrs);
+    declareProperty("DetectorNodes",   	           m_detNodes );
+    declareProperty("DecodeIdDict",	           m_decodeIdDict );
+    declareProperty("IdDictName",   	           m_idDictName );
+    declareProperty("IdDictFromRDB",   	           m_idDictFromRDB );
+    declareProperty("IdDictGlobalTag",             m_idDictGlobalTag );
+    declareProperty("ReadFromROOT",   	           m_fromRoot );
+    declareProperty("ReadFromNova",   	           m_fromNova );
+    declareProperty("InitDetElemsFromGeoModel",    m_detElemsfromDetNodes);
+    declareProperty("CompactIDsOnly",              m_compact_ids_only);
+    declareProperty("DoIdChecks",                  m_do_checks);
+    declareProperty("DoInitNeighbours",            m_do_neighbours);
+
+    declareProperty("FaserIDFileName",             m_idDictFASERName);
+    // declareProperty("InDetIDFileName",             m_idDictInDetName);
+    declareProperty("ScintIDFileName",               m_idDictScintName);
+}
+
+//-------------------------------------------------------------------------
+
+/// Standard Destructor
+DetDescrCnvSvc::~DetDescrCnvSvc()   {
+}
+
+//-------------------------------------------------------------------------
+
+/// Identify interfaces to which this service is responsive
+StatusCode
+DetDescrCnvSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
+    if ( riid == IConversionSvc::interfaceID() )  {
+        *ppvInterface = (IConversionSvc*)this;
+    }
+    else if ( riid == IDetDescrCnvSvc::interfaceID() )  {
+        *ppvInterface = (IDetDescrCnvSvc*)this;
+    }
+    else   {
+        return ConversionSvc::queryInterface( riid, ppvInterface );
+    }
+    addRef();
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+
+/// Initialize the service.
+StatusCode
+DetDescrCnvSvc::initialize()     {
+
+    MsgStream log(msgSvc(),name());
+    StatusCode status = ConversionSvc::initialize();
+    if (status.isFailure()) {
+	log << MSG::FATAL << "Unable to initialize ConversionSvc !" << endmsg;
+	return StatusCode::FAILURE;
+    }
+
+    log << MSG::INFO << " initializing " <<endmsg ;
+
+    // get DetectorStore service
+    status = service("DetectorStore", m_detStore);
+    if (status.isFailure()) {
+	log << MSG::FATAL << "DetectorStore service not found !" << endmsg;
+	return StatusCode::FAILURE;
+    } else {
+	log << MSG::INFO << "Found DetectorStore service" << endmsg;
+    }
+
+    // fill in the Addresses for Transient Detector Store objects
+
+    log << MSG::INFO << " filling proxies for detector managers " <<endmsg ;
+
+    // IdDict:
+    status =  addToDetStore(2411, "IdDict");
+    if (status != StatusCode::SUCCESS) return status;
+
+    // IdHelpers
+    status =  addToDetStore(125694213, "FaserID");
+    if (status != StatusCode::SUCCESS) return status;
+    // status =  addToDetStore(2516, "ScintID");
+    // if (status != StatusCode::SUCCESS) return status;
+    // status =  addToDetStore(2517, "SCT_ID");
+    // if (status != StatusCode::SUCCESS) return status;
+
+    return status;
+}
+
+//-------------------------------------------------------------------------
+
+StoreGateSvc *
+DetDescrCnvSvc::detStore() const
+{
+    return (m_detStore);
+}
+
+//-------------------------------------------------------------------------
+
+/// Create a Generic address using explicit arguments to identify a single object.
+StatusCode DetDescrCnvSvc::createAddress(long            /* svc_type */,
+					 const CLID&          /* clid     */,
+					 const std::string*   /* par      */,
+					 const unsigned long* /* ip       */,
+					 IOpaqueAddress*& refpAddress)    {
+    refpAddress = 0;
+    return StatusCode::FAILURE;
+}
+
+//-------------------------------------------------------------------------
+
+StatusCode DetDescrCnvSvc::createAddress( long /* svc_type */,
+					  const CLID& clid,
+					  const std::string& refAddress,
+					  IOpaqueAddress*& refpAddress)
+{
+    try {
+	refpAddress = new DetDescrAddress(clid);
+	DetDescrAddress* ddAddr;
+	ddAddr = dynamic_cast<DetDescrAddress*> (refpAddress);
+	if(!ddAddr) {
+	    MsgStream log(msgSvc(),name());
+	    log << MSG::FATAL << "Could not cast to DetDescrAddress." << endmsg;
+	    return StatusCode::FAILURE;
+	}
+	ddAddr->fromString(refAddress);
+    }
+    catch(...) {
+	refpAddress = 0;
+    }
+    return (refpAddress != 0) ? StatusCode::SUCCESS : StatusCode::FAILURE;
+}
+
+//-------------------------------------------------------------------------
+
+StatusCode DetDescrCnvSvc::convertAddress( const IOpaqueAddress* pAddress,
+                                           std::string& refAddress)
+{
+  const DetDescrAddress* addr = dynamic_cast<const DetDescrAddress*>(pAddress);
+  if (!addr) return StatusCode::FAILURE;
+  return addr->toString(refAddress);
+}
+
+
+//-------------------------------------------------------------------------
+
+StatusCode
+DetDescrCnvSvc::addToDetStore(const CLID& clid, const std::string& name) const
+{
+
+    MsgStream log(msgSvc(), "DetDescrCnvSvc");
+
+    // Based on input parameters, create StoreGate proxies with
+    // DetDescrAddresses in the detector store for the different
+    // detectors.
+
+    // fill in the Addresses for Transient Detector Store objects
+
+    DetDescrAddress * addr;
+    addr  = new DetDescrAddress(clid, name, name);
+    StatusCode status = m_detStore->recordAddress(addr);
+    if (status != StatusCode::SUCCESS) {
+	log << MSG::INFO
+	    << " unable to fill address for " << (*addr->par())
+	    << " with CLID " << addr->clID()
+	    << " and storage type " << addr->svcType()
+	    << " to detector store " <<endmsg ;
+	return StatusCode::FAILURE;
+    }
+    else {
+	unsigned int st = addr->svcType();
+	log << MSG::INFO
+	    << " filling address for " << (*addr->par())
+	    << " with CLID " << addr->clID()
+	    << " and storage type " << st
+	    << " to detector store " <<endmsg ;
+    }
+    return status;
+}
+
diff --git a/DetectorDescription/DetDescrCnvSvc/src/DetDescrConverter.cxx b/DetectorDescription/DetDescrCnvSvc/src/DetDescrConverter.cxx
new file mode 100644
index 00000000..f4427802
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/src/DetDescrConverter.cxx
@@ -0,0 +1,145 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Detector description conversion service package
+ -----------------------------------------------
+ ***************************************************************************/
+
+//<doc><file>	$Id: DetDescrConverter.cxx,v 1.6 2008-12-14 02:24:44 ssnyder Exp $
+//<version>	$Name: not supported by cvs2svn $
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "DetDescrCnvSvc/DetDescrConverter.h"
+#include "DetDescrCnvSvc/DetDescrAddress.h"
+#include "DetDescrCnvSvc/DetDescrCnvSvc.h"
+#include "GaudiKernel/MsgStream.h"
+
+//<<<<<< PRIVATE DEFINES                                                >>>>>>
+//<<<<<< PRIVATE CONSTANTS                                              >>>>>>
+//<<<<<< PRIVATE TYPES                                                  >>>>>>
+//<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
+//<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
+//<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
+//<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
+
+StatusCode 
+DetDescrConverter::initialize()
+{
+    // Just call parent initialize
+    return Converter::initialize();
+}
+
+StatusCode 
+DetDescrConverter::finalize()
+{
+    // Just call parent finalize
+    return Converter::finalize();
+}
+
+
+StatusCode
+DetDescrConverter::fillObjRefs(IOpaqueAddress* /*pAddr*/, DataObject* /*pObj*/)
+{
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+DetDescrConverter::createRep(DataObject* /*pObj*/, IOpaqueAddress*& /*pAddr*/)
+{
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+DetDescrConverter::fillRepRefs(IOpaqueAddress* /*pAddr*/, DataObject* /*pObj*/)
+{
+    return StatusCode::SUCCESS;
+}
+
+long
+DetDescrConverter::storageType()
+{
+    return DetDescr_StorageType;
+}
+
+//  StatusCode 
+//  DetDescrConverter::addToDetStore(const CLID& clid, const std::string& name) const
+//  {
+
+//      StatusCode status = StatusCode::SUCCESS;
+//      MsgStream log(messageService(), "DetDescrConverter");
+//      log << MSG::DEBUG << "in addToDetStore" << endmsg;
+
+//      if(!m_cnvSvc) {
+//  	log << MSG::INFO << " Unable to add address for " << name 
+//  	    << " with CLID " << clid 
+//  	    << " to detector store " <<endmsg;
+//  	return StatusCode::FAILURE;
+//      }
+//      else {
+//  	m_cnvSvc->addToDetStore(clid, name);
+//      }
+//      return status;
+//  }
+
+
+//  d_Ref_Any
+//  DetDescrConverter::getRef(IOpaqueAddress* pAddr) const {
+//      d_Ref_Any retVal;
+//      DetDescrAddress *nAddr = dynamic_cast<DetDescrAddress*>(pAddr);
+//      if (0 != nAddr) {
+//          nAddr->getRef(retVal);
+//  // check for Gaudi NULL (different than ODMG NULL) here...
+//          if (65535==*((unsigned short*)(&retVal))) {
+//              retVal.clear();
+//          }
+//      }
+//      return retVal;
+//  }
+
+//  DetDescrAddress*
+//  DetDescrConverter::newDetDescrAddress(const d_Ref_Any& outRef) const {
+//      return new DetDescrAddress(m_CLID, "", "", outRef);
+//  }
+
+//  d_Ref_Any
+//  DetDescrConverter::where() const {
+//      return m_cnvSvc->getClustering(m_CLID);
+//  }
+
+DetDescrConverter::DetDescrConverter(const CLID& myCLID, ISvcLocator* svcloc) :
+    Converter(DetDescr_StorageType, myCLID, svcloc)
+    //m_CLID(myCLID)
+{
+
+    IInterface* toCnvSvc = 0;
+    m_cnvSvc = 0;
+    StatusCode status = serviceLocator()
+      ->getService("DetDescrCnvSvc",
+                   IConversionSvc::interfaceID(),
+                   toCnvSvc);
+    if (status.isSuccess()) {
+	m_cnvSvc = dynamic_cast<DetDescrCnvSvc*>(toCnvSvc);
+    }
+    if (0 == m_cnvSvc) {
+	// cout<<"DMM:  ERROR--converter could not find DetDescrCnvSvc"<<endl;
+    }
+}
+
+
+
+/// Provide access to Detector Store
+StoreGateSvc * 	DetDescrConverter::detStore() const
+{
+    if(m_cnvSvc) {
+	return (m_cnvSvc->detStore());
+    }
+    else {
+	return (0);
+    }
+}
+
diff --git a/DetectorDescription/DetDescrCnvSvc/src/components/DetDescrCnvSvc_entries.cxx b/DetectorDescription/DetDescrCnvSvc/src/components/DetDescrCnvSvc_entries.cxx
new file mode 100644
index 00000000..5c89829e
--- /dev/null
+++ b/DetectorDescription/DetDescrCnvSvc/src/components/DetDescrCnvSvc_entries.cxx
@@ -0,0 +1,4 @@
+#include "DetDescrCnvSvc/DetDescrCnvSvc.h"
+
+DECLARE_COMPONENT( DetDescrCnvSvc )
+
diff --git a/DetectorDescription/FaserDetDescr/CMakeLists.txt b/DetectorDescription/FaserDetDescr/CMakeLists.txt
new file mode 100644
index 00000000..c8572d14
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/CMakeLists.txt
@@ -0,0 +1,34 @@
+################################################################################
+# Package: FaserDetDescr
+################################################################################
+
+# Declare the package name:
+atlas_subdir( FaserDetDescr )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/AthenaKernel
+                          DetectorDescription/IdDict
+                          DetectorDescription/Identifier
+                          PRIVATE
+                          GaudiKernel )
+
+# External dependencies:
+find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
+
+# Component(s) in the package:
+atlas_add_library( FaserDetDescr
+                   src/FaserDetectorID.cxx
+                   src/FaserDetectorIDHelper.cxx
+                   src/FaserRegionHelper.cxx
+                   PUBLIC_HEADERS FaserDetDescr
+                   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} IdDict Identifier AthenaKernel
+                   PRIVATE_LINK_LIBRARIES GaudiKernel )
+
+atlas_add_dictionary( FaserDetDescrDict
+                      FaserDetDescr/FaserDetDescrDict.h
+                      FaserDetDescr/selection.xml
+                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+                      LINK_LIBRARIES ${ROOT_LIBRARIES} IdDict Identifier GaudiKernel FaserDetDescr )
+
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetDescrDict.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetDescrDict.h
new file mode 100644
index 00000000..4e359721
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetDescrDict.h
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserDetDescrDict.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERDETDESCR_FASERDETDESCRDICT_H
+#define FASERDETDESCR_FASERDETDESCRDICT_H 1
+
+#include "FaserDetDescr/FaserRegion.h"
+
+namespace FaserDetDescr {
+   // Athena namespace autoloading trigger for ROOT6
+   struct ROOT6_NamespaceAutoloadHook{};
+}
+
+#endif // FASERDETDESCR_FASERDETDESCRDICT_H
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
new file mode 100644
index 00000000..2a18fa9e
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserDetTechnology.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERDETDESCR_FASERDETTECHNOLOGY_H
+#define FASERDETDESCR_FASERDETTECHNOLOGY_H 1
+
+#include <assert.h>
+
+// use these macros to check a given FaserDetTechnology for its validity
+
+#define validFaserDetTechnology(detTechn) ( (detTechn<FaserDetDescr::fNumFaserDetTechnologies) && (detTechn>=FaserDetDescr::fFirstFaserDetTechnology) )
+#define assertFaserDetTechnology(detTechn) ( assert(validFaserDetTechnology(detTechn)) )
+
+namespace FaserDetDescr {
+
+ /** @enum FaserDetTechnology
+   
+     A simple enum of FASER detector technologies.
+
+   */
+
+   enum FaserDetTechnology {       
+        // Unset
+            fUndefined                  = 0,
+        // first Geometry element in enum, used in e.g. loops
+            fFirstFaserDetTechnology    = 1,
+        // Scintillator
+            fFirstFaserScintTechnology  = 1,
+            fFaserVeto                  = 1,
+            fFaserTrigger               = 2,
+            fFaserPreshower             = 3,
+            fLastFaserScintTechnology   = 3,
+        // Tracker
+            fFirstFaserTrackerTechnology = 4,
+            fFaserSCT                    = 4,
+            fLastFaserTrackerTechnology  = 4,
+        // Calorimeter
+            fFirstFaserCaloTechnology    = 5,
+            fFaserECAL                   = 5,
+            fLastFaserCaloTechnology     = 5,
+        // number of defined detector technologies
+            fNumFaserDetTechnologies    = 6
+   };
+
+} // end of namespace
+
+#endif // FASERDETDESCR_FASERDETTECHNOLOGY
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
new file mode 100644
index 00000000..b26a92c5
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
@@ -0,0 +1,470 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef FASERDETDESCR_FASERDETECTORID_H
+#define FASERDETDESCR_FASERDETECTORID_H
+/**
+ * @file FaserDetectorID.h
+ *
+ * @brief This class provides an interface to generate or decode an
+ *   identifier for the upper levels of the detector element
+ *   hierarchy, i.e. Faser, the detector systems and detector
+ *   subsystems. As well general "print out" methods are provide for
+ *   all detector systems. All id helper classes derive from this
+ *   class. This class also provides access to the version tags of the
+ *   id dictionaries used by the helper.
+ *
+ * @author RD Schaffer <R.D.Schaffer@cern.ch>
+ *
+ * $Id: AtlasDetectorID.h,v 1.38 2007-02-23 09:33:30 prieur Exp $
+ * Modified for FASER
+ */
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "Identifier/Identifier.h"
+#include "Identifier/IdContext.h"
+#include "Identifier/IdHelper.h"
+#include "Identifier/Range.h"
+#include "IdDict/IdDictFieldImplementation.h"
+#include "FaserDetTechnology.h"
+#include "AthenaKernel/CLASS_DEF.h"
+#include <string>
+#include <vector>
+
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+class IdDictDictionary;
+class FaserDetectorIDHelper;
+
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+
+/**
+ * @class FaserDetectorID
+ *   
+ * @brief This class provides an interface to generate or decode an
+ *   identifier for the upper levels of the detector element
+ *   hierarchy, i.e. Faser, the detector systems and detector
+ *   subsystems. As well general "print out" methods are provide for
+ *   all detector systems. All id helper classes derive from this
+ *   class. This class also provides access to the version tags of the
+ *   id dictionaries used by the helper.
+ **/
+
+class FaserDetectorID : public IdHelper
+{
+public:
+    
+    /// @name strutors
+    //@{
+    FaserDetectorID();
+    FaserDetectorID(const FaserDetectorID& other);
+    ~FaserDetectorID(void);
+    FaserDetectorID& operator= (const FaserDetectorID& other);
+    //@}
+    
+    /// @name Detector system ids
+    //@{
+    /// Detector systems:
+    Identifier          scint           (void) const;
+    Identifier          tracker         (void) const;
+    Identifier          calo            (void) const;
+    //@}
+
+    /// @name Scintillator subsystem ids
+    //@{
+    Identifier          veto            (void) const;
+    Identifier          trigger         (void) const;
+    Identifier          preshower       (void) const;
+    //@}
+
+    /// @name Tracker subsystem ids
+    //@{
+    Identifier          sct             (void) const;
+    //@}
+
+    /// @name Calorimeter subsystem ids
+    //@{
+    Identifier          ecal            (void) const;
+    //@}
+
+    /// @name Contexts to provide id length - e.g. for use in generic decoding
+    //@{
+    /// IdContext (indicates id length) for detector systems
+    IdContext           detsystem_context (void) const;
+
+    /// IdContext (indicates id length) for sub-detector
+    IdContext           subdet_context  (void) const;
+    //@}
+
+
+    /// @name Generic conversion between identifier and idhash
+    //@{
+    /// Create compact id from hash id (return == 0 for OK)
+    virtual int         get_id          (const IdentifierHash& hash_id,
+                                         Identifier& id,
+                                         const IdContext* context = 0) const;
+    
+    /// Create hash id from compact id (return == 0 for OK)
+    virtual int         get_hash        (const Identifier& id, 
+                                         IdentifierHash& hash_id,
+                                         const IdContext* context = 0) const;
+    //@}
+
+    /// @name Initialization and version name 
+    //@{
+    /// Initialization from the identifier dictionary
+    virtual int         initialize_from_dictionary(const IdDictMgr& dict_mgr);
+
+    // retrieve version of the dictionary
+    virtual std::string   dictionaryVersion  (void) const;
+    //@}
+
+
+    /// @name Generic printing of identifiers
+    //@{
+    /// Short print out of any identifier (optionally provide
+    /// separation character - default is '.'):
+    void                show            (Identifier id, 
+                                         const IdContext* context = 0,
+                                         char sep = '.' ) const;
+    /// or provide the printout in string form
+    std::string         show_to_string  (Identifier id, 
+                                         const IdContext* context = 0,
+                                         char sep = '.'  ) const;
+
+    /// Expanded print out of any identifier
+    void                print           (Identifier id,
+                                         const IdContext* context = 0) const;
+    /// or provide the printout in string form
+    std::string         print_to_string (Identifier id,
+                                         const IdContext* context = 0) const;
+    //@}
+
+    /// @name  Test of an Identifier to see if it belongs to a particular detector (sub)system:
+    //@{
+    bool                is_scint        (Identifier id) const;
+    bool                is_tracker      (Identifier id) const;
+    bool                is_calo         (Identifier id) const;
+    bool                is_veto         (Identifier id) const;
+    bool                is_trigger      (Identifier id) const;
+    bool                is_preshower    (Identifier id) const;
+    bool                is_sct          (Identifier id) const;
+    bool                is_ecal         (Identifier id) const;
+    //@}
+
+
+    /// @name  Test of an Identifier to see if it belongs to a particular detector (sub)system (using expanded ids):
+    //@{
+    bool                is_scint        (const ExpandedIdentifier& id) const;
+    bool                is_tracker      (const ExpandedIdentifier& id) const;
+    bool                is_calo         (const ExpandedIdentifier& id) const;
+    bool                is_veto         (const ExpandedIdentifier& id) const;
+    bool                is_trigger      (const ExpandedIdentifier& id) const;
+    bool                is_preshower    (const ExpandedIdentifier& id) const;
+    bool                is_sct          (const ExpandedIdentifier& id) const;
+    bool                is_ecal         (const ExpandedIdentifier& id) const;
+    //@}
+
+    /// @name  Dictionary versioning: provide access to dictionary names and versions. Note that a helper may correspond to one or more id dictionary
+    //@{
+    ///  Dictionary names
+    std::vector<std::string>  dict_names(void) const;
+    ///  File names for subdet dictionaries
+    std::vector<std::string>  file_names(void) const;
+    ///  Version tags for subdet dictionaries
+    std::vector<std::string>  dict_tags (void) const;
+    //@}
+
+    /// @name  Checks are performed by default in debug compilation and NOT in optimized compilation. One can switch or query this mode for any idHelper with the following methods:
+    //@{
+    virtual bool        do_checks       (void) const;
+    virtual void        set_do_checks   (bool do_checks) const;
+    //@}
+
+    /// @name neighbours are initialized by default. One can switch or query this mode with the following methods:
+    //@{
+    virtual bool        do_neighbours       (void) const;
+    virtual void        set_do_neighbours   (bool do_neighbours) const;
+    //@}
+
+    /// @name setting pointer to the MessageService
+    //@{
+    virtual void setMessageSvc  (IMessageSvc* msgSvc);
+    //@}
+
+    /// Set flag for suppressing informational output.
+    void set_quiet (bool quiet);
+
+
+protected:
+
+    friend class FaserDetectorIDHelper;
+
+    void                setDictVersion  (const IdDictMgr& dict_mgr, const std::string& name);
+
+    std::string         to_range        (const ExpandedIdentifier& id) const;
+    
+    std::string         fix_barrel_ec   (const std::string& barrel_ec) const;
+
+    /// Detector systems:
+    ExpandedIdentifier          scint_exp           (void) const;
+    ExpandedIdentifier          tracker_exp         (void) const;
+    ExpandedIdentifier          calo_exp            (void) const;
+
+    /// Scintillator:
+    ExpandedIdentifier          veto_exp            (void) const;
+    ExpandedIdentifier          trigger_exp         (void) const;
+    ExpandedIdentifier          preshower_exp       (void) const;
+
+    /// Tracker:
+    ExpandedIdentifier          sct_exp             (void) const;
+
+    /// Calorimeter:
+    ExpandedIdentifier          ecal_exp            (void) const;
+
+    /// Provide efficient access to individual field values, for
+    /// subclass idhelpers
+    int                 scint_field_value        () const;     
+    int                 tracker_field_value      () const;       
+    int                 calo_field_value         () const;
+    int                 veto_field_value         () const;     
+    int                 trigger_field_value      () const;       
+    int                 preshower_field_value    () const;       
+    int                 sct_field_value          () const;
+    int                 ecal_field_value         () const;
+
+    /// Register the file and tag names for a particular IdDict
+    /// dictionary
+    int                 register_dict_tag        (const IdDictMgr& dict_mgr,
+                                                  const std::string& dict_name);
+
+    /// Test whether an idhelper should be reinitialized based on the
+    /// change of tags 
+    bool                reinitialize             (const IdDictMgr& dict_mgr);
+
+    /// Flag for subclasses to know whether or not to perform
+    /// checks. In general, this is set to false in optimized mode.
+    mutable bool        m_do_checks;
+    /// Flag for subclasses to know whether or not to perform
+    /// neighbour initialization
+    mutable bool        m_do_neighbours;
+
+    /// pointer to the message service
+    IMessageSvc*        m_msgSvc;
+
+    /// If true, suppress DEBUG/INFO messages.
+    bool m_quiet;
+
+
+    /// List of dictionary names used by this helper
+    std::vector<std::string>  m_dict_names;
+
+    /// List of dictionary file names used by this helper
+    std::vector<std::string>  m_file_names;
+
+    /// List of dictionary versions used by this helper
+    std::vector<std::string>  m_dict_tags;
+private:
+
+    typedef Identifier::size_type                       size_type; 
+    
+    // Identifiear numbering:
+    enum        ID   { 
+                        FASER_ID		= static_cast<Identifier::value_type>(0),
+                        MAX_BIT 		= Identifier::MAX_BIT,
+            	        ALL_BITS		= Identifier::ALL_BITS };
+
+    int                 initLevelsFromDict(const IdDictMgr& dict_mgr);
+
+    // dictionary version
+    std::string         m_dict_version;
+    bool                m_is_initialized_from_dict;
+    size_type           m_DET_INDEX;
+    size_type           m_SUBDET_INDEX;
+    int                 m_SCINT_ID;     
+    int                 m_TRACKER_ID;       
+    int                 m_CALO_ID;
+    int                 m_VETO_ID;     
+    int                 m_TRIGGER_ID;       
+    int                 m_PRESHOWER_ID;       
+    int                 m_SCT_ID;
+    int                 m_ECAL_ID;
+
+    /// Flag for slhc layout:
+    bool                m_isSLHC;
+
+    IdDictDictionary*   m_faser_dict;
+    IdDictDictionary*   m_scint_dict;
+    IdDictDictionary*   m_tracker_dict;
+    IdDictDictionary*   m_calo_dict;
+    FaserDetectorIDHelper* m_helper;
+    IdDictFieldImplementation m_det_impl;
+    IdDictFieldImplementation m_scint_part_impl;
+    IdDictFieldImplementation m_tracker_part_impl;
+    IdDictFieldImplementation m_calo_part_impl;
+};
+
+
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+
+//using the macros below we can assign an identifier (and a version)
+//This is required and checked at compile time when you try to record/retrieve
+CLASS_DEF(FaserDetectorID, 125694213, 1)
+
+/////////////////////////////////////////////////////////////////////////////
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+/////////////////////////////////////////////////////////////////////////////
+
+inline ExpandedIdentifier          
+FaserDetectorID::scint_exp           (void) const
+{
+    ExpandedIdentifier result;
+    return (result << m_SCINT_ID);
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::tracker_exp             (void) const
+{
+    ExpandedIdentifier result;
+    return (result << m_TRACKER_ID);  
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::calo_exp(void) const
+{
+    ExpandedIdentifier result;
+    return (result << m_CALO_ID);
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::veto_exp           (void) const
+{
+    ExpandedIdentifier result(scint_exp());
+    return (result << m_VETO_ID);
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::trigger_exp             (void) const
+{
+    ExpandedIdentifier result(scint_exp());
+    return (result << m_TRIGGER_ID);  
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::preshower_exp             (void) const
+{
+    ExpandedIdentifier result(scint_exp());
+    return (result << m_PRESHOWER_ID);  
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::sct_exp                   (void) const
+{
+    ExpandedIdentifier result(tracker_exp());
+    return (result << m_SCT_ID);  
+}
+
+inline ExpandedIdentifier          
+FaserDetectorID::ecal_exp                (void) const
+{
+    ExpandedIdentifier result(calo_exp());
+    return (result << m_ECAL_ID);  
+}
+
+inline int                 
+FaserDetectorID::scint_field_value        () const {return (m_SCINT_ID);}     
+
+inline int                 
+FaserDetectorID::tracker_field_value      () const {return (m_TRACKER_ID);}
+
+inline int                 
+FaserDetectorID::calo_field_value         () const {return (m_CALO_ID);}
+
+inline int                 
+FaserDetectorID::veto_field_value         () const {return (m_VETO_ID);}     
+
+inline int                 
+FaserDetectorID::trigger_field_value      () const {return (m_TRIGGER_ID);}       
+
+inline int                 
+FaserDetectorID::preshower_field_value    () const {return (m_PRESHOWER_ID);}       
+
+inline int                 
+FaserDetectorID::sct_field_value          () const {return (m_SCT_ID);}       
+
+inline int                 
+FaserDetectorID::ecal_field_value         () const {return (m_ECAL_ID);}       
+
+inline bool               
+FaserDetectorID::is_scint                (Identifier id) const
+{
+    return (m_det_impl.unpack(id) == m_SCINT_ID);
+}
+
+inline bool               
+FaserDetectorID::is_tracker              (Identifier id) const
+{
+    return (m_det_impl.unpack(id) == m_TRACKER_ID);
+}
+
+inline bool                
+FaserDetectorID::is_calo                 (Identifier id) const
+{
+    return (m_det_impl.unpack(id) == m_CALO_ID);
+}
+
+inline bool               
+FaserDetectorID::is_veto       (Identifier id) const
+{
+    bool result = false;
+    if(is_scint(id)) {
+        result = (m_scint_part_impl.unpack(id) == m_VETO_ID);
+    }
+    return result;
+}
+
+inline bool               
+FaserDetectorID::is_trigger     (Identifier id) const
+{
+    bool result = false;
+    if(is_scint(id)) { 
+	result = (m_scint_part_impl.unpack(id) == m_TRIGGER_ID);
+    }
+    return result;
+}
+
+inline bool               
+FaserDetectorID::is_preshower         (Identifier id) const
+{
+    bool result = false;
+    if(is_scint(id)) {
+        result = (m_scint_part_impl.unpack(id) == m_PRESHOWER_ID);
+    }
+    return result;
+}
+
+inline bool               
+FaserDetectorID::is_sct              (Identifier id) const
+{
+    bool result = false;
+    if(is_tracker(id)) {
+        result = (m_tracker_part_impl.unpack(id) == m_SCT_ID);
+    }
+    return result;
+}
+
+inline bool               
+FaserDetectorID::is_ecal             (Identifier id) const
+{
+    bool result = false;
+    if(is_calo(id)) {
+        result = (m_calo_part_impl.unpack(id) == m_ECAL_ID);
+    }
+    return result;
+}
+
+#endif // FASERDETDESCR_FASERDETECTORID_H
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegion.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegion.h
new file mode 100644
index 00000000..66347392
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegion.h
@@ -0,0 +1,42 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserRegion.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERDETDESCR_FASERREGION_H
+#define FASERDETDESCR_FASERREGION_H 1
+
+#include <assert.h>
+
+// use these macros to check a given FaserRegion for its validity
+#define validFaserRegion(region) ( (region<FaserDetDescr::fNumFaserRegions) && (region>=FaserDetDescr::fFirstFaserRegion) )
+#define assertFaserRegion(region) ( assert(validFaserRegion(region)) )
+
+namespace FaserDetDescr {
+
+ /** @enum FaserRegion
+   
+     A simple enum of FASER regions and sub-detectors.
+
+   */
+
+   enum FaserRegion {       
+        // Unset
+            fUndefinedFaserRegion = 0,
+        // first Geometry element in enum, used in e.g. loops
+            fFirstFaserRegion     = 1,
+        // FASER Detector setup: geometrical ones
+            fFaserScint           = 1,
+            fFaserTracker         = 2,
+            fFaserCalo            = 3,
+            fFaserCavern          = 4,
+        // number of defined GeoIDs
+            fNumFaserRegions      = 5
+   };
+
+} // end of namespace
+
+#endif // FASERDETDESCR_FASERREGION
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegionHelper.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegionHelper.h
new file mode 100644
index 00000000..857c95ce
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserRegionHelper.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserRegionHelper.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERDETDESCR_FASERREGIONHELPER_H
+#define FASERDETDESCR_FASERREGIONHELPER_H 1
+
+#include "FaserDetDescr/FaserRegion.h"
+
+namespace FaserDetDescr {
+
+ /** @class FaserRegionHelper
+   
+     A simple helper class (functional) to translate FaserDetDesc::FaserRegion enums
+     into a string description.
+
+   */
+
+   class FaserRegionHelper {       
+     public:
+       static const char * getName( int region );
+       static const char * getName( FaserDetDescr::FaserRegion region );
+
+     private:
+       FaserRegionHelper();
+
+   };
+
+} // end of namespace
+
+#endif // FASERDETDESCR_FASERREGIONHELPER_H
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/selection.xml b/DetectorDescription/FaserDetDescr/FaserDetDescr/selection.xml
new file mode 100644
index 00000000..0525485e
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/selection.xml
@@ -0,0 +1,4 @@
+<lcgdict>
+  <enum pattern="FaserDetDescr::*"/>
+  <class name="FaserDetDescr::ROOT6_NamespaceAutoloadHook" />   
+</lcgdict>
diff --git a/DetectorDescription/FaserDetDescr/doc/packagedoc.h b/DetectorDescription/FaserDetDescr/doc/packagedoc.h
new file mode 100644
index 00000000..4f0940c7
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/doc/packagedoc.h
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+
+
+@page FaserDetDescr_page 
+
+This package contains an implentation base class for all identifier
+helper classes - FaserDetectorID. This class contains the information
+of the "upper levels" of identifiers, i.e. which detector system
+(Scint, Tracker, Calorimeter) and which subdetector. All concrete helpers
+derive from FaserDetectorID and thus each one can respond to the
+generic queries on the upper levels of identifiers. 
+
+FaserDetectorID also provides facilities for printing out identifiers,
+e.g. show_to_string, and maintains the version tags.
+
+
+
+
+
+
+*/
diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
new file mode 100644
index 00000000..f8b00fec
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
@@ -0,0 +1,1134 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Detector Description
+ -----------------------------------------
+***************************************************************************/
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "GaudiKernel/MsgStream.h"
+#include "FaserDetDescr/FaserDetectorID.h"
+#include "IdDict/IdDictDefs.h"
+#include "FaserDetectorIDHelper.h"
+#include <iostream>
+#include <stdio.h>
+#include <assert.h>
+
+//<<<<<< PRIVATE DEFINES                                                >>>>>>
+//<<<<<< PRIVATE CONSTANTS                                              >>>>>>
+//<<<<<< PRIVATE TYPES                                                  >>>>>>
+//<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
+//<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
+//<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
+//<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
+
+FaserDetectorID::FaserDetectorID()
+        :
+        m_do_checks(false),
+        m_do_neighbours(true),
+        m_msgSvc(0),
+        m_quiet(false),
+        m_is_initialized_from_dict(false),
+        m_DET_INDEX(999),
+        m_SUBDET_INDEX(999),
+        m_SCINT_ID(2),
+        m_TRACKER_ID(3),
+        m_CALO_ID(4),
+        m_VETO_ID(1),
+        m_TRIGGER_ID(2),
+        m_PRESHOWER_ID(3),
+        m_SCT_ID(1),
+        m_ECAL_ID(1),
+        m_isSLHC(false),
+        m_faser_dict(0),
+        m_scint_dict(0),
+        m_tracker_dict(0),
+        m_calo_dict(0),
+        m_helper(0)
+{}
+
+FaserDetectorID::~FaserDetectorID(void)
+{
+    delete m_helper;
+}
+
+FaserDetectorID::FaserDetectorID(const FaserDetectorID& other)
+        :
+        IdHelper(),
+        m_do_checks               (other.m_do_checks),
+        m_do_neighbours           (other.m_do_neighbours),
+        m_msgSvc                  (other.m_msgSvc),
+        m_quiet                   (other.m_quiet),
+        m_dict_version            (other.m_dict_version),
+        m_is_initialized_from_dict(other.m_is_initialized_from_dict),
+        m_DET_INDEX               (other.m_DET_INDEX),
+        m_SUBDET_INDEX            (other.m_SUBDET_INDEX),
+        m_SCINT_ID                (other.m_SCINT_ID),
+        m_TRACKER_ID              (other.m_TRACKER_ID),
+        m_CALO_ID                 (other.m_CALO_ID),
+        m_VETO_ID                 (other.m_VETO_ID),
+        m_TRIGGER_ID              (other.m_TRIGGER_ID),
+        m_PRESHOWER_ID            (other.m_PRESHOWER_ID),
+        m_SCT_ID                  (other.m_SCT_ID),
+        m_ECAL_ID                 (other.m_ECAL_ID),
+        m_isSLHC                  (other.m_isSLHC),
+        m_faser_dict              (other.m_faser_dict),
+        m_scint_dict              (other.m_scint_dict),
+        m_tracker_dict            (other.m_tracker_dict),
+        m_calo_dict               (other.m_calo_dict),
+        m_helper                  (0),
+        m_det_impl                (other.m_det_impl),
+        m_scint_part_impl         (other.m_scint_part_impl),
+        m_tracker_part_impl       (other.m_tracker_part_impl),
+        m_calo_part_impl          (other.m_calo_part_impl)
+
+{
+    if (other.m_helper) {
+        // Must copy helper
+        m_helper = new  FaserDetectorIDHelper(*other.m_helper);
+        m_helper->setMsgSvc(m_msgSvc);
+    }
+}
+
+FaserDetectorID&
+FaserDetectorID::operator= (const FaserDetectorID& other)
+{
+    if (this != &other) {
+        m_do_checks             = other.m_do_checks;
+        m_do_neighbours         = other.m_do_neighbours;
+        m_msgSvc                = other.m_msgSvc;
+        m_quiet                 = other.m_quiet;
+        m_dict_version          = other.m_dict_version;
+        m_is_initialized_from_dict = other.m_is_initialized_from_dict;
+        m_DET_INDEX             = other.m_DET_INDEX;
+        m_SUBDET_INDEX          = other.m_SUBDET_INDEX;
+        m_SCINT_ID              = other.m_SCINT_ID;
+        m_TRACKER_ID            = other.m_TRACKER_ID;
+        m_CALO_ID               = other.m_CALO_ID;
+        m_VETO_ID               = other.m_VETO_ID;
+        m_TRIGGER_ID            = other.m_TRIGGER_ID;
+        m_PRESHOWER_ID          = other.m_PRESHOWER_ID;
+        m_SCT_ID                = other.m_SCT_ID;
+        m_ECAL_ID               = other.m_ECAL_ID;
+        m_faser_dict            = other.m_faser_dict;
+        m_scint_dict            = other.m_scint_dict;
+        m_tracker_dict          = other.m_tracker_dict;
+        m_calo_dict             = other.m_calo_dict;
+        m_det_impl              = other.m_det_impl;
+        m_scint_part_impl       = other.m_scint_part_impl;
+        m_tracker_part_impl     = other.m_tracker_part_impl;
+        m_calo_part_impl        = other.m_calo_part_impl;
+
+        if (other.m_helper) {
+            // Must copy helper.
+            delete m_helper;
+            m_helper = new  FaserDetectorIDHelper(*other.m_helper);
+            m_helper->setMsgSvc(m_msgSvc);
+        }
+    }
+
+    return (*this);
+}
+
+
+Identifier
+FaserDetectorID::scint        (void) const
+{
+
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack    (scint_field_value(), result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::tracker      (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack    (tracker_field_value(), result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::calo(void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack    (calo_field_value(), result);
+    return (result);
+}
+
+
+Identifier
+FaserDetectorID::veto        (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (scint_field_value(), result);
+    m_scint_part_impl.pack(m_VETO_ID, result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::trigger          (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (scint_field_value(), result);
+    m_scint_part_impl.pack(m_TRIGGER_ID, result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::preshower          (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (scint_field_value(), result);
+    m_scint_part_impl.pack(m_PRESHOWER_ID, result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::sct          (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (tracker_field_value(), result);
+    m_tracker_part_impl.pack(m_SCT_ID, result);
+    return (result);
+}
+
+Identifier
+FaserDetectorID::ecal          (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (calo_field_value(), result);
+    m_calo_part_impl.pack(m_ECAL_ID, result);
+    return (result);
+}
+
+/// IdContext (indicates id length) for detector systems
+IdContext
+FaserDetectorID::detsystem_context (void) const
+{
+    ExpandedIdentifier id;
+    return (IdContext(id, 0, m_DET_INDEX));
+}
+
+/// IdContext (indicates id length) for sub-detector
+IdContext
+FaserDetectorID::subdet_context  (void) const
+{
+    ExpandedIdentifier id;
+    return (IdContext(id, 0, m_SUBDET_INDEX));
+}
+
+
+int
+FaserDetectorID::get_id          (const IdentifierHash& /*hash_id*/,
+                                  Identifier& /*id*/,
+                                  const IdContext* /*context*/) const
+{
+    return (0);
+}
+
+int
+FaserDetectorID::get_hash        (const Identifier& /*id*/,
+                                  IdentifierHash& /*hash_id*/,
+                                  const IdContext* /*context*/) const
+{
+    return (0);
+}
+
+int
+FaserDetectorID::register_dict_tag        (const IdDictMgr& dict_mgr,
+                                           const std::string& dict_name)
+{
+    // Register version of dictionary dict_name
+
+    // Access dictionary by name
+    IdDictDictionary* dict = dict_mgr.find_dictionary(dict_name);
+    if (!dict) return(1);
+    // Add in dict name, file name and version
+    m_dict_names.push_back(dict_name);
+    m_file_names.push_back(dict->file_name());
+    m_dict_tags.push_back(dict->dict_tag());
+    return (0);
+}
+
+/// Test whether an idhelper should be reinitialized based on the
+/// change of tags
+bool
+FaserDetectorID::reinitialize             (const IdDictMgr& dict_mgr)
+{
+    // If no tag has been registered, then reinitialize
+    if (m_dict_tags.size() == 0) return (true);
+
+    // If no dict names have been registered, then reinitialize
+    if (m_dict_names.size() == 0) return (true);
+
+    // Loop over dict names and check version tags
+    if (m_dict_names.size() != m_dict_tags.size()) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorID" );
+            log << MSG::ERROR << "reinitialize: dict names and tags vectors not the same length " << endmsg;
+            log << MSG::ERROR << "names: " << m_dict_names.size() << " tags: " << m_dict_tags.size() << endmsg;
+        }
+        else {
+            std::cout << MSG::ERROR << "reinitialize: dict names and tags vectors not the same length " << std::endl;
+            std::cout << "FaserDetectorID::reinitialize ERROR names: " << m_dict_names.size() << " tags: " << m_dict_tags.size() << std::endl;
+        }
+    }
+    for (unsigned int i = 0; i < m_dict_names.size(); ++i) {
+        // Access dictionary by name
+        IdDictDictionary* dict = dict_mgr.find_dictionary(m_dict_names[i]);
+        if (!dict) {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "reinitialize: could not find dict -  " << m_dict_names[i] << endmsg;
+            }
+            else {
+              std::cout << "FaserDetectorID::reinitialize ERROR could not find dict -  " << m_dict_names[i] << std::endl;
+            }
+            return(false);
+        }
+        if (m_dict_tags[i] != dict->dict_tag()) {
+            // Remove all memory of versions
+            m_dict_names.clear();
+            m_dict_tags.clear();
+            m_file_names.clear();
+            return (true);
+        }
+    }
+
+    // Tags match - don't reinitialize
+    return (false);
+}
+
+
+
+int
+FaserDetectorID::initialize_from_dictionary(const IdDictMgr& dict_mgr)
+{
+
+    // Register version of FASER dictionary
+    if (register_dict_tag(dict_mgr, "FASER")) return(1);
+
+    // Initialize helper, needed for init of FaserDetectorID
+    if(!m_helper) {
+        m_helper = new FaserDetectorIDHelper;
+        m_helper->setMsgSvc(m_msgSvc);
+    }
+
+    if(m_helper->initialize_from_dictionary(dict_mgr, m_quiet)) return (1);
+
+    // Initialize level indices and id values from dicts
+    if(initLevelsFromDict(dict_mgr)) return (1);
+
+    m_is_initialized_from_dict = true;
+
+    if (!m_quiet) {
+      if(m_msgSvc) {
+        MsgStream log(m_msgSvc, "FaserDetectorID" );
+        log << MSG::INFO << "initialize_from_dictionary - OK" << endmsg;
+      }
+      else {
+        std::cout << " FaserDetectorID::initialize_from_dictionary - OK " << std::endl;
+      }
+    }
+    
+    return (0);
+}
+
+
+std::string
+FaserDetectorID::dictionaryVersion  (void) const
+{
+    return (m_dict_version);
+}
+
+bool
+FaserDetectorID::is_scint       (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( id.fields() > 0 ){
+        if ( id[0] == m_SCINT_ID) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_tracker                 (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( id.fields() > 0 ){
+        if ( id[0] == m_TRACKER_ID) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_calo                (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( id.fields() > 0 ){
+        if ( id[0] == m_CALO_ID ) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_veto       (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_scint(id) && id.fields() > 1 ){
+        if ( id[1] == m_VETO_ID ) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_trigger         (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_scint(id) && id.fields() > 1 ){
+        if ( id[1] == m_TRIGGER_ID ) return(true);
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_preshower         (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_scint(id) && id.fields() > 1 ){
+        if ( id[1] == m_PRESHOWER_ID ) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_sct         (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_tracker(id) && id.fields() > 1 ){
+        if ( id[1] == m_SCT_ID ) result = true;
+    }
+    return result;
+}
+
+bool
+FaserDetectorID::is_ecal         (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_calo(id) && id.fields() > 1 ){
+        if ( id[1] == m_ECAL_ID ) result = true;
+    }
+    return result;
+}
+
+// Short print out of any identifier:
+void
+FaserDetectorID::show           (Identifier id,
+                                 const IdContext* context,
+                                 char sep ) const
+{
+    if(m_msgSvc) {
+        MsgStream log(m_msgSvc, "FaserDetectorID" );
+        log << MSG::INFO << show_to_string(id, context, sep) << endmsg;
+    }
+    else {
+        std::cout << show_to_string(id, context, sep) << std::endl;
+    }
+}
+
+// or provide the printout in string form
+std::string
+FaserDetectorID::show_to_string (Identifier id,
+                                 const IdContext* context,
+                                 char sep ) const
+{
+    // Do a generic printout of identifier
+
+    std::string result("Unable to decode id");
+    unsigned int max_index = (context) ? context->end_index()  : 999;
+
+    if (!m_is_initialized_from_dict) return  (result);
+
+    // Find the dictionary to use:
+    IdDictDictionary*   dict = 0;
+    ExpandedIdentifier expId;
+    ExpandedIdentifier prefix;  // default is null prefix
+    Identifier compact = id;
+
+    if (is_scint(id)) {
+        dict = m_scint_dict;
+    }
+    else if (is_tracker(id)) {
+        dict = m_tracker_dict;
+    }
+    else if (is_calo(id)) {
+        dict = m_calo_dict;
+    }
+
+    if (!dict) return (result);
+
+    if (dict->unpack(compact,
+                     prefix,
+                     max_index,
+                     expId)) {
+        return (result);
+    }
+
+    bool first = true;
+    char temp[20];
+
+    result = "";
+    if ('.' == sep) result = "[";
+    for (unsigned int i = 0; i < expId.fields(); ++i) {
+        if (first) first = false;
+        else result += sep;
+        sprintf (temp, "%d", expId[i]);
+        result += temp;
+    }
+    if ('.' == sep) result += "]";
+
+//      result += " compact [";
+//      sprintf (temp, "0x%x", (unsigned int)compact);
+//      result += temp;
+//      result += "]";
+
+    return (result);
+}
+
+
+
+void
+FaserDetectorID::print (Identifier id,
+                        const IdContext* context) const
+{
+    if(m_msgSvc) {
+        MsgStream log(m_msgSvc, "FaserDetectorID" );
+        log << MSG::INFO << print_to_string(id, context) << endmsg;
+    }
+    else {
+        std::cout << print_to_string(id, context) << std::endl;
+    }
+}
+
+std::string
+FaserDetectorID::print_to_string        (Identifier id,
+                                         const IdContext* context) const
+{
+    // Print out for any Faser identifier
+    std::string result;
+    if (m_is_initialized_from_dict) {
+
+        // Do a generic printout of identifier from dictionary
+        unsigned int max_index = (context) ? context->end_index()  : 999;
+
+        // Find the dictionary to use:
+        IdDictDictionary*       dict = 0;
+        ExpandedIdentifier expId;
+        ExpandedIdentifier prefix;  // default is null prefix
+        Identifier compact = id;
+
+        if (is_scint(id)) {
+            dict = m_scint_dict;
+        }
+        else if (is_tracker(id)) {
+            dict = m_tracker_dict;
+        }
+        else if (is_calo(id)) {
+            dict = m_calo_dict;
+        }
+
+        if (!dict) return (result);
+
+        if (dict->unpack(compact,
+                         prefix,
+                         max_index,
+                         " ",
+                         result)) {
+            return (result);
+        }
+    }
+    return (result);
+}
+
+///  Dictionary name
+std::vector<std::string>
+FaserDetectorID::dict_names         (void) const
+{
+    return (m_dict_names);
+}
+
+///  File name
+std::vector<std::string>
+FaserDetectorID::file_names         (void) const
+{
+    return (m_file_names);
+}
+
+///  Version tag for subdet dictionary
+std::vector<std::string>
+FaserDetectorID::dict_tags      (void) const
+{
+    return (m_dict_tags);
+}
+
+bool            
+FaserDetectorID::do_checks      (void) const
+{
+    return (m_do_checks);
+}
+
+void
+FaserDetectorID::set_do_checks  (bool do_checks) const
+{
+    m_do_checks = do_checks;
+}
+
+bool
+FaserDetectorID::do_neighbours  (void) const
+{
+    return (m_do_neighbours);
+}
+
+void
+FaserDetectorID::set_do_neighbours      (bool do_neighbours) const
+{
+    m_do_neighbours = do_neighbours;
+}
+
+void
+FaserDetectorID::setMessageSvc  (IMessageSvc* msgSvc)
+{
+    m_msgSvc = msgSvc ;
+}
+
+void
+FaserDetectorID::set_quiet  (bool quiet)
+{
+    m_quiet = quiet ;
+}
+
+void
+FaserDetectorID::setDictVersion  (const IdDictMgr& dict_mgr, const std::string& name)
+{
+    const IdDictDictionary* dict = dict_mgr.find_dictionary (name);
+
+    m_dict_version = dict->m_version;
+}
+
+std::string
+FaserDetectorID::to_range (const ExpandedIdentifier& id) const
+{
+
+    // Build a string from the contents of an identifier
+
+    int fields = id.fields();
+    char temp[10] = "";
+    std::string result("");
+
+    for (int i = 0; i < fields; ++i) {
+        sprintf( temp, "%d", id[i]);
+        if (i > 0) result += '/'; // add '/' only if NOT last one
+        result += temp;
+    }
+
+    return result;
+}
+
+int
+FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr)
+{
+
+    // Set do_checks flag
+    if (dict_mgr.do_checks()) m_do_checks = true;
+    // Set do_neighbours flag
+    if (!dict_mgr.do_neighbours()) m_do_neighbours = false;
+
+    IdDictLabel* label = 0;
+    IdDictField* field = 0;
+
+    // Find out from the dictionary the detector and subdetector
+    // levels and id values
+    m_DET_INDEX             = 999;
+    m_SUBDET_INDEX          = 999;
+    m_SCINT_ID              = -1;
+    m_TRACKER_ID            = -1;
+    m_CALO_ID               = -1;
+    m_VETO_ID               = -1;
+    m_TRIGGER_ID            = -1;
+    m_PRESHOWER_ID          = -1;
+    m_SCT_ID                = -1;
+    m_ECAL_ID               = -1;
+
+    // Save generic dict for top levels
+    IdDictDictionary*   top_dict = 0;
+
+    // Get det ids
+
+    // Initialize ids for InDet subdet
+    m_scint_dict = dict_mgr.find_dictionary ("Scintillator");
+    if(!m_scint_dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorID" );
+            log << MSG::WARNING << "initLevelsFromDict - cannot access Scintillator dictionary" << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorID::initLevelsFromDict - Warning cannot access Scintillator dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+
+        // Found Scint dict
+
+        top_dict = m_scint_dict;  // save as top_dict
+
+        // Check if this is SLHC layout
+        m_isSLHC = (m_scint_dict->m_version=="SLHC");
+
+        // Get Scint subdets
+
+        field = m_scint_dict->find_field("part");
+        if (!field) {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'part' field for Scintillator dictionary" << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'part' field for Scintillator dictionary"
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        label = field->find_label("Veto");
+        if (label) {
+            if (label->m_valued) {
+                m_VETO_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Veto does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Veto does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Veto' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Veto' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        label = field->find_label("Trigger");
+        if (label) {
+            if (label->m_valued) {
+                m_TRIGGER_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Trigger does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Trigger does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Trigger' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Trigger' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        label = field->find_label("Preshower");
+        if (label) {
+            if (label->m_valued) {
+                m_PRESHOWER_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Preshower does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Preshower does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Preshower' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Preshower' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+    }
+
+    // Initialize ids for Tracker
+    m_tracker_dict = dict_mgr.find_dictionary ("Tracker");
+    if(!m_tracker_dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorID" );
+            log << MSG::WARNING << "initLevelsFromDict -  cannot access Tracker dictionary "
+                << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorID::initLevelsFromDict - Warning cannot access Tracker dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+        // Found Tracker dict
+
+        if (!top_dict) top_dict = m_tracker_dict;  // save as top_dict
+
+        field = m_tracker_dict->find_field("part");
+        if (!field) {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'part' field for Tracker dictionary"
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'part' field for Tracker dictionary"
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        label = field->find_label("SCT");
+        if (label) {
+            if (label->m_valued) {
+                m_SCT_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label SCT does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label SCT does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'SCT' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'SCT' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+    }
+
+    // Initialize id for Calo and fields for lvl1 and dead material
+    m_calo_dict = dict_mgr.find_dictionary ("Calorimeter");
+    if(!m_calo_dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorID" );
+            log << MSG::ERROR << "initLevelsFromDict - Warning cannot access Calorimeter dictionary "
+                << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorID::initLevelsFromDict - Warning cannot access Calorimeter dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+        // Found calo dict
+        if (!top_dict) top_dict = m_calo_dict;  // save as top_dict
+
+        // Get Scint subdets
+        field = m_calo_dict->find_field("part");
+        if (!field) {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'part' field for Calorimeter dictionary" << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'part' field for Calorimeter dictionary"
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        label = field->find_label("ECAL");
+        if (label) {
+            if (label->m_valued) {
+                m_ECAL_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label ECAL does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label ECAL does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'ECAL' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'ECAL' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+    }
+
+    // set det/subdet indices
+    if (top_dict) {
+        field = top_dict->find_field("subdet");
+        if (field) {
+            m_DET_INDEX = field->m_index;
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict -  - unable to find 'subdet' field from dict "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'subdet' field from dict "
+                          << top_dict->m_name
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        // Get scint id
+        label = field->find_label("Scintillator");
+        if (label) {
+            if (label->m_valued) {
+                m_SCINT_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Scintillator does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Scintillator does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Scintillator' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Scintillator' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        // Get Tracker id
+        label = field->find_label("Tracker");
+        if (label) {
+            if (label->m_valued) {
+                m_TRACKER_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Tracker does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Tracker does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Tracker' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Tracker' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        // Get Calo id
+        label = field->find_label("Calorimeter");
+        if (label) {
+            if (label->m_valued) {
+                m_CALO_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label Calorimeter does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label Calorimeter does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'Calorimeter' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Calorimeter' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+        // Get name of next level
+        std::string name;
+        if (top_dict->m_name == "Scintillator") {
+            name = "part";
+        }
+        else if (top_dict->m_name == "Calorimeter") {
+            name = "part";
+        }
+        else if (top_dict->m_name == "Tracker") {
+            name = "part";
+        }
+
+        // While we're here, save the index to the sub-detector level
+        // ("part" for InDet)
+        field = top_dict->find_field(name);
+        if (field) {
+            m_SUBDET_INDEX = field->m_index;
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find field "
+                    << name << " from dict "
+                    << top_dict->m_name
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find field "
+                          << name << " from dict "
+                          << top_dict->m_name
+                          << std::endl;
+            }
+            return (1);
+        }
+    }
+    else {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorID" );
+            log << MSG::ERROR << "initLevelsFromDict - no top dictionary defined "
+                << endmsg;
+        }
+        else {
+            std::cout << "FaserDetectorID::initLevelsFromDict - no top dictionary defined "
+                      << std::endl;
+        }
+        return (1);
+    }
+
+
+    // Set the field implementations
+
+    const IdDictRegion* region = 0;
+    size_type region_index =  m_helper->veto_region_index();
+    if (m_scint_dict && FaserDetectorIDHelper::UNDEFINED != region_index) {
+        region                 =  m_scint_dict->m_regions[region_index];
+        // Detector
+        m_det_impl             = region->m_implementation[m_DET_INDEX];
+        // InDet part
+        m_scint_part_impl      = region->m_implementation[m_SUBDET_INDEX];
+    }
+
+    region_index =  m_helper->sct_region_index();
+    if (m_tracker_dict && FaserDetectorIDHelper::UNDEFINED != region_index) {
+        region                 =  m_tracker_dict->m_regions[region_index];
+        // Detector
+        m_det_impl             = region->m_implementation[m_DET_INDEX];
+        // InDet part
+        m_tracker_part_impl    = region->m_implementation[m_SUBDET_INDEX];
+    }
+
+    region_index =  m_helper->ecal_region_index();
+    if (m_calo_dict && FaserDetectorIDHelper::UNDEFINED != region_index) {
+        region                 =  m_calo_dict->m_regions[region_index];
+        // Detector
+        m_det_impl             = region->m_implementation[m_DET_INDEX];
+        // InDet part
+        m_calo_part_impl    = region->m_implementation[m_SUBDET_INDEX];
+    }
+    return (0);
+}
diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx
new file mode 100644
index 00000000..3fcf1c00
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx
@@ -0,0 +1,185 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ 
+ -----------------------------------------
+ ***************************************************************************/
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "FaserDetectorIDHelper.h"
+#include "IdDict/IdDictDefs.h"  
+#include "FaserDetDescr/FaserDetectorID.h"
+#include "GaudiKernel/MsgStream.h"
+#include <iostream>
+
+//<<<<<< PRIVATE DEFINES                                                >>>>>>
+//<<<<<< PRIVATE CONSTANTS                                              >>>>>>
+//<<<<<< PRIVATE TYPES                                                  >>>>>>
+//<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
+//<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
+//<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
+//<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
+
+FaserDetectorIDHelper::FaserDetectorIDHelper(void)
+	:
+	m_isSLHC(false),
+	m_veto_region_index(UNDEFINED),
+	m_trigger_region_index(UNDEFINED),
+	m_preshower_region_index(UNDEFINED),
+    m_sct_region_index(UNDEFINED),
+    m_ecal_region_index(UNDEFINED),
+	m_initialized(false),
+    m_msgSvc(0)
+{}
+
+FaserDetectorIDHelper::~FaserDetectorIDHelper(void)
+{
+}
+
+int         
+FaserDetectorIDHelper::initialize_from_dictionary(const IdDictMgr& dict_mgr,
+                                                  bool quiet)
+{
+
+    if(m_initialized) return(0);
+    m_initialized = true;
+
+    FaserDetectorID faser_id;
+    ExpandedIdentifier id;
+
+    const IdDictDictionary* 	dict = dict_mgr.find_dictionary ("Scintillator"); 
+    if(!dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+            log << MSG::WARNING << "initialize_from_dictionary - cannot access Scintillator dictionary "
+                << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorIDHelper::initialize_from_dictionary - Warning: cannot access Scintillator dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+	// Check if this is SLHC layout
+	m_isSLHC = (dict->m_version=="SLHC");
+
+	// Save index to a VETO region for unpacking
+	id = faser_id.veto_exp(); 
+	if (dict->find_region(id, m_veto_region_index)) {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+                log << MSG::WARNING << "initialize_from_dictionary - unable to find veto region index: id, reg "  
+                    << (std::string)id << " " << m_veto_region_index
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to find veto region index: id, reg "  
+                          << (std::string)id << " " << m_veto_region_index
+                          << std::endl;
+            }
+	}
+
+	//if (!m_isSLHC) {
+	    
+	    // Save index to a TRIGGER region for unpacking
+	    id = faser_id.trigger_exp();
+	    if (dict->find_region(id, m_trigger_region_index)) {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+                    log << MSG::WARNING << "initialize_from_dictionary - unable to find trigger region index: id, reg "  
+                        << (std::string)id << " " << m_trigger_region_index
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to trigger sct region index: id, reg "  
+                              << (std::string)id << " " << m_trigger_region_index
+                              << std::endl;
+                }
+	    }
+
+	    // Save index to a PRESHOWER region for unpacking
+	    id = faser_id.preshower_exp(); 
+	    if (dict->find_region(id, m_preshower_region_index)) {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+                    log << MSG::WARNING << "initialize_from_dictionary - unable to find preshower region index: id, reg "  
+                        << (std::string)id << " " << m_preshower_region_index
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to find preshower region index: id, reg "  
+                              << (std::string)id << " " << m_preshower_region_index
+                              << std::endl;
+                }
+            }
+	//}
+    }
+    
+    dict = dict_mgr.find_dictionary ("Tracker"); 
+    if(!dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+            log << MSG::WARNING << "initialize_from_dictionary - cannot access Tracker dictionary "
+                << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorIDHelper::initialize_from_dictionary - Warning: cannot access Tracker dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+        // Save index to a SCT region for unpacking
+        id = faser_id.sct_exp(); 
+        if (dict->find_region(id, m_sct_region_index)) {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+                    log << MSG::WARNING << "initialize_from_dictionary - unable to find sct region index: id, reg "  
+                        << (std::string)id << " " << m_sct_region_index
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to find sct region index: id, reg "  
+                            << (std::string)id << " " << m_sct_region_index
+                            << std::endl;
+                }
+        }	
+    }
+    
+    // Get Calorimetry dictionary for both LVL1 and Dead material
+    dict = dict_mgr.find_dictionary ("Calorimeter"); 
+    if(!dict) {
+        if(m_msgSvc) {
+            MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+            log << MSG::WARNING << "initialize_from_dictionary - cannot access Calorimeter dictionary "
+                << endmsg;
+        }
+        else {
+            std::cout << " FaserDetectorIDHelper::initialize_from_dictionary - Warning: cannot access Calorimeter dictionary "
+                      << std::endl;
+        }
+    }
+    else {
+        // Save index to an ECAL region for unpacking
+        id = faser_id.ecal_exp(); 
+        if (dict->find_region(id, m_ecal_region_index)) {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorIDHelper" );
+                    log << MSG::WARNING << "initialize_from_dictionary - unable to find ecal region index: id, reg "  
+                        << (std::string)id << " " << m_ecal_region_index
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to find ecal region index: id, reg "  
+                            << (std::string)id << " " << m_ecal_region_index
+                            << std::endl;
+                }
+        }	
+    }
+        
+    return (0);
+}
diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h
new file mode 100644
index 00000000..2028b09e
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h
@@ -0,0 +1,94 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ 
+ -----------------------------------------
+ ***************************************************************************/
+
+#ifndef SRC_FASERDETECTORIDHELPER_H
+# define SRC_FASERDETECTORIDHELPER_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "Identifier/Identifier.h"
+#include "Identifier/IdContext.h"
+#include "Identifier/IdHelper.h"
+#include <string>
+#include <vector>
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+class IdDictField;
+
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+class FaserDetectorIDHelper
+{
+public:
+    
+    enum ERRORS { UNDEFINED = 999 };
+
+
+    FaserDetectorIDHelper(void);
+
+    typedef Identifier::size_type 			size_type; 
+
+   
+    /// Initialization from the identifier dictionary
+  int         initialize_from_dictionary(const IdDictMgr& dict_mgr, bool quiet);
+
+    ~FaserDetectorIDHelper(void);
+    
+    size_type   veto_region_index();
+    size_type   trigger_region_index();
+    size_type   preshower_region_index();
+    size_type   sct_region_index();
+    size_type   ecal_region_index();
+
+    void        setMsgSvc(IMessageSvc* msgSvc) { m_msgSvc = msgSvc; }
+
+
+private:
+
+
+    /// Flag for slhc layout:
+    bool                m_isSLHC;
+    size_type		m_veto_region_index;
+    size_type		m_trigger_region_index;
+    size_type		m_preshower_region_index;
+    size_type   m_sct_region_index;
+    size_type   m_ecal_region_index;
+    bool		m_initialized;
+    /// pointer to the message service
+    IMessageSvc*        m_msgSvc;
+    
+};
+
+
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+inline FaserDetectorIDHelper::size_type   FaserDetectorIDHelper::veto_region_index()
+{return (m_veto_region_index);}       
+
+inline FaserDetectorIDHelper::size_type   FaserDetectorIDHelper::trigger_region_index()
+{return (m_trigger_region_index);}         
+
+inline FaserDetectorIDHelper::size_type   FaserDetectorIDHelper::preshower_region_index()
+{return (m_preshower_region_index);}         
+
+inline FaserDetectorIDHelper::size_type   FaserDetectorIDHelper::sct_region_index()
+{return (m_sct_region_index);}         
+
+inline FaserDetectorIDHelper::size_type   FaserDetectorIDHelper::ecal_region_index()
+{return (m_ecal_region_index);}         
+
+
+#endif // SRC_FASERDETECTORIDHELPER_H
diff --git a/DetectorDescription/FaserDetDescr/src/FaserRegionHelper.cxx b/DetectorDescription/FaserDetDescr/src/FaserRegionHelper.cxx
new file mode 100644
index 00000000..5d9193d8
--- /dev/null
+++ b/DetectorDescription/FaserDetDescr/src/FaserRegionHelper.cxx
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserRegionName.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "FaserDetDescr/FaserRegionHelper.h"
+
+namespace FaserDetDescr {
+
+  const char * FaserRegionHelper::getName( int region ) {
+    return getName( FaserDetDescr::FaserRegion( region ) );
+  }
+
+  const char * FaserRegionHelper::getName( const FaserDetDescr::FaserRegion region ) {
+
+    if      ( region == FaserDetDescr::fFaserScint   ) return "FaserScint";
+    else if ( region == FaserDetDescr::fFaserTracker ) return "FaserTracker";
+    else if ( region == FaserDetDescr::fFaserCalo    ) return "FaserCalo";
+    else if ( region == FaserDetDescr::fFaserCavern  ) return "FaserCavern";
+    else                                               return "UndefinedFaserRegion";
+
+  }
+
+} // end of namespace
+
-- 
GitLab