diff --git a/InnerDetector/InDetConfig/python/ITkConfigFlags.py b/InnerDetector/InDetConfig/python/ITkConfigFlags.py
index 9e22248894f30474d4e3834b841facf375e3ed8d..3eb9e05f4b3aa3edab784734695f63ea3c0c1e07 100644
--- a/InnerDetector/InDetConfig/python/ITkConfigFlags.py
+++ b/InnerDetector/InDetConfig/python/ITkConfigFlags.py
@@ -9,6 +9,7 @@ def createITkConfigFlags():
   # take geometry XML files from local instance rather than Detector Database, for development
   itkcf.addFlag("ITk.pixelGeometryFilename", "ITKLayouts/Pixel/ITkPixel.gmx")
   itkcf.addFlag("ITk.stripGeometryFilename", "ITKLayouts/Strip/ITkStrip.gmx")
+  itkcf.addFlag("ITk.bcmPrimeGeometryFilename", "ITKLayouts/Pixel/BCMPrime.gmx")
 
   itkcf.addFlag("ITk.doPrintConfigurables",False) # if this is on all the print(ITkXYZ) lines are activated
   itkcf.addFlag("ITk.doSplitReco", False    	 ) # Turn running of the truth seeded pseudo tracking only for pileup on and off. Only makes sense to run on RDO file where SplitDigi was used!
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorFactory.h b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0f349e66f049223d1014680ca99857f3898250
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorFactory.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef BCMPRIMEGEOMODELXML_BCMPRIMEDETECTORFACTORY_H 
+#define BCMPRIMEGEOMODELXML_BCMPRIMEDETECTORFACTORY_H 
+
+#include "InDetGeoModelUtils/InDetDetectorFactoryBase.h" 
+#include "BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h"
+
+namespace InDetDD {class AthenaComps;}
+class GeoPhysVol;
+
+namespace InDetDDSLHC {
+  class BCMPrimeOptions;
+
+  //
+  //    Main routine to build the GeoModel geometry, and handle the GeometryManager and 
+  //    DetectorManager.
+  // 
+  class BCMPrimeDetectorFactory : public InDetDD::DetectorFactoryBase {   
+  public: 
+
+    BCMPrimeDetectorFactory(InDetDD::AthenaComps *athenaComps, 
+                            BCMPrimeOptions &options);
+    virtual ~BCMPrimeDetectorFactory(); 
+
+    /** Creation of geometry */
+    virtual void create(GeoPhysVol *world);
+  
+    /** Access to the results */
+    virtual InDetDD::BCMPrimeDetectorManager * getDetectorManager() const;
+
+  private: 
+
+    // Copy and assignments operations illegal and so are made private
+    BCMPrimeDetectorFactory(BCMPrimeDetectorFactory &right); 
+    BCMPrimeDetectorFactory & operator=(BCMPrimeDetectorFactory &right); 
+
+    InDetDD::BCMPrimeDetectorManager *m_detectorManager;
+    InDetDD::AthenaComps *m_athenaComps;
+    BCMPrimeOptions *m_options;
+  }; 
+}  
+#endif 
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorTool.h b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f3fef9652e422a92cd7404c178782fb118c89c6
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeDetectorTool.h
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef BCMPRIMEGEOMODELXML_BCMPRIMEDETECTORTOOL_H
+#define BCMPRIMEGEOMODELXML_BCMPRIMEDETECTORTOOL_H
+
+#include "GeoModelUtilities/GeoModelTool.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include <string>
+
+class IGeoModelSvc;
+class IRDBAccessSvc;
+class IGeoDbTagSvc;
+class IGeometryDBSvc;
+
+namespace InDetDD {
+  class AthenaComps;
+  class BCMPrimeDetectorManager;
+}
+
+/** @class BCMPrimeDetectorTool
+
+    Create an Athena Tool; handle Athena services and Tools needed for
+    building the BCM' geometry. Then create the geometry using the BCMPrimeDetectorFactory.
+
+    @author  Jakob Novak <jakob.novak@cern.ch>
+
+    */
+
+class BCMPrimeDetectorTool : public GeoModelTool {
+ public: 
+  BCMPrimeDetectorTool(const std::string &type, const std::string &name, const IInterface *parent);
+  virtual ~BCMPrimeDetectorTool();
+  StatusCode create() override final;
+  StatusCode clear() override final;
+  StatusCode registerCallback() override final;
+  virtual StatusCode align(IOVSVC_CALLBACK_ARGS_P(I,keys)) override;
+  
+ private:
+  std::string m_detectorName;
+  bool m_alignable;
+  std::string m_gmxFilename;
+  const InDetDD::BCMPrimeDetectorManager *m_manager;
+  InDetDD::AthenaComps *m_athenaComps;
+  ServiceHandle<IRDBAccessSvc> m_rdbAccessSvc;
+  ServiceHandle<IGeometryDBSvc> m_geometryDBSvc;
+  ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc;
+};
+
+#endif // BCMPRIMEGEOMODELXML_BCMPRIMEDETECTORTOOL_H
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeGmxInterface.h b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeGmxInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..2935d6c6a08ebe90ee746d913d8f650371d4540b
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeGmxInterface.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef BCMPRIMEGEOMODELXML_BCMPRIMEGMXINTERFACE_H
+#define BCMPRIMEGEOMODELXML_BCMPRIMEGMXINTERFACE_H
+
+#include "GeoModelXml/GmxInterface.h"
+
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+
+class MsgStream;
+namespace InDetDD {class BCMPrimeDetectorManager;}
+
+namespace ITk {
+
+  class BCMPrimeGmxInterface: public GmxInterface {
+  public:
+    BCMPrimeGmxInterface(InDetDD::BCMPrimeDetectorManager *detectorManager);
+    ~BCMPrimeGmxInterface();
+    virtual int sensorId(std::map<std::string, int> &index) const override final;
+    virtual void addAlignable(int /*level*/, std::map<std::string, int> &index,
+                              GeoVFullPhysVol *fpv, GeoAlignableTransform *transform) override final;
+
+  private:
+    InDetDD::BCMPrimeDetectorManager *m_detectorManager;
+    std::unique_ptr<MsgStream> m_log;
+  };
+
+} // namespace ITk
+
+#endif // BCMPRIMEGEOMODELXML_BCMPRIMEGMXINTERFACE_H
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeOptions.h b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeOptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe3a0c729cf2dfff19496646fb451d96e3e19047
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/BCMPrimeGeoModelXml/BCMPrimeOptions.h
@@ -0,0 +1,76 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef BCMPRIMEGEOMODELXML_BCMPRIMEOPTIONS_H
+#define BCMPRIMEGEOMODELXML_BCMPRIMEOPTIONS_H
+#include <string>
+
+namespace InDetDDSLHC {
+
+  //
+  //    Class to store run time options.
+  //
+  class BCMPrimeOptions {
+  public:
+    BCMPrimeOptions();
+    bool alignable() const;
+    bool alignAtModuleLevel() const;
+    std::string gmxFilename() const;
+    std::string detectorName() const;
+    void setAlignable(bool flag = true);
+    void setAlignAtModuleLevel(bool flag = true);
+    void setGmxFilename(std::string filename); 
+    void setDetectorName(std::string detectorname);
+
+  private:
+    bool m_alignable;
+    bool m_alignModule;
+    std::string m_gmxFilename;
+    std::string m_detectorName;
+  };
+
+  //
+  // Inlined methods
+  //
+  inline BCMPrimeOptions::BCMPrimeOptions() :
+    m_alignable(true),
+    m_alignModule(true), 
+    m_gmxFilename(""),
+    m_detectorName("BCMPrime")
+      {}
+
+  inline bool BCMPrimeOptions::alignable() const {
+    return m_alignable;
+  }
+
+  inline bool BCMPrimeOptions::alignAtModuleLevel() const {
+    return m_alignModule;
+  }
+
+  inline std::string BCMPrimeOptions::gmxFilename() const {
+    return m_gmxFilename;
+  }
+
+  inline std::string BCMPrimeOptions::detectorName() const {
+    return m_detectorName;
+  }
+
+  inline void BCMPrimeOptions::setAlignable(bool flag) {
+    m_alignable = flag;
+  }
+
+  inline void BCMPrimeOptions::setAlignAtModuleLevel(bool flag) {
+    m_alignModule = flag;
+  }
+
+  inline void BCMPrimeOptions::setGmxFilename(std::string filename) {
+    m_gmxFilename = filename;
+  }
+
+  inline void BCMPrimeOptions::setDetectorName(std::string detectorname) {
+    m_detectorName = detectorname;
+  }
+
+}
+#endif // BCMPRIMEGEOMODELXML_BCMPRIMEOPTIONS_H
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/CMakeLists.txt b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3317939b6f1c7b8ee6689ee17a643e68d291bf11
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( BCMPrimeGeoModelXml )
+
+# External dependencies:
+find_package( GeoModel COMPONENTS GeoModelKernel )
+
+# Component(s) in the package:
+atlas_add_library( BCMPrimeGeoModelXmlLib
+                   src/*.cxx
+                   PUBLIC_HEADERS BCMPrimeGeoModelXml
+                   PRIVATE_INCLUDE_DIRS ${GEOMODEL_INCLUDE_DIRS}
+                   LINK_LIBRARIES GaudiKernel GeoModelUtilities GeoModelXml InDetGeoModelUtils BCMPrimeReadoutGeometry
+                   PRIVATE_LINK_LIBRARIES ${GEOMODEL_LIBRARIES} AthenaPoolUtilities DetDescrConditions GeoModelInterfaces GeometryDBSvcLib InDetSimEvent PathResolver RDBAccessSvcLib SGTools StoreGateLib )
+
+atlas_add_component( BCMPrimeGeoModelXml
+                     src/components/*.cxx
+                     LINK_LIBRARIES BCMPrimeGeoModelXmlLib )
+                     
+# Install files from the package:
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/python/BCMPrimeGeoModelConfig.py b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/python/BCMPrimeGeoModelConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca94302ae4b31479b692da8360fc455b526e1e33
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/python/BCMPrimeGeoModelConfig.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+
+def BCMPrimeGeometryCfg(flags):
+    from AtlasGeoModel.GeoModelConfig import GeoModelCfg
+    acc = GeoModelCfg(flags)
+    geoModelSvc = acc.getPrimary()
+
+    GeometryDBSvc = CompFactory.GeometryDBSvc
+    acc.addService(GeometryDBSvc("BCMPrimeGeometryDBSvc"))
+
+    BCMPrimeDetectorTool = CompFactory.BCMPrimeDetectorTool
+    bcmPrimeDetectorTool = BCMPrimeDetectorTool()
+    bcmPrimeDetectorTool.Alignable = False # make this a flag? Set true as soon as decided on folder structure
+    bcmPrimeDetectorTool.DetectorName = "BCMPrime"
+    if flags.GeoModel.useLocalGeometry:
+      # Setting this filename triggers reading from local file rather than DB
+      bcmPrimeDetectorTool.GmxFilename = flags.ITk.bcmPrimeGeometryFilename
+    geoModelSvc.DetectorTools += [ bcmPrimeDetectorTool ]
+
+    return acc
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorFactory.cxx b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorFactory.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3e46bc3016821c38df98f0c3bf14c646f7ac77b6
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorFactory.cxx
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BCMPrimeGeoModelXml/BCMPrimeDetectorFactory.h"
+#include "BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h"
+
+#include <string>
+#include <sstream>
+
+#include "StoreGate/StoreGateSvc.h" // For alignment getAlignableFolderType()
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "DetDescrConditions/AlignableTransformContainer.h"
+
+#include "InDetGeoModelUtils/InDetDDAthenaComps.h"
+#include "GeoModelKernel/GeoPhysVol.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+
+#include "BCMPrimeGeoModelXml/BCMPrimeOptions.h"
+#include "GeoModelXml/Gmx2Geo.h"
+#include "BCMPrimeGeoModelXml/BCMPrimeGmxInterface.h"
+#include "GeoModelXml/GmxInterface.h"
+
+#include "PathResolver/PathResolver.h"
+
+using namespace std;
+
+namespace InDetDDSLHC {
+
+  BCMPrimeDetectorFactory::BCMPrimeDetectorFactory(InDetDD::AthenaComps *athenaComps,
+                                                   BCMPrimeOptions &options) :
+    InDetDD::DetectorFactoryBase(athenaComps),
+    m_athenaComps(athenaComps),
+    m_options(&options) 
+  {
+  
+    // Create the detector manager
+    m_detectorManager = new InDetDD::BCMPrimeDetectorManager(detStore(),m_options->detectorName());
+  }
+
+  BCMPrimeDetectorFactory::~BCMPrimeDetectorFactory() {
+    // NB the detector manager (m_detectorManager) is stored in the detector store by the Tool and so we don't delete it.
+  }
+
+  void BCMPrimeDetectorFactory::create(GeoPhysVol *world) {
+    ATH_MSG_INFO( "C R E A T E   W O R L D" );
+   
+    ITk::BCMPrimeGmxInterface gmxInterface(m_detectorManager);
+    //    To set up solid geometry only, without having to worry about sensitive detectors etc., and get loads of debug output,
+    //    comment out above line and uncomment the following line; also, switch header files above.
+    //    GmxInterface gmxInterface;
+    
+    int flags(0);
+    string gmxInput;
+    
+    if (m_options->gmxFilename().empty()) {
+      ATH_MSG_ERROR( "gmxFilename not set; getting .gmx from Geometry database Blob not supported");
+      // gmxInput = getBlob();
+    }
+    else {
+      flags = 0;
+      gmxInput = PathResolver::find_file(m_options->gmxFilename(), "DATAPATH");
+      if (gmxInput.empty()) { // File not found
+        string errMessage("BCMPrimeDetectorFactory::create: Unable to find file " + m_options->gmxFilename() +
+                            " with PathResolver; check filename and DATAPATH environment variable");
+        throw runtime_error(errMessage);
+      }
+    }
+    
+    Gmx2Geo gmx2Geo(gmxInput, world, gmxInterface, flags);
+
+    //
+    //   Add the tree-top to the detector manager.
+    //
+    unsigned int nChildren = world->getNChildVols();
+    bool foundVolume = false;
+
+    for (int iChild = nChildren - 1; iChild>=0; --iChild) {
+      if (world->getNameOfChildVol(iChild) == "BCMPrime") {
+        // The * converts from a ConstPVLink to a reference to a GeoVPhysVol;
+        // the & takes its address.
+        foundVolume  = true;
+        m_detectorManager->addTreeTop(&*world->getChildVol(iChild));
+        break;
+      }
+    }
+    
+    if(!foundVolume) ATH_MSG_ERROR("Could not find a logicalVolume named \"BCMPrime\" - this is required to provide the Envelope!");
+
+  }
+  
+  InDetDD::BCMPrimeDetectorManager * BCMPrimeDetectorFactory::getDetectorManager() const {
+    return m_detectorManager;
+  }
+
+
+}
+
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorTool.cxx b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d5a92a63ea88bac864d55fd7f0793491ced3fd99
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeDetectorTool.cxx
@@ -0,0 +1,163 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BCMPrimeGeoModelXml/BCMPrimeDetectorTool.h"
+#include "BCMPrimeGeoModelXml/BCMPrimeDetectorFactory.h"
+#include "BCMPrimeGeoModelXml/BCMPrimeOptions.h"
+#include "InDetGeoModelUtils/InDetDDAthenaComps.h"
+#include "GeoModelUtilities/GeoModelExperiment.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "GeometryDBSvc/IGeometryDBSvc.h"
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+#include "DetDescrConditions/AlignableTransformContainer.h"
+#include "SGTools/DataProxy.h"
+
+BCMPrimeDetectorTool::BCMPrimeDetectorTool(const std::string &type,
+                                           const std::string &name,
+                                           const IInterface *parent) :
+    GeoModelTool(type, name, parent),
+    m_detectorName("BCMPrime"),
+    m_alignable(false),
+    m_gmxFilename(""),
+    m_manager(nullptr),
+    m_athenaComps(nullptr),
+    m_rdbAccessSvc("RDBAccessSvc", name),
+    m_geometryDBSvc("InDetGeometryDBSvc", name),
+    m_geoDbTagSvc{"GeoDbTagSvc", name}
+
+    {
+
+    //
+    // Get parameter values from jobOptions file
+    //
+    declareProperty("DetectorName", m_detectorName);
+    declareProperty("Alignable", m_alignable);
+    declareProperty("GmxFilename", m_gmxFilename);
+    declareProperty("RDBAccessSvc", m_rdbAccessSvc);
+    declareProperty("GeometryDBSvc", m_geometryDBSvc);
+    declareProperty("GeoDbTagSvc", m_geoDbTagSvc);
+
+}
+
+BCMPrimeDetectorTool::~BCMPrimeDetectorTool() {
+    delete m_athenaComps;
+}
+
+StatusCode BCMPrimeDetectorTool::create() {
+
+    //
+    //   Retrieve all services
+    //
+    // Get the detector configuration.
+    ATH_CHECK(m_geoDbTagSvc.retrieve());
+    ATH_CHECK(m_rdbAccessSvc.retrieve());
+    ATH_CHECK(m_geometryDBSvc.retrieve());
+    GeoModelExperiment *theExpt;
+    ATH_CHECK(detStore()->retrieve(theExpt, "ATLAS"));
+
+    //
+    //    Get their interfaces to pass to the DetectorFactory
+    //
+    m_athenaComps = new InDetDD::AthenaComps("BCMPrimeGeoModelXml");
+    m_athenaComps->setDetStore(&*(detStore()));
+    m_athenaComps->setRDBAccessSvc(&*m_rdbAccessSvc);
+    m_athenaComps->setGeometryDBSvc(&*m_geometryDBSvc);
+    m_athenaComps->setGeoDbTagSvc(&*m_geoDbTagSvc);
+
+    //
+    //    Get options from python
+    //
+    InDetDDSLHC::BCMPrimeOptions options;
+    options.setAlignable(m_alignable);
+    options.setGmxFilename(m_gmxFilename);
+    options.setDetectorName(m_detectorName);
+
+    //
+    // Create the BCMPrimeDetectorFactory
+    //
+    // The * converts a ConstPVLink to a ref to a GeoVPhysVol
+    // The & takes the address of the GeoVPhysVol
+    GeoPhysVol *world = &*theExpt->getPhysVol();
+    InDetDDSLHC::BCMPrimeDetectorFactory bcmPrime(m_athenaComps, options);
+    bcmPrime.create(world);
+
+    //
+    // Get the manager from the factory and store it in the detector store.
+    //
+    m_manager = bcmPrime.getDetectorManager();
+
+    if (!m_manager) {
+        ATH_MSG_ERROR( "PixelDetectorManager not found; not created in BCMPrimeDetectorFactory?" );
+        return(StatusCode::FAILURE);
+    }
+
+    StatusCode sc;
+    sc = detStore()->record(m_manager, m_manager->getName());
+    if (sc.isFailure() ) {
+        ATH_MSG_ERROR( "Could not register BCMPrimeDetectorManager" );
+        return StatusCode::FAILURE;
+    }
+    theExpt->addManager(m_manager);
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode BCMPrimeDetectorTool::clear() {
+    SG::DataProxy* proxy = detStore()->proxy(ClassID_traits<InDetDD::BCMPrimeDetectorManager>::ID(),m_manager->getName());
+    if(proxy) {
+        proxy->reset();
+        m_manager = nullptr;
+    }
+    return StatusCode::SUCCESS;
+}
+
+StatusCode BCMPrimeDetectorTool::registerCallback() {
+
+    // 
+    //    Register call-back for software alignment
+    //
+    StatusCode sc = StatusCode::FAILURE;
+    if (m_alignable) {
+        std::string folderName = "/ITk/Align";
+        if (detStore()->contains<AlignableTransformContainer>(folderName)) {
+            ATH_MSG_DEBUG( "Registering callback on AlignableTransformContainer with folder " << folderName );
+            const DataHandle<AlignableTransformContainer> atc;
+            sc =  detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool *>(this), atc, folderName);
+            if(sc.isFailure()) {
+                ATH_MSG_ERROR( "Could not register callback on AlignableTransformContainer with folder " << 
+                                    folderName );
+            } 
+        } 
+        else {
+            ATH_MSG_WARNING( "Unable to register callback on AlignableTransformContainer with folder " <<
+                                 folderName << ", Alignment disabled (only if no Run2 scheme is loaded)!" );
+        }
+    } 
+    else {
+        ATH_MSG_INFO( "Alignment disabled. No callback registered" );
+        // We return failure otherwise it will try and register a GeoModelSvc callback associated with this callback.
+    }
+    return sc;
+}
+
+StatusCode BCMPrimeDetectorTool::align(IOVSVC_CALLBACK_ARGS_P(I, keys)) {
+
+    //
+    //    The call-back routine, which just calls the real call-back routine from the manager.
+    //
+    if (!m_manager) {
+        ATH_MSG_WARNING( "Manager does not exist" );
+        return StatusCode::FAILURE;
+    }
+    if (m_alignable) {
+        return m_manager->align(I, keys);
+    } 
+    else {
+        ATH_MSG_DEBUG( "Alignment disabled. No alignments applied" );
+        return StatusCode::SUCCESS;
+    }
+}
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeGmxInterface.cxx b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeGmxInterface.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2a60d023a495f7412bf96be5b918c244355741c9
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/BCMPrimeGmxInterface.cxx
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BCMPrimeGeoModelXml/BCMPrimeGmxInterface.h"
+
+#include <cstdlib>
+#include <sstream>
+
+#include "InDetSimEvent/SiHitIdHelper.h" 
+
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IMessageSvc.h" 
+#include "GaudiKernel/MsgStream.h"
+
+#include "BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h"
+
+using namespace std;
+
+namespace ITk {
+
+  BCMPrimeGmxInterface::BCMPrimeGmxInterface(InDetDD::BCMPrimeDetectorManager *detectorManager):
+    m_detectorManager(detectorManager)
+  {
+    // Logging: ref https://wiki.bnl.gov/dayabay/index.php?title=Logging
+    // Turn on logging in job-options with: MessageSvc.setDebug += {"BCMPrimeGmxInterface"}
+    ServiceHandle<IMessageSvc> msgh("MessageSvc", "BCMPrimeGmxInterface");
+    
+    m_log = std::make_unique<MsgStream>(&(*msgh), "BCMPrimeGmxInterface");
+
+  }
+
+  BCMPrimeGmxInterface::~BCMPrimeGmxInterface() {
+  }
+
+  int BCMPrimeGmxInterface::sensorId(map<string, int> &index) const {
+    //
+    //    Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers")
+    //
+    
+    int hitIdOfModule = SiHitIdHelper::GetHelper()->buildHitId(0, 0, index["diamond_number"], 
+                  index["module_number"], 0, 0);
+
+    *m_log << MSG::DEBUG  << "Index list: " << index["diamond_number"] << " " << index["module_number"] << endmsg;
+    *m_log << MSG::DEBUG << "hitIdOfModule = " << std::hex << hitIdOfModule << std::dec << endmsg;
+    *m_log << MSG::DEBUG << " dia = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfModule) <<
+                            " mod = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfModule) << endmsg;
+    return hitIdOfModule;
+  }
+
+  void BCMPrimeGmxInterface::addAlignable(int /*level*/, std::map<std::string, int> &index,
+                                          GeoVFullPhysVol *fpv, GeoAlignableTransform *transform)
+  {
+    *m_log << MSG::DEBUG  << "alignable transform added for indices: " << index["diamond_number"] << " " << index["module_number"] << endmsg;
+
+    // A preliminary id scheme
+    int id = index["diamond_number"] + 8*index["module_number"];
+
+    m_detectorManager->addAlignableTransform(id, transform, fpv);
+  }
+
+} // namespace ITk
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/components/BCMPrimeGeoModelXml_entries.cxx b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/components/BCMPrimeGeoModelXml_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8b044e46b9f475c8d5a293b1a7e95e5128b3fd77
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml/src/components/BCMPrimeGeoModelXml_entries.cxx
@@ -0,0 +1,3 @@
+#include "BCMPrimeGeoModelXml/BCMPrimeDetectorTool.h"
+
+DECLARE_COMPONENT( BCMPrimeDetectorTool )
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..959d5f46362b6608a7193f264aacf5754a63965e
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h
@@ -0,0 +1,83 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef BCMPRIMEREADOUTGEOMETRY_BCMPRIMEDETECTORMANAGER_H
+#define BCMPRIMEREADOUTGEOMETRY_BCMPRIMEDETECTORMANAGER_H
+
+#include "GeoPrimitives/GeoPrimitives.h"
+
+#include "GeoModelKernel/GeoVPhysVol.h"
+#include "GeoModelKernel/GeoVDetectorManager.h"
+
+#include "GeoModelKernel/GeoAlignableTransform.h"
+
+// Message Stream Member
+#include "AthenaKernel/MsgStreamMember.h"
+
+#include "AthenaKernel/IIOVSvc.h"
+
+class StoreGateSvc;
+
+/** @class BCMPrimeDetectorManager
+
+    The Detector manager registers the call backs and infrastructure to
+    associate the alignment transforms with the appropriate alignable
+    transform in GeoModel.
+
+    @author Jakob Novak <jakob.novak@cern.ch>
+
+    */
+
+namespace InDetDD {
+
+    class BCMPrimeDetectorManager : public GeoVDetectorManager {
+    public:
+
+        /** Constructor */
+        BCMPrimeDetectorManager(StoreGateSvc* detStore, const std::string & name);
+
+        /** Destructor */
+        ~BCMPrimeDetectorManager();
+
+        /** Access to raw geometry: */
+        virtual unsigned int getNumTreeTops()           const;
+        virtual PVConstLink  getTreeTop(unsigned int i) const;
+
+        /** Add a Tree top: */
+        virtual void addTreeTop (PVLink treeTop);
+
+        void addAlignableTransform (int /*id*/, GeoAlignableTransform * /*transform*/, const GeoVPhysVol * /*child*/);
+        StatusCode align( IOVSVC_CALLBACK_ARGS ) const;
+
+        /** 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; }
+
+    private:
+
+        /** Prevent copy and assignment */
+        const BCMPrimeDetectorManager & operator=(const BCMPrimeDetectorManager &right);
+        BCMPrimeDetectorManager(const BCMPrimeDetectorManager &right);
+
+        /** Private member data */
+        std::vector<PVLink>              m_volume;
+
+        /** Detector store */
+        StoreGateSvc * m_detStore;
+
+        /** Declaring private message stream member */
+        mutable Athena::MsgStreamMember  m_msg;
+
+    };
+
+} // namespace InDetDD
+
+#ifndef GAUDI_NEUTRAL
+#include "AthenaKernel/CLASS_DEF.h"
+CLASS_DEF(InDetDD::BCMPrimeDetectorManager, 162824294, 1)
+#endif
+
+#endif // BCMPRIMEREADOUTGEOMETRY_BCMPRIMEDETECTORMANAGER_H
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/CMakeLists.txt b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3840b153e71e9f37d7ede6526dcc410082a19a5a
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( BCMPrimeReadoutGeometry )
+
+# External dependencies:
+find_package( GeoModel COMPONENTS GeoModelKernel )
+
+atlas_add_library( BCMPrimeReadoutGeometry
+  src/*.cxx
+  PUBLIC_HEADERS BCMPrimeReadoutGeometry
+  LINK_LIBRARIES ${GEOMODEL_LIBRARIES} AthenaKernel CxxUtils GeoPrimitives
+  PRIVATE_LINK_LIBRARIES AthenaBaseComps AthenaPoolUtilities )
+
diff --git a/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/src/BCMPrimeDetectorManager.cxx b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/src/BCMPrimeDetectorManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..333c1eb595f87b0f39af246fbd9b8c3743afd707
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/BCMPrimeReadoutGeometry/src/BCMPrimeDetectorManager.cxx
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BCMPrimeReadoutGeometry/BCMPrimeDetectorManager.h"
+
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
+
+namespace InDetDD {
+
+    BCMPrimeDetectorManager::BCMPrimeDetectorManager(StoreGateSvc* detStore, const std::string & name)
+                        : m_detStore(detStore)
+    {
+        setName(name);
+    }
+
+    BCMPrimeDetectorManager::~BCMPrimeDetectorManager() {
+
+        //
+        // Clean up
+        //
+        for (size_t i=0; i < m_volume.size(); i++) {
+            m_volume[i]->unref();
+        }
+    }
+
+    unsigned int BCMPrimeDetectorManager::getNumTreeTops() const {
+        return m_volume.size();
+    }
+
+    PVConstLink BCMPrimeDetectorManager::getTreeTop(unsigned int i) const {
+        return m_volume[i];
+    }
+
+    void BCMPrimeDetectorManager::addTreeTop(PVLink vol) {
+        vol->ref();
+        m_volume.push_back(vol);
+    }
+
+    void BCMPrimeDetectorManager::addAlignableTransform(int /*id*/, 
+                                                        GeoAlignableTransform * /*transform*/,
+                                                        const GeoVPhysVol * /*child*/)
+    {
+        // Here alignment transforms will be added
+    }
+
+    StatusCode BCMPrimeDetectorManager::align( IOVSVC_CALLBACK_ARGS_P( /*I*/, /*keys*/) ) const {
+        // Here alignment transform deltas will be set
+        return StatusCode::SUCCESS;
+    }
+
+} // namespace InDetDD