From 1a3e314994708727f255a4e36d09b6806f27c1de Mon Sep 17 00:00:00 2001
From: Ke Li <ke.li@cern.ch>
Date: Sat, 1 Oct 2022 11:42:07 +0200
Subject: [PATCH] Add dipole and update scintillator layers in ACTS tracking
 geometry and material mapping

---
 .../G4FaserAlg/test/runGeantinoScan.py        |  42 ++---
 .../FaserActsGeometry/FaserActsLayerBuilder.h |  14 +-
 .../FaserActsMaterialMapping_jobOptions.py    |  13 +-
 .../FaserActsWriteTrackingGeometryConfig.py   |   2 +-
 .../src/CuboidVolumeBuilder.cxx               |   2 -
 .../src/FaserActsLayerBuilder.cxx             | 154 +++++++++++++++---
 .../src/FaserActsMaterialMapping.cxx          |   3 +-
 .../src/FaserActsTrackingGeometrySvc.cxx      |  23 ++-
 .../src/FaserActsTrackingGeometrySvc.h        |   2 +-
 .../test/FaserActsWriteTrackingGeometry.py    |   2 +-
 10 files changed, 184 insertions(+), 73 deletions(-)

diff --git a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
index 7e0a93719..46021eb4b 100644
--- a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
+++ b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
@@ -19,41 +19,34 @@ if __name__ == "__main__":
     from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
     from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
     from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserMaterialStepRecorderAlgCfg
     from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
+    from G4FaserServices.G4FaserUserActionConfigNew import UserActionMaterialStepRecorderSvcCfg
 #
 # Set up logging and new style config
 #
     log.setLevel(VERBOSE)
     Configurable.configurableRun3Behavior = True
-#
-# Input settings (Generator file)
-#
-#   from AthenaConfiguration.TestDefaults import defaultTestFiles
-#   ConfigFlags.Input.Files = defaultTestFiles.EVNT
-#
-# Alternatively, these must ALL be explicitly set to run without an input file
-# (if missing, it will try to read metadata from a non-existent file and crash)
-#
+    from AthenaConfiguration.Enums import ProductionStep
+    ConfigFlags.Common.ProductionStep = ProductionStep.Simulation
+    ConfigFlags.Sim.ReleaseGeoModel     = False
     ConfigFlags.Input.Files = [""]
     ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
+    ConfigFlags.Input.RunNumber = [12345]
+    ConfigFlags.Input.OverrideRunNumber = True
+    ConfigFlags.Input.LumiBlockNumber = [1]
+    Configurable.configurableRun3Behavior = 1
     ConfigFlags.Common.isOnline = False
     ConfigFlags.Beam.Type = "collisions"
     ConfigFlags.Beam.Energy = 7*TeV                              # Informational, does not affect simulation
-    ConfigFlags.GeoModel.FaserVersion = "FASER-01"               # Always needed
-    ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01"             # Always needed; must match FaserVersion
-# Workaround for bug/missing flag; unimportant otherwise 
+    ConfigFlags.GeoModel.FaserVersion = "FASERNU-03"               # Always needed
+    ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
     ConfigFlags.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
 #
 # Output settings
 #
     ConfigFlags.Output.HITSFileName = "MaterialStepCollection.root"
     ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
+    ConfigFlags.GeoModel.Align.Dynamic  = False
 #
 # Geometry-related settings
 # Do not change!
@@ -61,8 +54,6 @@ if __name__ == "__main__":
     detectors = ['Veto', 'Trigger', 'Preshower', 'FaserSCT', 'Dipole', 'Ecal']
     from CalypsoConfiguration.DetectorConfigFlags import setupDetectorsFromList
     setupDetectorsFromList(ConfigFlags, detectors, toggle_geometry=True)
-    ConfigFlags.GeoModel.Align.Dynamic  = False
-    ConfigFlags.Sim.ReleaseGeoModel     = False
 #
 # All flags should be set before calling lock
 #
@@ -79,9 +70,9 @@ if __name__ == "__main__":
     pg.McEventKey = "BeamTruthEvent"
     pg.randomSeed = 123456
     pg.sampler.pid = 999
-    pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/20], phi=[0, 2*pi])
-    pg.sampler.pos = PG.PosSampler(x=[-5, 5], y=[-5, 5], z=-2100.0, t=0.0)
-    acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4
+    pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/200], phi=[0, 2*pi])
+    pg.sampler.pos = PG.PosSampler(x=[-150, 150], y=[-150, 150], z=-2100.0, t=0.0)
+    acc.addEventAlgo(pg, "AthBeginSeq", primary =  True) # to run *before* G4
 #
 # Only one of these two should be used in a given job
 # (MCEventSelectorCfg for generating events with no input file,
@@ -107,7 +98,8 @@ if __name__ == "__main__":
 #  Here is the configuration of the Geant4 pieces
 #    
     acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserMaterialStepRecorderAlgCfg(ConfigFlags))
+    acc.merge(UserActionMaterialStepRecorderSvcCfg(ConfigFlags))
+    acc.merge(G4FaserAlgCfg(ConfigFlags))
     acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
 #
 # Verbosity
@@ -125,4 +117,4 @@ if __name__ == "__main__":
 #
 # Execute and finish
 #
-    sys.exit(int(acc.run(maxEvents=20000).isFailure()))
+    sys.exit(int(acc.run(maxEvents=1000000).isFailure()))
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
index 132fd1ca2..52aa75240 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
@@ -51,9 +51,10 @@ public:
     std::string                          configurationName = "undefined";
     FaserActsDetectorElement::Subdetector subdetector
         = FaserActsDetectorElement::Subdetector::SCT;
-    const TrackerDD::SCT_DetectorManager*   mng;
-    const GeoVDetectorManager*   vetomng;
-    const GeoVDetectorManager*   triggermng;
+    const TrackerDD::SCT_DetectorManager*   mng=nullptr;
+    const GeoVDetectorManager*   vetomng=nullptr;
+    const GeoVDetectorManager*   triggermng=nullptr;
+    const GeoVDetectorManager*   dipolemng=nullptr;
     std::shared_ptr<const Acts::LayerCreator> layerCreator = nullptr;
     std::shared_ptr<std::vector<std::shared_ptr<const FaserActsDetectorElement>>> elementStore;
     std::shared_ptr<std::map<Identifier, Acts::GeometryIdentifier>> identifierMap;
@@ -109,15 +110,16 @@ public:
 
 private:
 
-  FaserActs::CuboidVolumeBuilder::VolumeConfig buildScintVolume(double , double , std::string );
+  FaserActs::CuboidVolumeBuilder::VolumeConfig buildScintVolume(const Acts::GeometryContext& ,double, double, double ,double, double,  double , std::string );
+FaserActs::CuboidVolumeBuilder::VolumeConfig buildDipoleVolume(const Acts::GeometryContext& ,double , double , double , double , std::string );
 
   double m_ModuleWidth;
   double m_ModuleLength;
   /// configruation object
   Config m_cfg;
-  Acts::Vector3 m_worldDimensions = { 400.0_mm, 400.0_mm, 8000.0_mm };
+  Acts::Vector3 m_worldDimensions = { 600.0_mm, 600.0_mm, 8000.0_mm };
   Acts::Vector3 m_worldCenter = {0.0, 0.0, 0.0};
-  Acts::Vector3 m_trackerDimensions = { 400.0_mm, 400.0_mm, 100.0_mm };
+  Acts::Vector3 m_trackerDimensions = { 600.0_mm, 600.0_mm, 100.0_mm };
 
   /// Private access to the logger
   const Acts::Logger&
diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
index 99e81e8cd..92c1b6039 100644
--- a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
+++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
@@ -26,10 +26,6 @@ from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
 def ActsMaterialMappingCfg(configFlags, name = "FaserActsMaterialMapping", **kwargs):
   result = ComponentAccumulator()
 
-  MaterialStepConverterTool = ActsMaterialStepConverterToolCfg()
-  kwargs["MaterialStepConverterTool"] = MaterialStepConverterTool.getPrimary()   
-  result.merge(MaterialStepConverterTool)
-
   ActsSurfaceMappingTool = ActsSurfaceMappingToolCfg(configFlags)
   kwargs["SurfaceMappingTool"] = ActsSurfaceMappingTool.getPrimary()   
   result.merge(ActsSurfaceMappingTool)
@@ -64,11 +60,10 @@ if "__main__" == __name__:
   ## Just enable ID for the moment.
   ConfigFlags.Input.isMC             = True
   ConfigFlags.Beam.Type = "collisions" 
-  ConfigFlags.GeoModel.FaserVersion  = "FASER-01"
-  ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01"             # Always needed; must match FaserVersion
+  ConfigFlags.GeoModel.FaserVersion  = "FASERNU-03"
+  ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
   ConfigFlags.TrackingGeometry.MaterialSource = "geometry-maps.json"
-  ConfigFlags.Concurrency.NumThreads = 1
-  ConfigFlags.Concurrency.NumConcurrentEvents = 1
+  ConfigFlags.GeoModel.Align.Dynamic = False
 
   ConfigFlags.lock()
   ConfigFlags.dump()
@@ -101,4 +96,4 @@ if "__main__" == __name__:
 
   log.info("CONFIG DONE")
 
-  cfg.run(80000)
+  cfg.run(-1)
diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py
index c760be884..77e6921bf 100644
--- a/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py
+++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py
@@ -31,7 +31,7 @@ def FaserActsWriteTrackingGeometryBasicCfg(flags, **kwargs):
     actsWriteTrackingGeometry.ObjWriterTool=FaserActsObjWriterTool("FaserActsObjWriterTool",OutputDirectory="./", SubDetectors=["Station_0","Station_1","Station_2","Station_3"])
     actsWriteTrackingGeometry.MaterialJsonWriterTool= FaserActsMaterialJsonWriterTool(OutputFile = "geometry-maps.json",
        processSensitives = False,
-       processnonmaterial = True)
+       processnonmaterial = False)
 
     acc.addEventAlgo(actsWriteTrackingGeometry)
     return acc
diff --git a/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx b/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx
index df96a311c..e382d4cd3 100644
--- a/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx
@@ -138,8 +138,6 @@ std::shared_ptr<Acts::TrackingVolume> CuboidVolumeBuilder::buildVolume(
 
     cfg.layerCfg.push_back(lCfg);
   }
-  else{
-  }
 
   // Gather the layers
   Acts::LayerVector layVec;
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx
index 8ed2d7893..c5f6a68ab 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx
@@ -12,11 +12,13 @@
 #include "FaserActsGeometry/CuboidVolumeBuilder.h"
 #include "ActsInterop/IdentityHelper.h"
 #include "GeoModelKernel/GeoBox.h"
+#include "GeoModelKernel/GeoTube.h"
 
 // ACTS
 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
 #include "Acts/Surfaces/CylinderSurface.hpp"
 #include "Acts/Surfaces/PlaneSurface.hpp"
+#include "Acts/Surfaces/DiscSurface.hpp"
 #include "Acts/Surfaces/RectangleBounds.hpp"
 #include "Acts/Geometry/GenericApproachDescriptor.hpp"
 #include "Acts/Geometry/ApproachDescriptor.hpp"
@@ -89,41 +91,63 @@ FaserActs::CuboidVolumeBuilder::Config FaserActsLayerBuilder::buildVolume(const
   //veto station
   //Veto A, VetoRadiator, Veto B
   auto vetoManager = static_cast<const GeoVDetectorManager*>(m_cfg.vetomng);
+  if(vetoManager!=nullptr){
   for(unsigned int i=0; i<vetoManager->getNumTreeTops(); i++){
     auto vol0 = vetoManager->getTreeTop(i)->getLogVol();
     //get the shape params and translation
     const GeoBox* shape = dynamic_cast<const GeoBox*>(vol0->getShape());
     auto trans = vetoManager->getTreeTop(i)->getX();
     if(vetoManager->getTreeTop(i)->getNChildVols()==0){
-      volumeConfigs.emplace_back(buildScintVolume(trans.translation().z(), shape->getZHalfLength(),vol0->getName()));
+      volumeConfigs.emplace_back(buildScintVolume(gctx, trans.translation().x(),trans.translation().y(),trans.translation().z(), shape->getXHalfLength(),shape->getYHalfLength(),shape->getZHalfLength(),vol0->getName()));
     }
     else{
       for(size_t j =0 ;j< vetoManager->getTreeTop(i)->getNChildVols();j++){
 	auto childtrans=vetoManager->getTreeTop(i)->getXToChildVol(j);
 	const GeoBox* childshape = dynamic_cast<const GeoBox*>(vetoManager->getTreeTop(i)->getChildVol(j)->getLogVol()->getShape());
-	volumeConfigs.emplace_back(buildScintVolume(trans.translation().z() + childtrans.translation().z(), childshape->getZHalfLength(),vol0->getName()+std::string("_")+std::to_string(j)));
+	volumeConfigs.emplace_back(buildScintVolume(gctx, trans.translation().x() + childtrans.translation().x(),trans.translation().y() + childtrans.translation().y(),trans.translation().z() + childtrans.translation().z(), childshape->getXHalfLength(), childshape->getXHalfLength(), childshape->getZHalfLength(),vol0->getName()+std::string("_")+std::to_string(j)));
       }
     }
   }
+  }
   //build trigger stations
   auto triggerManager = static_cast<const GeoVDetectorManager*>(m_cfg.triggermng);
+  if(triggerManager!=nullptr){
   for(unsigned int i=0; i<triggerManager->getNumTreeTops(); i++){
     auto vol0 = triggerManager->getTreeTop(i)->getLogVol();
     //get the shape params and translation
     const GeoBox* shape = dynamic_cast<const GeoBox*>(vol0->getShape());
     auto trans = triggerManager->getTreeTop(i)->getX();
     if(triggerManager->getTreeTop(i)->getNChildVols()==0){
-      volumeConfigs.emplace_back(buildScintVolume(trans.translation().z(), shape->getZHalfLength(),vol0->getName()));
+      volumeConfigs.emplace_back(buildScintVolume(gctx,  trans.translation().x(), trans.translation().y(),trans.translation().z(), shape->getXHalfLength(), shape->getYHalfLength(), shape->getZHalfLength(),vol0->getName()));
     }
     else{
       for(size_t j =0 ;j< triggerManager->getTreeTop(i)->getNChildVols();j++){
 	auto childtrans=triggerManager->getTreeTop(i)->getXToChildVol(j);
 	const GeoBox* childshape = dynamic_cast<const GeoBox*>(triggerManager->getTreeTop(i)->getChildVol(j)->getLogVol()->getShape());
-	volumeConfigs.emplace_back(buildScintVolume(trans.translation().z() + childtrans.translation().z(), childshape->getZHalfLength(),vol0->getName()+std::string("_")+std::to_string(j)));
+	volumeConfigs.emplace_back(buildScintVolume(gctx, trans.translation().x() + childtrans.translation().x(), trans.translation().y() + childtrans.translation().y(), trans.translation().z() + childtrans.translation().z(), childshape->getXHalfLength(), childshape->getYHalfLength(), childshape->getZHalfLength(),vol0->getName()+std::string("_")+std::to_string(j)));
       }
     }
   }
+  }
 
+  //build dipole magnets
+  auto dipoleManager = static_cast<const GeoVDetectorManager*>(m_cfg.dipolemng);
+  for(unsigned int i=0; i<dipoleManager->getNumTreeTops(); i++){
+    auto vol0 = dipoleManager->getTreeTop(i)->getLogVol();
+    //get the shape params and translation
+    const GeoTube* shape = dynamic_cast<const GeoTube*>(vol0->getShape());
+    auto trans = dipoleManager->getTreeTop(i)->getX();
+    if(dipoleManager->getTreeTop(i)->getNChildVols()==0){
+      volumeConfigs.emplace_back(buildDipoleVolume(gctx, trans.translation().z(), shape->getZHalfLength(), shape->getRMin(), shape->getRMax(), vol0->getName()+std::string("_")+std::to_string(i)));
+    }
+    else{
+      for(size_t j =0 ;j< dipoleManager->getTreeTop(i)->getNChildVols();j++){
+	auto childtrans=dipoleManager->getTreeTop(i)->getXToChildVol(j);
+	const GeoTube* childshape = dynamic_cast<const GeoTube*>(dipoleManager->getTreeTop(i)->getChildVol(j)->getLogVol()->getShape());
+	volumeConfigs.emplace_back(buildDipoleVolume(gctx, trans.translation().z() + childtrans.translation().z(), childshape->getZHalfLength(), childshape->getRMin(), childshape->getRMax(), vol0->getName()+std::string("_")+std::to_string(j)));
+      }
+    }
+  }
 
   //sort the geometry by the  Z position, neccessary to have the correct boundary
   auto sortFunc = [](FaserActs::CuboidVolumeBuilder::VolumeConfig& v1, FaserActs::CuboidVolumeBuilder::VolumeConfig& v2){return v1.position.z()<v2.position.z();};
@@ -242,7 +266,8 @@ FaserActsLayerBuilder::buildLayers(const Acts::GeometryContext& gctx,
 
 }
 
-FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildScintVolume(double zpos, double zhalflength, std::string name){
+
+FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildDipoleVolume(const Acts::GeometryContext& gctx, double zpos, double zhalflength, double rmin, double rmax, std::string name){
 
   FaserActs::CuboidVolumeBuilder::VolumeConfig volumeConfig;
 
@@ -253,7 +278,6 @@ FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildScintVo
   FaserActs::CuboidVolumeBuilder::SurfaceConfig surfacecfg;
   surfacecfg.position = Acts::Vector3(0, 0, zpos);
   surfacecfg.thickness=zhalflength;
-  layercfg.active = true;
 
   std::vector<std::shared_ptr<const Acts::Surface>> surfaces;
   surfaces.clear();
@@ -264,37 +288,52 @@ FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildScintVo
   layercfg.active = true;
 
   //bounds are hard coded
-  auto rBounds = std::make_shared<const Acts::RectangleBounds>( 130.*1_mm, 130.*1_mm) ;
-  surfacecfg.rBounds=rBounds;
   layercfg.surfaceCfg = surfacecfg;
 
+  Transform3 transformCenter(Translation3(0., 0., (zpos)*1_mm));
 
-  Transform3 transformInner(Translation3(0., 0., (zpos)*1_mm));
+  std::shared_ptr<Acts::DiscSurface> centerBoundary =
+   Acts::Surface::makeShared<Acts::DiscSurface>(
+   transformCenter, rmin, rmax);
 
-  std::shared_ptr<Acts::PlaneSurface> innerBoundary 
-    = Acts::Surface::makeShared<Acts::PlaneSurface>(transformInner, rBounds);
+  Transform3 transformInner(Translation3(0., 0., (zpos-zhalflength)*1_mm));
+
+  std::shared_ptr<Acts::DiscSurface> innerBoundary =
+   Acts::Surface::makeShared<Acts::DiscSurface>(
+   transformInner, rmin, rmax);
+
+  Transform3 transformOuter(Translation3(0., 0., (zpos+zhalflength)*1_mm));
 
+  std::shared_ptr<Acts::DiscSurface> outerBoundary =
+   Acts::Surface::makeShared<Acts::DiscSurface>(
+   transformOuter, rmin, rmax);
 
-  size_t matBinsX = m_cfg.MaterialBins.first;
+
+//  size_t matBinsX = m_cfg.MaterialBins.first;
   size_t matBinsY = m_cfg.MaterialBins.second;
+//  set bin size to 1 at phi and MaterialBins-Y at r direction
+  Acts::BinUtility materialBinUtil(1, -M_PI, M_PI, Acts::closed, Acts::binPhi);
+  materialBinUtil +=
+    Acts::BinUtility(matBinsY, rmin, rmax, Acts::open, Acts::binR, transformInner);
+
+  std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy =
+    std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
 
-  Acts::BinUtility materialBinUtil(
-      matBinsX, -130*1_mm, 130.*1_mm, Acts::open, Acts::binX);
-  materialBinUtil += Acts::BinUtility(
-      matBinsY, -130*1_mm, 130.*1_mm, Acts::open, Acts::binY, transformInner);
 
-  std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy
-    = std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
   innerBoundary->assignSurfaceMaterial(materialProxy);
 
   std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces;
   aSurfaces.push_back(std::move(innerBoundary));
+//  aSurfaces.push_back(std::move(centerBoundary));
+//  aSurfaces.push_back(std::move(outerBoundary));
+  Acts::ProtoLayer pl(gctx, aSurfaces);
 
   layercfg.surfaces = aSurfaces;
-  layerConfigs.push_back(layercfg);
+  layercfg.approachDescriptor = new Acts::GenericApproachDescriptor(aSurfaces);
 
+  layerConfigs.push_back(layercfg);
   volumeConfig.position = Acts::Vector3(0, 0, zpos); 
-  Acts::Vector3 length= { 300.0*1_mm, 300.0*1_mm, zhalflength*2.*1_mm };
+  Acts::Vector3 length= { 500.0*1_mm, 500.0*1_mm, zhalflength*2.*1_mm };
   volumeConfig.length   = length;
   //volumeConfig.layerCfg = {};
   volumeConfig.layerCfg = layerConfigs;
@@ -304,4 +343,79 @@ FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildScintVo
 
 }
 
+FaserActs::CuboidVolumeBuilder::VolumeConfig FaserActsLayerBuilder::buildScintVolume(const Acts::GeometryContext& gctx, double xpos, double ypos, double zpos, double xhalflength, double yhalflength, double zhalflength, std::string name){
+
+  FaserActs::CuboidVolumeBuilder::VolumeConfig volumeConfig;
+
+  std::vector<FaserActs::CuboidVolumeBuilder::LayerConfig> layerConfigs;
+  layerConfigs.clear();
+
+  FaserActs::CuboidVolumeBuilder::LayerConfig layercfg;
+  FaserActs::CuboidVolumeBuilder::SurfaceConfig surfacecfg;
+  surfacecfg.position = Acts::Vector3(xpos, ypos, zpos);
+  surfacecfg.thickness=zhalflength;
+
+  std::vector<std::shared_ptr<const Acts::Surface>> surfaces;
+  surfaces.clear();
+
+  layercfg.binsX = 1;
+  layercfg.binsY = 1;
+
+  layercfg.active = true;
+
+  //bounds are hard coded
+  layercfg.surfaceCfg = surfacecfg;
+
+  auto rBounds = std::make_shared<const Acts::RectangleBounds>( xhalflength*1_mm, yhalflength*1_mm) ;
+//  surfacecfg.rBounds=rBounds;
+
+
+  Transform3 transformInner(Translation3(xpos*1_mm, ypos*1_mm, (zpos-zhalflength)*1_mm));
+
+  std::shared_ptr<Acts::PlaneSurface> innerBoundary =
+   Acts::Surface::makeShared<Acts::PlaneSurface>(
+   transformInner, rBounds);
+
+  Transform3 transformCenter(Translation3(xpos*1_mm, ypos*1_mm, zpos*1_mm));
+  std::shared_ptr<Acts::PlaneSurface> centerBoundary =
+   Acts::Surface::makeShared<Acts::PlaneSurface>(
+   transformCenter, rBounds);
+
+  Transform3 transformOuter(Translation3(xpos*1_mm, ypos*1_mm, (zpos+zhalflength)*1_mm));
+
+  std::shared_ptr<Acts::PlaneSurface> outerBoundary =
+   Acts::Surface::makeShared<Acts::PlaneSurface>(
+   transformOuter, rBounds);
+
+
+//  set bin size to 2 
+  Acts::BinUtility materialBinUtil(2, (0.-xhalflength)*1_mm, xhalflength*1_mm, Acts::open, Acts::binX);
+  materialBinUtil +=
+    Acts::BinUtility(2, (0.-yhalflength)*1_mm, yhalflength*1_mm, Acts::open, Acts::binY, transformInner);
+
+  std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy =
+    std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
+
+
+  innerBoundary->assignSurfaceMaterial(materialProxy);
+
+  std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces;
+  aSurfaces.push_back(std::move(innerBoundary));
+  aSurfaces.push_back(std::move(centerBoundary));
+  aSurfaces.push_back(std::move(outerBoundary));
+  Acts::ProtoLayer pl(gctx, aSurfaces);
+
+  layercfg.surfaces = aSurfaces;
+  layercfg.approachDescriptor = new Acts::GenericApproachDescriptor(aSurfaces);
+
+  layerConfigs.push_back(layercfg);
+  volumeConfig.position = Acts::Vector3(0, 0, zpos); 
+  Acts::Vector3 length= { 500.0*1_mm, 500.0*1_mm, zhalflength*2.*1_mm };
+  volumeConfig.length   = length;
+  //volumeConfig.layerCfg = {};
+  volumeConfig.layerCfg = layerConfigs;
+  volumeConfig.name     = name;
+
+  return volumeConfig;
 
+}
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialMapping.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialMapping.cxx
index 9edaa72ff..2595b42dc 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialMapping.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialMapping.cxx
@@ -79,7 +79,8 @@ StatusCode FaserActsMaterialMapping::execute(const EventContext &ctx) const {
     const Trk::MaterialStep* mat = *iter;
     Trk::MaterialStep* newmat  = const_cast<Trk::MaterialStep*>(mat);
     //remove the magnets, need to be updated
-    if((newmat->hitZ()<-1600&&newmat->hitZ()>-1920)||(newmat->hitZ()>-200&&newmat->hitZ()<100)||(newmat->hitZ()>1000&&newmat->hitZ()<1300)||(newmat->hitZ()>2000&&newmat->hitZ()<2500))
+//    if((newmat->hitZ()<-1600&&newmat->hitZ()>-1920)||(newmat->hitZ()>-200&&newmat->hitZ()<100)||(newmat->hitZ()>1000&&newmat->hitZ()<1300)||(newmat->hitZ()>2000&&newmat->hitZ()<2500))
+    if(newmat->hitZ()>-1920&&newmat->hitZ()<2500)
       newmaterialStepCollection->push_back(newmat);
   }
   if(newmaterialStepCollection->size()<1)
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
index c6f476e7c..a45c7c06d 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
@@ -63,9 +63,10 @@ FaserActsTrackingGeometrySvc::initialize()
 
   //get all the subdetectors
   const GeoModelExperiment* theExpt = nullptr;
-  ATH_CHECK( m_detStore->retrieve( theExpt ));
+  ATH_CHECK( m_detStore->retrieve( theExpt ,"FASER"));
   const GeoVDetectorManager *vetoManager = theExpt->getManager("Veto");
   const GeoVDetectorManager *triggerManager = theExpt->getManager("Trigger");
+  const GeoVDetectorManager *dipoleManager = theExpt->getManager("Dipole");
 
   Acts::LayerArrayCreator::Config lacCfg;
   auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
@@ -104,7 +105,7 @@ FaserActsTrackingGeometrySvc::initialize()
     // SCT
     tgbConfig.trackingVolumeBuilders.push_back([&](
 	  const auto& gctx, const auto& /*inner*/, const auto&) {
-	auto tv = makeVolumeBuilder(gctx, p_SCTManager, vetoManager, triggerManager);
+	auto tv = makeVolumeBuilder(gctx, p_SCTManager, vetoManager, triggerManager, dipoleManager);
 	return tv->trackingVolume(gctx);
 	});
   }
@@ -151,7 +152,7 @@ FaserActsTrackingGeometrySvc::trackingGeometry() {
 }
 
 std::shared_ptr<const Acts::ITrackingVolumeBuilder>
-FaserActsTrackingGeometrySvc::makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager, const GeoVDetectorManager* vetoManager, const GeoVDetectorManager* triggerManager)
+FaserActsTrackingGeometrySvc::makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager, const GeoVDetectorManager* vetoManager, const GeoVDetectorManager* triggerManager, const GeoVDetectorManager* dipoleManager)
 {
   std::string managerName = manager->getName();
 
@@ -161,8 +162,18 @@ FaserActsTrackingGeometrySvc::makeVolumeBuilder(const Acts::GeometryContext& gct
   cfg.subdetector = FaserActsDetectorElement::Subdetector::SCT;
   cfg.mng = static_cast<const TrackerDD::SCT_DetectorManager*>(manager);
   //get veto and trigger manager
-  cfg.vetomng = static_cast<const GeoVDetectorManager*>(vetoManager);
-  cfg.triggermng = static_cast<const GeoVDetectorManager*>(triggerManager);
+  if(vetoManager!=nullptr)
+    cfg.vetomng = static_cast<const GeoVDetectorManager*>(vetoManager);
+  else
+    ATH_MSG_WARNING(name() << " can not find veto stations");
+  if(triggerManager!=nullptr)
+    cfg.triggermng = static_cast<const GeoVDetectorManager*>(triggerManager);
+  else
+    ATH_MSG_WARNING(name() << " can not find trigger stations");
+  if(dipoleManager!=nullptr)
+    cfg.dipolemng = static_cast<const GeoVDetectorManager*>(dipoleManager);
+  else
+    ATH_MSG_WARNING(name() << " can not find dipoles");
   cfg.elementStore = m_elementStore;
   cfg.identifierMap = m_identifierMap;
   std::vector<size_t> matBins(m_MaterialBins);
@@ -181,8 +192,6 @@ FaserActsTrackingGeometrySvc::populateAlignmentStore(FaserActsAlignmentStore *st
   // populate the alignment store with all detector elements
   m_trackingGeometry->visitSurfaces(
       [store](const Acts::Surface* srf) {
-      FaserActsGeometryContext constructionContext;
-      constructionContext.construction = true;
       const Acts::DetectorElementBase* detElem = srf->associatedDetectorElement();
       if(detElem){
       const auto* gmde = dynamic_cast<const FaserActsDetectorElement*>(detElem);
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.h b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.h
index 83ef0efae..3b191202b 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.h
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.h
@@ -71,7 +71,7 @@ public:
 
 private:
   std::shared_ptr<const Acts::ITrackingVolumeBuilder>
-  makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager, const GeoVDetectorManager* vetoManager, const GeoVDetectorManager* triggerManager);
+  makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager, const GeoVDetectorManager* vetoManager, const GeoVDetectorManager* triggerManager, const GeoVDetectorManager* dipoleManager);
 
   ServiceHandle<StoreGateSvc> m_detStore;
   const TrackerDD::SCT_DetectorManager* p_SCTManager;
diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
index 21dfba7e5..ed998b3b4 100644
--- a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
+++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
@@ -17,7 +17,7 @@ log.setLevel(DEBUG)
 Configurable.configurableRun3Behavior = True
 
 # Configure
-ConfigFlags.Input.Files = ["my03.HITS.pool.root"]
+ConfigFlags.Input.Files = ["myevt4.HITS.pool.root"]
 #ConfigFlags.Output.RDOFileName = "myRDO_sp.pool.root"
 ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
 ConfigFlags.GeoModel.FaserVersion = "FASERNU-03"               # Always needed
-- 
GitLab