From 9c1fb2ecf6182da99a3edea7ee4093c26625a3d2 Mon Sep 17 00:00:00 2001
From: Dave Casper <dcasper@uci.edu>
Date: Sat, 9 Feb 2019 21:20:41 -0800
Subject: [PATCH] Clean-up and start of some restructuring to reduce number of
 classes

---
 .../FaserReadoutGeometry}/CMakeLists.txt      |  16 +-
 .../FaserReadoutGeometry/FaserDD_Defs.h       |  22 +
 .../FaserDetectorManager.h                    | 194 ++++++++
 .../FaserReadoutGeometry/Version.h            |  91 ++++
 .../src/FaserDetectorManager.cxx              | 436 ++++++++++++++++++
 .../FaserReadoutGeometry/src/Version.cxx      | 121 +++++
 .../Veto_GeoModel/CMakeLists.txt              |  43 --
 7 files changed, 871 insertions(+), 52 deletions(-)
 rename {Scintillator/ScintDetDescr/ScintReadoutGeometry => DetectorDescription/FaserReadoutGeometry}/CMakeLists.txt (75%)
 create mode 100644 DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDD_Defs.h
 create mode 100644 DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDetectorManager.h
 create mode 100644 DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/Version.h
 create mode 100644 DetectorDescription/FaserReadoutGeometry/src/FaserDetectorManager.cxx
 create mode 100644 DetectorDescription/FaserReadoutGeometry/src/Version.cxx
 delete mode 100644 Scintillator/ScintDetDescr/Veto_GeoModel/CMakeLists.txt

diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/CMakeLists.txt b/DetectorDescription/FaserReadoutGeometry/CMakeLists.txt
similarity index 75%
rename from Scintillator/ScintDetDescr/ScintReadoutGeometry/CMakeLists.txt
rename to DetectorDescription/FaserReadoutGeometry/CMakeLists.txt
index 827090aa..7866144d 100644
--- a/Scintillator/ScintDetDescr/ScintReadoutGeometry/CMakeLists.txt
+++ b/DetectorDescription/FaserReadoutGeometry/CMakeLists.txt
@@ -1,9 +1,9 @@
 ################################################################################
-# Package: ScintReadoutGeometry
+# Package: FaserReadoutGeometry
 ################################################################################
 
 # Declare the package name:
-atlas_subdir( ScintReadoutGeometry )
+atlas_subdir( FaserReadoutGeometry )
 
 # Declare the package's dependencies:
 atlas_depends_on_subdirs( PUBLIC
@@ -12,19 +12,17 @@ atlas_depends_on_subdirs( PUBLIC
                           Control/StoreGate
                           DetectorDescription/FaserDetDescr
                           DetectorDescription/GeoModel/GeoModelUtilities
-                          DetectorDescription/GeoModel/GeoModelFaserUtilities
                           DetectorDescription/GeoPrimitives
                           DetectorDescription/Identifier
                           GaudiKernel
-                          Scintillator/ScintDetDescr/ScintIdentifier
+                          InnerDetector/InDetConditions/InDetCondTools
                           Tracking/TrkDetDescr/TrkDetElementBase
                           Tracking/TrkDetDescr/TrkSurfaces
                           Tracking/TrkEvent/TrkEventPrimitives
                           DetectorDescription/DetDescrCond/DetDescrConditions
                           PRIVATE
                           Database/AthenaPOOL/AthenaPoolUtilities
-                          DetectorDescription/IdDictDetDescr
-                          )
+                          DetectorDescription/IdDictDetDescr )
 
 # External dependencies:
 find_package( CLHEP )
@@ -32,11 +30,11 @@ find_package( Eigen )
 find_package( GeoModel )
 
 # Component(s) in the package:
-atlas_add_library( ScintReadoutGeometry
+atlas_add_library( FaserReadoutGeometry
                    src/*.cxx
-                   PUBLIC_HEADERS ScintReadoutGeometry
+                   PUBLIC_HEADERS FaserReadoutGeometry
                    INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
                    DEFINITIONS ${CLHEP_DEFINITIONS}
-                   LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel FaserDetDescr GeoModelUtilities GeoModelFaserUtilities GeoPrimitives Identifier GaudiKernel ScintIdentifier TrkDetElementBase TrkSurfaces TrkEventPrimitives StoreGateLib SGtests AthenaBaseComps DetDescrConditions
+                   LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel FaserDetDescr GeoModelUtilities GeoModelFaserUtilities GeoPrimitives Identifier GaudiKernel InDetCondTools TrkDetElementBase TrkSurfaces TrkEventPrimitives StoreGateLib SGtests AthenaBaseComps DetDescrConditions
                    PRIVATE_LINK_LIBRARIES AthenaPoolUtilities IdDictDetDescr )
 
diff --git a/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDD_Defs.h b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDD_Defs.h
new file mode 100644
index 00000000..814fcbd1
--- /dev/null
+++ b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDD_Defs.h
@@ -0,0 +1,22 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserDD_Defs.h
+///////////////////////////////////////////////////////////////////
+// (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERREADOUTGEOMETRY_FASERDD_Defs_H
+#define FASERREADOUTGEOMETRY_FASERDD_Defs_H
+
+
+namespace FaserDD {
+  enum FrameType {local, global, other};
+  enum CarrierType {holes, electrons};
+  // new enumerator to select given align-folder structure
+  enum AlignFolderType {none = -1, static_run1 = 0, timedependent_run2 = 1};
+}
+
+#endif // FASERREADOUTGEOMETRY_FASERDD_DEFS_H
diff --git a/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDetectorManager.h b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDetectorManager.h
new file mode 100644
index 00000000..1371cc40
--- /dev/null
+++ b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/FaserDetectorManager.h
@@ -0,0 +1,194 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// FaserDectorManager.h
+///////////////////////////////////////////////////////////////////
+// (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef FASERREADOUTGEOMETRY_FASERDETECTORMANAGER_H
+#define FASERREADOUTGEOMETRY_FASERDETECTORMANAGER_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// GeoModel stuff
+#include "GeoModelKernel/GeoVDetectorManager.h"
+#include "FaserReadoutGeometry/FaserDD_Defs.h"
+#include "FaserReadoutGeometry/Version.h"
+#include "CLHEP/Geometry/Transform3D.h"
+// Message Stream Member
+#include "AthenaKernel/MsgStreamMember.h"
+
+// IOV SVC for alignment:
+#include "AthenaKernel/IIOVSvc.h"
+
+#include "DetDescrConditions/AlignableTransformContainer.h"
+
+class StoreGateSvc;
+class AlignableTransform;
+class Identifier; 
+class FaserDetectorID;
+class GeoVAlignmentStore;
+class CondAttrListCollection;
+
+#include <string>
+#include <map>
+#include <set>
+#include <list>
+
+namespace FaserDD {
+
+  typedef std::map<std::string, const void*> RawAlignmentObjects;
+
+    /** @class FaserDetectorManager
+    
+        Virtual base class for all FASER detector managers.
+        
+        It implements the processKey() method for alingment
+        which calls the setAlignableTransformDelta() method which
+        is specified in the extended classes. This method supports both,
+        local and global delta's in the frame and translates it to the 
+        underlying GeoModel transform. As GeoModel (CLHEP) and tracking
+        (Amg) use different geo libraries, these are the methods that
+        act as the CLHEP <--> Amg interface
+        
+        @author: Grant Gorfine
+        - modified & maintained: Nick Styles & Andreas Salzburger 
+        - adapted for FASER from InDetDetectorManager
+    */
+    class FaserDetectorManager : public GeoVDetectorManager  {
+    
+    public:
+    
+      // Constructor
+      FaserDetectorManager(StoreGateSvc * detStore, const std::string & name);
+     
+      // Destructor
+      virtual ~FaserDetectorManager();
+    
+      
+      /** Get version information */
+      const Version & getVersion() const; 
+      const std::string & getLayout() const; // eg Initial, Final, TestBeam 
+      void setVersion(const Version & version); 
+    
+      /** Alignment access */
+      void addChannel(const std::string & key, int level, FrameType frame);
+      void addFolder(const std::string & key);
+      void addSpecialFolder(const std::string & key);
+      void addGlobalFolder(const std::string & key); 
+      void addAlignFolderType(const AlignFolderType alignfolder);
+
+      StatusCode align( IOVSVC_CALLBACK_ARGS ) const;
+
+      StatusCode align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const;
+    
+      /** Invalidate cache for all detector elements */
+      virtual void invalidateAll() const = 0;
+    
+      /** Update all caches */
+      virtual void updateAll() const = 0;
+    
+      /** Check identifier is for this detector */
+      virtual bool identifierBelongs(const Identifier & id) const = 0;
+    
+      /** Declaring the Message method for further use */
+      MsgStream& msg (MSG::Level lvl) const { return m_msg.get() << lvl; }
+
+      /** Declaring the Method providing Verbosity Level */
+      bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; }
+
+      AlignFolderType                           m_alignfoldertype;
+    
+    protected:
+      StoreGateSvc * m_detStore;
+    
+    private:
+      /** @class LevelInfo
+         Private helper class definition.
+         */
+      class LevelInfo {
+
+        private:
+          int m_level;
+          FrameType m_type;
+        
+        public:
+          LevelInfo(): m_level(-1), m_type(FaserDD::global) {};
+          LevelInfo(int level, FrameType frame): m_level(level), m_type(frame) {};
+        
+          int level() const {return m_level;}
+          FrameType frame() const {return m_type;} 
+          bool isGlobalDelta() const {return m_type == FaserDD::global;}
+          bool isLocalDelta() const {return m_type == FaserDD::local;} 
+          bool isValid() const {return (m_level >= 0);}
+        
+      };
+
+      class AlignInfo {
+
+        private:
+        AlignFolderType m_aligntype;
+
+        public:
+          AlignInfo(): m_aligntype(FaserDD::none) {};
+          AlignInfo(AlignFolderType alignfolder): m_aligntype(alignfolder) {};
+          AlignFolderType AlignFolder() const {return m_aligntype;}
+          bool isValidAlign() const {return (m_aligntype != FaserDD::none);}
+
+      };
+
+    
+      /** Retrieve level information */
+      const LevelInfo & getLevel(const std::string & key) const;
+
+      /** return align folder string to use **/
+      //      InDetDD::AlignFolderType getAlignInfo();
+
+      /** Process the alignment container, calls processKey */
+      bool processAlignmentContainer(const std::string & key) const;
+      bool processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const;
+
+      /** Called by processAlignmentContainer, 
+          applies only one key on the transform Collections */
+      bool processKey(const std::string key, 
+                      const AlignableTransform* transformCollection,
+                      GeoVAlignmentStore* alignStore=nullptr) const;
+    
+      /** Set method applying the delta transform (in global or local frame)
+          onto the geoModel transform : CLHEP <--> Amg interface */
+      virtual bool setAlignableTransformDelta(int level, 
+                                              const Identifier & id, 
+                                              const Amg::Transform3D & delta,
+                                              FrameType frame,
+                                              GeoVAlignmentStore* alignStore=nullptr) const = 0;
+    
+      virtual bool processSpecialAlignment(const std::string & key, FaserDD::AlignFolderType alignfolder) const;
+
+      bool processGlobalAlignmentContainer(const std::string & key,
+                                           const CondAttrListCollection* obj=nullptr,
+                                           GeoVAlignmentStore* alignStore=nullptr) const;
+
+      virtual bool processGlobalAlignment(const std::string & key, int level, FrameType frame,
+                                          const CondAttrListCollection* obj=nullptr,
+                                          GeoVAlignmentStore* alignStore=nullptr) const;
+      
+      virtual const FaserDetectorID* getIdHelper() const = 0;
+    
+      //Declaring private message stream member.
+      mutable Athena::MsgStreamMember           m_msg;
+      
+      Version                                   m_version;
+      std::map<std::string, LevelInfo>          m_keys;
+      std::set<std::string>                     m_folders;
+      std::set<std::string>                     m_specialFolders;
+      std::set<std::string>                     m_globalFolders; // new time-dependent global folders
+      mutable bool                              m_suppressWarnings;
+    
+    };
+
+} // namespace FaserDD
+
+#endif // FASERREADOUTGEOMETRY_FASERDETECTORMANAGER_H
diff --git a/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/Version.h b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/Version.h
new file mode 100644
index 00000000..47d93e8f
--- /dev/null
+++ b/DetectorDescription/FaserReadoutGeometry/FaserReadoutGeometry/Version.h
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////
+// Version.h
+////////////////////////////////////////////////////////////
+// (c) ATLAS Detector software
+////////////////////////////////////////////////////////////
+
+#ifndef FASERREADOUTGEOMETRY_VERSION 
+#define FASERREADOUTGEOMETRY_VERSION 
+
+#include <string>
+
+namespace FaserDD {
+
+  /** @class Version
+
+    Class to hold version information consisting of tag, name layout and description as strings,
+    such as their integer regpresentation in the major-minor-tag scheme 
+    */
+
+  class Version {
+
+    public:
+
+      /** Constructor.  */
+      Version(const std::string & tag, 
+	  const std::string & name, 
+	  const std::string & layout, 
+	  const std::string & description, 
+	  int major,
+	  int minor,
+	  int patch);
+
+     /** Constructor. DEPRECATED */
+      Version(const std::string & name, 
+	  const std::string & layout, 
+	  const std::string & description, 
+	  int major,
+	  int minor,
+	  int patch);
+
+      /** Empty Constructor  */
+      Version();
+
+      /** Version tag */
+      const std::string & tag() const;
+
+      /** Version label */
+      const std::string & name() const;
+  
+      /** Layout (eg Initial, Final, TestBeam) */
+      const std::string & layout() const;
+
+      /** Description or comment. */
+      const std::string & description() const;
+
+      /** Major version number */
+      int majorNum() const;
+  
+      /** Minor version number */
+      int minorNum() const;
+
+      /** Patch version number  */
+      int patchNum() const;
+
+      /** Print out version number (eg. 2.00.00) */
+      std::string versionNumber() const;
+  
+      /** Full Description 
+          For example,
+          Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 2.00.00, Description: DC1 Geometry */
+      std::string fullDescription() const;
+
+  
+   private:
+ 
+      std::string m_tag;
+      std::string m_name;
+      std::string m_layout;
+      std::string m_description;
+      int m_major;
+      int m_minor;
+      int m_patch;
+  };
+
+} //  namespace  FaserDD
+
+#endif // FASERREADOUTGEOMETRY_VERSION 
diff --git a/DetectorDescription/FaserReadoutGeometry/src/FaserDetectorManager.cxx b/DetectorDescription/FaserReadoutGeometry/src/FaserDetectorManager.cxx
new file mode 100644
index 00000000..053bf0d9
--- /dev/null
+++ b/DetectorDescription/FaserReadoutGeometry/src/FaserDetectorManager.cxx
@@ -0,0 +1,436 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "FaserReadoutGeometry/FaserDetectorManager.h"
+
+#include "StoreGate/StoreGateSvc.h"
+#include "DetDescrConditions/AlignableTransform.h"
+#include "FaserDetDescr/FaserDetectorID.h"
+#include "GeoPrimitives/CLHEPtoEigenConverter.h" 
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
+
+#include <map>
+
+namespace FaserDD 
+{
+
+    FaserDetectorManager::FaserDetectorManager(StoreGateSvc * detStore, const std::string & name)
+        : m_alignfoldertype{none},m_detStore(detStore), 
+        m_msg(name+"DetectorManager"), 
+        m_suppressWarnings(false)
+    {
+        setName(name);
+    }
+
+  // Destructor
+    FaserDetectorManager::~FaserDetectorManager() 
+        {}
+
+
+    const Version& FaserDetectorManager::getVersion() const
+    {
+        return m_version;
+    }
+
+    const std::string& FaserDetectorManager::getLayout() const
+    {
+        return m_version.layout();
+    }
+
+    void FaserDetectorManager::setVersion(const Version & version)
+    {
+        m_version = version;
+    }
+
+    void FaserDetectorManager::addChannel(const std::string & key, int level, FrameType frame)
+    {
+        std::string frameStr = "other";
+        if (frame == FaserDD::global) frameStr = "global";
+        if (frame == FaserDD::local) frameStr  = "local";
+        ATH_MSG_INFO("Registering alignment channel with key " << key << ", level " << level 
+                     << ", with frame " << frameStr << ".");
+        m_keys[key] = LevelInfo(level, frame); 
+    }
+
+    void FaserDetectorManager::addFolder(const std::string & key)
+    {
+        m_folders.insert(key);
+    }
+
+    void FaserDetectorManager::addSpecialFolder(const std::string & key)
+    {
+        m_specialFolders.insert(key);
+    }
+
+    void FaserDetectorManager::addGlobalFolder(const std::string & key)
+    {
+        m_globalFolders.insert(key);
+    }
+
+    void FaserDetectorManager::addAlignFolderType(const AlignFolderType  alignfolder)
+    {
+        m_alignfoldertype = alignfolder;
+    }
+
+  // Return the level in the hierarchy (user defined) corresponding to the key.
+    const FaserDetectorManager::LevelInfo& FaserDetectorManager::getLevel(const std::string & key) const 
+    {
+        static LevelInfo invalidLevel;
+        std::map<std::string, LevelInfo>::const_iterator iter;
+        iter = m_keys.find(key);
+        if (iter == m_keys.end()) return invalidLevel;
+        return iter->second;
+    }
+
+    StatusCode FaserDetectorManager::align( IOVSVC_CALLBACK_ARGS_P(I,keys) ) const
+    {
+
+        (void) I; // avoid warning about unused parameter 
+
+        ATH_MSG_DEBUG("AlignmentCallback called ");
+
+        if (!getIdHelper()) return StatusCode::SUCCESS;
+
+        bool alignmentChange = false;
+        const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
+
+        // If dummy arguments
+        if (keys.empty()) {
+
+
+            // New global aligment folders should be processed first
+            for (std::set<std::string>::const_iterator iterFolders = m_globalFolders.begin();
+            iterFolders != m_globalFolders.end();
+            ++iterFolders) {
+
+                try {
+                    bool status = processGlobalAlignmentContainer(*iterFolders);
+                    alignmentChange = (alignmentChange || status);
+                } catch(std::runtime_error& err) {
+                    // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
+                  ATH_MSG_FATAL(err.what());
+                  return StatusCode::FAILURE;
+                }
+            }
+
+            // Regular alignments. Loop through folder keys. Normally only one.
+            for (std::set<std::string>::const_iterator iterFolders = m_folders.begin();
+            iterFolders != m_folders.end();
+            ++iterFolders) {
+
+                try {
+                    bool status = processAlignmentContainer(*iterFolders);
+                    alignmentChange = (alignmentChange || status);
+                }
+                catch(std::runtime_error& err) {
+                    // alignments should always exist so we return fatal if we could not process the alignment for this key
+                    ATH_MSG_FATAL(err.what());
+                    return StatusCode::FAILURE;
+                }
+            }  
+            // Detector specific aligments
+            for (std::set<std::string>::const_iterator iterFolders = m_specialFolders.begin();
+            iterFolders != m_specialFolders.end();
+            ++iterFolders) {
+                try {
+                    bool status = processSpecialAlignment(*iterFolders, aligninfo.AlignFolder());
+                    alignmentChange = (alignmentChange || status);
+                } catch(std::runtime_error& err) {
+                    // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
+                    ATH_MSG_INFO(err.what());
+                    // We continue as detector specific aligments don't always exist.
+                }
+            }
+
+        } else {
+            // Loop over all the keys.
+            for (std::list<std::string>::const_iterator itr=keys.begin(); itr!=keys.end(); ++itr) {
+
+                const std::string & key = *itr;
+
+                ATH_MSG_DEBUG(" Processing call back key  " << key);
+
+                if ( m_globalFolders.find(key) != m_globalFolders.end() ) { 
+
+                    try {
+                        // New global alignemnts
+                        bool status = processGlobalAlignmentContainer(key);
+                        alignmentChange = (alignmentChange || status);
+                    } catch(std::runtime_error& err) {
+                        // alignments should always exist so we return fatal if we could not process the alignment for this key
+                        ATH_MSG_FATAL(err.what());
+                        return StatusCode::FAILURE;
+                    }
+
+                } else if ( m_folders.find(key) != m_folders.end() ) { 
+
+                    try {
+                        // Regular alignemnts
+                        bool status = processAlignmentContainer(key);
+                        alignmentChange = (alignmentChange || status);
+                    } catch(std::runtime_error& err) {
+                        // alignments should always exist so we return fatal if we could not process the alignment for this key
+                        ATH_MSG_FATAL(err.what());
+                        return StatusCode::FAILURE;
+                    }
+
+                } else if ( m_specialFolders.find(key) !=  m_specialFolders.end() ) {
+                    try {
+                        // Detector specific alignments
+                        bool status = processSpecialAlignment(key, aligninfo.AlignFolder());
+                        alignmentChange = (alignmentChange || status);
+                    } 
+                    catch(std::runtime_error& err) {
+                        // Should always exist if the folder was requested so we return fatal if we could not process the alignment for this key
+                        ATH_MSG_FATAL(err.what());
+                        return StatusCode::FAILURE;
+                    }
+                } else {
+                    // Should not be any other keys specified in call back.
+                    ATH_MSG_ERROR("Unrecognized key in call back.");
+                    return  StatusCode::RECOVERABLE;
+                }
+            }
+        }
+
+    // We invalidate all the elements if at least one alignment changed.
+        if (alignmentChange) {
+            invalidateAll();
+        }    
+
+        return StatusCode::SUCCESS;
+    }
+
+    StatusCode FaserDetectorManager::align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const
+    {
+
+        ATH_MSG_DEBUG("align() called from an alignment CondAlg");
+        if (!getIdHelper()) return StatusCode::SUCCESS; // To Do: is it really a success?
+
+        bool alignmentChange = false;
+        //      const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
+      
+        for(const auto& alignObj : alignObjects) {
+            const std::string& key = alignObj.first;
+
+            ATH_MSG_DEBUG(" Processing folder  " << key);
+
+            if(m_globalFolders.find(key)!=m_globalFolders.end()) {  
+                try {
+                    // New global alignemnts
+                    const CondAttrListCollection* obj = static_cast<const CondAttrListCollection*>(alignObj.second);
+                    bool status = processGlobalAlignmentContainer(key,obj,alignStore);
+                    alignmentChange = (alignmentChange || status);
+                } catch(std::runtime_error& err) {
+                    // alignments should always exist so we return fatal if we could not process the alignment for this key
+                    ATH_MSG_FATAL(err.what());
+                    return StatusCode::FAILURE;
+                }
+            } 
+            else if(m_folders.find(key)!=m_folders.end()) { 
+                try {
+                    // Regular alignemnts
+                    const AlignableTransformContainer* container = static_cast<const AlignableTransformContainer*>(alignObj.second);
+                    bool status = processAlignmentContainer(container,alignStore);
+                    alignmentChange = (alignmentChange || status);
+                } catch(std::runtime_error& err) {
+                    // alignments should always exist so we return fatal if we could not process the alignment for this key
+                    ATH_MSG_FATAL(err.what());
+                    return StatusCode::FAILURE;
+                }
+            } 
+            else if(m_specialFolders.find(key)!=m_specialFolders.end()) {
+                // To Do: do we really need this?
+
+                /*
+                  try {
+                  // Detector specific alignments
+                  bool status = processSpecialAlignment(key, aligninfo.AlignFolder(),alignStore);
+                  alignmentChange = (alignmentChange || status);
+                  } 
+                  catch(std::runtime_error& err) {
+                  // Should always exist if the folder was requested so we return fatal if we could not process the alignment for this key
+                  ATH_MSG_FATAL(err.what());
+                  return StatusCode::FAILURE;
+                  }
+                */
+            } 
+            else {
+                // Should not be any other keys specified in call back.
+                ATH_MSG_ERROR("Unrecognized folder name.");
+                return StatusCode::RECOVERABLE;
+            }
+        }
+        // To Do: custom caching is not going to work in MT
+        /*
+          if(alignmentChange) invalidateAll(); 
+        */
+
+        return StatusCode::SUCCESS;      
+    }
+
+    bool FaserDetectorManager::processAlignmentContainer(const std::string & key) const
+    {
+        bool alignmentChange = false;
+
+        ATH_MSG_DEBUG("Dealing with key as container");
+        const AlignableTransformContainer* container;
+        if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) {        
+            ATH_MSG_ERROR("Cannot find AlignableTransformContainer for key " 
+                          << key << " - no misalignment");
+            // This should not occur in normal situations so we force job to abort.
+            throw std::runtime_error("Unable to apply " + getName() + " alignments");
+        }
+        // Check if container is empty - this can occur if it is an invalid IOV.
+        if (container->empty()) {
+            ATH_MSG_ERROR("AlignableTransformContainer for key " 
+                          << key << " is empty. Probably due to out of range IOV");
+            // This should not occur in normal situations so we force job to abort.
+            throw std::runtime_error("Unable to apply " + getName() + " alignments.");
+        }
+        // loop over all the AlignableTransform objects in the collection
+        for (DataVector<AlignableTransform>::const_iterator pat=container->begin();
+        pat!=container->end();++pat) {
+
+            bool status = processKey((*pat)->tag(),*pat);
+            alignmentChange = (alignmentChange || status);
+        }
+        return alignmentChange;
+    } 
+
+    bool FaserDetectorManager::processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const
+    {
+        bool alignmentChange = false;
+
+        // Check if container is empty - this can occur if it is an invalid IOV.
+        if (container->empty()) {
+            ATH_MSG_ERROR("AlignableTransformContainer " 
+                          << " is empty. Probably due to out of range IOV"); // To Do: add key to this printout for making it more informative
+            // This should not occur in normal situations so we force job to abort.
+            throw std::runtime_error("Unable to apply " + getName() + " alignments.");
+        }
+        // loop over all the AlignableTransform objects in the collection
+        // use only the last ones.
+        // /Indet/AlignL3/SCTEA9 appear repeatedly in tags of the /Indet/AlignL3 folder
+        std::map<const std::string, const AlignableTransform*> stringToTransform;
+        for (DataVector<AlignableTransform>::const_iterator pat=container->begin();
+             pat!=container->end();++pat) {
+            stringToTransform[(*pat)->tag()] = *pat;
+        }
+        for (std::pair<const std::string, const AlignableTransform*> value: stringToTransform) {
+            bool status = processKey(value.first, value.second, alignStore);
+            alignmentChange = (alignmentChange || status);
+        }
+        return alignmentChange;
+    }
+
+    bool FaserDetectorManager::processKey(const std::string key,
+                                          const AlignableTransform* transformCollection,
+                                          GeoVAlignmentStore* alignStore) const 
+    {  
+        bool alignmentChange = false;
+
+        // From the key determine what level in hierarchy we are dealing with.
+        // returns -1 if unrecognized.  
+        const LevelInfo & levelInfo = getLevel(key);
+        if (levelInfo.isValid()) {
+            ATH_MSG_VERBOSE("Processing channel: " << key);
+        } else {
+            ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
+        }
+        // return silently if unrecognised - this can happen in container mode
+        // when a single container holds transforms for both pixel and SCT
+        if (!levelInfo.isValid() ) return false;
+
+        //Loop over the effected nodes.
+        for (AlignableTransform::AlignTransMem_citr trans_iter = transformCollection->begin(); 
+             trans_iter != transformCollection->end(); 
+             ++trans_iter) {
+            ATH_MSG_DEBUG( "Get alignment for identifier " 
+                           << getIdHelper()->show_to_string(trans_iter->identify())  
+                           << " at level " << levelInfo.level());
+
+            // The delta in the conditions DB is not necessarily the same as what is needed in the
+            // alignable transform. At the moment we support global frame, local frame or an alternative frame
+            // The setAlignableTransformDelta method takes care of this correction - this is CLHEP <--> Amg interfaced
+            bool status = setAlignableTransformDelta(levelInfo.level(), 
+                                                     trans_iter->identify(),
+                                                     Amg::CLHEPTransformToEigen(trans_iter->transform()),
+                                                     levelInfo.frame(),
+                                                     alignStore);
+
+            alignmentChange = (alignmentChange || status);
+
+            if (!status) {
+                if (!identifierBelongs(trans_iter->identify())) {
+                    // Its probably OK. Eg /Indet/Align/ID contains alse pixel and sct ids.
+                    ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier."
+                                //   << " Probably OK if its /Indet/Align/ID folder. "  
+                                  << getIdHelper()->show_to_string(trans_iter->identify())  
+                                  << " at level " << levelInfo.level());
+                } else {
+                    if (m_suppressWarnings) {
+                        ATH_MSG_DEBUG("WARNING: Cannot set AlignableTransform for identifier  " 
+                                      << getIdHelper()->show_to_string(trans_iter->identify())  
+                                      << " at level " << levelInfo.level());
+                    } else {
+                        ATH_MSG_WARNING("Cannot set AlignableTransform for identifier  " 
+                                        << getIdHelper()->show_to_string(trans_iter->identify())  
+                                        << " at level " << levelInfo.level());
+                        ATH_MSG_WARNING("Subsequent WARNINGS will be printed at DEBUG level.");
+                        m_suppressWarnings = true; 
+                    }
+                }
+            }  
+        }
+        return alignmentChange;
+    }
+
+  // We provide a default implementation of any detector specific alignment.
+    bool FaserDetectorManager::processGlobalAlignmentContainer(const std::string & key,
+                                                               const CondAttrListCollection* obj,
+                                                               GeoVAlignmentStore* alignStore) const
+    {
+      bool alignmentChange = false;
+
+      ATH_MSG_DEBUG("processing GlobalAlignmentContainer with key:  " << key);
+      // From the key determine what level in hierarchy we are dealing with.                                                                                   
+      // returns -1 if unrecognized.                                                                                                                           
+      const LevelInfo & levelInfo = getLevel(key);
+      if (levelInfo.isValid()) {
+          ATH_MSG_VERBOSE("Processing channel: " << key);
+      } else {
+          ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
+      }
+      // return silently if unrecognised - this can happen in container mode                                                                                   
+      // when a single container holds transforms for both pixel and SCT                                                                                       
+      if (!levelInfo.isValid() ) return false;
+        
+      // Within detector specific code
+      bool status = processGlobalAlignment(key, levelInfo.level(), levelInfo.frame(), obj, alignStore);
+      
+      alignmentChange = (alignmentChange || status);
+
+      return alignmentChange;
+
+    }
+  
+  // We provide a default implementation of any detector specific alignment.                                                                                 
+    bool FaserDetectorManager::processGlobalAlignment(const std::string &, int /*level*/, FrameType /*frame*/,
+                                                      const CondAttrListCollection* /*obj*/, GeoVAlignmentStore* /*alignStore*/) const
+    {
+        return false;
+    }
+
+
+  // We provide a default implementation of any detector specific alignment.
+    bool FaserDetectorManager::processSpecialAlignment(const std::string &, FaserDD::AlignFolderType) const
+    {
+        return false;
+    }
+
+
+} // namespace FaserDD
diff --git a/DetectorDescription/FaserReadoutGeometry/src/Version.cxx b/DetectorDescription/FaserReadoutGeometry/src/Version.cxx
new file mode 100644
index 00000000..0975220f
--- /dev/null
+++ b/DetectorDescription/FaserReadoutGeometry/src/Version.cxx
@@ -0,0 +1,121 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "FaserReadoutGeometry/Version.h"
+
+#include <sstream>
+#include <string>
+#include <iomanip>
+
+namespace FaserDD {
+
+Version::Version(const std::string & tag, 
+		 const std::string & name, 
+		 const std::string & layout, 
+		 const std::string & description, 
+		 int major,
+		 int minor,
+		 int patch)
+  : m_tag(tag),
+    m_name(name),
+    m_layout(layout),
+    m_description(description),
+    m_major(major),
+    m_minor(minor),
+    m_patch(patch)
+{}
+
+// For backward compatibility
+Version::Version(const std::string & name, 
+		 const std::string & layout, 
+		 const std::string & description, 
+		 int major,
+		 int minor,
+		 int patch)
+  : m_tag("-"),
+    m_name(name),
+    m_layout(layout),
+    m_description(description),
+    m_major(major),
+    m_minor(minor),
+    m_patch(patch)
+{}
+
+
+
+Version::Version()
+  : m_major(0),
+    m_minor(0),
+    m_patch(0)
+{}
+
+const std::string & 
+Version::tag() const 
+{
+  return m_tag;
+}
+
+const std::string & 
+Version::name() const 
+{
+  return m_name;
+}
+
+const std::string & 
+Version::layout() const 
+{
+  return m_layout;
+}
+
+const std::string & 
+Version::description() const 
+{
+  return m_description;
+}
+
+int 
+Version::majorNum() const 
+{
+  return m_major;
+}
+
+int 
+Version::minorNum() const 
+{
+  return m_minor;
+}
+
+int 
+Version::patchNum() const 
+{
+  return m_patch;
+}
+
+std::string 
+Version::versionNumber() const
+{
+  std::ostringstream ostr;
+  ostr << m_major 
+       << "." << std::setfill('0') << std::setw(2) << m_minor 
+       << "." << std::setfill('0') << std::setw(2) << m_patch;
+  return ostr.str();
+}
+
+std::string  
+Version::fullDescription() const 
+{
+
+  //  Output of the form
+  //  Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 02.01.01, Description: DC1 Geometry
+
+  std::ostringstream ostr;
+  ostr << "Version: " << m_tag << ", Name: " << m_name << ", Layout: " << m_layout 
+       << ", Code Version: " << versionNumber();
+  if (!m_description.empty()) { 
+    ostr << ", Description: " << m_description;
+  }
+  return ostr.str();
+}
+
+} // namespace FaserDD
diff --git a/Scintillator/ScintDetDescr/Veto_GeoModel/CMakeLists.txt b/Scintillator/ScintDetDescr/Veto_GeoModel/CMakeLists.txt
deleted file mode 100644
index 2c2a1a8c..00000000
--- a/Scintillator/ScintDetDescr/Veto_GeoModel/CMakeLists.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-################################################################################
-# Package: Veto_GeoModel
-################################################################################
-
-# Declare the package name:
-atlas_subdir( Veto_GeoModel )
-
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaKernel
-                          Database/RDBAccessSvc
-                          DetectorDescription/GeoModel/GeoModelUtilities
-                          DetectorDescription/GeoModel/GeoModelFaserUtilities
-			              DetectorDescription/GeoPrimitives
-                          GaudiKernel
-                          InnerDetector/InDetDetDescr/InDetGeoModelUtils
-                          Scintillator/ScintDetDescr/ScintReadoutGeometry
-                          PRIVATE
-                          Control/SGTools
-                          Control/StoreGate
-                          Database/AthenaPOOL/AthenaPoolUtilities
-                          DetectorDescription/DetDescrCond/DetDescrConditions
-                          DetectorDescription/GeoModel/GeoModelInterfaces
-                          DetectorDescription/GeometryDBSvc
-                          DetectorDescription/Identifier
-                          Scintillator/ScintDetDescr/ScintIdentifier )
-
-# External dependencies:
-find_package( Boost COMPONENTS filesystem thread system )
-find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess )
-find_package( Eigen )
-find_package( GeoModel )
-
-# Component(s) in the package:
-atlas_add_component( Scint_GeoModel
-		     src/*.cxx
-                     src/components/*.cxx
-                     INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} 
-                     LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel GeoModelUtilities GeoModelFaserUtilities GaudiKernel InDetGeoModelUtils ScintReadoutGeometry SGTools StoreGateLib SGtests AthenaPoolUtilities DetDescrConditions Identifier ScintIdentifier )
-
-# Install files from the package:
-atlas_install_python_modules( python/*.py )
-
-- 
GitLab