diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9a46a954291cc94e931b6915370d5e6e688db9bc..3cba605b33ce3adcd9ad6a604170521570005156 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,7 +25,7 @@ build_image:
     - mkdir build
     - cd build
     - set +e && source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh; set -e
-    - set +e && asetup --input=../../calypso/asetup.faser Athena,22.0.31; set -e
+    - set +e && asetup --input=../../calypso/asetup.faser Athena,22.0.40; set -e
     - cmake ../../calypso
     - make -j 3
   artifacts:
@@ -41,8 +41,8 @@ test_unittest:
     - yum -y install man
     - cd build
     - set +e && source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh; set -e
-    - set +e && asetup --input=../../calypso/asetup.faser Athena,22.0.31; set -e 
+    - set +e && asetup --input=../../calypso/asetup.faser Athena,22.0.40; set -e 
     - set +e && source `find . -name 'setup.sh'`; set -e
-    - ctest -j12
+    - ctest -j3
   dependencies:
     - build_image
diff --git a/Calorimeter/CaloDetDescr/CaloIdDictFiles/data/IdDictCalorimeter_TB00.xml b/Calorimeter/CaloDetDescr/CaloIdDictFiles/data/IdDictCalorimeter_TB00.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c932a0c74bfeaf9d15648d49eb6a2cfa5aeb49b8
--- /dev/null
+++ b/Calorimeter/CaloDetDescr/CaloIdDictFiles/data/IdDictCalorimeter_TB00.xml
@@ -0,0 +1,27 @@
+<IdDictionary name="Calorimeter">
+
+  <field name="part" >
+    <label name="Ecal" value="1" />
+  </field>
+
+  <field name="row">
+    <label name="Bottom"       value="0" /> 
+    <label name="Top"          value="1" />
+  </field>
+
+  <field name="module">
+  <!-- facing downstream (hence "starboard" and "port")
+       x must increase right to left for a right-handed
+       coordinate system -->
+    <label name="Starboard"   value="0" />
+    <label name="Center"      value="1" />
+    <label name="Port"        value="2" />
+  </field>
+
+  <region>
+    <range field="part"       value="Ecal" />
+    <range field="row"        values="Bottom Top" wraparound="FALSE" />
+    <range field="module"     values="Starboard Center Port" wraparound="FALSE" />
+    <range field="pmt"        minvalue="0" maxvalue="0" />
+  </region>
+</IdDictionary>
\ No newline at end of file
diff --git a/Calorimeter/CaloDetDescr/CaloReadoutGeometry/CaloReadoutGeometry/CaloDetectorElement.h b/Calorimeter/CaloDetDescr/CaloReadoutGeometry/CaloReadoutGeometry/CaloDetectorElement.h
index 452822c0a481ba734b8c18aa5174cc04c3179e8f..a9b29abde4e5b14eaf7664488a030514aed1f474 100644
--- a/Calorimeter/CaloDetDescr/CaloReadoutGeometry/CaloReadoutGeometry/CaloDetectorElement.h
+++ b/Calorimeter/CaloDetDescr/CaloReadoutGeometry/CaloReadoutGeometry/CaloDetectorElement.h
@@ -38,6 +38,7 @@ class GeoAlignmentStore;
 namespace Trk{
  class Surface;
  class SurfaceBounds;
+ constexpr DetectorElemType Calorimeter = DetectorElemType::Csc;
 }
 
 namespace CaloDD {
@@ -403,6 +404,10 @@ namespace CaloDD {
     public:
     
       const CaloCommonItems* getCommonItems() const;
+
+      /** TrkDetElementBase interface detectorType
+      */
+      virtual Trk::DetectorElemType detectorType() const override final;
     
       ///////////////////////////////////////////////////////////////////
       // Private methods:
@@ -514,7 +519,12 @@ namespace CaloDD {
     ///////////////////////////////////////////////////////////////////
     // Inline methods:
     ///////////////////////////////////////////////////////////////////
-       
+
+
+    inline Trk::DetectorElemType CaloDetectorElement::detectorType() const{
+      return Trk::Calorimeter;
+    }
+
     inline HepGeom::Point3D<double> CaloDetectorElement::globalPositionHit(const HepGeom::Point3D<double> &localPos) const
     {
       return Amg::EigenTransformToCLHEP(transformHit())*localPos;
diff --git a/Calorimeter/CaloDetDescr/EcalGeoModel/src/EcalDetectorTool.cxx b/Calorimeter/CaloDetDescr/EcalGeoModel/src/EcalDetectorTool.cxx
index bd4b729877d78083bbad2fa08091686d0c10f884..cdd48cd1f9287fd33b3158897f9b54cf4607d70e 100644
--- a/Calorimeter/CaloDetDescr/EcalGeoModel/src/EcalDetectorTool.cxx
+++ b/Calorimeter/CaloDetDescr/EcalGeoModel/src/EcalDetectorTool.cxx
@@ -65,7 +65,7 @@ EcalDetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the Ecal version tag:
   std::string ecalVersionTag{m_rdbAccessSvc->getChildTag("Ecal", versionKey.tag(), versionKey.node(), "FASERDD")};
-  ATH_MSG_INFO("Ecal Version: " << ecalVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Ecal Version: " << ecalVersionTag);
   // Check if version is empty. If so, then the Ecal cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (ecalVersionTag.empty()) {
@@ -181,7 +181,7 @@ EcalDetectorTool::clear()
 StatusCode 
 EcalDetectorTool::registerCallback ATLAS_NOT_THREAD_SAFE ()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
     if (m_useDynamicAlignFolders.value()) {
       ATH_MSG_WARNING("Called unsupported EcalDetectorTool::registerCallback() with useDynamicAlignFolders = true");
diff --git a/Calorimeter/FaserCaloSimEvent/src/CaloHitIdHelper.cxx b/Calorimeter/FaserCaloSimEvent/src/CaloHitIdHelper.cxx
index cdf4d186395589cc2f7b025201afc3e487028334..eec88553dae53bc6e415b385494b32a7f83645ad 100644
--- a/Calorimeter/FaserCaloSimEvent/src/CaloHitIdHelper.cxx
+++ b/Calorimeter/FaserCaloSimEvent/src/CaloHitIdHelper.cxx
@@ -48,8 +48,8 @@ void CaloHitIdHelper::Initialize() {
     if (detStore->retrieve(pix, "EcalID").isFailure()) { pix = 0; }
   }
 
-  InitializeField("Row", 0, 1);
-  InitializeField("Module", 0, 1);
+  InitializeField("Row", 0, 2);
+  InitializeField("Module", 0, 2);  // Need three values for test beam
 }
 
 // Station
diff --git a/Control/CalypsoConfiguration/python/AllConfigFlags.py b/Control/CalypsoConfiguration/python/AllConfigFlags.py
index cf26c40c3229ededad7f96a8080896e990cc30ef..3fd0a09b8d1ceedfdde7c1e83e2c75815c25fbe3 100644
--- a/Control/CalypsoConfiguration/python/AllConfigFlags.py
+++ b/Control/CalypsoConfiguration/python/AllConfigFlags.py
@@ -32,7 +32,7 @@ def _createCfgFlags():
     # acf=AthConfigFlags()
     fcf = athenaConfigFlags
 
-    fcf.Input.Files = ["_FASER_GENERIC_INPUTFILE_NAME_",]  # former global.InputFiles
+    fcf.Input.Files = ["_CALYPSO_GENERIC_INPUTFILE_NAME_",]  # former global.InputFiles
     # acf.addFlag('Input.SecondaryFiles', []) # secondary input files for DoubleEventSelector
     # acf.addFlag('Input.isMC', lambda prevFlags : "IS_SIMULATION" in GetFileMD(prevFlags.Input.Files).get("eventTypes",[]) ) # former global.isMC
     # acf.addFlag('Input.RunNumber', lambda prevFlags : list(GetFileMD(prevFlags.Input.Files).get("runNumbers",[]))) # former global.RunNumber
diff --git a/Control/CalypsoConfiguration/python/DetectorConfigFlags.py b/Control/CalypsoConfiguration/python/DetectorConfigFlags.py
index 5588000a509db94c0317d831ab1893a1461dde17..763f1176951ecef9e3ecb3a57d7b8a607d449bbb 100644
--- a/Control/CalypsoConfiguration/python/DetectorConfigFlags.py
+++ b/Control/CalypsoConfiguration/python/DetectorConfigFlags.py
@@ -220,35 +220,33 @@ def disableDetectors(flags, detectors, toggle_geometry=False):
 
 def modifyDetectorConfigFlags(flags):
     # disable problematic ATLAS flags by hand
-    flags.Detector.GeometryCSC = False
-    flags.Detector.GeometrysTGC = False
-    flags.Detector.GeometryMM = False
+    # flags.Detector.GeometryCSC = False
+    # flags.Detector.GeometrysTGC = False
+    # flags.Detector.GeometryMM = False
 
-    flags.Detector.EnableBCM = False
-    flags.Detector.EnableDBM = False
-    flags.Detector.EnablePixel = False
-    flags.Detector.EnableSCT = False
-    flags.Detector.EnableTRT = False
+    # flags.Detector.EnableBCM = False
+    # flags.Detector.EnableDBM = False
+    # flags.Detector.EnablePixel = False
+    # flags.Detector.EnableSCT = False
+    # flags.Detector.EnableTRT = False
 
     # Upgrade ITk Inner Tracker is a separate and parallel detector
-    flags.Detector.EnableBCMPrime = False
-    flags.Detector.EnableITkPixel = False
-    flags.Detector.EnableITkStrip = False
+    # flags.Detector.EnableBCMPrime = False
+    # flags.Detector.EnableITkPixel = False
+    # flags.Detector.EnableITkStrip = False
 
-    flags.Detector.EnableHGTD = False
+    # flags.Detector.EnableHGTD = False
 
     # Calorimeters
-    flags.Detector.EnableLAr = False
-    flags.Detector.EnableTile = False
+    # flags.Detector.EnableLAr = False
+    # flags.Detector.EnableTile = False
 
     # Muon Spectrometer
-    flags.Detector.EnableCSC = False 
-    flags.Detector.EnableMDT = False
-    flags.Detector.EnableRPC = False
-    flags.Detector.EnableTGC = False
-    flags.Detector.EnablesTGC = False
-    flags.Detector.EnableMM = False
-
-    flags.Detector.RecoIBL = False
+    # flags.Detector.EnableCSC = False 
+    # flags.Detector.EnableMDT = False
+    # flags.Detector.EnableRPC = False
+    # flags.Detector.EnableTGC = False
+    # flags.Detector.EnablesTGC = False
+    # flags.Detector.EnableMM = False
 
     return flags
\ No newline at end of file
diff --git a/Control/CalypsoExample/GenEventExample/src/GenEventReadAlg.h b/Control/CalypsoExample/GenEventExample/src/GenEventReadAlg.h
index b99e07a09e679336b85ab27d464f60cdc18c82d4..4e45d15d349898a6691d46eff484d4740c66a15d 100644
--- a/Control/CalypsoExample/GenEventExample/src/GenEventReadAlg.h
+++ b/Control/CalypsoExample/GenEventExample/src/GenEventReadAlg.h
@@ -29,6 +29,6 @@ class GenEventReadAlg : public AthHistogramAlgorithm
 
     // Read handle keys for data containers
     // Any other event data can be accessed identically
-    // Note the key names ("GEN_EVENT" or "SCT_Hits") are Gaudi properties and can be configured at run-time
-    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "GEN_EVENT" };
+    // Note the key names ("BeamTruthEvent" or "SCT_Hits") are Gaudi properties and can be configured at run-time
+    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "BeamTruthEvent" };
 };
\ No newline at end of file
diff --git a/Control/CalypsoExample/GeoModelTest/CMakeLists.txt b/Control/CalypsoExample/GeoModelTest/CMakeLists.txt
index d42aea9fde56245e7b3ffd663ba39a9280352e39..5c4205019552d4db08974473329ba6fdca37cb44 100644
--- a/Control/CalypsoExample/GeoModelTest/CMakeLists.txt
+++ b/Control/CalypsoExample/GeoModelTest/CMakeLists.txt
@@ -20,6 +20,11 @@ atlas_add_test( GeoModelCheck
                 PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
                 PROPERTIES TIMEOUT 300 )
 
+atlas_add_test( TestBeamGeoCheck
+                SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/python/TestBeamTestConfig.py
+                PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+                PROPERTIES TIMEOUT 300 )
+
 # Install files from the package:
 #atlas_install_headers( GeoModelTest )
 #atlas_install_joboptions( share/*.py )
diff --git a/Control/CalypsoExample/GeoModelTest/python/TestBeamTestConfig.py b/Control/CalypsoExample/GeoModelTest/python/TestBeamTestConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..641c9a7558a39389d33e2c6f220b951af096f7dc
--- /dev/null
+++ b/Control/CalypsoExample/GeoModelTest/python/TestBeamTestConfig.py
@@ -0,0 +1,72 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+#!/usr/bin/env python
+import sys
+from AthenaCommon.Constants import VERBOSE, INFO
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+def GeoModelTestCfg(flags, name="GeoModelTestAlg", **kwargs):
+
+    # Initialize GeoModel
+    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
+    a = FaserGeometryCfg(flags)
+
+    # Initialize field service
+    from MagFieldServices.MagFieldServicesConfig import MagneticFieldSvcCfg
+    a.merge(MagneticFieldSvcCfg(flags))
+    # Disable the field
+    cacheAlg = a.getCondAlgo("FaserFieldCacheCondAlg")
+    cacheAlg.UseDipoScale = 0.0
+    cacheAlg.UseDCS = False
+
+    # Configure the algorithm itself
+    GeoModelTestAlg = CompFactory.GeoModelTestAlg
+    a.addEventAlgo(GeoModelTestAlg(name, FirstSCTStation=0, 
+                                         LastSCTStation=0,
+                                         NumVetoStations=1, 
+                                         NumVetoPlatesPerStation=2,
+                                         NumTriggerStations=0,
+                                         **kwargs))
+
+    return a
+
+if __name__ == "__main__":
+    from AthenaCommon.Logging import log#, logging
+    from AthenaCommon.Configurable import Configurable
+    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+
+    Configurable.configurableRun3Behavior = True
+    
+# Flags for this job
+    ConfigFlags.Input.isMC = True                                # Needed to bypass autoconfig
+    ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
+    ConfigFlags.GeoModel.FaserVersion     = "FASER-TB00"           # Default FASER geometry
+    ConfigFlags.GeoModel.GeoExportFile    = "faserTestBeamGeo.db"        # Writes out a GeoModel file with the full geometry tree (optional, comment out to skip)
+    # ConfigFlags.Detector.EnableVeto     = True
+    # ConfigFlags.Detector.EnableTrigger  = True
+    # ConfigFlags.Detector.EnablePreshower= True
+    # ConfigFlags.Detector.EnableFaserSCT = True
+    # ConfigFlags.Detector.EnableUpstreamDipole = True
+    # ConfigFlags.Detector.EnableCentralDipole = True
+    # ConfigFlags.Detector.EnableDownstreamDipole = True
+    # ConfigFlags.Detector.EnableEcal = True
+    ConfigFlags.lock()
+
+# Configure components
+    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
+    acc = MainServicesCfg(ConfigFlags)
+
+# Set up algorithm
+    acc.merge(GeoModelTestCfg(ConfigFlags))
+
+# Configure verbosity    
+    msgSvc = acc.getService("MessageSvc")
+    msgSvc.Format = "% F%30W%S%7W%R%T %0W%M"
+    # ConfigFlags.dump()
+    # logging.getLogger('forcomps').setLevel(VERBOSE)
+    acc.foreach_component("*").OutputLevel = VERBOSE
+    acc.foreach_component("*ClassID*").OutputLevel = INFO
+    log.setLevel(VERBOSE)
+    
+# Execute and finish
+    sys.exit(int(acc.run(maxEvents=1).isFailure()))
diff --git a/Control/CalypsoExample/GeoModelTest/src/GeoModelTestAlg.cxx b/Control/CalypsoExample/GeoModelTest/src/GeoModelTestAlg.cxx
index 85bcd7e50311645693e8cba809cfc41e31beb093..2deb292d34deba66b91761a7a9d95f10fdcbf0c1 100644
--- a/Control/CalypsoExample/GeoModelTest/src/GeoModelTestAlg.cxx
+++ b/Control/CalypsoExample/GeoModelTest/src/GeoModelTestAlg.cxx
@@ -545,17 +545,17 @@ StatusCode GeoModelTestAlg::testVeto() const
     {
         ATH_MSG_ALWAYS("Retrieved (typed) Veto detector manager with " << vetoMgr->getNumTreeTops() << " treetops directly from DetStore.");
         // Compare numerology with the "right" answers from our properties
-        if (vetoMgr->numerology().numStations() != m_numVetoStations || vetoMgr->getNumTreeTops() != m_numVetoStations)
+        if (vetoMgr->numerology().numStations() != m_numVetoStations)
         {
             ATH_MSG_FATAL("Disagreement in number of veto stations.");
             return StatusCode::FAILURE;
         }
-        if (vetoMgr->numerology().numPlatesPerStation() != m_numVetoPlatesPerStation)
+        if (m_numVetoStations > 0 && vetoMgr->numerology().numPlatesPerStation() != m_numVetoPlatesPerStation)
         {
             ATH_MSG_FATAL("Disagreement in number of plates per veto station.");
             return StatusCode::FAILURE;
         }
-        if (vetoMgr->numerology().numPmtsPerPlate() != m_numVetoPmtsPerPlate)
+        if (m_numVetoStations > 0 && m_numVetoPlatesPerStation > 0 && vetoMgr->numerology().numPmtsPerPlate() != m_numVetoPmtsPerPlate)
         {
             ATH_MSG_FATAL("Disagreement in number of pmts per veto plate.");
             return StatusCode::FAILURE;
@@ -605,7 +605,7 @@ StatusCode GeoModelTestAlg::testVeto() const
                         return StatusCode::FAILURE;
                     }
                 }
-                if (next == nullptr && prev == nullptr)
+                if (next == nullptr && prev == nullptr && m_numVetoPlatesPerStation > 1)
                 {
                     ATH_MSG_FATAL("Veto element " << hash << " has no previous OR next neighbor.");
                     return StatusCode::FAILURE;
@@ -704,12 +704,12 @@ StatusCode GeoModelTestAlg::testTrigger() const
             ATH_MSG_FATAL("Disagreement in number of Trigger stations.");
             return StatusCode::FAILURE;
         }
-        if (triggerMgr->numerology().numPlatesPerStation() != m_numTriggerPlatesPerStation)
+        if (m_numTriggerStations > 0 && triggerMgr->numerology().numPlatesPerStation() != m_numTriggerPlatesPerStation)
         {
             ATH_MSG_FATAL("Disagreement in number of plates per Trigger station.");
             return StatusCode::FAILURE;
         }
-        if (triggerMgr->numerology().numPmtsPerPlate() != m_numTriggerPmtsPerPlate)
+        if (m_numTriggerStations > 0 && m_numTriggerPlatesPerStation > 0 && triggerMgr->numerology().numPmtsPerPlate() != m_numTriggerPmtsPerPlate)
         {
             ATH_MSG_FATAL("Disagreement in number of pmts per Trigger plate.");
             return StatusCode::FAILURE;
@@ -759,7 +759,7 @@ StatusCode GeoModelTestAlg::testTrigger() const
                         return StatusCode::FAILURE;
                     }
                 }
-                if (next == nullptr && prev == nullptr)
+                if (next == nullptr && prev == nullptr && m_numTriggerPlatesPerStation > 1)
                 {
                     ATH_MSG_FATAL("Trigger element " << hash << " has no previous OR next neighbor.");
                     return StatusCode::FAILURE;
@@ -858,12 +858,12 @@ StatusCode GeoModelTestAlg::testPreshower() const
             ATH_MSG_FATAL("Disagreement in number of preshower stations.");
             return StatusCode::FAILURE;
         }
-        if (preshowerMgr->numerology().numPlatesPerStation() != m_numPreshowerPlatesPerStation)
+        if (m_numPreshowerStations > 0 && preshowerMgr->numerology().numPlatesPerStation() != m_numPreshowerPlatesPerStation)
         {
             ATH_MSG_FATAL("Disagreement in number of plates per preshower station.");
             return StatusCode::FAILURE;
         }
-        if (preshowerMgr->numerology().numPmtsPerPlate() != m_numPreshowerPmtsPerPlate)
+        if (m_numPreshowerStations > 0 && m_numPreshowerPlatesPerStation > 0 && preshowerMgr->numerology().numPmtsPerPlate() != m_numPreshowerPmtsPerPlate)
         {
             ATH_MSG_FATAL("Disagreement in number of pmts per preshower plate.");
             return StatusCode::FAILURE;
@@ -913,7 +913,7 @@ StatusCode GeoModelTestAlg::testPreshower() const
                         return StatusCode::FAILURE;
                     }
                 }
-                if (next == nullptr && prev == nullptr)
+                if (next == nullptr && prev == nullptr && m_numPreshowerPlatesPerStation > 1)
                 {
                     ATH_MSG_FATAL("Preshower element " << hash << " has no previous OR next neighbor.");
                     return StatusCode::FAILURE;
diff --git a/Control/CalypsoExample/RDOReadExample/src/RDOReadAlg.h b/Control/CalypsoExample/RDOReadExample/src/RDOReadAlg.h
index 9f3dd5f4ef98cd67204712be254313e6f3fa2910..40f0e1f2a29ccccf3d8f1499c381fc70ec3d1e39 100644
--- a/Control/CalypsoExample/RDOReadExample/src/RDOReadAlg.h
+++ b/Control/CalypsoExample/RDOReadExample/src/RDOReadAlg.h
@@ -27,7 +27,7 @@ class RDOReadAlg : public AthHistogramAlgorithm
 
     // Read handle keys for data containers
     // Any other event data can be accessed identically
-    // Note the key names ("GEN_EVENT" or "SCT_Hits") are Gaudi properties and can be configured at run-time
+    // Note the key names ("BeamTruthEvent" or "SCT_Hits") are Gaudi properties and can be configured at run-time
     SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "TruthEvent" };
     SG::ReadHandleKey<FaserSiHitCollection> m_faserSiHitKey { this, "FaserSiHitCollection", "SCT_Hits" };
     SG::ReadHandleKey<FaserSCT_RDO_Container> m_faserRdoKey { this, "FaserSCT_RDO_Container", "SCT_RDOs"};
diff --git a/Control/CalypsoExample/SimHitExample/CaloREADME.md b/Control/CalypsoExample/SimHitExample/CaloREADME.md
new file mode 100644
index 0000000000000000000000000000000000000000..a93c9216916fd7c5359a996ee89e6a44888fff0e
--- /dev/null
+++ b/Control/CalypsoExample/SimHitExample/CaloREADME.md
@@ -0,0 +1,47 @@
+
+# Running the ECAL simulation  
+
+Use runEcal.py to specify particle type, energy, mass, z position in calo, theta and phi ranges etc
+runEcal.py location: calypso/Simulation/G4Faser/G4FaserAlg/test/runEcal.py
+ - ConfigFlags.Output.HITSFileName = ""
+specifies the output name of the HITS file
+ - pg.sampler.pid = -11
+particle ID (-11 = electron)
+ - pg.sampler.mom = PG.EThetaMPhiSampler(energy=100*GeV, theta=[0,pi/20], phi=[0,2*pi], mass=0.511)
+set particle energy, theta, phi and mass
+ - pg.sampler.pos = PG.PosSampler(x=[-5.0, 5.0], y=[-5.0, 5.0], z=2744.1, t=0.0)
+set position of beam in terms of x and y coordinates 
+z = 2744.1 (mm) corresponds to calorimeter face 
+x=60.9 and y=49.6 corresponds to centre of top left module
+ - sys.exit(int(acc.run(maxEvents=1000).isFailure()))
+set the number of events to simulate
+1000 event simulations at 1 TeV for electrons and photons need to be split
+change the random seed in this case
+ - pg.randomSeed = 123456
+
+Run this file in Calypso's run directory to genetate HITS file of simulation.
+
+# Plotting Histograms in CaloSimHitAlg
+
+Once the HITS file has been generated from runEcal.py:
+ - use CaloSimHitExample_jobOptions.py to loop over HITS and generate HistoFile
+ - the histogram plotting is specified in CaloSimHitAlg.h and CaloSimHitAlg.cxx
+
+CaloSimHitAlg.cxx plots variations of 6 histograms:
+ - eLoss - energy deposited per hit in the 4 ECAL modules (GeV)
+    - eLossBR - eLoss in bottom right ECAL module
+    - eLossTR - eLoss in top right ECAL module
+    - eLossBL - eLoss in bottom left ECAL module
+    - eLossTL - eLoss in top left ECAL module
+ - eLossTot - total energy deposited by particle across all 4 ECAL modules (GeV)
+    - eLossBRTot - eLossTot in bottom right ECAL module
+    - eLossTRTot - eLossTot in top right ECAL module
+    - eLossBLTot - eLossTot in bottom left ECAL module
+    - eLossTLTot - eLossTot in top left ECAL module
+ - module - cross section of hits in the calo, where (0,0), (1,0), (0,1) and (1,1) correspond to ECAL module centres
+ - modulePos - cross section of hits in the calo, showing their position in mm
+ - meanTime - events in the calo as a function of mean time (ns)
+ - weightedTime - energy weighted events in the calo as a function of mean time (ns)
+
+There are also fractional histograms for eLoss and eLossTot that give the deposited energy as a fraction of injected energy.
+Due to the histograms not depending on injected energy of simulated particle, may need to Rebin() when drawing eLoss and eLossTot histograms.
diff --git a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
index f99ce4b4a9d68c0df89d918aa96d26d53a96efbc..fb4049f7aa40da02ce37ca2ad7d1686cc672d972 100644
--- a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
+++ b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
@@ -14,22 +14,46 @@ StatusCode CaloSimHitAlg::initialize()
     // initialize a histogram 
     // letter at end of TH1 indicated variable type (D double, F float etc)
     // first string is root object name, second is histogram title
+ 
+
+  m_eloss = new TH1D("eLoss", "Calo Hit Energy Loss;Energy Loss [GeV];Events", 1000000, 0, 100); // 100000 bins, can rebin if needed - 1000 GeV inj - max 100 per event 
+    m_elossTL = new TH1D("eLossTL", "Calo Hit Energy Loss Top Left Module;Energy Loss [GeV];Events", 100000, 0, 100);
+    m_elossTR = new TH1D("eLossTR", "Calo Hit Energy Loss Top Right Module;Energy Loss [GeV];Events", 100000, 0, 100);
+    m_elossBR = new TH1D("eLossBR", "Calo Hit Energy Loss Bottom Right Module;Energy Loss [GeV];Events", 100000, 0, 100);
+    m_elossBL = new TH1D("eLossBL", "Calo Hit Energy Loss Bottom Left Module;Energy Loss [GeV];Events", 100000, 0, 100);
+// 1 million bins
+    m_elossTot = new TH1D("eLossTot", "Total Energy Deposited in Calorimeter;Deposited Energy [GeV];Events", 1000000, 0, 1000);   
+    m_elossTLTot = new TH1D("eLossTLTot", "Total Energy Deposited in Top Left Module;Deposited Energy [GeV];Events", 1000000, 0, 1000);
+    m_elossTRTot = new TH1D("eLossTRTot", "Total Energy Deposited in Top Right Module;Deposited Energy [GeV];Events", 1000000, 0, 1000);
+    m_elossBRTot = new TH1D("eLossBRTot", "Total Energy Deposited in Bottom Right Module;Deposited Energy [GeV];Events", 1000000, 0, 1000);
+    m_elossBLTot = new TH1D("eLossBLTot", "Total Energy Deposited in Bottom Left Module;Deposited Energy [GeV];Events", 1000000, 0, 1000);    
 
-    m_eloss = new TH1D("eLoss", "Calo Hit Energy Loss Fraction;Fraction;Events", 1000, 0, 0.0001); 
-    m_elossTL = new TH1D("eLossTL", "Calo Hit Energy Loss Fraction Top Left Module;Fraction;Events", 1000, 0, 0.0001);
-    m_elossTR = new TH1D("eLossTR", "Calo Hit Energy Loss Fraction Top Right Module;Fraction;Events", 1000, 0, 0.0001);
-    m_elossBR = new TH1D("eLossBR", "Calo Hit Energy Loss Fraction Bottom Right Module;Fraction;Events", 1000, 0, 0.0001);
-    m_elossBL = new TH1D("eLossBL", "Calo Hit Energy Loss Fraction Bottom Left Module;Fraction;Events", 1000, 0, 0.0001);
+    m_module = new TH2D("module;x;y", "Calo Hit Module", 2, -0.5, 1.5, 2, -0.5, 1.5 );
+    // m_modulePos = new TH2D("modulePos;x;y", "Calo Hit Module Position", 13, -130, 130, 13, -130, 130 );
+    // x4 original number of bins
+    m_modulePos = new TH2D("modulePos;x;y", "Calo Hit Module Position", 52, -130, 130, 52, -130, 130 );
 
-    m_elossTot = new TH1D("eLossTot", "Total Energy Fraction Deposited in Calorimeter;Fraction;Events", 1000, 0, 1);   
-    m_elossTLTot = new TH1D("eLossTLTot", "Total Energy Fraction Deposited in Top Left Module;Fraction;Events", 1000, 0, 1);
-    m_elossTRTot = new TH1D("eLossTRTot", "Total Energy Fraction Deposited in Top Right Module;Fraction;Events", 1000, 0, 1);
-    m_elossBRTot = new TH1D("eLossBRTot", "Total Energy Fraction Deposited in Bottom Right Module;Fraction;Events", 1000, 0, 1);
-    m_elossBLTot = new TH1D("eLossBLTot", "Total Energy Fraction Deposited in Bottom Left Module;Fraction;Events", 1000, 0, 1);    
+    // as a fraction of injected energy (when known)
 
-    m_module = new TH2D("module;x;y", "Calo Hit Module", 2, -0.5, 1.5, 2, -0.5, 1.5 );
-    m_modulePos = new TH2D("modulePos;x;y", "Calo Hit Module Position", 13, -130, 130, 13, -130, 130 );
-        
+    m_eloss_frac = new TH1D("eLoss_frac", "Calo Hit Energy Loss Fraction;Fraction;Events", 100000, 0, 0.1); 
+    m_elossTL_frac = new TH1D("eLossTL_frac", "Calo Hit Energy Loss Fraction Top Left Module;Fraction;Events", 100000, 0, 0.01);
+    m_elossTR_frac = new TH1D("eLossTR_frac", "Calo Hit Energy Loss Fraction Top Right Module;Fraction;Events", 100000, 0, 0.01);
+    m_elossBR_frac = new TH1D("eLossBR_frac", "Calo Hit Energy Loss Fraction Bottom Right Module;Fraction;Events", 100000, 0, 0.01);
+    m_elossBL_frac = new TH1D("eLossBL_frac", "Calo Hit Energy Loss Fraction Bottom Left Module;Fraction;Events", 100000, 0, 0.01);
+
+    m_elossTot_frac = new TH1D("eLossTot_frac", "Total Energy Fraction Deposited in Calorimeter;Fraction;Events", 1000000, 0, 1);   
+    m_elossTLTot_frac = new TH1D("eLossTLTot_frac", "Total Energy Fraction Deposited in Top Left Module;Fraction;Events", 1000000, 0, 1);
+    m_elossTRTot_frac = new TH1D("eLossTRTot_frac", "Total Energy Fraction Deposited in Top Right Module;Fraction;Events", 1000000, 0, 1);
+    m_elossBRTot_frac = new TH1D("eLossBRTot_frac", "Total Energy Fraction Deposited in Bottom Right Module;Fraction;Events", 1000000, 0, 1);
+    m_elossBLTot_frac = new TH1D("eLossBLTot_frac", "Total Energy Fraction Deposited in Bottom Left Module;Fraction;Events", 1000000, 0, 1);  
+
+    // new histograms hits vs time 29/6/21
+
+    m_meanTime = new TH1D("meanTime", "Events vs Mean Time;Time [ns];Events",4000, 0, 2);
+    m_weightedTime = new TH1D("weightedTime", "Weighted Events vs Time;Time [ns];Events",4000, 0, 2); // weighted energy should be in GeV
+
+    ATH_CHECK(histSvc()->regHist("/HIST/meanTime", m_meanTime));
+    ATH_CHECK(histSvc()->regHist("/HIST/weightedTime", m_weightedTime));     
 
     ATH_CHECK(histSvc()->regHist("/HIST/eloss", m_eloss));
     ATH_CHECK(histSvc()->regHist("/HIST/elossTL", m_elossTL)); 
@@ -42,10 +66,24 @@ StatusCode CaloSimHitAlg::initialize()
     ATH_CHECK(histSvc()->regHist("/HIST/elossTRTot", m_elossTRTot));
     ATH_CHECK(histSvc()->regHist("/HIST/elossBRTot", m_elossBRTot));
     ATH_CHECK(histSvc()->regHist("/HIST/elossBLTot", m_elossBLTot));
-
+ 
     ATH_CHECK(histSvc()->regHist("/HIST/modules", m_module));
     ATH_CHECK(histSvc()->regHist("/HIST/modulePos", m_modulePos));
 
+    // as a fraction of injected energy 
+
+    ATH_CHECK(histSvc()->regHist("/HIST/eloss_frac", m_eloss_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossTL_frac", m_elossTL_frac)); 
+    ATH_CHECK(histSvc()->regHist("/HIST/elossTR_frac", m_elossTR_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossBR_frac", m_elossBR_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossBL_frac", m_elossBL_frac));
+
+    ATH_CHECK(histSvc()->regHist("/HIST/elossTot_frac", m_elossTot_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossTLTot_frac", m_elossTLTot_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossTRTot_frac", m_elossTRTot_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossBRTot_frac", m_elossBRTot_frac));
+    ATH_CHECK(histSvc()->regHist("/HIST/elossBLTot_frac", m_elossBLTot_frac));
+
     // initialize data handle keys
     ATH_CHECK( m_mcEventKey.initialize() );
     ATH_CHECK( m_faserCaloHitKey.initialize() );
@@ -78,8 +116,18 @@ StatusCode CaloSimHitAlg::execute()
     if (ev->particles_size() > 0)
     {
         HepMC::GenEvent::particle_const_iterator p = ev->particles_begin();
-        ePrimary = (*p)->momentum().e();
+        //ePrimary = (*p)->momentum().e();
+
+	for ( ; p !=  ev->particles_end(); ++p) {
+	  // Particle gun primaries have BCs starting at 10000, while others have 3 digit values
+	  if ((*p)->barcode() > 11000) continue;
+	  ePrimary += (*p)->momentum().e();
+	}
+	std::cout << "E Primary " << ePrimary << std::endl;
     } 
+    
+    //ev->print();
+    //ePrimary = 1000000;
 
     // The hit container might be empty because particles missed the modules
     if (h_caloHits->size() == 0) return StatusCode::SUCCESS;
@@ -91,18 +139,38 @@ StatusCode CaloSimHitAlg::execute()
     // BL = bottom left calorimeter module
     // BR = bottom right calorimeter module 
 
-    float e(0);;
+    float e(0);
     float tl(0);
     float tr(0);
     float br(0);
     float bl(0);
 
+    float e_frac(0);
+    float tl_frac(0);
+    float tr_frac(0);
+    float br_frac(0);
+    float bl_frac(0);
+
+  
+
     for (const CaloHit& hit : *h_caloHits)  {
       //hit.print();
-      float ehit = hit.energyLoss()/ePrimary;
+      float ehit_frac = hit.energyLoss()/ePrimary;
+      float ehit = hit.energyLoss()/1000; // to convert from MeV to GeV
+      m_eloss_frac->Fill(ehit_frac);
       m_eloss->Fill(ehit);
+      e_frac += ehit_frac;
       e += ehit;
 
+      // add extra time hist
+      float time = hit.meanTime();
+      m_meanTime->Fill(time);
+
+      // add weighted energy hist
+      m_weightedTime->Fill(time,ehit);
+
+      //
+
       m_module->Fill(hit.getModule(), hit.getRow());	
       m_modulePos->Fill(hit.getModule()==0 ? -121.9/2 + hit.localStartPosition().x() : 121.9/2 + hit.localStartPosition().x(), hit.getRow()==0 ? -121.9/2 + hit.localStartPosition().y() : 121.9/2 + hit.localStartPosition().y());
 
@@ -110,21 +178,29 @@ StatusCode CaloSimHitAlg::execute()
       if (hit.getModule() == 0 && hit.getRow() == 1) // 0 1 TL
 	{
 	  m_elossTL->Fill(ehit);
+	  m_elossTL_frac->Fill(ehit_frac);
+	  tl_frac += ehit_frac;
 	  tl += ehit;
 	}
       if (hit.getModule() == 1 && hit.getRow() == 1) // 1 1 TR
 	{
 	  m_elossTR->Fill(ehit);
+	  m_elossTR_frac->Fill(ehit_frac);
+	  tr_frac += ehit_frac;
 	  tr += ehit;
 	}
       if (hit.getModule() == 1 && hit.getRow() == 0) // 1 0 BR
 	{
 	  m_elossBR->Fill(ehit);
+	  m_elossBR_frac->Fill(ehit_frac);
+	  br_frac += ehit_frac;
 	  br += ehit;
 	}
       if (hit.getModule() == 0 && hit.getRow() == 0) // 0 0 BL
 	{
 	  m_elossBL->Fill(ehit);
+	  m_elossBL_frac->Fill(ehit_frac);
+	  bl_frac += ehit_frac;
 	  bl += ehit;
 	}
 
@@ -136,6 +212,14 @@ StatusCode CaloSimHitAlg::execute()
     m_elossBRTot->Fill(br);
     m_elossBLTot->Fill(bl); 
 
+    // as a fraction of injected energy 
+
+    m_elossTot_frac->Fill(e_frac);
+    m_elossTLTot_frac->Fill(tl_frac);
+    m_elossTRTot_frac->Fill(tr_frac);
+    m_elossBRTot_frac->Fill(br_frac);
+    m_elossBLTot_frac->Fill(bl_frac);
+
     return StatusCode::SUCCESS;
 }
 
diff --git a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.h b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.h
index 6f34f71f14cb04df34e1c17b5256027d4f0d2a9b..3c912341eb84e10d4447f6e66b9373f2e79469c4 100644
--- a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.h
+++ b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.h
@@ -21,6 +21,9 @@ class CaloSimHitAlg : public AthHistogramAlgorithm
     TH2* m_module;
     TH2* m_modulePos;
     TH1* m_elossTot; 
+ 
+    TH1* m_meanTime;
+    TH1* m_weightedTime;
 
     // add new histograms
     // TL = top left calorimeter module
@@ -35,11 +38,24 @@ class CaloSimHitAlg : public AthHistogramAlgorithm
     TH1* m_elossTLTot;
     TH1* m_elossTRTot;
     TH1* m_elossBRTot;
-    TH1* m_elossBLTot;   
+    TH1* m_elossBLTot;    
+
+    // add in fractional histograms
+
+    TH1* m_eloss_frac;
+    TH1* m_elossTL_frac;
+    TH1* m_elossTR_frac;
+    TH1* m_elossBR_frac; 
+    TH1* m_elossBL_frac; 
+    TH1* m_elossTot_frac;
+    TH1* m_elossTLTot_frac;
+    TH1* m_elossTRTot_frac;
+    TH1* m_elossBRTot_frac;
+    TH1* m_elossBLTot_frac;  
 
     // Read handle keys for data containers
     // Any other event data can be accessed identically
-    // Note the key names ("GEN_EVENT" or "SCT_Hits") are Gaudi properties and can be configured at run-time
-    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "GEN_EVENT" };
+    // Note the key names ("BeamTruthEvent" or "SCT_Hits") are Gaudi properties and can be configured at run-time
+    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "BeamTruthEvent" };
     SG::ReadHandleKey<CaloHitCollection> m_faserCaloHitKey { this, "CaloHitCollection", "EcalHits" };
 };
diff --git a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h
index d7747bbfb9fc3c95920c99cbbe7ea0537bad0dca..476f2999a4c403d73d7d303c1ed45256e0f9f7f5 100644
--- a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h
+++ b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h
@@ -36,10 +36,10 @@ class SimHitAlg : public AthHistogramAlgorithm
 
     // Read handle keys for data containers
     // Any other event data can be accessed identically
-    // Note the key names ("GEN_EVENT" or "SCT_Hits") are Gaudi properties and can be configured at run-time
+    // Note the key names ("BeamTruthEvent" or "SCT_Hits") are Gaudi properties and can be configured at run-time
 
     // Truth information
-    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "GEN_EVENT" };
+    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "BeamTruthEvent" };
 
     // Tracker hits
     SG::ReadHandleKey<FaserSiHitCollection> m_faserSiHitKey { this, "FaserSiHitCollection", "SCT_Hits" };
diff --git a/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py b/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py
index 0a2d083a8d0ca8a201bf9b34e4e8947289b57666..066f8560b4df98fae490fc79a876c21ae1332313 100755
--- a/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py
+++ b/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py
@@ -4,7 +4,7 @@
 
 import sys
 from AthenaConfiguration.ComponentFactory import CompFactory
-from AthenaCommon.Constants import VERBOSE, INFO
+from AthenaCommon.Constants import INFO, WARNING
 
 Cmake_working_dir = sys.argv[1]
 print("Cmake_working_dir = ", Cmake_working_dir)
@@ -30,6 +30,7 @@ def TrackerDataAccessExampleCfg(flags, name="TrackerDataAccessExampleAlg", **kwa
 if __name__ == "__main__":
     from AthenaCommon.Configurable import Configurable
     from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaCommon.Logging import logging
 
     Configurable.configurableRun3Behavior = True
     
@@ -66,16 +67,11 @@ if __name__ == "__main__":
 
 # Configure verbosity    
     # ConfigFlags.dump()
-    # logging.getLogger('forcomps').setLevel(VERBOSE)
-    acc.foreach_component("*").OutputLevel = VERBOSE
+    logging.getLogger('forcomps').setLevel(WARNING)
+    acc.foreach_component("*").OutputLevel = INFO
     acc.foreach_component("*ClassID*").OutputLevel = INFO
+    acc.foreach_component("*TrackerDataAccess*").OutputLevel = WARNING
     # log.setLevel(VERBOSE)
 
-    acc.getService("FaserByteStreamInputSvc").DumpFlag = True
-    acc.getService("FaserEventSelector").OutputLevel = VERBOSE
-    acc.getService("FaserByteStreamInputSvc").OutputLevel = VERBOSE
-    acc.getService("FaserByteStreamCnvSvc").OutputLevel = VERBOSE
-    acc.getService("FaserByteStreamAddressProviderSvc").OutputLevel = VERBOSE
-    acc.getService("MessageSvc").Format = "% F%40W%S%7W%R%T %0W%M"
 # Execute and finish
     sys.exit(int(acc.run(maxEvents=-1).isFailure()))
diff --git a/Control/CalypsoExample/WaveformAnalysisExample/CMakeLists.txt b/Control/CalypsoExample/WaveformAnalysisExample/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3c40f4c6ca6b4b34a6d25464a6aa05156bd9411c
--- /dev/null
+++ b/Control/CalypsoExample/WaveformAnalysisExample/CMakeLists.txt
@@ -0,0 +1,8 @@
+atlas_subdir( WaveformAnalysisExample )
+
+atlas_add_component( WaveformAnalysisExample
+                    src/*.cxx
+		            src/components/WaveformAnalysisExample_entries.cxx
+                    LINK_LIBRARIES AthenaBaseComps xAODFaserWaveform
+        )
+
diff --git a/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.cxx b/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1e6a1a68fc3935e4c7374007eca47902d4f44d1f
--- /dev/null
+++ b/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.cxx
@@ -0,0 +1,26 @@
+#include "WaveformHitAlg.h"
+
+WaveformHitAlg::WaveformHitAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthHistogramAlgorithm(name, pSvcLocator) { }
+
+WaveformHitAlg::~WaveformHitAlg() { }
+
+StatusCode WaveformHitAlg::initialize()
+{
+  //ATH_CHECK( m_faserWaveformHitKey.initialize() );
+  //ATH_MSG_INFO( "Using Faser WaveformHit collection with key " << m_faserWaveformHitKey.key());
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode WaveformHitAlg::execute()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode WaveformHitAlg::finalize()
+{
+  return StatusCode::SUCCESS;
+}
diff --git a/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.h b/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aa6798c1c32e14e8da9870ebe6a410725f9246f
--- /dev/null
+++ b/Control/CalypsoExample/WaveformAnalysisExample/src/WaveformHitAlg.h
@@ -0,0 +1,28 @@
+#ifndef WAVEFORMANALYSISEXAMPLE_WAVEFORMHITALG_H
+#define WAVEFORMANALYSISEXAMPLE_WAVEFORMHITALG_H
+
+#include "AthenaBaseComps/AthHistogramAlgorithm.h"
+#include "xAODFaserWaveform/WaveformHitContainer.h"
+
+#include <TH1.h>
+
+/* WaveformHit reading example - Carl Gwilliam + Lottie Cavanagh, Liverpool */
+
+class WaveformHitAlg : public AthHistogramAlgorithm
+{
+public:
+  WaveformHitAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  
+  virtual ~WaveformHitAlg();
+  
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+  
+private:
+  
+  SG::ReadHandle<xAOD::WaveformHitContainer> m_waveformHits;   
+  //SG::ReadHandleKey<xAOD::WaveformHitContainer> m_faserWaveformHitKey { this, "WaveformHitContainerKey", "CaloWaveformHits" };
+};
+
+#endif
diff --git a/Control/CalypsoExample/WaveformAnalysisExample/src/components/WaveformAnalysisExample_entries.cxx b/Control/CalypsoExample/WaveformAnalysisExample/src/components/WaveformAnalysisExample_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..370b5668e5824c05cb3cd7fb227e6350f543be51
--- /dev/null
+++ b/Control/CalypsoExample/WaveformAnalysisExample/src/components/WaveformAnalysisExample_entries.cxx
@@ -0,0 +1,3 @@
+#include "../WaveformHitAlg.h"
+
+DECLARE_COMPONENT( WaveformHitAlg )
diff --git a/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py b/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
index 40a838de765d5aafaa1eb5bb34352cb5211b6db7..1e769c27f31cf8550872bf168ed98a39d4a8ff91 100644
--- a/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
+++ b/DetectorDescription/DetDescrCnvSvc/python/DetStoreConfig.py
@@ -6,11 +6,11 @@
 #
 
 def _setupDetStoreConfig():
-    from AthenaCommon.AppMgr import theApp
+    # from AthenaCommon.AppMgr import theApp
     from AthenaCommon.AppMgr import ServiceMgr as svcMgr
 
     # first, make sure we create a DetectorStore
-    import AthenaCommon.AtlasUnixStandardJob
+    # import AthenaCommon.AtlasUnixStandardJob
     #theApp.CreateSvc += [ svcMgr.DetectorStore.getFullName() ]
 
     # now configure the Detector Description converter service
diff --git a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql
index edd02d7b67c730dfc55387e0123d9b53d858fa96..25673485d439d673d60366b80f62285228601f98 100644
--- a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql
+++ b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql
@@ -235,6 +235,21 @@ CREATE TABLE IF NOT EXISTS "VETOPLATEGENERAL_DATA2TAG" (
 	"VETOPLATEGENERAL_DATA_ID" SLONGLONG
 );
 --
+DROP TABLE IF EXISTS "VETORADIATORGENERAL_DATA";
+CREATE TABLE IF NOT EXISTS "VETORADIATORGENERAL_DATA" (
+	"VETORADIATORGENERAL_DATA_ID" SLONGLONG UNIQUE,
+	"WIDTH" DOUBLE,
+	"LENGTH" DOUBLE,
+	"THICKNESS" DOUBLE,
+	"MATERIAL" TEXT
+);
+--
+DROP TABLE IF EXISTS "VETORADIATORGENERAL_DATA2TAG";
+CREATE TABLE IF NOT EXISTS "VETORADIATORGENERAL_DATA2TAG" (
+	"VETORADIATORGENERAL_TAG_ID" SLONGLONG,
+	"VETORADIATORGENERAL_DATA_ID" SLONGLONG
+);
+--
 -- Tables for describing Trigger scintillator plates (and passive radiators)
 --
 DROP TABLE IF EXISTS "TRIGGERTOPLEVEL_DATA";
@@ -326,6 +341,7 @@ CREATE TABLE IF NOT EXISTS "PRESHOWERSTATIONGENERAL_DATA2TAG" (
 	"PRESHOWERSTATIONGENERAL_TAG_ID" SLONGLONG,
 	"PRESHOWERSTATIONGENERAL_DATA_ID" SLONGLONG
 );
+--
 DROP TABLE IF EXISTS "PRESHOWERPLATEGENERAL_DATA";
 CREATE TABLE IF NOT EXISTS "PRESHOWERPLATEGENERAL_DATA" (
 	"PRESHOWERPLATEGENERAL_DATA_ID" SLONGLONG UNIQUE,
@@ -342,6 +358,40 @@ CREATE TABLE IF NOT EXISTS "PRESHOWERPLATEGENERAL_DATA2TAG" (
 	"PRESHOWERPLATEGENERAL_DATA_ID" SLONGLONG
 );
 --
+-- The Preshower radiators
+--
+DROP TABLE IF EXISTS "PRESHOWERRADIATORGENERAL_DATA";
+CREATE TABLE IF NOT EXISTS "PRESHOWERRADIATORGENERAL_DATA" (
+	"PRESHOWERRADIATORGENERAL_DATA_ID" SLONGLONG UNIQUE,
+	"WIDTH" DOUBLE,
+	"LENGTH" DOUBLE,
+	"THICKNESS" DOUBLE,
+	"MATERIAL" TEXT
+);
+--
+DROP TABLE IF EXISTS "PRESHOWERRADIATORGENERAL_DATA2TAG";
+CREATE TABLE IF NOT EXISTS "PRESHOWERRADIATORGENERAL_DATA2TAG" (
+	"PRESHOWERRADIATORGENERAL_TAG_ID" SLONGLONG,
+	"PRESHOWERRADIATORGENERAL_DATA_ID" SLONGLONG
+);
+--
+-- The Preshower absorbers
+--
+DROP TABLE IF EXISTS "PRESHOWERABSORBERGENERAL_DATA";
+CREATE TABLE IF NOT EXISTS "PRESHOWERABSORBERGENERAL_DATA" (
+	"PRESHOWERABSORBERGENERAL_DATA_ID" SLONGLONG UNIQUE,
+	"WIDTH" DOUBLE,
+	"LENGTH" DOUBLE,
+	"THICKNESS" DOUBLE,
+	"MATERIAL" TEXT
+);
+--
+DROP TABLE IF EXISTS "PRESHOWERABSORBERGENERAL_DATA2TAG";
+CREATE TABLE IF NOT EXISTS "PRESHOWERABSORBERGENERAL_DATA2TAG" (
+	"PRESHOWERABSORBERGENERAL_TAG_ID" SLONGLONG,
+	"PRESHOWERABSORBERGENERAL_DATA_ID" SLONGLONG
+);
+--
 -- Ecal top level tables
 --
 DROP TABLE IF EXISTS "ECALTOPLEVEL_DATA";
@@ -662,6 +712,7 @@ INSERT INTO "HVS_NODE" VALUES (210,  "VetoTopLevel", 21, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (211,  "VetoStationGeneral", 21, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (212,  "VetoPlateGeneral", 21, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (214,  "VetoSwitches", 21, 0, NULL );
+INSERT INTO "HVS_NODE" VALUES (215,  "VetoRadiatorGeneral", 21, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (22,   "Trigger", 2, 1, NULL);
 INSERT INTO "HVS_NODE" VALUES (220,  "TriggerTopLevel", 22, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (221,  "TriggerStationGeneral", 22, 0, NULL);
@@ -672,6 +723,8 @@ INSERT INTO "HVS_NODE" VALUES (230,  "PreshowerTopLevel", 23, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (231,  "PreshowerStationGeneral", 23, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (232,  "PreshowerPlateGeneral", 23, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (234,  "PreshowerSwitches", 23, 0, NULL );
+INSERT INTO "HVS_NODE" VALUES (235,  "PreshowerRadiatorGeneral", 23, 0, NULL);
+INSERT INTO "HVS_NODE" VALUES (236,  "PreshowerAbsorberGeneral", 23, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (3,    "Tracker", 0, 1, NULL);
 INSERT INTO "HVS_NODE" VALUES (3003, "TrackerMaterials", 3, 0, NULL);
 INSERT INTO "HVS_NODE" VALUES (3004, "TrackerMatComponents", 3, 0, NULL);
@@ -708,14 +761,18 @@ INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-01", 100039, NULL, 0, 0, 1590796800
 INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-CR", 107784, NULL, 0, 0, 1598400000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-02", 107788, NULL, 0, 0, 1619222400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASERNU-02", 107804, NULL, 0, 0, 1619308800000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-TB00", 107834, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (90,   "FaserCommon-00", 100013, NULL, 0, 0, 1549324800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (9000, "Materials-00", 100005, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (9001, "StdMaterials-00", 100006, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (9002, "StdMatComponents-00", 100007, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (9003, "Elements-00", 100008, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (1, "Neutrino-00", 100031, NULL, 0, 0, 1582416000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (1, "Neutrino-TB00", 107811, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (11,"Emulsion-00", 100034, NULL, 0, 0, 1582416000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (11,"Emulsion-TB00", 107812, NULL, 0, 0, 1582416000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (110, "EmulsionTopLevel-00", 100035, NULL, 0, 0, 1582416000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (110, "EmulsionTopLevel-TB00", 107813, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (111, "EmulsionGeneral-00", 107805, NULL, 0, 0, 1619308800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (112, "EmulsionFilm-00", 107806, NULL, 0, 0, 1619308800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (113, "EmulsionPlates-00", 107807, NULL, 0, 0, 1619308800000000000, NULL, 22);
@@ -723,21 +780,26 @@ INSERT INTO "HVS_TAG2NODE" VALUES (114, "EmulsionSwitches-00", 100036, NULL, 0,
 INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-00", 100001, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-01", 100042, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-02", 107789, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-TB00", 107814, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-00", 100002, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-01", 100038, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-CR", 107783, NULL, 0, 0, 1598400000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-02", 107790, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-TB00", 107815, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-00", 100026, NULL, 0, 0, 1567987200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-01", 100037, NULL, 0, 0, 1159079680000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-CR", 107781, NULL, 0, 0, 1598400000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-02", 107791, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-TB00", 107816, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-00", 100027, NULL, 0, 0, 1568678400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-01", 100041, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-02", 107792, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-TB00", 107817, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-00", 106788, NULL, 0, 0, 1567987200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-01", 106790, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-CR", 107786, NULL, 0, 0, 1598400000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-02", 107793, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-TB00", 107818, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (311, "SctBarrelModule-00", 107003, NULL, 0, 0, 1567987200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (312, "SctBarrelSensor-00", 106730, NULL, 0, 0, 1567987200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (313, "SctFaserGeneral-00", 106789, NULL, 0, 0, 1567987200000000000, NULL, 22);
@@ -753,35 +815,47 @@ INSERT INTO "HVS_TAG2NODE" VALUES (3182,"SctFrameShape-00", 100055, NULL, 0, 0,
 INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-00", 100029, NULL, 0, 0, 1568678400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-01", 100040, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-02", 107794, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-TB00", 107819, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (321, "DipoleGeneral-00", 100004, NULL, 0, 0, 1568678400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (324, "DipoleSwitches-00", 100028, NULL, 0, 0, 1568678400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (4, "Calorimeter-00", 100003, NULL, 0, 0, 1549238400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (4, "Calorimeter-02", 107795, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (4, "Calorimeter-TB00", 107820, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (41, "Ecal-00", 100056, NULL, 0, 0,    1593907200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (41, "Ecal-02", 107796, NULL, 0, 0,    1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (41, "Ecal-TB00", 107821, NULL, 0, 0,    1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (410, "EcalTopLevel-00", 100058, NULL, 0, 0, 1599350400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (410, "EcalTopLevel-02", 107797, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (410, "EcalTopLevel-TB00", 107822, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (411, "EcalRowGeneral-00", 100059, NULL, 0, 0, 1599350400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (411, "EcalRowGeneral-TB00", 107830, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (414, "EcalSwitches-00", 100057, NULL, 0, 0, 1593907200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (210,  "VetoTopLevel-00", 100009, NULL, 0, 0, 1567123200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (210,  "VetoTopLevel-01", 100046, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (210,  "VetoTopLevel-02", 107798, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (210,  "VetoTopLevel-TB00", 107823, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (211,  "VetoStationGeneral-00", 100010, NULL, 0, 0, 1567123200000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (212,  "VetoPlateGeneral-00", 100025, NULL, 0, 0, 1567209600000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (211,  "VetoStationGeneral-01", 100049, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (212,  "VetoPlateGeneral-01", 100050, NULL, 0, 0, 1590796800000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (211,  "VetoStationGeneral-TB00", 107833, NULL, 0, 0, 1627862400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (215,  "VetoRadiatorGeneral-00", 107810, NULL, 0, 0, 1627776000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (220,  "TriggerTopLevel-00", 110009, NULL, 0, 0, 1581292800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (220,  "TriggerTopLevel-01", 100047, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (220,  "TriggerTopLevel-02", 107799, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (220,  "TriggerTopLevel-TB00", 107824, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (221,  "TriggerStationGeneral-00", 110010, NULL, 0, 0, 1581292800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (221,  "TriggerStationGeneral-01", 100051, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (222,  "TriggerPlateGeneral-00", 110025, NULL, 0, 0, 1581292800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (230,  "PreshowerTopLevel-00", 120009, NULL, 0, 0, 1581292800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (230,  "PreshowerTopLevel-01", 100048, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (230,  "PreshowerTopLevel-02", 107800, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (230,  "PreshowerTopLevel-TB00", 107825, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (231,  "PreshowerStationGeneral-00", 120010, NULL, 0, 0, 1581292800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (231,  "PreshowerStationGeneral-01", 100052, NULL, 0, 0, 1590796800000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (232,  "PreshowerPlateGeneral-00", 120025, NULL, 0, 0, 1581292800000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (235,  "PreshowerRadatorGeneral-00", 107808, NULL, 0, 0, 1627776000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (236,  "PreshowerAbsorberGeneral-00", 107809, NULL, 0, 0, 1627776000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (1003, "NeutrinoMaterials-00", 100032, NULL, 0, 0, 1582416000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (1004, "NeutrinoMatComponents-00", 100033, NULL, 0, 0, 1582416000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (2003, "ScintMaterials-00", 100011, NULL, 0, 0, 1549238400000000000, NULL, 22);
@@ -802,45 +876,66 @@ INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-01", 100045, NULL, 0, 0, 15907
 INSERT INTO "HVS_TAG2NODE" VALUES (21, "Veto-02", 107801, NULL, 0, 0, 1619222400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (22, "Trigger-02", 107802, NULL, 0, 0, 1619222400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-02", 107803, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (21, "Veto-TB00", 107826, NULL, 0, 0, 1627862400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (22, "Trigger-TB00", 107827, NULL, 0, 0, 1627862400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-TB00", 107828, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (1005, "NeutrinoIdentifier-00", 100030, NULL, 0, 0, 1582416000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (2005, "ScintIdentifier-00", 100016, NULL, 0, 0, 1550448000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (2005, "ScintIdentifier-TB00", 107832, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-00", 100017, NULL, 0, 0, 1550448000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-CR", 107785, NULL, 0, 0, 1598400000000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-02", 107787, NULL, 0, 0, 1619222400000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-TB00", 107829, NULL, 0, 0, 1627862400000000000, NULL, 22);
 INSERT INTO "HVS_TAG2NODE" VALUES (4005, "CaloIdentifier-00", 100018, NULL, 0, 0, 1550448000000000000, NULL, 22);
+INSERT INTO "HVS_TAG2NODE" VALUES (4005, "CaloIdentifier-TB00", 107831, NULL, 0, 0, 1627862400000000000, NULL, 22);
 -- Data for the HVS_LTAG2LTAG table
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107804, 1,    100031);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 1,    107811);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100000, 2,    100001);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100039, 2,    100042);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107784, 2,    100042);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107788, 2,    107789);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 2,    107814);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100000, 3,    100002);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100039, 3,    100038);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107784, 3,    107783);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107788, 3,    107790);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 3,    107815);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100000, 4,    100003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100039, 4,    100003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107784, 4,    100003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107788, 4,    107795);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 4,    107820);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100000, 90,   100013);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100039, 90,   100013);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107788, 90,   100013);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 90,   100013);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100000, 9000,  100005);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   100039, 9000,  100005);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107784, 9000,  100005);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107788, 9000,  100005);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (0,   107834, 9000,  100005);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9001,  100006);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9002,  100007);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9003,  100008);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   100031,  11,  100034);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   107811,  11,  107812);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  100034, 110,  100035);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  100034, 111,  107805);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  100034, 112,  107806);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  100034, 113,  107807);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  100034, 114,  100036);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  107812, 110,  107813);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  107812, 111,  107805);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  107812, 112,  107806);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  107812, 113,  107807);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (11,  107812, 114,  100036);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   100031, 1003, 100032);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   100031, 1004, 100033);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   100031, 1005, 100030);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   107811, 1003, 100032);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   107811, 1004, 100033);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (1,   107811, 1005, 100030);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 21,   100015);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 22,   100019);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 23,   100020);
@@ -850,6 +945,9 @@ INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100042, 23,   100045);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 21,   107801);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 22,   107802);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 23,   107803);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 21,   107826);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 22,   107827);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 23,   107828);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 2003, 100011);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 2004, 100012);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100001, 2005, 100016);
@@ -859,113 +957,152 @@ INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   100042, 2005, 100016);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 2003, 100011);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 2004, 100012);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107789, 2005, 100016);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 2003, 100011);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 2004, 100012);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (2,   107814, 2005, 100016);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100015, 210,  100009);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100043, 210,  100046);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107801, 210,  100046);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107826, 210,  107823);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100015, 211,  100010);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100043, 211,  100049);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107801, 211,  100049);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107826, 211,  100049);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100015, 212,  100025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100043, 212,  100050);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107801, 212,  100050);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107826, 212,  100050);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100015, 214,  100014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  100043, 214,  100014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107801, 214,  100014);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (21,  107826, 214,  100014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100019, 220,  110009);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100044, 220,  100047);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107802, 220,  100047);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107827, 220,  107824);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100019, 221,  110010);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100044, 221,  100051);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107802, 221,  100051);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107827, 221,  100051);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100019, 222,  110025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100044, 222,  110025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107802, 222,  110025);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107827, 222,  110025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100019, 224,  110014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  100044, 224,  110014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107802, 224,  110014);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (22,  107827, 224,  110014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100020, 230,  120009);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100045, 230,  120048);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107803, 230,  120048);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107828, 230,  107825);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100020, 231,  120010);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100045, 231,  100052);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107803, 231,  100052);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107828, 231,  100052);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100020, 232,  120025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100045, 232,  120025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107803, 232,  120025);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107828, 232,  120025);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100020, 234,  120014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  100045, 234,  120014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107803, 234,  120014);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (23,  107828, 234,  120014);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100002, 31,   100026);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100038, 31,   100037);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107783, 31,   107781);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107790, 31,   107791);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107815, 31,   107816);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100002, 32,   100027);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100038, 32,   100041);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107790, 32,   107792);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107815, 32,   107817);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100002, 3003, 100021);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100038, 3003, 100021);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107790, 3003, 100021);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107815, 3003, 100021);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100002, 3004, 100022);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100038, 3004, 100022);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107790, 3004, 100022);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107815, 3004, 100022);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100002, 3005, 100017);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   100038, 3005, 100017);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107781, 3005, 107785);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107790, 3005, 107787);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (3,   107815, 3005, 107829);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 310,  106788);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 310,  106790);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100081, 310,  107786);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 310,  106790);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 310,  107818);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 311,  107003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 311,  107003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 311,  107003);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 311,  107003);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 312,  106730);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 312,  106730);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 312,  106730);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 312,  106730);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 313,  106789);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 313,  106791);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107781, 313,  107780);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 313,  106791);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 313,  106791);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 314,  107782);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 314,  107782);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 314,  107782);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 314,  107782);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 315,  107777);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 315,  107777);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 315,  107777);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 315,  107777);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 316,  107778);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 316,  107778);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 316,  107778);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 316,  107778);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 317,  107779);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 317,  107779);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 317,  107779);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 317,  107779);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100026, 318,  100053);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  100037, 318,  100053);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107791, 318,  100053);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (31,  107816, 318,  100053);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (318, 100053, 3181, 100054);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (318, 100053, 3182, 100055);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100027, 320,  100029);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100041, 320,  100040);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107792, 320,  107794);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107817, 320,  107819);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100027, 321,  100004);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100041, 321,  100004);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107792, 321,  100004);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107817, 321,  100004);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100027, 324,  100028);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  100041, 324,  100028);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107792, 324,  100028);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (32,  107817, 324,  100028);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   100003, 41,   100056);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107795, 41,   107796);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107820, 41,   107821);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   100003, 4003, 100023);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   100003, 4004, 100024);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   100003, 4005, 100018);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107795, 4003, 100023);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107795, 4004, 100024);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107795, 4005, 100018);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107820, 4003, 100023);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107820, 4004, 100024);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (4,   107820, 4005, 100018);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  100056, 410,  100058);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107796, 410,  107797);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107821, 410,  107822);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  100056, 411,  100059);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  100056, 414,  100057);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107796, 411,  100059);
 INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107796, 414,  100057);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107821, 411,  107830);
+INSERT INTO "HVS_LTAG2LTAG" VALUES (41,  107821, 414,  100057);
 -- Data for the HVS_TAGCACHE table
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FASER",              "FASER-00",                100000);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FaserCommon",        "FaserCommon-00",          100013);
@@ -1003,12 +1140,15 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "EcalSwitches",       "EcalSwitch
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "VetoTopLevel",       "VetoTopLevel-00",         100009);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "VetoStationGeneral", "VetoStationGeneral-00",   100010);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "VetoPlateGeneral",   "VetoPlateGeneral-00",     100025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "VetoRadiatorGeneral",   "VetoRadiatorGeneral-00", 107810);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "TriggerTopLevel",       "TriggerTopLevel-00",         110009);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "TriggerStationGeneral", "TriggerStationGeneral-00",   110010);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "PreshowerTopLevel",     "PreshowerTopLevel-00",         120009);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "PreshowerStationGeneral", "PreshowerStationGeneral-00",   120010);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintMaterials",     "ScintMaterials-00",       100011);
@@ -1027,6 +1167,7 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "NeutrinoIdentifier", "NeutrinoId
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintIdentifier",    "ScintIdentifier-00",      100016);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "TrackerIdentifier",  "TrackerIdentifier-00",    100017);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "CaloIdentifier",     "CaloIdentifier-00",       100018);
+--
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "FASER",              "FASER-01",                100039);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "FaserCommon",        "FaserCommon-00",          100013);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "Materials",          "Materials-00",            100005);
@@ -1063,12 +1204,15 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "EcalSwitches",       "EcalSwitch
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "VetoTopLevel",       "VetoTopLevel-01",         100046);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "VetoStationGeneral", "VetoStationGeneral-01",   100049);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "VetoPlateGeneral",   "VetoPlateGeneral-01",     100050);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "VetoRadiatorGeneral",   "VetoRadiatorGeneral-00", 107810);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "TriggerTopLevel",       "TriggerTopLevel-01",         100047);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "TriggerStationGeneral", "TriggerStationGeneral-01",   100051);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "PreshowerTopLevel",     "PreshowerTopLevel-01",         100048);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "PreshowerStationGeneral", "PreshowerStationGeneral-01",   100052);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "ScintMaterials",     "ScintMaterials-00",       100011);
@@ -1087,6 +1231,7 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "NeutrinoIdentifier", "NeutrinoId
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "ScintIdentifier",    "ScintIdentifier-00",      100016);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "TrackerIdentifier",  "TrackerIdentifier-00",    100017);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-01", "CaloIdentifier",     "CaloIdentifier-00",       100018);
+--
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "FASER",              "FASER-CR",                107784);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "FaserCommon",        "FaserCommon-00",          100013);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "Materials",          "Materials-00",            100005);
@@ -1123,12 +1268,15 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "EcalSwitches",       "EcalSwitch
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "VetoTopLevel",       "VetoTopLevel-01",         100046);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "VetoStationGeneral", "VetoStationGeneral-01",   100049);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "VetoPlateGeneral",   "VetoPlateGeneral-01",     100050);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "VetoRadiatorGeneral",   "VetoRadiatorGeneral-00", 107810);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "TriggerTopLevel",       "TriggerTopLevel-01",         100047);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "TriggerStationGeneral", "TriggerStationGeneral-01",   100051);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "PreshowerTopLevel",     "PreshowerTopLevel-01",         100048);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "PreshowerStationGeneral", "PreshowerStationGeneral-01",   100052);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "ScintMaterials",     "ScintMaterials-00",       100011);
@@ -1147,7 +1295,7 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "NeutrinoIdentifier", "NeutrinoId
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "ScintIdentifier",    "ScintIdentifier-00",      100016);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "TrackerIdentifier",  "TrackerIdentifier-CR",    107785);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "CaloIdentifier",     "CaloIdentifier-00",       100018);
-
+--
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "FASER",              "FASER-02",                107788);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "FaserCommon",        "FaserCommon-00",          100013);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Materials",          "Materials-00",            100005);
@@ -1180,12 +1328,15 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "EcalSwitches",       "EcalSwitch
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoTopLevel",       "VetoTopLevel-02",         107798);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoStationGeneral", "VetoStationGeneral-01",   100049);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoPlateGeneral",   "VetoPlateGeneral-01",     100050);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoRadiatorGeneral",   "VetoRadiatorGeneral-00", 107810);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerTopLevel",       "TriggerTopLevel-02",         107799);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerStationGeneral", "TriggerStationGeneral-01",   100051);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerTopLevel",     "PreshowerTopLevel-02",         107800);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerStationGeneral", "PreshowerStationGeneral-01",   100052);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "ScintMaterials",     "ScintMaterials-00",       100011);
@@ -1204,7 +1355,7 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoIdentifier", "NeutrinoId
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "ScintIdentifier",    "ScintIdentifier-00",      100016);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TrackerIdentifier",  "TrackerIdentifier-02",     107787);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "CaloIdentifier",     "CaloIdentifier-00",       100018);
-
+--
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "FASER",              "FASERNU-02",              107804);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "FaserCommon",        "FaserCommon-00",          100013);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Materials",          "Materials-00",            100005);
@@ -1244,12 +1395,15 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EcalSwitches",       "EcalSwit
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoTopLevel",       "VetoTopLevel-02",         107798);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoStationGeneral", "VetoStationGeneral-01",   100049);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoPlateGeneral",   "VetoPlateGeneral-01",     100050);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoRadiatorGeneral",   "VetoRadiatorGeneral-00", 107810);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerTopLevel",       "TriggerTopLevel-02",         107799);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerStationGeneral", "TriggerStationGeneral-01",   100051);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerTopLevel",     "PreshowerTopLevel-02",         107800);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerStationGeneral", "PreshowerStationGeneral-01",   100052);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "ScintMaterials",     "ScintMaterials-00",       100011);
@@ -1268,7 +1422,73 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoIdentifier", "Neutrino
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "ScintIdentifier",    "ScintIdentifier-00",      100016);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TrackerIdentifier",  "TrackerIdentifier-02",     107787);
 INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "CaloIdentifier",     "CaloIdentifier-00",       100018);
-
+--
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "FASER",              "FASER-TB00",              107834);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "FaserCommon",        "FaserCommon-00",          100013);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Materials",          "Materials-00",            100005);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "StdMaterials",       "StdMaterials-00",         100006);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "StdMatComponents",   "StdMatComponents-00",     100007);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Elements",           "Elements-00",             100008);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Neutrino",           "Neutrino-TB00",           107811);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Emulsion",           "Emulsion-TB00",           107812);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EmulsionTopLevel",   "EmulsionTopLevel-TB00",   107813);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EmulsionGeneral",    "EmulsionGeneral-00",      107805);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EmulsionFilm",       "EmulsionFilm-00",         107806);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EmulsionPlates",     "EmulsionPlates-00",       107807);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EmulsionSwitches",   "EmulsionSwitches-00",     100036);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Scintillator",       "Scintillator-TB00",       107814);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Tracker",            "Tracker-TB00",            107815);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SCT",                "SCT-TB00",                107816);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctTopLevel",        "SCTTopLevel-TB00",        107818);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctBrlModule",       "SCTBrlModule-00",         107003);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctBrlSensor",       "SCTBrlSensor-00",         106730);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctFaserGeneral",    "SCTFaserGeneral-01",      106791);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctSwitches",        "SCTSwitches-00",          107782);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SCTMaterials",       "SCTMaterials-00",         107777);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SCTMatComponents",   "SCTMatComponents-00",     107778);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctConditions",      "SctConditions-00",        107779);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctFrame",           "SctFrame-00",             100053);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctFrameGeneral",    "SctFrameGeneral-00",      100054);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "SctFrameShape",      "SctFrameShape-00",        100055);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Dipole",             "Dipole-TB00",             107817);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "DipoleTopLevel",     "DipoleTopLevel-TB00",     107819);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "DipoleGeneral",      "DipoleGeneral-00",        100004);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "DipoleSwitches",     "DipoleSwitches-00",       100028);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Calorimeter",        "Calorimeter-TB00",        107820);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Ecal",               "Ecal-TB00",               107821);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EcalTopLevel",       "EcalTopLevel-TB00",       107822);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EcalRowGeneral",     "EcalRowGeneral-TB00",     107830);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "EcalSwitches",       "EcalSwitches-00",         100057);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "VetoTopLevel",       "VetoTopLevel-TB00",       107823);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "VetoStationGeneral", "VetoStationGeneral-TB00", 107833);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "VetoPlateGeneral",   "VetoPlateGeneral-01",     100050);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "VetoRadiatorGeneral","VetoRadiatorGeneral-00",  107810);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TriggerTopLevel",    "TriggerTopLevel-TB00",    107824);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TriggerStationGeneral", "TriggerStationGeneral-01",   100051);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TriggerPlateGeneral",   "TriggerPlateGeneral-00",     110025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerTopLevel",     "PreshowerTopLevel-TB00",         107825);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerStationGeneral", "PreshowerStationGeneral-01",   100052);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerPlateGeneral",   "PreshowerPlateGeneral-00",     120025);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerRadiatorGeneral",   "PreshowerRadiatorGeneral-00",     107808);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerAbsorberGeneral",   "PreshowerAbsorberGeneral-00",     107809);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "NeutrinoMaterials",     "NeutrinoMaterials-00",       100032);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "NeutrinoMatComponents", "NeutrinoMatComponents-00",   100033);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "ScintMaterials",     "ScintMaterials-00",       100011);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "ScintMatComponents", "ScintMatComponents-00",   100012);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TrackerMaterials",     "TrackerMaterials-00",     100021);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TrackerMatComponents", "TrackerMatComponents-00", 100022);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "CaloMaterials",     "CaloMaterials-00",         100023);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "CaloMatComponents", "CaloMatComponents-00",     100024);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "VetoSwitches",       "VetoSwitches-00",         100014);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TriggerSwitches",    "TriggerSwitches-00",      110014);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "PreshowerSwitches",  "PreshowerSwitches-00",    120014);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Veto",               "Veto-TB00",                 107826);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Trigger",            "Trigger-TB00",              107827);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "Preshower",          "Preshower-TB00",            107828);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "NeutrinoIdentifier", "NeutrinoIdentifier-00",   100030);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "ScintIdentifier",    "ScintIdentifier-TB00",    107832);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "TrackerIdentifier",  "TrackerIdentifier-TB00",  107829);
+INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-TB00", "CaloIdentifier",     "CaloIdentifier-TB00",     107831);
 -- 
 --
 -- Part 2b: Content (Leaf node) data
@@ -1815,6 +2035,7 @@ INSERT INTO "EMULSIONTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, -2475.72, 0.0, 0.0, 0.0
 INSERT INTO "EMULSIONTOPLEVEL_DATA" VALUES (1, 0.0, 0.0,     0.0, 0.0, 0.0, 0.0, 321, "StationA");
 INSERT INTO "EMULSIONTOPLEVEL_DATA2TAG" VALUES (100035, 0);
 INSERT INTO "EMULSIONTOPLEVEL_DATA2TAG" VALUES (100035, 1);
+INSERT INTO "EMULSIONTOPLEVEL_DATA2TAG" VALUES (107813, 0);
 --
 --
 INSERT INTO "EMULSIONGENERAL_DATA" VALUES (0, 35, 22, -524.275, 525.275);
@@ -1868,6 +2089,9 @@ INSERT INTO "VETOTOPLEVEL_DATA" VALUES (5, 0.0, 0.0,  100.0, 0.0, 0.0, 0.0, 321,
 INSERT INTO "VETOTOPLEVEL_DATA" VALUES (6, 0.0, 0.0, -1694.65, 0.0, 0.0, 0.0, 321, "Veto");
 INSERT INTO "VETOTOPLEVEL_DATA" VALUES (7, 0.0, 0.0, -85.0, 0.0, 0.0, 2.6, 321, "StationA");
 INSERT INTO "VETOTOPLEVEL_DATA" VALUES (8, 0.0, 0.0,  85.0, 0.0, 0.0,-2.6, 321, "StationB");
+INSERT INTO "VETOTOPLEVEL_DATA" VALUES (9, 0.0, 0.0,  0.0, 0.0, 0.0, 0.0, 321, "Radiator");
+INSERT INTO "VETOTOPLEVEL_DATA" VALUES (10, 0.0, 0.0, 21.0, 0.0, 0.0, 0.0, 321, "Veto");
+INSERT INTO "VETOTOPLEVEL_DATA" VALUES (11, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA");
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 0);
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 1);
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 2);
@@ -1877,29 +2101,39 @@ INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100046, 5);
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 6);
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 7);
 INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 8);
+INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 9);
+INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107823, 10);
+INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107823, 11);
 --
 --
 INSERT INTO "VETOSTATIONGENERAL_DATA" VALUES (0, 2, 100.0);
 INSERT INTO "VETOSTATIONGENERAL_DATA" VALUES (1, 2, 20.0);
+INSERT INTO "VETOSTATIONGENERAL_DATA" VALUES (2, 2, 21.0);
 INSERT INTO "VETOSTATIONGENERAL_DATA2TAG" VALUES (100010, 0);
 INSERT INTO "VETOSTATIONGENERAL_DATA2TAG" VALUES (100049, 1);
+INSERT INTO "VETOSTATIONGENERAL_DATA2TAG" VALUES (107833, 2);
 --
 INSERT INTO "VETOPLATEGENERAL_DATA" VALUES (0, 1, 300.0, 300.0, 20.0, "scint::Scintillator");
 INSERT INTO "VETOPLATEGENERAL_DATA" VALUES (1, 1, 300.0, 300.0, 19.5, "scint::Scintillator");
 INSERT INTO "VETOPLATEGENERAL_DATA2TAG" VALUES (100025, 0);
 INSERT INTO "VETOPLATEGENERAL_DATA2TAG" VALUES (100050, 1);
 --
+INSERT INTO "VETORADIATORGENERAL_DATA" VALUES (0, 400.0, 350.0, 100.0, "std::Lead");
+INSERT INTO "VETORADIATORGENERAL_DATA2TAG" VALUES (107810, 0);
+--
 --
 INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, 187.0, 0.0, 0.0, 0.0, 321, "Trigger");
 INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA");
 INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (2, 0.0, -5.0, -28.9, 0.0, 0.0, 0.0, 321, "Trigger");
 INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (3, 0.0, -5.0, -29.2, 0.0, 0.0, 0.0, 321, "Trigger");
+INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (4, 0.0, -5.0, -29.2, 0.0, 0.0, 0.0, 321, "Trigger");
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (110009, 0);
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (110009, 1);
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (100047, 1);
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (100047, 2);
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (107799, 3);
 INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (107799, 1);
+INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (107824, 4);
 --
 --
 INSERT INTO "TRIGGERSTATIONGENERAL_DATA" VALUES (0, 2, 195.0, 11.0);
@@ -1914,48 +2148,71 @@ INSERT INTO "TRIGGERPLATEGENERAL_DATA2TAG" VALUES (110025, 0);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, 2626.0, 0.0, 0.0, 0.0, 321, "Preshower");
 INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA");
 INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (2, 0.0, 0.0, 2662.7, 0.0, 0.0, 0.0, 321, "Preshower");
-INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, 2662.35, 0.0, 0.0, 0.0, 321, "Preshower");
+--INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, 2662.35, 0.0, 0.0, 0.0, 321, "Preshower");
+INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, 2618.35, 0.0, 0.0, 0.0, 321, "Preshower");
+INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (4, 0.0, 0.0, 522.0, 0.0, 0.0, 0.0, 321, "Preshower");
+INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA");
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (120009, 0);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (120009, 1);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (100048, 1);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (100048, 2);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107800, 1);
 INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107800, 3);
+INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107825, 4);
+INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107825, 5);
 --
 --
 INSERT INTO "PRESHOWERSTATIONGENERAL_DATA" VALUES (0, 2, 80.0);
-INSERT INTO "PRESHOWERSTATIONGENERAL_DATA" VALUES (1, 2, 82.0);
+INSERT INTO "PRESHOWERSTATIONGENERAL_DATA" VALUES (1, 2, 75.0);
 INSERT INTO "PRESHOWERSTATIONGENERAL_DATA2TAG" VALUES (120010, 0);
 INSERT INTO "PRESHOWERSTATIONGENERAL_DATA2TAG" VALUES (100052, 1);
 --
 INSERT INTO "PRESHOWERPLATEGENERAL_DATA" VALUES (0, 1, 300.0, 300.0, 20.0, "scint::Scintillator");
 INSERT INTO "PRESHOWERPLATEGENERAL_DATA2TAG" VALUES (120025, 0);
 --
+INSERT INTO "PRESHOWERRADIATORGENERAL_DATA" VALUES (0, 300.0, 300.0, 3.0, "std::Wolfram");
+INSERT INTO "PRESHOWERRADIATORGENERAL_DATA2TAG" VALUES (107808, 0);
+--
+INSERT INTO "PRESHOWERABSORBERGENERAL_DATA" VALUES (0, 300.0, 300.0, 50.0, "scint::Graphite");
+INSERT INTO "PRESHOWERABSORBERGENERAL_DATA2TAG" VALUES (107809, 0);
+--
 --
 INSERT INTO "ECALTOPLEVEL_DATA" VALUES (0, 0.0,   0.0, 3099.2, 0.0, 0.0, 0.0, 321, "Ecal");
 INSERT INTO "ECALTOPLEVEL_DATA" VALUES (1, 0.0, -71.6,    0.0, 0.0, 2.8, 0.0, 321, "BottomRow");
 INSERT INTO "ECALTOPLEVEL_DATA" VALUES (2, 0.0,  49.6,    0.0, 0.0, 2.8, 0.0, 321, "TopRow");
 INSERT INTO "ECALTOPLEVEL_DATA" VALUES (3, 0.0,   0.0, 3098.9, 0.0, 0.0, 0.0, 321, "Ecal");
+INSERT INTO "ECALTOPLEVEL_DATA" VALUES (4, 0.0, -71.6,    0.0, 0.0, 0.0, 0.0, 321, "BottomRow");
+INSERT INTO "ECALTOPLEVEL_DATA" VALUES (5, 0.0,  49.6,    0.0, 0.0, 0.0, 0.0, 321, "TopRow");
+INSERT INTO "ECALTOPLEVEL_DATA" VALUES (6, -17.22, -22.80, 1088.66, -2.8, -2.8, 0.0, 321, "Ecal");
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 0);
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 1);
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 2);
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 1);
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 2);
 INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 3);
+INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107822, 4);
+INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107822, 5);
+INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107822, 6);
 --
 --
 INSERT INTO "ECALROWGENERAL_DATA" VALUES (0, 2, 0.0, 2.8);
+INSERT INTO "ECALROWGENERAL_DATA" VALUES (1, 3, 0.0, 0.0);
 INSERT INTO "ECALROWGENERAL_DATA2TAG" VALUES (100059, 0);
+INSERT INTO "ECALROWGENERAL_DATA2TAG" VALUES (107830, 1);
 --
 --
 INSERT INTO "SCINTMATERIALS_DATA" VALUES (0, "Scintillator", 1.032);
+INSERT INTO "SCINTMATERIALS_DATA" VALUES (1, "Graphite", 1.8);
 INSERT INTO "SCINTMATERIALS_DATA2TAG" VALUES (100011, 0);
+INSERT INTO "SCINTMATERIALS_DATA2TAG" VALUES (100011, 1);
 --
 --
 INSERT INTO "SCINTMATCOMPONENTS_DATA" VALUES (0, 0, "Carbon", 0.475);
 INSERT INTO "SCINTMATCOMPONENTS_DATA" VALUES (1, 0, "Hydrogen", 0.525);
+INSERT INTO "SCINTMATCOMPONENTS_DATA" VALUES (2, 1, "Carbon", 1.0);
 INSERT INTO "SCINTMATCOMPONENTS_DATA2TAG" VALUES (100012, 0);
 INSERT INTO "SCINTMATCOMPONENTS_DATA2TAG" VALUES (100012, 1);
+INSERT INTO "SCINTMATCOMPONENTS_DATA2TAG" VALUES (100012, 2);
 --
 --
 INSERT INTO "FASERCOMMON_DATA" VALUES (0, "RUN3", "TRACKER", "NONE");
@@ -1987,19 +2244,25 @@ INSERT INTO "NEUTRINOIDENTIFIER_DATA2TAG" VALUES (100030, 0);
 --
 --
 INSERT INTO "SCINTIDENTIFIER_DATA" VALUES (0, "Scintillator", "ScintIdDictFiles/IdDictScintillator.xml", "Baseline layout");
+INSERT INTO "SCINTIDENTIFIER_DATA" VALUES (1, "Scintillator", "ScintIdDictFiles/IdDictScintillator_TB00.xml", "2021 Test-beam layout");
 INSERT INTO "SCINTIDENTIFIER_DATA2TAG" VALUES (100016, 0);
+INSERT INTO "SCINTIDENTIFIER_DATA2TAG" VALUES (107832, 1);
 --
 --
 INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (0, "Tracker", "TrackerIdDictFiles/IdDictTracker.xml", "Baseline layout");
 INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (1, "Tracker", "TrackerIdDictFiles/IdDictCosmic.xml", "Cosmic ray test stand");
 INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (2, "Tracker", "TrackerIdDictFiles/IdDictInterface.xml", "Tracker with interface detector");
+INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (3, "Tracker", "TrackerIdDictFiles/IdDictInterface_TB00.xml", "2021 Test-beam layout");
 INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (100017, 0);
 INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (107785, 1);
 INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (107787, 2);
+INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (107829, 3);
 --
 --
 INSERT INTO "CALOIDENTIFIER_DATA" VALUES (0, "Calorimeter", "CaloIdDictFiles/IdDictCalorimeter.xml", "Baseline layout");
+INSERT INTO "CALOIDENTIFIER_DATA" VALUES (1, "Calorimeter", "CaloIdDictFiles/IdDictCalorimeter_TB00.xml", "2021 Test-beam layout");
 INSERT INTO "CALOIDENTIFIER_DATA2TAG" VALUES (100018, 0);
+INSERT INTO "CALOIDENTIFIER_DATA2TAG" VALUES (107831, 1);
 --
 --
 DROP TABLE IF EXISTS "SCTBRLSENSOR_DATA";
@@ -2034,6 +2297,9 @@ INSERT INTO "SCTTOPLEVEL_DATA" VALUES(6,0.0,0.0, 1190.0,0.0,0.0,0.0,312,'Station
 INSERT INTO "SCTTOPLEVEL_DATA" VALUES(7,0.0,0.0, 1237.7075,0.0,0.0,0.0,312,'SCT');
 INSERT INTO "SCTTOPLEVEL_DATA" VALUES(8,0.0,0.0, 1237.4   ,0.0,0.0,0.0,312,'SCT');
 INSERT INTO "SCTTOPLEVEL_DATA" VALUES(9,0.0,0.0,-3097.55  ,0.0,0.0,0.0,312,'Interface');
+INSERT INTO "SCTTOPLEVEL_DATA" VALUES(10,0.0,0.0, 276.75   ,0.0,0.0,0.0,312,'SCT');
+INSERT INTO "SCTTOPLEVEL_DATA" VALUES(11,0.0,0.0, 0.0  ,0.0,0.0,0.0,312,'Interface');
+
 
 
 DROP TABLE IF EXISTS "SCTTOPLEVEL_DATA2TAG";
@@ -2053,6 +2319,8 @@ INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,5);
 INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,6);
 INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,8);
 INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,9);
+INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107818,10);
+INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107818,11);
 --
 --
 DROP TABLE IF EXISTS "SCTFASERGENERAL_DATA";
@@ -2174,7 +2442,7 @@ INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(6,0.0,0.0,1837.726,0.0,0.0,0.0,312,'Dow
 INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(7,0.0,0.0,-812.60,0.0,0.0,0.0,312,'UpstreamDipole');
 INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(8,0.0,0.0, 637.40,0.0,0.0,0.0,312,'CentralDipole');
 INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(9,0.0,0.0,1837.40,0.0,0.0,0.0,312,'DownstreamDipole');
-
+INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(10,0.0,0.0, 0.0,0.0,0.0,0.0,312,'Dipole');
 
 DROP TABLE IF EXISTS "DIPOLETOPLEVEL_DATA2TAG";
 CREATE TABLE "DIPOLETOPLEVEL_DATA2TAG" ( "DIPOLETOPLEVEL_TAG_ID" SLONGLONG ,"DIPOLETOPLEVEL_DATA_ID" SLONGLONG  );
@@ -2190,6 +2458,7 @@ INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,3);
 INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,7);
 INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,8);
 INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,9);
+INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107819,10);
 --
 --
 DROP TABLE IF EXISTS "DIPOLEGENERAL_DATA";
diff --git a/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py b/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py
index 0820c0ad2e863b540776c8ce14612235138fb2a2..0911c1db4ec3b16c8720abf755edf2c2568db721 100644
--- a/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py
+++ b/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py
@@ -25,7 +25,7 @@ def _setupGeoModel():
     # Set up detector tools here
 
 
-    if "FaserNu" in DDversion and not hasattr(svcMgr,'NeutrinoGeometryDBSvc'):
+    if "FASERNU" in DDversion and not hasattr(svcMgr,'NeutrinoGeometryDBSvc'):
         from GeometryDBSvc.GeometryDBSvcConf import GeometryDBSvc
         svcMgr+=GeometryDBSvc("NeutrinoGeometryDBSvc")
 
@@ -42,7 +42,7 @@ def _setupGeoModel():
         svcMgr+=GeometryDBSvc("CaloGeometryDBSvc")
 
     # from AthenaCommon import CfgGetter
-    if "FaserNu" in DDversion:
+    if "FASERNU" in DDversion:
         from EmulsionGeoModel.EmulsionGeoModelConf import EmulsionDetectorTool
         emulsionDetectorTool = EmulsionDetectorTool(DetectorName = "Emulsion", Alignable = True, RDBAccessSvc = "RDBAccessSvc", GeometryDBSvc = "NeutrinoGeometryDBSvc", GeoDbTagSvc = "GeoDbTagSvc")
         geoModelSvc.DetectorTools += [ emulsionDetectorTool ]
diff --git a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx
index c35ddacbbf70b2e92c5b5122ee5df4408114e545..08197aa15ffe3d7e046e564d56689c2c2516dfe1 100644
--- a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx
+++ b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx
@@ -14,7 +14,7 @@
 //#include "eformat/SourceIdentifier.h"
 //#include "eformat/StreamTag.h"
 
-#include "AthenaKernel/IClassIDSvc.h"
+#include "GaudiKernel/IClassIDSvc.h"
 
 #include "AthenaPoolUtilities/CondAttrListCollection.h"
 
diff --git a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx
index 8695ec12b9233fff232a3759e78891d8f8caeb90..e2d659995a21c00f125e8dfb32a779fe202a27c6 100644
--- a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx
+++ b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx
@@ -67,7 +67,7 @@ FaserByteStreamInputSvc::~FaserByteStreamInputSvc() {
 }
 //------------------------------------------------------------------------------
 StatusCode FaserByteStreamInputSvc::initialize() {
-   ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION);
+   ATH_MSG_INFO("Initializing " << name() );
 
    ATH_CHECK(m_storeGate.retrieve());
    ATH_CHECK(m_robProvider.retrieve());
diff --git a/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx
index ef11d4c96265b1a8c8bd74e373dc59a8be8299cd..5a29672fe71cc9eff05810a13303bc2f0077e0c0 100644
--- a/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx
+++ b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx
@@ -95,7 +95,7 @@ FaserEventSelectorByteStream::~FaserEventSelectorByteStream() {
 }
 //________________________________________________________________________________
 StatusCode FaserEventSelectorByteStream::initialize() {
-  ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Initializing " << name());
   if (!::AthService::initialize().isSuccess()) {
     ATH_MSG_FATAL("Cannot initialize AthService base class.");
     return(StatusCode::FAILURE);
@@ -806,7 +806,8 @@ StatusCode FaserEventSelectorByteStream::makeServer(int /*num*/) {
   if (m_eventStreamingTool.empty()) {
     return(StatusCode::FAILURE);
   }
-  return(m_eventStreamingTool->makeServer(1));
+  std::string dummyString;
+  return(m_eventStreamingTool->makeServer(1, dummyString));
 }
 
 //________________________________________________________________________________
@@ -814,7 +815,8 @@ StatusCode FaserEventSelectorByteStream::makeClient(int /*num*/) {
   if (m_eventStreamingTool.empty()) {
     return(StatusCode::FAILURE);
   }
-  return(m_eventStreamingTool->makeClient(0));
+  std::string dummyString;
+  return(m_eventStreamingTool->makeClient(0, dummyString));
 }
 
 //________________________________________________________________________________
diff --git a/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamAddressProviderSvc.cxx b/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamAddressProviderSvc.cxx
index e5b16c854481b52a346ef7bbf9131e4d0d31e813..252075361d8e75084d78dc4359ec8b29deb7ffd5 100644
--- a/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamAddressProviderSvc.cxx
+++ b/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamAddressProviderSvc.cxx
@@ -11,7 +11,7 @@
 #include "SGTools/TransientAddress.h"
 #include "GaudiKernel/ListItem.h"
 
-#include "AthenaKernel/IClassIDSvc.h"
+#include "GaudiKernel/IClassIDSvc.h"
 
 //#include "eformat/SourceIdentifier.h"
 
@@ -27,7 +27,7 @@ FaserByteStreamAddressProviderSvc::~FaserByteStreamAddressProviderSvc() {
 }
 //________________________________________________________________________________
 StatusCode FaserByteStreamAddressProviderSvc::initialize() {
-   ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION);
+   ATH_MSG_INFO("Initializing " << name());
    if (!::AthService::initialize().isSuccess()) {
       ATH_MSG_FATAL("Cannot initialize AthService base class.");
       return(StatusCode::FAILURE);
diff --git a/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamCnvSvcBase.cxx b/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamCnvSvcBase.cxx
index a250c8597214513e610c2598efb41448489d21a2..b41792c41b68e6814edcba83e229d43012ddedcc 100644
--- a/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamCnvSvcBase.cxx
+++ b/Event/FaserByteStreamCnvSvcBase/src/FaserByteStreamCnvSvcBase.cxx
@@ -11,7 +11,7 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/IIncidentSvc.h"
 
-#include "AthenaKernel/IClassIDSvc.h"
+#include "GaudiKernel/IClassIDSvc.h"
 #include "StoreGate/StoreGateSvc.h" 
 
 //______________________________________________________________________________
diff --git a/Event/FaserByteStreamCnvSvcBase/src/FaserROBDataProviderSvc.cxx b/Event/FaserByteStreamCnvSvcBase/src/FaserROBDataProviderSvc.cxx
index a897e51681e2278a7b0a02cb8f7569c2042c121e..4863796dab9affef15b662cbeb0091c62b8115c1 100644
--- a/Event/FaserByteStreamCnvSvcBase/src/FaserROBDataProviderSvc.cxx
+++ b/Event/FaserByteStreamCnvSvcBase/src/FaserROBDataProviderSvc.cxx
@@ -98,7 +98,7 @@ FaserROBDataProviderSvc::~FaserROBDataProviderSvc() {
 
 // Initialization
 StatusCode FaserROBDataProviderSvc::initialize() {
-   ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION);
+   ATH_MSG_INFO("Initializing " << name());
    if (!::AthService::initialize().isSuccess()) {
       ATH_MSG_FATAL("Cannot initialize AthService base class.");
       return(StatusCode::FAILURE);
diff --git a/Generators/DIFGenerator/python/DIFSampler.py b/Generators/DIFGenerator/python/DIFSampler.py
index 18f9156b4c385cc11614ac0937897ac813b34583..24659c0178d8cbefc9843a24a1a10ef38bbcde21 100644
--- a/Generators/DIFGenerator/python/DIFSampler.py
+++ b/Generators/DIFGenerator/python/DIFSampler.py
@@ -344,7 +344,7 @@ if __name__ == "__main__":
         s = daughters[0].mom+daughters[1].mom
 
         try:
-            assert DIFS.mother_sampler.pid() == None
+            assert DIFS.mother_sampler.pid() is None
             assert mother_mom.E()**2 -  mother_mom.P()**2 - epsilon <= s.E()**2 - s.P()**2 <= mother_mom.E()**2 - mother_mom.P()**2 + epsilon
             assert mother_mom.Px() - epsilon <= s.Px() <= mother_mom.Px() + epsilon
             assert mother_mom.Py() - epsilon <= s.Py() <= mother_mom.Py() + epsilon
diff --git a/Generators/FaserCosmicGenerator/README.md b/Generators/FaserCosmicGenerator/README.md
index 7a2ea2f057ee6eeb89851b4a0ed0d8de168ede4b..512c32c60d6d875dba083a0fc2e5dc34e7dc8499 100644
--- a/Generators/FaserCosmicGenerator/README.md
+++ b/Generators/FaserCosmicGenerator/README.md
@@ -2,11 +2,11 @@
 
 ## Setup
 
-In Athena 22.0.31, the scipy module is missing from the LCG environment for some reason.
+In Athena 22.0.40, the scipy module is missing from the LCG environment for some reason.
 
 To use the generator, the following command is required after the usual steps to setup the release:
 
-`lsetup "lcgenv -p LCG_98python3_ATLAS_8 x86_64-centos7-gcc8-opt scipy"`
+`export PYTHONPATH=/cvmfs/sft.cern.ch/lcg/releases/LCG_100_ATLAS_5/scipy/1.5.1/x86_64-centos7-gcc8-opt/lib/python3.8/site-packages:${PYTHONPATH}`
 
 ## Usage
 
diff --git a/Generators/FaserParticleGun/CMakeLists.txt b/Generators/FaserParticleGun/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dfc2bbd92f4488e6ccf0a4fffab49d98460234e9
--- /dev/null
+++ b/Generators/FaserParticleGun/CMakeLists.txt
@@ -0,0 +1,10 @@
+################################################################################
+# Package: FaserParticleGun
+################################################################################
+
+# Declare the package name:
+atlas_subdir( FaserParticleGun )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
+
diff --git a/Generators/FaserParticleGun/python/FaserParticleGunConfig.py b/Generators/FaserParticleGun/python/FaserParticleGunConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..f5ba68bcba67791b3d7fa6792518ba74b90d1bb6
--- /dev/null
+++ b/Generators/FaserParticleGun/python/FaserParticleGunConfig.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# import sys
+from AthenaConfiguration.MainServicesConfig import AthSequencer
+import ParticleGun as PG
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+# from AthenaCommon.Constants import VERBOSE, INFO
+from AthenaCommon.SystemOfUnits import TeV
+from AthenaCommon.PhysicalConstants import pi
+
+
+def FaserParticleGunCommonCfg(ConfigFlags, **kwargs) :
+    cfg = ComponentAccumulator(AthSequencer("AthBeginSeq", Sequential = True))
+
+
+    # have to do this in a clunky way, since ParticleGun does not recognize all keywords we might get passed
+    pg = PG.ParticleGun( name = kwargs.setdefault("name", "ParticleGun"),
+                         randomSeed = kwargs.setdefault("randomSeed", 12345),
+                         randomSvcName = kwargs.setdefault("randomSvcName", "AtRndmGenSvc"),
+                         randomStream = kwargs.setdefault("randomStream", "ParticleGun") )
+
+    pg.McEventKey = kwargs.setdefault("McEventKey", "BeamTruthEvent")
+    cfg.addEventAlgo(pg, sequenceName = "AthBeginSeq", primary = True) # to run *before* G4
+
+    return cfg
+
+
+def FaserParticleGunSingleParticleCfg(ConfigFlags, **kwargs) :
+    cfg = FaserParticleGunCommonCfg(ConfigFlags, **kwargs)
+
+    pg = cfg.getPrimary()
+
+    pg.sampler.pid = kwargs.setdefault("pid", -13)
+    pg.sampler.mom = PG.EThetaMPhiSampler(energy = kwargs.setdefault("energy", 1*TeV),
+                                          theta = kwargs.setdefault("theta", [0, pi/20]), 
+                                          phi = kwargs.setdefault("phi", [0, 2*pi]), 
+                                          mass = kwargs.setdefault("mass", 0.0) )
+    pg.sampler.pos = PG.PosSampler(x = kwargs.setdefault("x", [-5, 5]), 
+                                   y = kwargs.setdefault("y", [-5, 5]), 
+                                   z = kwargs.setdefault("z", -3750.0), 
+                                   t = kwargs.setdefault("t", 0.0) )
+
+    return cfg
+
+def FaserParticleGunSingleEcalParticleCfg(ConfigFlags, **kwargs) :
+    cfg = FaserParticleGunCommonCfg(ConfigFlags, **kwargs)
+
+    pg = cfg.getPrimary()
+
+    pg.sampler.pid = kwargs.setdefault("pid", 11)
+    pg.sampler.mom = PG.EThetaMPhiSampler(energy = kwargs.setdefault("energy", 1*TeV),
+                                          theta = kwargs.setdefault("theta", [0, pi/200]), 
+                                          phi = kwargs.setdefault("phi", [0, 2*pi]), 
+                                          mass = kwargs.setdefault("mass", 0.0) )
+    pg.sampler.pos = PG.PosSampler(x = kwargs.setdefault("x", [-5, 5]), 
+                                   y = kwargs.setdefault("y", [-5, 5]), 
+                                   z = kwargs.setdefault("z", 2730.0), 
+                                   t = kwargs.setdefault("t", 0.0) )
+
+    return cfg
+
+def FaserParticleGunCosmicsCfg(ConfigFlags, **kwargs) :
+    # Supported keyword arguments:
+    #
+    # chargeRatio       (default: 1.27)
+    # maxMuonEnergyGeV  (default: 10000)
+    # thetaMinDegree    (default: 0)
+    # thetaMaxDegree    (default: 80)
+    # targetDepthMeters (default: 85)
+    # targetDxMm        (default: 600)  - width of target slab
+    # targetDyMm        (default: 600)  - height of target slab
+    # targetDzMm        (default: 7000) - length of target slab
+    # x0Mm              (default: 0)    - X center of target slab in FASER coordinate system
+    # y0Mm              (default: 0)    - Y center of target slab in FASER coordinate system
+    # z0Mm              (default: 150)  - Z center of target slab in FASER coordinate system
+    #
+    
+    cfg = FaserParticleGunCommonCfg(ConfigFlags, **kwargs)
+
+    pg = cfg.getPrimary()
+
+    from FaserCosmicGenerator import CosmicSampler
+    pg.sampler = CosmicSampler(**kwargs)
+
+    return cfg
+
+def FaserParticleGunDecayInFlightCfg(ConfigFlags, **kwargs) :
+    # Supported keyword arguments:
+    #
+    # daughter1_pid (default:  11)
+    # daughter2_pid (default: -11)
+    # mother_pid    (default: none)
+    # mother_mom    (default: PG.EThetaMPhiSampler(sqrt((1*TeV)**2 + (10*MeV)**2),0,10*MeV,0))
+    # mother_pos    (default: CylinderSampler([0, 100**2],[0, 2*pi],[-1500, 0],0))
+    #
+    # Note that ALL of these can be samplers themselves - either the simple, "literal" variety or a sampler object configured by the caller
+    #
+
+    cfg = FaserParticleGunCommonCfg(ConfigFlags, **kwargs)
+
+    pg = cfg.getPrimary()
+
+    from DIFGenerator import DIFSampler
+    pg.sampler = DIFSampler(**kwargs)
+
+    return cfg
+
+def FaserParticleGunCfg(ConfigFlags) :
+    generator = ConfigFlags.Sim.Gun.setdefault("Generator", "SingleParticle")
+    kwargs = ConfigFlags.Sim.Gun
+    if generator == "SingleEcalParticle" :
+        return FaserParticleGunSingleEcalParticleCfg(ConfigFlags, **kwargs)
+    elif generator == "Cosmics" :
+        return FaserParticleGunCosmicsCfg(ConfigFlags, **kwargs)
+    elif generator == "DecayInFlight" :
+        return FaserParticleGunDecayInFlightCfg(ConfigFlags, **kwargs)
+    else :
+        return FaserParticleGunSingleParticleCfg(ConfigFlags, **kwargs )
diff --git a/Generators/FaserParticleGun/python/__init__.py b/Generators/FaserParticleGun/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/MagneticField/MagFieldElements/MagFieldElements/FaserFieldCache.h b/MagneticField/MagFieldElements/MagFieldElements/FaserFieldCache.h
index 6011b4658c310962a68f6dd63d65caa81435617e..3e1c8df5c9e04f9ae4b6c0b3759780529dfe639f 100644
--- a/MagneticField/MagFieldElements/MagFieldElements/FaserFieldCache.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/FaserFieldCache.h
@@ -37,11 +37,12 @@ namespace MagField {
     // : public ::AthMessaging
     {
     public:
-        FaserFieldCache();
+        FaserFieldCache() = default;
         // ** constructor to setup with field scale and magnetic field service for first access to field */
         FaserFieldCache(double fieldScale,
                         const FaserFieldMap* fieldMap);
-        FaserFieldCache& operator= (FaserFieldCache&& other)      = default;
+        FaserFieldCache& operator= (FaserFieldCache&& other) = default;
+        FaserFieldCache(FaserFieldCache&& other) = default;
         ~FaserFieldCache() = default; 
  
         /** get B field value at given position */
@@ -58,7 +59,6 @@ namespace MagField {
     
         FaserFieldCache(const FaserFieldCache& other)             = delete;
         FaserFieldCache& operator= (const FaserFieldCache& other) = delete;
-        FaserFieldCache(FaserFieldCache&& other)                  = delete;
 
         inline bool fillFieldCache(double x, double y, double z);
         // inline bool fillFieldCacheZR(double z, double r);
diff --git a/MagneticField/MagFieldElements/src/FaserFieldCache.cxx b/MagneticField/MagFieldElements/src/FaserFieldCache.cxx
index 5d08317efd2b4e9847046bee2393b6e808a489e6..040dc170ba0b1ec106dc2bf2aa4449b8159ba01d 100644
--- a/MagneticField/MagFieldElements/src/FaserFieldCache.cxx
+++ b/MagneticField/MagFieldElements/src/FaserFieldCache.cxx
@@ -12,9 +12,6 @@
 #include "MagFieldElements/FaserFieldCache.h"
 
 /// Constructor
-MagField::FaserFieldCache::FaserFieldCache()
-{}
-
 MagField::FaserFieldCache::FaserFieldCache(double scale,
                                            const FaserFieldMap* fieldMap)
     :
diff --git a/Monitoring/python/MonitorValueBase.py b/Monitoring/python/MonitorValueBase.py
index 82220c35ca5d513952bb1fd71ecac5cf4f38fd96..c4f5552d8da5e3c4ee0e24d5e03520896a2883e3 100644
--- a/Monitoring/python/MonitorValueBase.py
+++ b/Monitoring/python/MonitorValueBase.py
@@ -148,7 +148,7 @@ class MonitorValueBase ():
 
         # Set type if not configured
         actualType = self.__class__.__name__
-        if self.conf.type == None:
+        if self.conf.type is None:
             self.conf.type = actualType
 
         # Check that type is correct
diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx
index ed7015b1f6734f3f5be7ba60b4594ea830896ea6..11f32197b20833c8cfeb8c3fc7c566fc7fea959b 100644
--- a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx
+++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx
@@ -66,7 +66,7 @@ EmulsionDetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the Emulsion version tag:
   std::string emulsionVersionTag{m_rdbAccessSvc->getChildTag("Emulsion", versionKey.tag(), versionKey.node(), "FASERDD")};
-  ATH_MSG_INFO("Emulsion Version: " << emulsionVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Emulsion Version: " << emulsionVersionTag);
   // Check if version is empty. If so, then the Emulsion cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (emulsionVersionTag.empty()) {
@@ -172,7 +172,7 @@ EmulsionDetectorTool::clear()
 StatusCode 
 EmulsionDetectorTool::registerCallback()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
       ATH_MSG_WARNING("Called untested EmulsionDetectorTool::registerCallback()");
     if (m_useDynamicAlignFolders.value()) {
diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h
index 14641723e8d8d81878772e3d4cba75c2b5158f3d..492daccd4dfd15e7bbe15ce19a08311ab5198e17 100644
--- a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h
+++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h
@@ -38,6 +38,7 @@ class GeoAlignmentStore;
 namespace Trk{
  class Surface;
  class SurfaceBounds;
+ constexpr DetectorElemType Emulsion = DetectorElemType::SolidState;
 }
 
 namespace NeutrinoDD {
@@ -382,6 +383,10 @@ namespace NeutrinoDD {
     public:
     
       const NeutrinoCommonItems* getCommonItems() const;
+
+      /** TrkDetElementBase interface detectorType
+      */
+      virtual Trk::DetectorElemType detectorType() const override final;
     
       ///////////////////////////////////////////////////////////////////
       // Private methods:
@@ -487,6 +492,10 @@ namespace NeutrinoDD {
     // Inline methods:
     ///////////////////////////////////////////////////////////////////
 
+    inline Trk::DetectorElemType NeutrinoDetectorElement::detectorType() const{
+      return Trk::Emulsion;
+    }
+
     inline HepGeom::Point3D<double> NeutrinoDetectorElement::globalPositionHit(const HepGeom::Point3D<double> &localPos) const
     {
       return Amg::EigenTransformToCLHEP(transformHit())*localPos;
diff --git a/README.md b/README.md
index 00cfe12e7f430130237cb366a8b761cde37e5568..310f3646591eae6b890efc2f8f461a11aa0e5c7e 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ git clone --recursive https://:@gitlab.cern.ch:8443/$USERNAME/calypso.git
 #The next three lines are used to setup the ATLAS release environment
 export ATLAS_LOCAL_ROOT_BASE=/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase 
 source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh
-asetup --input=calypso/asetup.faser Athena,22.0.31
+asetup --input=calypso/asetup.faser Athena,22.0.40
 
 #create build directory
 mkdir build
@@ -41,6 +41,8 @@ It can be convenient to alias the "asetup --input=calypso/asetup.faser" to somet
 
 ** `ConfigFlags.GeoModel.FaserVersion = "FASERNU-02"` and `ConfigFlags.IOVDb.GlobalTag = OFLCOND-FASER-02` enables the full FaserNu (IFT + emulsion) setup
 
+** `ConfigFlags.GeoModel.FaserVersion = "FASER-TB00"` and `ConfigFlags.IOVDb.GlobalTag = OFLCOND-FASER-02` enables the 2021 Test-beam setup.
+
 * The "FaserActsKalmanFilter" package is temporarily disabled.
 
 * The command `lsetup "lcgenv -p LCG_98python3_ATLAS_8 x86_64-centos7-gcc8-opt sqlite"` may be necessary to avoid errors when generating a database
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f1d515e0ad3cabd93796f1f3f2426d34a9a0d289
--- /dev/null
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "PreshowerAbsorberParameters.h"
+#include "PreshowerGeometryManager.h"
+
+#include "PreshowerDataBase.h"
+
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+#include <cmath>
+
+
+PreshowerAbsorberParameters::PreshowerAbsorberParameters(PreshowerDataBase* rdb)
+{
+  m_rdb = rdb;
+}
+
+//
+// Absorber General
+//
+double 
+PreshowerAbsorberParameters::absorberWidth() const
+{
+  return m_rdb->absorberGeneral()->getDouble("WIDTH") * Gaudi::Units::mm; 
+}
+
+double 
+PreshowerAbsorberParameters::absorberLength() const
+{
+  return m_rdb->absorberGeneral()->getDouble("LENGTH") * Gaudi::Units::mm; 
+}
+
+double 
+PreshowerAbsorberParameters::absorberThickness() const
+{
+  return m_rdb->absorberGeneral()->getDouble("THICKNESS") * Gaudi::Units::mm; 
+}
+
+std::string PreshowerAbsorberParameters::absorberMaterial() const
+{
+  return m_rdb->absorberGeneral()->getString("MATERIAL");
+}
+
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d2bafd3d501d26bba2cca36a0b25e6c8b969057
--- /dev/null
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerAbsorberParameters.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PreshowerGeoModel_PreshowerAbsorberParameters_H
+#define PreshowerGeoModel_PreshowerAbsorberParameters_H
+
+#include <string>
+
+class PreshowerDataBase;
+
+class PreshowerAbsorberParameters {
+
+public:
+
+  // Constructor 
+  PreshowerAbsorberParameters(PreshowerDataBase* rdb);
+
+  // General
+  double absorberThickness() const;
+  double absorberWidth() const;
+  double absorberLength() const;
+  std::string absorberMaterial() const;
+
+ private:
+  PreshowerDataBase * m_rdb;
+
+};
+
+
+#endif // PreshowerGeoModel_PreshowerAbsorberParameters_H
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.cxx
index e45e3051cf883674f2216a86579ebdf2856aaa41..422c40ab4347b2669792d43994e0cc7dbc2c90c6 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.cxx
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.cxx
@@ -77,6 +77,12 @@ PreshowerDataBase::PreshowerDataBase(const PreshowerGeoModelAthenaComps * athena
   m_plateGeneral = rdbSvc->getRecordsetPtr("PreshowerPlateGeneral", versionTag, versionNode, "FASERDD");
   msg(MSG::DEBUG) << "Table PreshowerPlateGeneral Fetched" << endmsg;
 
+  m_radiatorGeneral = rdbSvc->getRecordsetPtr("PreshowerRadiatorGeneral", versionTag, versionNode, "FASERDD");
+  msg(MSG::DEBUG) << "Table PreshowerRadiatorGeneral Fetched" << endmsg;
+
+  m_absorberGeneral = rdbSvc->getRecordsetPtr("PreshowerAbsorberGeneral", versionTag, versionNode, "FASERDD");
+  msg(MSG::DEBUG) << "Table PreshowerAbsorberGeneral Fetched" << endmsg;
+
 }
 
 const PreshowerGeoModelAthenaComps* PreshowerDataBase::athenaComps() const { return m_athenaComps; }
@@ -93,6 +99,8 @@ IRDBRecordset_ptr PreshowerDataBase::topLevelTable() const {return m_topLevel;}
 
 const IRDBRecord* PreshowerDataBase::stationGeneral() const {return (*m_stationGeneral)[0];}
 const IRDBRecord* PreshowerDataBase::plateGeneral() const {return (*m_plateGeneral)[0];}
+const IRDBRecord* PreshowerDataBase::radiatorGeneral() const {return (*m_radiatorGeneral)[0];}
+const IRDBRecord* PreshowerDataBase::absorberGeneral() const {return (*m_absorberGeneral)[0];}
 
 const std::string & PreshowerDataBase::versionTag() const {
   return m_preshowerVersionTag;
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.h
index 7021191a20b434a95dfe66606c742ba9258e5f52..ef6e4acbbe74446a4dd3035ea2bb0242d9de1e17 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.h
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDataBase.h
@@ -28,6 +28,8 @@ public:
 
   const IRDBRecord* stationGeneral() const;
   const IRDBRecord* plateGeneral() const;
+  const IRDBRecord* radiatorGeneral() const;
+  const IRDBRecord* absorberGeneral() const;
 
   // Return the Preshower version tag.
   const std::string & versionTag() const;
@@ -52,6 +54,8 @@ private:
 
   IRDBRecordset_ptr m_stationGeneral;
   IRDBRecordset_ptr m_plateGeneral;
+  IRDBRecordset_ptr m_radiatorGeneral;
+  IRDBRecordset_ptr m_absorberGeneral;
 
 
 };
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDetectorTool.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDetectorTool.cxx
index a64eead9a31c558994b87fb61c9366ad62d977c0..dfa1e24e35c5f224d802369f81fd4c377a15581f 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDetectorTool.cxx
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerDetectorTool.cxx
@@ -66,7 +66,7 @@ PreshowerDetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the Preshower version tag:
   std::string preshowerVersionTag{m_rdbAccessSvc->getChildTag("Preshower", versionKey.tag(), versionKey.node(), "FASERDD")};
-  ATH_MSG_INFO("Preshower Version: " << preshowerVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Preshower Version: " << preshowerVersionTag);
   // Check if version is empty. If so, then the Preshower cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (preshowerVersionTag.empty()) {
@@ -172,7 +172,7 @@ PreshowerDetectorTool::clear()
 StatusCode 
 PreshowerDetectorTool::registerCallback()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
       ATH_MSG_WARNING("Called untested PreshowerDetectorTool::registerCallback()");
     if (m_useDynamicAlignFolders.value()) {
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.cxx
index 6be4e0d11075d22a7f89c8bbb2421c47247ca47f..f635cf293ba2abcc77a39d63f58ada3fff845272 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.cxx
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.cxx
@@ -9,6 +9,8 @@
 #include "ScintReadoutGeometry/ScintCommonItems.h"
 #include "PreshowerStationParameters.h"
 #include "PreshowerPlateParameters.h"
+#include "PreshowerRadiatorParameters.h"
+#include "PreshowerAbsorberParameters.h"
 #include "PreshowerDataBase.h"
 #include "PreshowerGeneralParameters.h"
 #include "PreshowerGeoModel/PreshowerGeoModelAthenaComps.h"
@@ -22,6 +24,8 @@ PreshowerGeometryManager::PreshowerGeometryManager(PreshowerDataBase* rdb)
 
   m_stationParameters = std::make_unique<PreshowerStationParameters>(m_rdb);
   m_plateParameters = std::make_unique<PreshowerPlateParameters>(m_rdb);
+  m_radiatorParameters = std::make_unique<PreshowerRadiatorParameters>(m_rdb);
+  m_absorberParameters = std::make_unique<PreshowerAbsorberParameters>(m_rdb);
   m_generalParameters = std::make_unique<PreshowerGeneralParameters>(m_rdb);
   m_distortedMatManager = std::make_unique<ScintDD::DistortedMaterialManager>();
 }
@@ -73,6 +77,17 @@ PreshowerGeometryManager::plateParameters() const
   return m_plateParameters.get();
 }
 
+const PreshowerRadiatorParameters * 
+PreshowerGeometryManager::radiatorParameters() const
+{    
+  return m_radiatorParameters.get();
+}
+const PreshowerAbsorberParameters * 
+PreshowerGeometryManager::absorberParameters() const
+{    
+  return m_absorberParameters.get();
+}
+
 const PreshowerGeneralParameters * 
 PreshowerGeometryManager::generalParameters() const
 {    
@@ -94,6 +109,8 @@ PreshowerGeometryManager::operator=(const PreshowerGeometryManager& right) {
     m_rdb = right.m_rdb;
     m_stationParameters.reset(new PreshowerStationParameters(m_rdb));
     m_plateParameters.reset(new PreshowerPlateParameters(m_rdb));
+    m_radiatorParameters.reset(new PreshowerRadiatorParameters(m_rdb));
+    m_absorberParameters.reset(new PreshowerAbsorberParameters(m_rdb));
     m_generalParameters.reset(new PreshowerGeneralParameters(m_rdb));
     m_distortedMatManager.reset(new ScintDD::DistortedMaterialManager());
   }
@@ -107,6 +124,8 @@ PreshowerGeometryManager::PreshowerGeometryManager(const PreshowerGeometryManage
   m_rdb = right.m_rdb;
   m_stationParameters.reset(new PreshowerStationParameters(m_rdb));
   m_plateParameters.reset(new PreshowerPlateParameters(m_rdb));
+  m_radiatorParameters.reset(new PreshowerRadiatorParameters(m_rdb));
+  m_absorberParameters.reset(new PreshowerAbsorberParameters(m_rdb));
   m_generalParameters.reset(new PreshowerGeneralParameters(m_rdb));
   m_distortedMatManager.reset(new ScintDD::DistortedMaterialManager());
 }
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.h
index 4f8336cdda68af6ac37c8d09f2c39f718d751b7f..23d24bde7ac19e6db4de05fea7ee341b18149db8 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.h
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerGeometryManager.h
@@ -16,6 +16,8 @@ namespace ScintDD {
 
 class PreshowerStationParameters;
 class PreshowerPlateParameters;
+class PreshowerRadiatorParameters;
+class PreshowerAbsorberParameters;
 class PreshowerDataBase;
 class PreshowerGeneralParameters;
 class PreshowerGeoModelAthenaComps;
@@ -42,6 +44,8 @@ public:
 
   const PreshowerStationParameters*             stationParameters() const;
   const PreshowerPlateParameters*               plateParameters() const;
+  const PreshowerRadiatorParameters*            radiatorParameters() const;
+  const PreshowerAbsorberParameters*            absorberParameters() const;
   const PreshowerGeneralParameters*             generalParameters() const;
   const ScintDD::DistortedMaterialManager* distortedMatManager() const;
 
@@ -57,6 +61,8 @@ private:
  
   std::unique_ptr<PreshowerStationParameters> m_stationParameters;
   std::unique_ptr<PreshowerPlateParameters> m_plateParameters;
+  std::unique_ptr<PreshowerRadiatorParameters> m_radiatorParameters;
+  std::unique_ptr<PreshowerAbsorberParameters> m_absorberParameters;
   std::unique_ptr<PreshowerGeneralParameters> m_generalParameters;
   std::unique_ptr<ScintDD::DistortedMaterialManager> m_distortedMatManager;
 
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b3d95c86f41f05b7897fb7fe95e07cccae43c7f7
--- /dev/null
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "PreshowerRadiatorParameters.h"
+#include "PreshowerGeometryManager.h"
+
+#include "PreshowerDataBase.h"
+
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+#include <cmath>
+
+
+PreshowerRadiatorParameters::PreshowerRadiatorParameters(PreshowerDataBase* rdb)
+{
+  m_rdb = rdb;
+}
+
+//
+// Radiator General
+//
+double 
+PreshowerRadiatorParameters::radiatorWidth() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("WIDTH") * Gaudi::Units::mm; 
+}
+
+double 
+PreshowerRadiatorParameters::radiatorLength() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("LENGTH") * Gaudi::Units::mm; 
+}
+
+double 
+PreshowerRadiatorParameters::radiatorThickness() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("THICKNESS") * Gaudi::Units::mm; 
+}
+
+std::string PreshowerRadiatorParameters::radiatorMaterial() const
+{
+  return m_rdb->radiatorGeneral()->getString("MATERIAL");
+}
+
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..68d9ce08ae76376216a35c66da8dcc5b5cc7076a
--- /dev/null
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerRadiatorParameters.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PreshowerGeoModel_PreshowerRadiatorParameters_H
+#define PreshowerGeoModel_PreshowerRadiatorParameters_H
+
+#include <string>
+
+class PreshowerDataBase;
+
+class PreshowerRadiatorParameters {
+
+public:
+
+  // Constructor 
+  PreshowerRadiatorParameters(PreshowerDataBase* rdb);
+
+  // General
+  double radiatorThickness() const;
+  double radiatorWidth() const;
+  double radiatorLength() const;
+  std::string radiatorMaterial() const;
+
+ private:
+  PreshowerDataBase * m_rdb;
+
+};
+
+
+#endif // PreshowerGeoModel_PreshowerRadiatorParameters_H
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.cxx b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.cxx
index bdd8c5b964fb26c4db91f09764ed1dd98e66721d..a511085e1fda3124716531849a838d773a2cf726 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.cxx
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.cxx
@@ -9,6 +9,8 @@
 #include "PreshowerGeometryManager.h"
 #include "PreshowerStationParameters.h"
 #include "PreshowerGeneralParameters.h"
+#include "PreshowerRadiatorParameters.h"
+#include "PreshowerAbsorberParameters.h"
 #include "PreshowerIdentifier.h"
 #include "PreshowerPlate.h"
 
@@ -55,13 +57,36 @@ PreshowerStation::getParameters()
   const PreshowerGeneralParameters* generalParameters = m_geometryManager->generalParameters();
   m_safety = generalParameters->safety();
 
-  m_width  = m_plate->width() + m_safety;
-  m_length = m_plate->length() + m_safety;
-  // pitch includes thickness of one plate
-  m_thickness = (m_numPlates - 1) * m_platePitch + m_plate->thickness() + m_safety;
-
   // Set numerology
   m_detectorManager->numerology().setNumPlatesPerStation(m_numPlates);
+
+  // Passive radiator information
+  const PreshowerRadiatorParameters* radiatorParameters = m_geometryManager->radiatorParameters();
+  m_radiatorWidth  = radiatorParameters->radiatorWidth();
+  m_radiatorLength = radiatorParameters->radiatorLength();
+  m_radiatorThickness = radiatorParameters->radiatorThickness();
+  m_radiatorMaterial = m_materials->getMaterial(radiatorParameters->radiatorMaterial());
+
+  // Passive absorber information
+  const PreshowerAbsorberParameters* absorberParameters = m_geometryManager->absorberParameters();
+  m_absorberWidth  = absorberParameters->absorberWidth();
+  m_absorberLength = absorberParameters->absorberLength();
+  m_absorberThickness = absorberParameters->absorberThickness();
+  m_absorberMaterial = m_materials->getMaterial(absorberParameters->absorberMaterial());
+
+  // pitch includes thickness of one plate
+  m_width  = std::max(std::max(m_plate->width(), m_radiatorWidth), m_absorberWidth) + m_safety;
+  m_length = std::max(std::max(m_plate->length(), m_radiatorLength), m_absorberLength) + m_safety;
+
+  // Compute air-gaps between slabs; for now assumed equal based on scintillator pitch
+  m_airGap = (m_platePitch - m_plate->thickness() - m_radiatorThickness - m_absorberThickness)/3;
+  if (m_airGap < 0)
+  {
+    m_detectorManager->msg(MSG::FATAL) << "Invalid passive material geometry for preshower; air gap is negative." << endmsg;
+  }
+
+  m_thickness = (m_numPlates - 1) * m_platePitch + m_plate->thickness() + 3 * m_airGap + 2 * m_absorberThickness + m_radiatorThickness + m_safety;
+
 }
 
 const GeoLogVol * 
@@ -71,6 +96,13 @@ PreshowerStation::preBuild()
   // Box envelope containing the station.
   const GeoBox* stationEnvelopeShape = new GeoBox(0.5 * m_width, 0.5 * m_length, 0.5 * m_thickness);
   GeoLogVol* stationLog = new GeoLogVol(getName(), stationEnvelopeShape, m_materials->gasMaterial());
+
+  const GeoBox* radiatorShape = new GeoBox(0.5 * m_radiatorWidth, 0.5 * m_radiatorLength, 0.5 * m_radiatorThickness);
+  m_radiatorLog = new GeoLogVol("PreshowerRadiator", radiatorShape, m_radiatorMaterial);
+
+  const GeoBox* absorberShape = new GeoBox(0.5 * m_absorberWidth, 0.5 * m_absorberLength, 0.5 * m_absorberThickness);
+  m_absorberLog = new GeoLogVol("PreshowerAbsorber", absorberShape, m_absorberMaterial);
+
   return stationLog;
 }
 
@@ -80,21 +112,51 @@ PreshowerStation::build(PreshowerIdentifier id)
 
   GeoFullPhysVol * station = new GeoFullPhysVol(m_logVolume);
 
-  double activeDepth = m_thickness - m_safety;
+  // double activeDepth = m_thickness - m_safety;
   double plateThickness = m_plate->thickness();
   for (int iPlate = 0; iPlate < m_numPlates; iPlate++)
   {
+    station->add(new GeoNameTag("Absorber#"+intToString(iPlate)));
+    double zA = (-m_numPlates/2.0 + iPlate) * m_platePitch;
+    GeoTransform* absorberTransform = new GeoTransform(GeoTrf::Translate3D(0.0,
+                                                                           0.0,
+                                                                           zA));
+    station->add(absorberTransform);
+    GeoVPhysVol* absorberPV = new GeoPhysVol(m_absorberLog);
+    station->add(absorberPV);
+
+    station->add(new GeoNameTag("Radiator#"+intToString(iPlate)));
+    double zR = zA + m_airGap + (m_absorberThickness + m_radiatorThickness)/2;
+    GeoTransform* radiatorTransform = new GeoTransform(GeoTrf::Translate3D(0.0,
+                                                                           0.0,
+                                                                           zR));
+    station->add(radiatorTransform);
+    GeoVPhysVol* radiatorPV = new GeoPhysVol(m_radiatorLog);
+    station->add(radiatorPV);
+
     station->add(new GeoNameTag("Plate#"+intToString(iPlate)));
     station->add(new GeoIdentifierTag(iPlate));
     id.setPlate(iPlate);
+    double zP = zR + m_airGap + (plateThickness + m_radiatorThickness)/2;
     GeoAlignableTransform* transform = new GeoAlignableTransform(GeoTrf::Translate3D(0.0, 
                                                                                      0.0,
-                                                                                     (plateThickness - activeDepth)/2 + iPlate * m_platePitch));
+                                                                                     zP));
     station->add(transform);
     GeoVPhysVol* platePV = m_plate->build(id);
     station->add(platePV);
     m_detectorManager->addAlignableTransform(0, id.getPlateId(), transform, platePV);
-  }  
+  }
+
+  // Now add the final downstream absorber after the last plate
+  station->add(new GeoNameTag("Absorber#"+intToString(m_numPlates)));
+  double zA = m_numPlates/2.0 * m_platePitch;
+  GeoTransform* absorberTransform = new GeoTransform(GeoTrf::Translate3D(0.0,
+                                                                         0.0,
+                                                                         zA));
+  station->add(absorberTransform);
+  GeoVPhysVol* absorberPV = new GeoPhysVol(m_absorberLog);
+  station->add(absorberPV);
+
   return station;
 }
 
diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.h
index fb4d6f588699db07cb0212bb850d59b1062bee21..e1307290b3ef3c89f26a4453a0515f80780d9fea 100644
--- a/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.h
+++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/src/PreshowerStation.h
@@ -10,6 +10,7 @@
 class GeoVPhysVol;
 class GeoFullPhysVol;
 class GeoLogVol;
+class GeoMaterial;
 class PreshowerIdentifier;
 class PreshowerPlate;
 
@@ -30,7 +31,19 @@ public:
   double thickness()   const {return m_thickness;}
   double width()       const {return m_width;}
   double length()      const {return m_length;}
+
+  double radiatorThickness() const {return m_radiatorThickness;}
+  double radiatorWidth() const {return m_radiatorWidth;}
+  double radiatorLength() const {return m_radiatorLength;}
+  const GeoMaterial* radiatorMaterial() const {return m_radiatorMaterial;}
+  
+  double absorberThickness() const {return m_absorberThickness;}
+  double absorberWidth() const {return m_absorberWidth;}
+  double absorberLength() const {return m_absorberLength;}
+  const GeoMaterial* absorberMaterial() const {return m_absorberMaterial;}
  
+  double airGap() const {return m_airGap;}
+
 private:
   void getParameters();
   virtual const GeoLogVol * preBuild();
@@ -44,6 +57,22 @@ private:
   double      m_width;
   double      m_length;
 
+  double      m_radiatorThickness;
+  double      m_radiatorWidth;
+  double      m_radiatorLength;
+
+  const GeoMaterial* m_radiatorMaterial;
+  const GeoLogVol*   m_radiatorLog;
+
+  double      m_absorberThickness;
+  double      m_absorberWidth;
+  double      m_absorberLength;
+
+  const GeoMaterial* m_absorberMaterial;
+  const GeoLogVol*   m_absorberLog;
+
+  double      m_airGap;
+
   double      m_safety;
 };
 
diff --git a/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a4b3f0c98f58f58bf64ef490bf6d6f446bb0256b
--- /dev/null
+++ b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml
@@ -0,0 +1,27 @@
+<IdDictionary name="Scintillator">
+
+  <field name="part" >
+    <label name="Veto" value="1" />
+    <label name="Trigger" value="2" />
+    <label name="Preshower" value="3" />
+  </field>
+
+  <region>
+    <range field="part" value="Veto" />
+    <range field="station" minvalue="0" maxvalue="0" />
+    <range field="plate" minvalue="0" maxvalue="1" />
+    <range field="pmt" minvalue="0" maxvalue="0" />
+  </region>
+  <region>
+    <range field="part" value="Trigger"/>
+    <range field="station" minvalue="0" maxvalue="0" />
+    <range field="plate" minvalue="0" maxvalue="1" />
+    <range field="pmt" minvalue="0" maxvalue="1" />
+  </region>
+  <region>
+    <range field="part" value="Preshower" />
+    <range field="station" minvalue="0" maxvalue="0" />
+    <range field="plate" minvalue="0" maxvalue="1" />
+    <range field="pmt" minvalue="0" maxvalue="0" />
+  </region>
+</IdDictionary>
\ No newline at end of file
diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorElement.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorElement.h
index 08d89603be7167480491a5beab34a1d6e0f783a1..2f1e7c0a95be335fcc8e349159d9f6b4b4efe213 100644
--- a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorElement.h
+++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorElement.h
@@ -38,6 +38,7 @@ class GeoAlignmentStore;
 namespace Trk{
  class Surface;
  class SurfaceBounds;
+ constexpr DetectorElemType Scintillator = DetectorElemType::TRT;
 }
 
 namespace ScintDD {
@@ -142,10 +143,12 @@ namespace ScintDD {
       //@{
     
       /// identifier of this detector element:
-      Identifier identify() const;
+      virtual Identifier identify() const override final;      
+      // Identifier identify() const;
     
       /// identifier hash
-      IdentifierHash identifyHash() const;
+      virtual IdentifierHash identifyHash() const override final;      
+      // IdentifierHash identifyHash() const;
     
       /// Returns the id helper
       const FaserDetectorID* getIdHelper() const;
@@ -188,13 +191,13 @@ namespace ScintDD {
       /// Local (simulation/hit frame) to global transform
       virtual const GeoTrf::Transform3D & transformHit() const;
       /// Local (reconstruction frame) to global transform
-      const Amg::Transform3D & transform() const;
+      virtual const Amg::Transform3D & transform() const override;
       /// Default Local (reconstruction frame) to global transform
       /// ie with no misalignment. 
       const HepGeom::Transform3D defTransformCLHEP() const;
       const Amg::Transform3D defTransform() const;
       /// Center in global coordinates
-      const Amg::Vector3D & center() const;
+      virtual const Amg::Vector3D & center() const override;
     
       const HepGeom::Transform3D & transformCLHEP() const;
     
@@ -233,7 +236,7 @@ namespace ScintDD {
       const Amg::Vector3D & etaAxis() const;
       const HepGeom::Vector3D<double> & etaAxisCLHEP() const;
       /// Get reconstruction local normal axes in global frame. Choosen to give right-handed coordinate frame.
-      const Amg::Vector3D & normal() const;
+      virtual const Amg::Vector3D & normal() const override;
      
       /// transform a hit local position into a global position:
       HepGeom::Point3D<double> globalPositionHit(const HepGeom::Point3D<double> &simulationLocalPos) const;
@@ -255,7 +258,7 @@ namespace ScintDD {
      
       /// Element Surface
       virtual Trk::Surface & surface();
-      virtual const Trk::Surface & surface() const;
+      virtual const Trk::Surface & surface() const override;
     
       //@}
 
@@ -332,7 +335,7 @@ namespace ScintDD {
       double length() const; // Length in y direction 
       double thickness() const; // Thickness in z direction
     
-      virtual const Trk::SurfaceBounds & bounds() const;
+      virtual const Trk::SurfaceBounds & bounds() const override;
     
       // Test that it is in the active region
       // Intersect has 3 states
@@ -393,7 +396,11 @@ namespace ScintDD {
     public:
     
       const ScintCommonItems* getCommonItems() const;
-    
+
+    /** TrkDetElementBase interface detectorType
+     */
+     virtual Trk::DetectorElemType detectorType() const override final;
+
       ///////////////////////////////////////////////////////////////////
       // Private methods:
       ///////////////////////////////////////////////////////////////////
@@ -500,6 +507,13 @@ namespace ScintDD {
     // Inline methods:
     ///////////////////////////////////////////////////////////////////
        
+
+    inline Trk::DetectorElemType ScintDetectorElement::detectorType() const{
+      return Trk::Scintillator;
+    }
+
+
+
     inline HepGeom::Point3D<double> ScintDetectorElement::globalPositionHit(const HepGeom::Point3D<double> &localPos) const
     {
       return Amg::EigenTransformToCLHEP(transformHit())*localPos;
diff --git a/Scintillator/ScintDetDescr/TriggerGeoModel/src/TriggerDetectorTool.cxx b/Scintillator/ScintDetDescr/TriggerGeoModel/src/TriggerDetectorTool.cxx
index 878e632899d7419a775994050861c1f32bb06327..acbaf4a282f115ee69ca6ef3fdfde81eee9251c6 100644
--- a/Scintillator/ScintDetDescr/TriggerGeoModel/src/TriggerDetectorTool.cxx
+++ b/Scintillator/ScintDetDescr/TriggerGeoModel/src/TriggerDetectorTool.cxx
@@ -66,7 +66,7 @@ TriggerDetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the Trigger version tag:
   std::string triggerVersionTag{m_rdbAccessSvc->getChildTag("Trigger", versionKey.tag(), versionKey.node(), "FASERDD")};
-  ATH_MSG_INFO("Trigger Version: " << triggerVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Trigger Version: " << triggerVersionTag);
   // Check if version is empty. If so, then the Trigger cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (triggerVersionTag.empty()) {
@@ -172,7 +172,7 @@ TriggerDetectorTool::clear()
 StatusCode 
 TriggerDetectorTool::registerCallback()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
       ATH_MSG_WARNING("Called untested TriggerDetectorTool::registerCallback()");
     if (m_useDynamicAlignFolders.value()) {
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.cxx
index 44bb1e086f16685bd9b7ce768d9942a08e9cf334..2ef72a43a9063a8f00c9f74b8eac89f75eb3121c 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.cxx
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.cxx
@@ -77,6 +77,10 @@ VetoDataBase::VetoDataBase(const VetoGeoModelAthenaComps * athenaComps)
   m_plateGeneral = rdbSvc->getRecordsetPtr("VetoPlateGeneral", versionTag, versionNode, "FASERDD");
   msg(MSG::DEBUG) << "Table VetoPlateGeneral Fetched" << endmsg;
 
+  m_radiatorGeneral = rdbSvc->getRecordsetPtr("VetoRadiatorGeneral", versionTag, versionNode, "FASERDD");
+  msg(MSG::DEBUG) << "Table VetoRadiatorGeneral Fetched" << endmsg;
+
+
 }
 
 const VetoGeoModelAthenaComps* VetoDataBase::athenaComps() const { return m_athenaComps; }
@@ -93,6 +97,7 @@ IRDBRecordset_ptr VetoDataBase::topLevelTable() const {return m_topLevel;}
 
 const IRDBRecord* VetoDataBase::stationGeneral() const {return (*m_stationGeneral)[0];}
 const IRDBRecord* VetoDataBase::plateGeneral() const {return (*m_plateGeneral)[0];}
+const IRDBRecord* VetoDataBase::radiatorGeneral() const {return (*m_radiatorGeneral)[0];}
 
 const std::string & VetoDataBase::versionTag() const {
   return m_vetoVersionTag;
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.h b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.h
index cce56bba95689ae521b73a419d8c72a9fb0552f4..74f2365b22dad7eb92ff5cb4513db45ceb29000f 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.h
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDataBase.h
@@ -41,6 +41,7 @@ public:
 //   const IRDBRecord* brlThermalShield() const;
   const IRDBRecord* stationGeneral() const;
   const IRDBRecord* plateGeneral() const;
+  const IRDBRecord* radiatorGeneral() const;
 //   const IRDBRecord* brlFSI() const;
 //   int brlFSISize() const;
 //   const IRDBRecord* brlFSILocation(int i) const;
@@ -119,6 +120,7 @@ private:
 //   IRDBRecordset_ptr m_brlThermalShield;
   IRDBRecordset_ptr m_stationGeneral;
   IRDBRecordset_ptr m_plateGeneral;
+  IRDBRecordset_ptr m_radiatorGeneral;
 //   IRDBRecordset_ptr m_brlFSI;
 //   IRDBRecordset_ptr m_brlFSILocation;
 //   IRDBRecordset_ptr m_fwdSensor;
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorFactory.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorFactory.cxx
index c85ae49d8c24d8c72debd67b90232054f7098749..9d3d9659f6fd590cb053c589e53d8719cce3ebea 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorFactory.cxx
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorFactory.cxx
@@ -20,6 +20,7 @@
 #include "ScintReadoutGeometry/ScintDetectorDesign.h" 
 
 #include "VetoStation.h"
+#include "VetoRadiator.h"
 #include "VetoPlate.h"
 #include "VetoDataBase.h"
 #include "VetoGeoModel/VetoGeoModelAthenaComps.h"
@@ -149,14 +150,11 @@ void VetoDetectorFactory::create(GeoPhysVol *world)
 
     std::string stationA_Label = "StationA";
     std::string stationB_Label = "StationB";
-    // std::string absorberA_Label = "AbsorberA";
-    // std::string absorberB_Label = "AbsorberB";
+    std::string radiator_Label = "Radiator";
 
     bool stationA_Present = vetoGeneral->partPresent(stationA_Label);
     bool stationB_Present = vetoGeneral->partPresent(stationB_Label);
-    // bool absorberA_Present = vetoGeneral->partPresent(absorberA_Label);
-    // bool absorberB_Present = vetoGeneral->partPresent(absorberB_Label);
-
+    bool radiator_Present = vetoGeneral->partPresent(radiator_Label);
   //
   //  Plate is the same for all stations
   //
@@ -214,6 +212,25 @@ void VetoDetectorFactory::create(GeoPhysVol *world)
     m_detectorManager->addAlignableTransform(1, id.getPlateId(), stationB_Transform, stationB_PV);
   }
 
+  // Passive radiator
+  if (radiator_Present)
+  {
+    msg(MSG::DEBUG) << "Building the Veto Radiator." << endmsg;
+
+    // Create the radiator
+    VetoRadiator radiator("VetoRadiator", m_detectorManager, m_geometryManager, m_materials);
+    GeoAlignableTransform* radiator_Transform = new GeoAlignableTransform(vetoTransform * vetoGeneral->partTransform(radiator_Label));
+
+    GeoNameTag* topLevelNameTag = new GeoNameTag("Veto");
+    scint->add(topLevelNameTag);
+    scint->add(new GeoIdentifierTag(0));
+    scint->add(radiator_Transform);
+    scint->add(radiator.getVolume());
+    m_detectorManager->addTreeTop(radiator.getVolume());
+
+  }
+
+
   // Set the neighbours
   m_detectorManager->initNeighbours();
 
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorTool.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorTool.cxx
index d588039a74e5df1973cc11b29be5311be1014af6..71ad2bf461c25eef45db32cae8496c5699bdcd02 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorTool.cxx
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoDetectorTool.cxx
@@ -66,7 +66,7 @@ VetoDetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the Veto version tag:
   std::string vetoVersionTag{m_rdbAccessSvc->getChildTag("Veto", versionKey.tag(), versionKey.node(), "FASERDD")};
-  ATH_MSG_INFO("Veto Version: " << vetoVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("Veto Version: " << vetoVersionTag);
   // Check if version is empty. If so, then the Veto cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (vetoVersionTag.empty()) {
@@ -172,7 +172,7 @@ VetoDetectorTool::clear()
 StatusCode 
 VetoDetectorTool::registerCallback()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
       ATH_MSG_WARNING("Called untested VetoDetectorTool::registerCallback()");
     if (m_useDynamicAlignFolders.value()) {
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.cxx
index 1e5757aff9a4f931b45c0e3cc6e0e3330328a8ff..53190a50a7897d448b2ebdea0f108b83d5917765 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.cxx
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.cxx
@@ -9,6 +9,7 @@
 #include "ScintReadoutGeometry/ScintCommonItems.h"
 #include "VetoStationParameters.h"
 #include "VetoPlateParameters.h"
+#include "VetoRadiatorParameters.h"
 #include "VetoDataBase.h"
 #include "VetoGeneralParameters.h"
 #include "VetoGeoModel/VetoGeoModelAthenaComps.h"
@@ -22,6 +23,7 @@ VetoGeometryManager::VetoGeometryManager(VetoDataBase* rdb)
 
   m_stationParameters = std::make_unique<VetoStationParameters>(m_rdb);
   m_plateParameters = std::make_unique<VetoPlateParameters>(m_rdb);
+  m_radiatorParameters = std::make_unique<VetoRadiatorParameters>(m_rdb);
   m_generalParameters = std::make_unique<VetoGeneralParameters>(m_rdb);
   m_distortedMatManager = std::make_unique<ScintDD::DistortedMaterialManager>();
 }
@@ -73,6 +75,13 @@ VetoGeometryManager::plateParameters() const
   return m_plateParameters.get();
 }
 
+const VetoRadiatorParameters * 
+VetoGeometryManager::radiatorParameters() const
+{    
+  return m_radiatorParameters.get();
+}
+
+
 const VetoGeneralParameters * 
 VetoGeometryManager::generalParameters() const
 {    
@@ -94,6 +103,7 @@ VetoGeometryManager::operator=(const VetoGeometryManager& right) {
     m_rdb = right.m_rdb;
     m_stationParameters.reset(new VetoStationParameters(m_rdb));
     m_plateParameters.reset(new VetoPlateParameters(m_rdb));
+    m_radiatorParameters.reset(new VetoRadiatorParameters(m_rdb));
     m_generalParameters.reset(new VetoGeneralParameters(m_rdb));
     m_distortedMatManager.reset(new ScintDD::DistortedMaterialManager());
   }
@@ -107,6 +117,7 @@ VetoGeometryManager::VetoGeometryManager(const VetoGeometryManager& right) {
   m_rdb = right.m_rdb;
   m_stationParameters.reset(new VetoStationParameters(m_rdb));
   m_plateParameters.reset(new VetoPlateParameters(m_rdb));
+  m_radiatorParameters.reset(new VetoRadiatorParameters(m_rdb));
   m_generalParameters.reset(new VetoGeneralParameters(m_rdb));
   m_distortedMatManager.reset(new ScintDD::DistortedMaterialManager());
 }
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.h b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.h
index 8531453e2791b7767e585d0f0bee5e1fe9b89f10..317cfd1442aace6744701381910420dec9172f13 100644
--- a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.h
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoGeometryManager.h
@@ -16,6 +16,7 @@ namespace ScintDD {
 
 class VetoStationParameters;
 class VetoPlateParameters;
+class VetoRadiatorParameters;
 class VetoDataBase;
 class VetoGeneralParameters;
 class VetoGeoModelAthenaComps;
@@ -42,6 +43,7 @@ public:
 
   const VetoStationParameters*             stationParameters() const;
   const VetoPlateParameters*               plateParameters() const;
+  const VetoRadiatorParameters*            radiatorParameters() const;
   const VetoGeneralParameters*             generalParameters() const;
   const ScintDD::DistortedMaterialManager* distortedMatManager() const;
 
@@ -57,6 +59,7 @@ private:
  
   std::unique_ptr<VetoStationParameters> m_stationParameters;
   std::unique_ptr<VetoPlateParameters> m_plateParameters;
+  std::unique_ptr<VetoRadiatorParameters> m_radiatorParameters;
   std::unique_ptr<VetoGeneralParameters> m_generalParameters;
   std::unique_ptr<ScintDD::DistortedMaterialManager> m_distortedMatManager;
 
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..74fb3adc6c23bfc463f0bf1bad45deeb29aaa3e5
--- /dev/null
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.cxx
@@ -0,0 +1,55 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "VetoRadiator.h"
+
+#include "VetoMaterialManager.h"
+
+#include "VetoGeometryManager.h"
+#include "VetoGeneralParameters.h"
+#include "VetoRadiatorParameters.h"
+
+#include "GeoModelKernel/GeoBox.h"
+#include "GeoModelKernel/GeoLogVol.h"
+#include "GeoModelKernel/GeoPhysVol.h"
+#include "GeoModelKernel/GeoMaterial.h"
+
+VetoRadiator::VetoRadiator(const std::string & name,
+                            ScintDD::VetoDetectorManager* detectorManager,
+                            const VetoGeometryManager* geometryManager,
+                            VetoMaterialManager* materials)
+  : VetoSharedComponentFactory(name, detectorManager, geometryManager, materials)
+{
+  getParameters();
+  m_physVolume = build();
+}
+
+void
+VetoRadiator::getParameters() 
+{
+  const VetoRadiatorParameters * parameters = m_geometryManager->radiatorParameters();
+  const VetoGeneralParameters* generalParameters = m_geometryManager->generalParameters();
+
+  m_material  = m_materials->getMaterial(parameters->radiatorMaterial());
+  m_safety    = generalParameters->safety();
+  m_thickness = parameters->radiatorThickness();
+  m_width     = parameters->radiatorWidth();
+  m_length    = parameters->radiatorLength();
+}
+
+GeoVPhysVol * 
+VetoRadiator::build()
+{
+  // Just a simple box.
+  const GeoBox * simpleRadiatorShape = new GeoBox(0.5*m_width,
+                                                  0.5*m_length,
+                                                  0.5*m_thickness);
+
+  const GeoLogVol * simpleRadiatorLog = 
+    new GeoLogVol(getName(), simpleRadiatorShape, m_material);
+
+  GeoPhysVol * simpleRadiator = new GeoPhysVol(simpleRadiatorLog);
+
+  return simpleRadiator;
+}
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.h b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.h
new file mode 100644
index 0000000000000000000000000000000000000000..20bb6099faa3d2c49d2ae15de81183fd4c95abca
--- /dev/null
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiator.h
@@ -0,0 +1,42 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef VETOGEOMODEL_VETORADIATOR_H
+#define VETOGEOMODEL_VETORADIATOR_H
+
+#include "VetoComponentFactory.h"
+
+class GeoVPhysVol;
+class GeoFullPhysVol;
+class GeoLogVol;
+class GeoMaterial;
+
+class VetoRadiator : public VetoSharedComponentFactory
+{
+
+public:
+  VetoRadiator(const std::string & name,
+               ScintDD::VetoDetectorManager* detectorManager,
+               const VetoGeometryManager* geometryManager,
+               VetoMaterialManager* materials);
+
+public:
+  const GeoMaterial * material() const {return m_material;}
+  double thickness()   const {return m_thickness;}
+  double width()       const {return m_width;}
+  double length()      const {return m_length;}
+ 
+private:
+  virtual GeoVPhysVol * build();
+  void getParameters();
+ 
+  const GeoMaterial * m_material;
+  double      m_thickness;
+  double      m_width;
+  double      m_length;
+
+  double      m_safety;
+};
+
+#endif // VETOGEOMODEL_VETORADIATOR_H
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.cxx b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..85e1f604cdcfa3939781b2261cf73f0423c20e15
--- /dev/null
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "VetoRadiatorParameters.h"
+#include "VetoGeometryManager.h"
+
+#include "VetoDataBase.h"
+
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+#include <cmath>
+
+
+VetoRadiatorParameters::VetoRadiatorParameters(VetoDataBase* rdb)
+{
+  m_rdb = rdb;
+}
+
+//
+// Radiator General
+//
+double 
+VetoRadiatorParameters::radiatorWidth() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("WIDTH") * Gaudi::Units::mm; 
+}
+
+double 
+VetoRadiatorParameters::radiatorLength() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("LENGTH") * Gaudi::Units::mm; 
+}
+
+double 
+VetoRadiatorParameters::radiatorThickness() const
+{
+  return m_rdb->radiatorGeneral()->getDouble("THICKNESS") * Gaudi::Units::mm; 
+}
+
+std::string VetoRadiatorParameters::radiatorMaterial() const
+{
+  return m_rdb->radiatorGeneral()->getString("MATERIAL");
+}
+
diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.h b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..83c8bc61bf3210a668a00000776ce361929c7de0
--- /dev/null
+++ b/Scintillator/ScintDetDescr/VetoGeoModel/src/VetoRadiatorParameters.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef VetoGeoModel_VetoRadiatorParameters_H
+#define VetoGeoModel_VetoRadiatorParameters_H
+
+#include <string>
+
+class VetoDataBase;
+
+class VetoRadiatorParameters {
+
+public:
+
+  // Constructor 
+  VetoRadiatorParameters(VetoDataBase* rdb);
+
+  // Barrel General
+  double radiatorThickness() const;
+  double radiatorWidth() const;
+  double radiatorLength() const;
+  std::string radiatorMaterial() const;
+
+ private:
+  VetoDataBase * m_rdb;
+
+};
+
+
+#endif // VetoGeoModel_VetoRadiatorParameters_H
diff --git a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
index 85a353a09cdab3ecdf23fc8e8ecedad51e345ad9..c68c89cb90516b534f91e376bdc4dafb23325f4d 100644
--- a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
+++ b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
@@ -143,7 +143,7 @@ ScintWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
 
     try {
       wfm->setWaveform( channel, digitizer->channel_adc_counts( channel ) );
-    } catch ( DigitizerDataException& e ) {
+    } catch ( DigitizerData::DigitizerDataException& e ) {
       ATH_MSG_WARNING("ScintWaveformDecoderTool:\n"
 		   <<e.what()
 		   << "\nChannel "
@@ -154,7 +154,7 @@ ScintWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
     try {
       wfm->setHeader( digitizer );
 
-    } catch ( DigitizerDataException& e ) {
+    } catch ( DigitizerData::DigitizerDataException& e ) {
       ATH_MSG_WARNING("ScintWaveformDecoderTool:\n"
 		      << e.what()
 		      << "\nCorrupted Digitizer data!\n"
diff --git a/Simulation/G4Faser/G4FaserAlg/CMakeLists.txt b/Simulation/G4Faser/G4FaserAlg/CMakeLists.txt
index 574f02421cdf6125e80cc0b83497e077db1e321b..76828930fd30794c8677e23fed1699158a80b091 100644
--- a/Simulation/G4Faser/G4FaserAlg/CMakeLists.txt
+++ b/Simulation/G4Faser/G4FaserAlg/CMakeLists.txt
@@ -26,8 +26,18 @@ atlas_add_component( G4FaserAlg
                      INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${HEPMC_INCLUDE_DIRS}
                      LINK_LIBRARIES ${GEANT4_LIBRARIES} ${EIGEN_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} AtlasHepMCLib AthenaBaseComps AthenaKernel GaudiKernel G4AtlasInterfaces G4FaserAlgLib G4AtlasAlgLib SGTools StoreGateLib SGtests EventInfo GeneratorObjects FaserMCTruthBaseLib )
 
-atlas_add_test( G4FaserAlgConfig_Test
-                SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/test/runG4.py
+atlas_add_test( G4FaserAlgConfig_TestFaser
+                SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/test/G4FaserAlgConfigNew_Test.py GeoModel.FaserVersion="'FASER-01'" IOVDb.GlobalTag="'OFLCOND-FASER-01'" Output.HITSFileName='faser.HITS.pool.root'
+                PROPERTIES TIMEOUT 300 
+                PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+
+atlas_add_test( G4FaserAlgConfig_TestFaserNu
+                SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/test/G4FaserAlgConfigNew_Test.py GeoModel.FaserVersion="'FASERNU-02'" IOVDb.GlobalTag="'OFLCOND-FASER-02'" Output.HITSFileName='faserNu.HITS.pool.root'
+                PROPERTIES TIMEOUT 300 
+                PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+
+atlas_add_test( G4FaserAlgConfig_TestTestbeam
+                SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/test/G4FaserAlgConfigNew_Test.py GeoModel.FaserVersion="'FASER-TB00'" IOVDb.GlobalTag="'OFLCOND-FASER-02'" Output.HITSFileName='tb.HITS.pool.root'
                 PROPERTIES TIMEOUT 300 
                 PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 
diff --git a/Simulation/G4Faser/G4FaserAlg/python/G4FaserAlgConfigNew.py b/Simulation/G4Faser/G4FaserAlg/python/G4FaserAlgConfigNew.py
index 7e24163ad90fc101363f39bc33e2c48670b3dd9a..82c35779d0225b979cf8d04c2f3b20bd17f5f930 100644
--- a/Simulation/G4Faser/G4FaserAlg/python/G4FaserAlgConfigNew.py
+++ b/Simulation/G4Faser/G4FaserAlg/python/G4FaserAlgConfigNew.py
@@ -1,230 +1,156 @@
-#
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-#
-from AthenaConfiguration.ComponentFactory import CompFactory
-#
-#  Manager classes for detector geometry and sensitive detectors
-#
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS and FASER collaborations
 from G4FaserServices.G4FaserServicesConfigNew import DetectorGeometrySvcCfg, PhysicsListSvcCfg
+from FaserISF_Services.FaserISF_ServicesConfigNew import FaserTruthServiceCfg, FaserInputConverterCfg
+from FaserISF_Services.FaserISF_ServicesCoreConfigNew import FaserGeoIDSvcCfg
 from G4FaserTools.G4FaserToolsConfigNew import SensitiveDetectorMasterToolCfg
+from G4FaserTools.G4FaserToolsConfigNew import FastSimulationMasterToolCfg
 from G4FaserServices.G4FaserUserActionConfigNew import UserActionSvcCfg
-from G4FaserServices.G4FaserUserActionConfigNew import UserActionMaterialStepRecorderSvcCfg
-# from G4AtlasApps.G4Atlas_MetadataNew import writeSimulationParametersMetadata
-#
-#  Framework utilities
-#
-from FaserISF_Services.FaserISF_ServicesConfigNew import FaserTruthServiceCfg, FaserInputConverterCfg, FaserGeoIDSvcCfg
-#
-# from  G4FaserAlg.G4FaserAlgConf import G4FaserAlg
-G4FaserAlg=CompFactory.G4FaserAlg
-
-def G4FaserAlgCfg(ConfigFlags, name='G4FaserAlg', **kwargs):
-    #
-    #  add Services to G4AtlasAlg
-    #
+# from G4FaserApps.G4Faser_MetadataNew import writeSimulationParametersMetadata
+from AthenaConfiguration.ComponentFactory import CompFactory
+from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+
+
+def G4FaserAlgBasicCfg(ConfigFlags, name="G4FaserAlg", **kwargs):
+    """Return ComponentAccumulator configured for Faser G4 simulation, without output"""
+    # wihout output
     result = DetectorGeometrySvcCfg(ConfigFlags)
-    kwargs.setdefault('DetGeoSvc', result.getService("DetectorGeometrySvc"))
-    #
-    #  MC particle container names
-    #
-    kwargs.setdefault("InputTruthCollection", "GEN_EVENT") 
+    kwargs.setdefault("DetGeoSvc", result.getService("DetectorGeometrySvc"))
+
+    kwargs.setdefault("InputTruthCollection", "BeamTruthEvent") #tocheck -are these string inputs?
     kwargs.setdefault("OutputTruthCollection", "TruthEvent")
-    #
-    #  Option to free memory by dropping GeoModel after construction
-    #
-    # if ConfigFlags.Sim.ReleaseGeoModel:
-    kwargs.setdefault('ReleaseGeoModel', ConfigFlags.Sim.ReleaseGeoModel)
-    #
-    #  Record the particle flux during the simulation
-    #
-    #if ConfigFlags.Sim.RecordFlux:
-    kwargs.setdefault('RecordFlux' , ConfigFlags.Sim.RecordFlux)
-    #
-    #  Treatment of bad events
-    #
-    # if ConfigFlags.Sim.FlagAbortedEvents:
+    ## Killing neutrinos
+
+    ## Don"t drop the GeoModel
+    kwargs.setdefault("ReleaseGeoModel", ConfigFlags.Sim.ReleaseGeoModel)
+
+    ## Record the particle flux during the simulation
+    kwargs.setdefault("RecordFlux", ConfigFlags.Sim.RecordFlux)
+
+    if ConfigFlags.Sim.FlagAbortedEvents:
         ## default false
-    kwargs.setdefault('FlagAbortedEvents' ,ConfigFlags.Sim.FlagAbortedEvents)
-    if ConfigFlags.Sim.FlagAbortedEvents and ConfigFlags.Sim.KillAbortedEvents:
-            print('WARNING When G4AtlasAlg.FlagAbortedEvents is True G4AtlasAlg.KillAbortedEvents should be False!!! Setting G4AtlasAlg.KillAbortedEvents = False now!')
-            kwargs.setdefault('KillAbortedEvents' ,False)
-    # if  ConfigFlags.Sim.KillAbortedEvents:
-        ## default true
-    kwargs.setdefault('KillAbortedEvents' ,ConfigFlags.Sim.KillAbortedEvents)
-    #
-    #  Random numbers
-    #
-    from RngComps.RandomServices import AthEngines, RNG
-    if ConfigFlags.Random.Engine in AthEngines.keys():
-        result.merge(RNG(ConfigFlags.Random.Engine, name="AthRNGSvc"))
-        kwargs.setdefault("AtRndmGenSvc",result.getService("AthRNGSvc"))
+        kwargs.setdefault("FlagAbortedEvents", ConfigFlags.Sim.FlagAbortedEvents)
+        if ConfigFlags.Sim.FlagAbortedEvents and ConfigFlags.Sim.KillAbortedEvents:
+            print("WARNING When G4FaserAlg.FlagAbortedEvents is True G4FaserAlg.KillAbortedEvents should be False. Setting G4FaserAlg.KillAbortedEvents = False now.")
+            kwargs.setdefault("KillAbortedEvents", False)
+
+    ## default true
+    kwargs.setdefault("KillAbortedEvents", ConfigFlags.Sim.KillAbortedEvents)
+
+    from RngComps.RandomServices import RNG
+    result.merge(RNG(ConfigFlags.Random.Engine, name="AthRNGSvc"))
+    kwargs.setdefault("AtRndmGenSvc", result.getService("AthRNGSvc"))
 
     kwargs.setdefault("RandomGenerator", "athena")
-    #
-    #  Multi-threading settings
-    #
-    is_hive = ConfigFlags.Concurrency.NumThreads > 1
-    kwargs.setdefault('MultiThreading', is_hive)
-    #
-    #  What truth information to save?
-    #
+
+    # Multi-threading settinggs
+    #is_hive = (concurrencyProps.ConcurrencyFlags.NumThreads() > 0)
+    is_hive = ConfigFlags.Concurrency.NumThreads > 0
+    kwargs.setdefault("MultiThreading", is_hive)
+
     accMCTruth = FaserTruthServiceCfg(ConfigFlags)
     result.merge(accMCTruth)
-    kwargs.setdefault('TruthRecordService', result.getService("FaserISF_TruthService"))
-    #kwargs.setdefault('TruthRecordService', ConfigFlags.Sim.TruthStrategy) # TODO need to have manual override (simFlags.TruthStrategy.TruthServiceName())
-    #
-    #  Locates detector region for space points (no longer used by G4FaserAlg)
-    #
-    accGeoID = FaserGeoIDSvcCfg(ConfigFlags)
-    result.merge(accGeoID)
-    #kwargs.setdefault('GeoIDSvc', result.getService('ISF_FaserGeoIDSvc'))
-    #
-    #  Converts generator particles to a proprietary type managed by ISF
-    #
+    kwargs.setdefault("TruthRecordService", result.getService("FaserISF_TruthService"))
+    #kwargs.setdefault("TruthRecordService", ConfigFlags.Sim.TruthStrategy) # TODO need to have manual override (simFlags.TruthStrategy.TruthServiceName())
+
+    # accGeoID = FaserGeoIDSvcCfg(ConfigFlags)
+    # result.merge(accGeoID)
+    # kwargs.setdefault("GeoIDSvc", result.getService("ISF_FaserGeoIDSvc"))
+
+    #input converter
     accInputConverter = FaserInputConverterCfg(ConfigFlags)
     result.merge(accInputConverter)
-    kwargs.setdefault('InputConverter', result.getService("ISF_FaserInputConverter"))
-    #
-    # Sensitive detector master tool
-    #
-    accSensitiveDetector = SensitiveDetectorMasterToolCfg(ConfigFlags)
-    result.merge(accSensitiveDetector)
-    kwargs.setdefault('SenDetMasterTool', result.getPublicTool("SensitiveDetectorMasterTool")) #NOTE - is still a public tool
-    #
+    kwargs.setdefault("InputConverter", result.getService("ISF_FaserInputConverter"))
+
+    #sensitive detector master tool
+    SensitiveDetector = result.popToolsAndMerge(SensitiveDetectorMasterToolCfg(ConfigFlags))
+    result.addPublicTool(SensitiveDetector)
+    kwargs.setdefault("SenDetMasterTool", result.getPublicTool(SensitiveDetector.name))
+
+    #fast simulation master tool
+    FastSimulation = result.popToolsAndMerge(FastSimulationMasterToolCfg(ConfigFlags))
+    result.addPublicTool(FastSimulation)
+    kwargs.setdefault("FastSimMasterTool", result.getPublicTool(FastSimulation.name))
+
     #Write MetaData container
-    #
-    #result.merge(writeSimulationParametersMetadata(ConfigFlags))
-    #
+    # result.merge(writeSimulationParametersMetadata(ConfigFlags))
+
     #User action services (Slow...)
-    #
     result.merge( UserActionSvcCfg(ConfigFlags) )
-    kwargs.setdefault('UserActionSvc', result.getService( "G4UA::UserActionSvc") )
+    kwargs.setdefault("UserActionSvc", result.getService( "G4UA::UserActionSvc") )
 
     #PhysicsListSvc
     result.merge( PhysicsListSvcCfg(ConfigFlags) )
-    kwargs.setdefault('PhysicsListSvc', result.getService( "PhysicsListSvc") )
+    kwargs.setdefault("PhysicsListSvc", result.getService( "PhysicsListSvc") )
 
-    #
-    #  Output level
-    #
     ## G4AtlasAlg verbosities (available domains = Navigator, Propagator, Tracking, Stepping, Stacking, Event)
     ## Set stepper verbose = 1 if the Athena logging level is <= DEBUG
     # TODO: Why does it complain that G4AtlasAlgConf.G4AtlasAlg has no "Verbosities" object? Fix.
-    verbosities=dict(Placeholder = '0')
-    if "OutputLevel" in kwargs and kwargs["OutputLevel"] <= 2 :
-       verbosities["Tracking"]='1'
-       print (verbosities)
-    kwargs.setdefault('Verbosities', verbosities)
-    #
-    # Set commands for the G4FaserAlg
-    #
+    # FIXME GaudiConfig2 seems to fail to distinguish an empty dict {} from None
+    verbosities=dict(foo="bar")
+    #from AthenaCommon.AppMgr import ServiceMgr
+    #if ServiceMgr.MessageSvc.OutputLevel <= 2:
+    #    verbosities["Tracking"]="1"
+    #    print verbosities
+    kwargs.setdefault("Verbosities", verbosities)
+
+    # Set commands for the G4AtlasAlg
     kwargs.setdefault("G4Commands", ConfigFlags.Sim.G4Commands)
 
-    result.addEventAlgo(G4FaserAlg(name, **kwargs))
+    result.addEventAlgo(CompFactory.G4FaserAlg(name, **kwargs))
+
     return result
 
-def G4FaserMaterialStepRecorderAlgCfg(ConfigFlags, name='G4FaserAlg', **kwargs):
-    #
-    #  add Services to G4AtlasAlg
-    #
-    result = DetectorGeometrySvcCfg(ConfigFlags)
-    kwargs.setdefault('DetGeoSvc', result.getService("DetectorGeometrySvc"))
-    #
-    #  MC particle container names
-    #
-    kwargs.setdefault("InputTruthCollection", "GEN_EVENT") 
-    kwargs.setdefault("OutputTruthCollection", "TruthEvent")
-    #
-    #  Option to free memory by dropping GeoModel after construction
-    #
-    # if ConfigFlags.Sim.ReleaseGeoModel:
-    kwargs.setdefault('ReleaseGeoModel', ConfigFlags.Sim.ReleaseGeoModel)
-    #
-    #  Record the particle flux during the simulation
-    #
-    #if ConfigFlags.Sim.RecordFlux:
-    kwargs.setdefault('RecordFlux' , ConfigFlags.Sim.RecordFlux)
-    #
-    #  Treatment of bad events
-    #
-    # if ConfigFlags.Sim.FlagAbortedEvents:
-        ## default false
-    kwargs.setdefault('FlagAbortedEvents' ,ConfigFlags.Sim.FlagAbortedEvents)
-    if ConfigFlags.Sim.FlagAbortedEvents and ConfigFlags.Sim.KillAbortedEvents:
-            print('WARNING When G4AtlasAlg.FlagAbortedEvents is True G4AtlasAlg.KillAbortedEvents should be False!!! Setting G4AtlasAlg.KillAbortedEvents = False now!')
-            kwargs.setdefault('KillAbortedEvents' ,False)
-    # if  ConfigFlags.Sim.KillAbortedEvents:
-        ## default true
-    kwargs.setdefault('KillAbortedEvents' ,ConfigFlags.Sim.KillAbortedEvents)
-    #
-    #  Random numbers
-    #
-    from RngComps.RandomServices import AthEngines, RNG
-    if ConfigFlags.Random.Engine in AthEngines.keys():
-        result.merge(RNG(ConfigFlags.Random.Engine, name="AthRNGSvc"))
-        kwargs.setdefault("AtRndmGenSvc",result.getService("AthRNGSvc"))
 
-    kwargs.setdefault("RandomGenerator", "athena")
-    #
-    #  Multi-threading settings
-    #
-    is_hive = ConfigFlags.Concurrency.NumThreads > 1
-    kwargs.setdefault('MultiThreading', is_hive)
-    #
-    #  What truth information to save?
-    #
-    accMCTruth = FaserTruthServiceCfg(ConfigFlags)
-    result.merge(accMCTruth)
-    kwargs.setdefault('TruthRecordService', result.getService("FaserISF_TruthService"))
-    #kwargs.setdefault('TruthRecordService', ConfigFlags.Sim.TruthStrategy) # TODO need to have manual override (simFlags.TruthStrategy.TruthServiceName())
-    #
-    #  Locates detector region for space points (no longer used by G4FaserAlg)
-    #
-    accGeoID = FaserGeoIDSvcCfg(ConfigFlags)
-    result.merge(accGeoID)
-    #kwargs.setdefault('GeoIDSvc', result.getService('ISF_FaserGeoIDSvc'))
-    #
-    #  Converts generator particles to a proprietary type managed by ISF
-    #
-    accInputConverter = FaserInputConverterCfg(ConfigFlags)
-    result.merge(accInputConverter)
-    kwargs.setdefault('InputConverter', result.getService("ISF_FaserInputConverter"))
-    #
-    # Sensitive detector master tool
-    #
-    accSensitiveDetector = SensitiveDetectorMasterToolCfg(ConfigFlags)
-    result.merge(accSensitiveDetector)
-    kwargs.setdefault('SenDetMasterTool', result.getPublicTool("SensitiveDetectorMasterTool")) #NOTE - is still a public tool
-    #
-    #Write MetaData container
-    #
-    #result.merge(writeSimulationParametersMetadata(ConfigFlags))
-    #
-    #User action services (Slow...)
-    #
-    result.merge(UserActionMaterialStepRecorderSvcCfg(ConfigFlags) )
-    kwargs.setdefault('UserActionSvc', result.getService( "G4UA::UserActionSvc") )
+def G4FaserAlgOutputCfg(ConfigFlags):
+    """
+    Return ComponentAccumulator with output for G4 simulation. Not standalone.
 
-    #PhysicsListSvc
-    result.merge( PhysicsListSvcCfg(ConfigFlags) )
-    kwargs.setdefault('PhysicsListSvc', result.getService( "PhysicsListSvc") )
+    follows G4Atlas.flat.configuration.py
+    """
+    ItemList = ["EventInfo#*",
+                "McEventCollection#TruthEvent"]
 
-    #
-    #  Output level
-    #
-    ## G4AtlasAlg verbosities (available domains = Navigator, Propagator, Tracking, Stepping, Stacking, Event)
-    ## Set stepper verbose = 1 if the Athena logging level is <= DEBUG
-    # TODO: Why does it complain that G4AtlasAlgConf.G4AtlasAlg has no "Verbosities" object? Fix.
-    verbosities=dict(Placeholder = '0')
-    if "OutputLevel" in kwargs and kwargs["OutputLevel"] <= 2 :
-       verbosities["Tracking"]='1'
-       print (verbosities)
-    kwargs.setdefault('Verbosities', verbosities)
-    #
-    # Set commands for the G4FaserAlg
-    #
-    kwargs.setdefault("G4Commands", ConfigFlags.Sim.G4Commands)
+    if ConfigFlags.Sim.IncludeParentsInG4Event:
+        ItemList += ["McEventCollection#BeamTruthEvent"]
+
+    if ConfigFlags.Detector.EnableEmulsion:
+        ItemList += ["NeutrinoHitCollection#*"]
+
+    if ConfigFlags.Detector.EnableFaserSCT:
+        ItemList += ["FaserSiHitCollection#*"]
+
+    if ConfigFlags.Detector.EnableEcal:
+        ItemList += ["CaloHitCollection#*"]
+
+    if ConfigFlags.Detector.EnableVeto:
+        ItemList += ["ScintHitCollection#VetoHits"]
+
+    if ConfigFlags.Detector.EnableTrigger:
+        ItemList += ["ScintHitCollection#TriggerHits"]
+
+    if ConfigFlags.Detector.EnablePreshower:
+        ItemList += ["ScintHitCollection#PreshowerHits"]
+
+    # TimingAlg
+    # ItemList += ["RecoTimingObj#EVNTtoHITS_timings"]
+
+    acc = OutputStreamCfg(ConfigFlags,"HITS", ItemList=ItemList, disableEventTag=True)
+
+    # Make stream aware of aborted events
+    OutputStreamHITS = acc.getEventAlgo("OutputStreamHITS")
+    OutputStreamHITS.AcceptAlgs += ["G4FaserAlg"]
+
+    # G4Atlas.flat.configuration.py#0333 onwards
+    # FIXME unifyset now fails
+    #PoolAttributes = ["TREE_BRANCH_OFFSETTAB_LEN = '100'"]
+    #PoolAttributes += ["DatabaseName = '" + ConfigFlags.Output.HITSFileName + "'; ContainerName = 'TTree=CollectionTree'; TREE_AUTO_FLUSH = '1'"]
+    #acc.addService(CompFactory.AthenaPoolCnvSvc(PoolAttributes=PoolAttributes))
+
+    return acc
 
-    result.addEventAlgo(G4FaserAlg(name, **kwargs))
-    return result
 
+def G4FaserAlgCfg(ConfigFlags, name="G4FaserAlg", **kwargs):
+    """Return ComponentAccumulator configured for Faser G4 simulation, with output"""
+    acc = G4FaserAlgBasicCfg(ConfigFlags, **kwargs)
+    acc.merge(G4FaserAlgOutputCfg(ConfigFlags))
+    return acc
diff --git a/Simulation/G4Faser/G4FaserAlg/src/G4FaserAlg.cxx b/Simulation/G4Faser/G4FaserAlg/src/G4FaserAlg.cxx
index 50cbcec1aff8dca123e64e2a4c4effb9dde42061..3ce528b032fd0ce76494e114623aa753dbc0345c 100644
--- a/Simulation/G4Faser/G4FaserAlg/src/G4FaserAlg.cxx
+++ b/Simulation/G4Faser/G4FaserAlg/src/G4FaserAlg.cxx
@@ -123,7 +123,7 @@ void G4FaserAlg::initializeOnce()
     std::unique_ptr<G4AtlasUserWorkerThreadInitialization> workerInit =
       std::make_unique<G4AtlasUserWorkerThreadInitialization>();
     workerInit->SetDetGeoSvc( m_detGeoSvc.typeAndName() );
-    workerInit->SetSDMasterTool( m_senDetTool.typeAndName() );
+    // workerInit->SetSDMasterTool( m_senDetTool.typeAndName() );
     workerInit->SetFastSimMasterTool( m_fastSimTool.typeAndName() );
     runMgr->SetUserInitialization( workerInit.release() );
     std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
@@ -140,7 +140,6 @@ void G4FaserAlg::initializeOnce()
     runMgr->SetRecordFlux( m_recordFlux, std::make_unique<G4FaserFluxRecorder>() );
     runMgr->SetLogLevel( int(msg().level()) ); // Synch log levels
     runMgr->SetDetGeoSvc( m_detGeoSvc.typeAndName() );
-    runMgr->SetSDMasterTool(m_senDetTool.typeAndName() );
     runMgr->SetFastSimMasterTool(m_fastSimTool.typeAndName() );
     runMgr->SetPhysListSvc(m_physListSvc.typeAndName() );
     std::unique_ptr<G4AtlasActionInitialization> actionInitialization =
@@ -190,7 +189,7 @@ void G4FaserAlg::initializeOnce()
     rm->RunInitialization();
   }
 
-  ATH_MSG_INFO( "retireving the Detector Geometry Service" );
+  ATH_MSG_INFO( "retrieving the Detector Geometry Service" );
   if(m_detGeoSvc.retrieve().isFailure()) {
     throw std::runtime_error("Could not initialize ATLAS DetectorGeometrySvc!");
   }
diff --git a/Simulation/G4Faser/G4FaserAlg/test/G4FaserAlgConfigNew_Test.py b/Simulation/G4Faser/G4FaserAlg/test/G4FaserAlgConfigNew_Test.py
new file mode 100644
index 0000000000000000000000000000000000000000..709797ae28bec863f565eba2aa662d8bcefc0e2e
--- /dev/null
+++ b/Simulation/G4Faser/G4FaserAlg/test/G4FaserAlgConfigNew_Test.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+"""Run tests on G4FaserAlgConfigNew
+
+Copyright (C) 2002-2021 CERN for the benefit of the ATLAS and FASER collaborations
+"""
+
+if __name__ == '__main__':
+
+    import time
+    a = time.time()
+#
+# Set up logging and config behaviour
+#
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import DEBUG
+    from AthenaCommon.Configurable import Configurable
+    log.setLevel(DEBUG)
+    Configurable.configurableRun3Behavior = 1
+#
+# Import and set config flags
+#
+    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+    ConfigFlags.Exec.MaxEvents = 4  # can be overridden from command line with --maxEvt=<number>
+    ConfigFlags.Exec.SkipEvents = 0 # can be overridden from command line with --skipEvt=<number>
+    from AthenaConfiguration.Enums import ProductionStep
+    ConfigFlags.Common.ProductionStep = ProductionStep.Simulation
+#
+# All these must be specified to avoid auto-configuration
+#
+    ConfigFlags.Input.RunNumber = [12345] #Isn't updating - todo: investigate
+    ConfigFlags.Input.OverrideRunNumber = True
+    ConfigFlags.Input.LumiBlockNumber = [1]
+    ConfigFlags.Input.isMC = True
+#
+# Output file name
+# 
+    ConfigFlags.Output.HITSFileName = "my.HITS.pool.root" # can be overridden from command line with Output.HITSFileName=<name>
+#
+# Sim ConfigFlags
+#
+    ConfigFlags.Sim.Layout = "FASER"
+    ConfigFlags.Sim.PhysicsList = "FTFP_BERT"
+    ConfigFlags.Sim.ReleaseGeoModel = False
+    ConfigFlags.Sim.IncludeParentsInG4Event = True # Controls whether BeamTruthEvent is written to output HITS file
+    ConfigFlags.addFlag("Sim.Gun",{"Generator" : "SingleParticle"})  # Property bag for particle gun keyword:argument pairs
+
+    ConfigFlags.GeoModel.FaserVersion = "FASERNU-02"             # Geometry set-up
+    ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Conditions set-up
+    ConfigFlags.addFlag("Input.InitialTimeStamp", 0)             # To avoid autoconfig 
+    ConfigFlags.GeoModel.Align.Dynamic = False
+#
+# Override flags above from command line
+#
+    import sys
+    ConfigFlags.fillFromArgs(sys.argv[1:])
+#
+# By being a little clever, we can steer the geometry setup from the command line using GeoModel.FaserVersion
+#
+# Start with minimal configuration for Testbeam
+#
+    detectors = ['Veto', 'Preshower', 'FaserSCT', 'Ecal']
+    if ConfigFlags.GeoModel.FaserVersion.count("TB") == 0 :
+        detectors += ['Trigger', 'Dipole']
+    if ConfigFlags.GeoModel.FaserVersion.count("FASERNU") > 0 :
+        detectors += ['Emulsion']
+#
+# Setup detector flags
+#
+    from CalypsoConfiguration.DetectorConfigFlags import setupDetectorsFromList
+    setupDetectorsFromList(ConfigFlags, detectors, toggle_geometry=True)
+#
+# Finalize flags
+#
+    ConfigFlags.lock()
+#
+# Initialize a new component accumulator
+#
+    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
+    cfg = MainServicesCfg(ConfigFlags)
+#
+# Check whether a real input file was specified
+#
+    if ConfigFlags.Input.Files and ConfigFlags.Input.Files != ["_CALYPSO_GENERIC_INPUTFILE_NAME_"] :
+        print("Input.Files = ",ConfigFlags.Input.Files)
+#
+# If so, set up to read it
+#
+        from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+        cfg.merge(PoolReadCfg(ConfigFlags))
+#
+# If not, configure the particle gun as requested, or using defaults
+#
+    else :
+#
+# Particle gun generators - the generator, energy, angle, particle type, position, etc can be modified by passing keyword arguments
+#
+        from FaserParticleGun.FaserParticleGunConfig import FaserParticleGunCfg
+        cfg.merge(FaserParticleGunCfg(ConfigFlags))
+        from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
+        cfg.merge(McEventSelectorCfg(ConfigFlags))
+#
+# Output file
+#
+    from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg
+    cfg.merge(PoolWriteCfg(ConfigFlags))
+#
+# Add the G4FaserAlg
+#
+    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
+    cfg.merge(G4FaserAlgCfg(ConfigFlags))
+#
+# Dump config
+#
+    from AthenaConfiguration.ComponentFactory import CompFactory
+    cfg.addEventAlgo(CompFactory.JobOptsDumperAlg(FileName="G4FaserTestConfig.txt"))
+    cfg.getService("StoreGateSvc").Dump = True
+    cfg.getService("ConditionStore").Dump = True
+    cfg.printConfig(withDetails=True, summariseProps = False)  # gags on ParticleGun if summariseProps = True?
+
+    ConfigFlags.dump()
+    f = open("test.pkl","wb")
+    cfg.store(f)
+    f.close()
+#
+# Execute and finish
+#
+    sc = cfg.run()
+
+    b = time.time()
+    log.info("Run G4FaserAlg in " + str(b-a) + " seconds")
+#
+# Success should be 0
+#
+    sys.exit(not sc.isSuccess())
+
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runEcal.py b/Simulation/G4Faser/G4FaserAlg/test/runEcal.py
deleted file mode 100755
index eaef5c20150c9ffc1b0e2a59d6b8004a7dbf0310..0000000000000000000000000000000000000000
--- a/Simulation/G4Faser/G4FaserAlg/test/runEcal.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-if __name__ == "__main__":
-    import os
-    import sys
-    import GaudiPython
-    import ParticleGun as PG
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaCommon.AppMgr import *
-    from AthenaCommon.Logging import log, logging
-    from AthenaCommon.SystemOfUnits import TeV
-    from AthenaCommon.PhysicalConstants import pi
-    from AthenaCommon.Constants import VERBOSE, INFO
-    from AthenaCommon.Configurable import Configurable
-    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
-    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
-    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
-#
-# 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)
-#
-    ConfigFlags.Input.Files = [""]
-    ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
-    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.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
-#
-# Output settings
-#
-    ConfigFlags.Output.HITSFileName = "ecalNone.1k.HITS.pool.root"
-    ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
-#
-# Geometry-related settings
-# Do not change!
-#
-    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
-#
-    ConfigFlags.lock()
-#
-# Construct ComponentAccumulator
-#
-    acc = MainServicesCfg(ConfigFlags)
-#
-# Particle Gun generator (comment out to read generator file)
-# Raw energies (without units given) are interpreted as MeV
-#
-    pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
-    pg.randomSeed = 1234567
-    pg.sampler.pid = 11
-    pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/200], phi=[0, 2*pi], mass=0.511)
-    pg.sampler.pos = PG.PosSampler(x=[-5.0, 5.0], y=[-5.0, 5.0], z=2730.0, t=0.0)
-    acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4
-#
-# Only one of these two should be used in a given job
-# (MCEventSelectorCfg for generating events with no input file,
-#  PoolReadCfg when reading generator data from an input file)
-#    
-    acc.merge(McEventSelectorCfg(ConfigFlags))
-    # acc.merge(PoolReadCfg(ConfigFlags))
-#
-#  Output stream configuration
-#
-    acc.merge(OutputStreamCfg(ConfigFlags, 
-                              "HITS", 
-                             ["EventInfo#*",
-                              "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
-                              "ScintHitCollection#*",
-                              "FaserSiHitCollection#*",
-                              "CaloHitCollection#*"
-                            ], disableEventTag=True))
-    acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"]               # optional
-    acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS"  # required
-#
-#  Here is the configuration of the Geant4 pieces
-#    
-    acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserAlgCfg(ConfigFlags))
-    acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
-#
-# Verbosity
-#
-#    ConfigFlags.dump()
-#    logging.getLogger('forcomps').setLevel(VERBOSE)
-#    acc.foreach_component("*").OutputLevel = VERBOSE
-#    acc.foreach_component("*ClassID*").OutputLevel = INFO
-#    acc.getService("StoreGateSvc").Dump=True
-#    acc.getService("ConditionStore").Dump=True
-#    acc.printConfig()
-    f=open('FaserG4AppCfg_EVNT.pkl','wb')
-    acc.store(f)
-    f.close()
-#
-# Execute and finish
-#
-    sys.exit(int(acc.run(maxEvents=1000).isFailure()))
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4.py b/Simulation/G4Faser/G4FaserAlg/test/runG4.py
deleted file mode 100644
index 9538edac50589c38fbfc3a54bb0f512359232861..0000000000000000000000000000000000000000
--- a/Simulation/G4Faser/G4FaserAlg/test/runG4.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-if __name__ == "__main__":
-    import os
-    import sys
-    import GaudiPython
-    import ParticleGun as PG
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaCommon.AppMgr import *
-    from AthenaCommon.Logging import log, logging
-    from AthenaCommon.SystemOfUnits import TeV
-    from AthenaCommon.PhysicalConstants import pi
-    from AthenaCommon.Constants import VERBOSE, INFO
-    from AthenaCommon.Configurable import Configurable
-    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
-    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
-    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
-#
-# 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)
-#
-    ConfigFlags.Input.Files = [""]
-    ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
-    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.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
-#
-# Output settings
-#
-    ConfigFlags.Output.HITSFileName = "my.HITS.pool.root"
-    ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
-#
-# Geometry-related settings
-# Do not change!
-#
-    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
-#
-# Physics list
-#
-    ConfigFlags.Sim.PhysicsList = "FTFP_BERT"
-#
-# All flags should be set before calling lock
-#
-    ConfigFlags.lock()
-#
-# Construct ComponentAccumulator
-#
-    acc = MainServicesCfg(ConfigFlags)
-#
-# Particle Gun generator (comment out to read generator file)
-# Raw energies (without units given) are interpreted as MeV
-#
-    pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
-    pg.randomSeed = 123456
-    pg.sampler.pid = -13
-    pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/20], phi=[0, 2*pi], mass=105.71)
-    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
-#
-# Only one of these two should be used in a given job
-# (MCEventSelectorCfg for generating events with no input file,
-#  PoolReadCfg when reading generator data from an input file)
-#    
-    acc.merge(McEventSelectorCfg(ConfigFlags))
-    # acc.merge(PoolReadCfg(ConfigFlags))
-#
-#  Output stream configuration
-#
-    acc.merge(OutputStreamCfg(ConfigFlags, 
-                              "HITS", 
-                             ["EventInfo#*",
-                              "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
-                              "ScintHitCollection#*",
-                              "FaserSiHitCollection#*",
-                              "CaloHitCollection#*"
-                            ], disableEventTag=True))
-    acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"]               # optional
-    acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS"  # required
-#
-#  Here is the configuration of the Geant4 pieces
-#    
-    acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserAlgCfg(ConfigFlags))
-    acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
-#
-# Verbosity
-#
-#    ConfigFlags.dump()
-#    logging.getLogger('forcomps').setLevel(VERBOSE)
-#    acc.foreach_component("*").OutputLevel = VERBOSE
-#    acc.foreach_component("*ClassID*").OutputLevel = INFO
-#    acc.getService("StoreGateSvc").Dump=True
-#    acc.getService("ConditionStore").Dump=True
-#    acc.printConfig()
-    f=open('FaserG4AppCfg_EVNT.pkl','wb')
-    acc.store(f)
-    f.close()
-#
-# Execute and finish
-#
-    sys.exit(int(acc.run(maxEvents=500).isFailure()))
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py b/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py
deleted file mode 100644
index 56618f6cebcdac90c40570797e1c17953653200e..0000000000000000000000000000000000000000
--- a/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env python
-if __name__ == "__main__":
-    import os
-    import sys
-    import GaudiPython
-    import ParticleGun as PG
-    from FaserCosmicGenerator import CosmicSampler
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaCommon.AppMgr import *
-    from AthenaCommon.Logging import log, logging
-    from AthenaCommon.SystemOfUnits import TeV
-    from AthenaCommon.PhysicalConstants import pi
-    from AthenaCommon.Constants import VERBOSE, INFO
-    from AthenaCommon.Configurable import Configurable
-    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
-    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
-    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
-#
-# 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)
-#
-    ConfigFlags.Input.Files = [""]
-    ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
-    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.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
-#
-# Output settings
-#
-    ConfigFlags.Output.HITSFileName = "cosmics.HITS.pool.root"
-    ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
-#
-# Geometry-related settings
-# Do not change!
-#
-    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
-
-#
-# Physics list
-#
-
-    ConfigFlags.Sim.PhysicsList = "FTFP_BERT"
-#
-# All flags should be set before calling lock
-#
-    ConfigFlags.lock()
-#
-# Construct ComponentAccumulator
-#
-    acc = MainServicesCfg(ConfigFlags)
-#
-# Particle Gun generator (comment out to read generator file)
-# Raw energies (without units given) are interpreted as MeV
-#
-    pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
-    pg.randomSeed = 123456
-
-    pg.sampler = CosmicSampler()
-    # For just box around Ecal:
-    # pg.sampler = CosmicSampler(z0Mm = 3099.2, targetDzMm = 705, targetDxMm = 200, targetDyMm = 200)
-    acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4
-#
-# Only one of these two should be used in a given job
-# (MCEventSelectorCfg for generating events with no input file,
-#  PoolReadCfg when reading generator data from an input file)
-#    
-    acc.merge(McEventSelectorCfg(ConfigFlags))
-    # acc.merge(PoolReadCfg(ConfigFlags))
-#
-#  Output stream configuration
-#
-    acc.merge(OutputStreamCfg(ConfigFlags, 
-                              "HITS", 
-                             ["EventInfo#*",
-                              "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
-                              "ScintHitCollection#*",
-                              "FaserSiHitCollection#*",
-                               "CaloHitCollection#*"
-                            ], disableEventTag=True))
-    acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"]               # optional
-    acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS"  # required
-#
-#  Here is the configuration of the Geant4 pieces
-#    
-    acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserAlgCfg(ConfigFlags))
-    acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
-#
-# Verbosity
-#
-#    ConfigFlags.dump()
-#    logging.getLogger('forcomps').setLevel(VERBOSE)
-#    acc.foreach_component("*").OutputLevel = VERBOSE
-#    acc.foreach_component("*ClassID*").OutputLevel = INFO
-#    acc.getService("StoreGateSvc").Dump=True
-#    acc.getService("ConditionStore").Dump=True
-#    acc.printConfig()
-    f=open('FaserG4AppCfg_EVNT.pkl','wb')
-    acc.store(f)
-    f.close()
-#
-# Execute and finish
-#
-    sys.exit(int(acc.run(maxEvents=50000).isFailure()))
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py b/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py
deleted file mode 100644
index 8110c6eeaaec03ef1ea21569f1d1bcd94b8fa0d9..0000000000000000000000000000000000000000
--- a/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-if __name__ == "__main__":
-    import os
-    import sys
-    import GaudiPython
-    import ParticleGun as PG
-    from DIFGenerator import DIFSampler
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaCommon.AppMgr import *
-    from AthenaCommon.Logging import log, logging
-    from AthenaCommon.SystemOfUnits import TeV
-    from AthenaCommon.PhysicalConstants import pi
-    from AthenaCommon.Constants import VERBOSE, INFO
-    from AthenaCommon.Configurable import Configurable
-    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
-    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
-    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
-#
-# 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)
-#
-    ConfigFlags.Input.Files = [""]
-    ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
-    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.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
-#
-# Output settings
-#
-    ConfigFlags.Output.HITSFileName = "DecayInFlight.HITS.pool.root"
-    ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
-#
-# Geometry-related settings
-# Do not change!
-#
-    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
-
-#
-# Physics list
-#
-
-    ConfigFlags.Sim.PhysicsList = "FTFP_BERT"
-#
-# All flags should be set before calling lock
-#
-    ConfigFlags.lock()
-#
-# Construct ComponentAccumulator
-#
-    acc = MainServicesCfg(ConfigFlags)
-#
-# Particle Gun generator (comment out to read generator file)
-# Raw energies (without units given) are interpreted as MeV
-#
-    pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
-    pg.randomSeed = 123456
-    pg.sampler = DIFSampler()
-# Next line sets the range of mother particle energies to [0.1 TeV, 0.2 TeV] (default is 1 TeV)
-#   pg.sampler.mother_sampler.mom.energy = [0.1*TeV, 0.2*TeV]
-# Next line sets the range of cylindrical radii to [90 mm, 100 mm] (default is [0, 100 mm])
-#   pg.sampler.mother_sampler.pos.rsq = [90**2, 100**2]
-# Next line changes the range of z vertex positions to [-1000 mm, -500 mm] (default is [-1500 mm, 0])
-#   pg.sampler.mother_sampler.pos.z = [-1000, -500]
-    acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4
-#
-# Only one of these two should be used in a given job
-# (MCEventSelectorCfg for generating events with no input file,
-#  PoolReadCfg when reading generator data from an input file)
-#    
-    acc.merge(McEventSelectorCfg(ConfigFlags))
-    # acc.merge(PoolReadCfg(ConfigFlags))
-#
-#  Output stream configuration
-#
-    acc.merge(OutputStreamCfg(ConfigFlags, 
-                              "HITS", 
-                             ["EventInfo#*",
-                              "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
-                              "ScintHitCollection#*",
-                              "FaserSiHitCollection#*",
-                              "CaloHitCollection#*"
-                            ], disableEventTag=True))
-    acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"]               # optional
-    acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS"  # required
-#
-#  Here is the configuration of the Geant4 pieces
-#    
-    acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserAlgCfg(ConfigFlags))
-    acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
-#
-# Verbosity
-#
-#    ConfigFlags.dump()
-#    logging.getLogger('forcomps').setLevel(VERBOSE)
-#    acc.foreach_component("*").OutputLevel = VERBOSE
-#    acc.foreach_component("*ClassID*").OutputLevel = INFO
-#    acc.getService("StoreGateSvc").Dump=True
-#    acc.getService("ConditionStore").Dump=True
-#    acc.printConfig()
-    f=open('FaserG4AppCfg_EVNT.pkl','wb')
-    acc.store(f)
-    f.close()
-#
-# Execute and finish
-#
-    sys.exit(int(acc.run(maxEvents=500).isFailure()))
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py b/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py
deleted file mode 100644
index 486b628c43b2e6dc5f37dbfefe39cd8a239b46f2..0000000000000000000000000000000000000000
--- a/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-if __name__ == "__main__":
-    import os
-    import sys
-    import GaudiPython
-    import ParticleGun as PG
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaCommon.AppMgr import *
-    from AthenaCommon.Logging import log, logging
-    from AthenaCommon.SystemOfUnits import TeV
-    from AthenaCommon.PhysicalConstants import pi
-    from AthenaCommon.Constants import VERBOSE, INFO
-    from AthenaCommon.Configurable import Configurable
-    from CalypsoConfiguration.AllConfigFlags import ConfigFlags
-    from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
-    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from McEventSelector.McEventSelectorConfig import McEventSelectorCfg
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-    from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
-    from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg
-    from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg
-#
-# 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)
-#
-    ConfigFlags.Input.Files = [""]
-    ConfigFlags.Input.isMC = True
-    ConfigFlags.Input.RunNumber = 12345
-    ConfigFlags.Input.Collections = [""]
-    ConfigFlags.Input.ProjectName = "mc19"
-    ConfigFlags.Common.isOnline = False
-    ConfigFlags.Beam.Type = "collisions"
-    ConfigFlags.Beam.Energy = 7*TeV                              # Informational, does not affect simulation
-    ConfigFlags.GeoModel.FaserVersion = "FASERNU-02"             # Always needed
-    ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
-# Workaround for bug/missing flag; unimportant otherwise 
-    ConfigFlags.addFlag("Input.InitialTimeStamp", 0)
-# Workaround to avoid problematic ISF code
-    ConfigFlags.GeoModel.Layout = "Development"
-#
-# Output settings
-#
-    ConfigFlags.Output.HITSFileName = "myFaserNu.HITS.pool.root"
-    ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light
-#
-# Geometry-related settings
-# Do not change!
-#
-    detectors = ['Emulsion', '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
-#
-# Physics list
-#
-    ConfigFlags.Sim.PhysicsList = "FTFP_BERT"
-#
-# All flags should be set before calling lock
-#
-    ConfigFlags.lock()
-#
-# Construct ComponentAccumulator
-#
-    acc = MainServicesCfg(ConfigFlags)
-#
-# Particle Gun generator (comment out to read generator file)
-# Raw energies (without units given) are interpreted as MeV
-#
-    pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
-    pg.randomSeed = 123456
-    pg.sampler.pid = -13
-    pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/20], phi=[0, 2*pi], mass=105.71)
-    pg.sampler.pos = PG.PosSampler(x=[-5, 5], y=[-5, 5], z=-3750.0, t=0.0)
-    acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4
-#
-# Only one of these two should be used in a given job
-# (MCEventSelectorCfg for generating events with no input file,
-#  PoolReadCfg when reading generator data from an input file)
-#    
-    acc.merge(McEventSelectorCfg(ConfigFlags))
-    # acc.merge(PoolReadCfg(ConfigFlags))
-#
-#  Output stream configuration
-#
-    acc.merge(OutputStreamCfg(ConfigFlags, 
-                              "HITS", 
-                             ["EventInfo#*",
-                              "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
-                              "NeutrinoHitCollection#*",
-                              "ScintHitCollection#*",
-                              "FaserSiHitCollection#*",
-                              "CaloHitCollection#*"
-                            ], disableEventTag=True))
-    acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"]               # optional
-    acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS"  # required
-#
-#  Here is the configuration of the Geant4 pieces
-#    
-    acc.merge(FaserGeometryCfg(ConfigFlags))
-    acc.merge(G4FaserAlgCfg(ConfigFlags))
-    acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True))
-#
-# Verbosity
-#
-#    ConfigFlags.dump()
-#    logging.getLogger('forcomps').setLevel(VERBOSE)
-#    acc.foreach_component("*").OutputLevel = VERBOSE
-#    acc.foreach_component("*ClassID*").OutputLevel = INFO
-#    acc.getService("StoreGateSvc").Dump=True
-#    acc.getService("ConditionStore").Dump=True
-#    acc.printConfig()
-    f=open('FaserG4AppCfg_EVNT.pkl','wb')
-    acc.store(f)
-    f.close()
-#
-# Execute and finish
-#
-    sys.exit(int(acc.run(maxEvents=50).isFailure()))
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
index 99c94f3cd0b4a528bf67abf855162dee9b27970f..7e0a93719a520de7bb819fe270f8666a00c42f5c 100644
--- a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
+++ b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py
@@ -76,7 +76,7 @@ if __name__ == "__main__":
 # Raw energies (without units given) are interpreted as MeV
 #
     pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
+    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])
@@ -96,7 +96,7 @@ if __name__ == "__main__":
                               "HITS", 
                              ["EventInfo#*",
                               "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
+                              "McEventCollection#BeamTruthEvent",
 			      "Trk::MaterialStepCollection#*",
                               "ScintHitCollection#*",
                               "FaserSiHitCollection#*"
diff --git a/Simulation/G4Faser/G4FaserAlg/test/runGen.py b/Simulation/G4Faser/G4FaserAlg/test/runGen.py
index 216688162a91f3ed561ef60566ea5d0c58ce6e28..e255b49ce3d866c457b691725bd9c15755a081b5 100755
--- a/Simulation/G4Faser/G4FaserAlg/test/runGen.py
+++ b/Simulation/G4Faser/G4FaserAlg/test/runGen.py
@@ -75,7 +75,7 @@ if __name__ == "__main__":
 # Raw energies (without units given) are interpreted as MeV
 #
     pg = PG.ParticleGun()
-    pg.McEventKey = "GEN_EVENT"
+    pg.McEventKey = "BeamTruthEvent"
     pg.randomSeed = 123456
     pg.sampler.pid = -13
     pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/20], phi=[0, 2*pi], mass=105.71)
@@ -95,7 +95,7 @@ if __name__ == "__main__":
                               "HITS", 
                              ["EventInfo#*",
                               "McEventCollection#TruthEvent",
-                              "McEventCollection#GEN_EVENT",
+                              "McEventCollection#BeamTruthEvent",
                               "ScintHitCollection#*",
                               "FaserSiHitCollection#*"
                             ], disableEventTag=True))
diff --git a/Simulation/G4Faser/G4FaserServices/python/G4FaserFieldServices.py b/Simulation/G4Faser/G4FaserServices/python/G4FaserFieldServices.py
index 9e502c2769e286af0da4e433fd3982a2f99ddfed..cb4f0bcfdb0aedfd41c7493269bc5f540839bc64 100644
--- a/Simulation/G4Faser/G4FaserServices/python/G4FaserFieldServices.py
+++ b/Simulation/G4Faser/G4FaserServices/python/G4FaserFieldServices.py
@@ -39,166 +39,3 @@ def ConstantFieldSvcCfg(ConfigFlags,name="ConstantField", **kwargs):
     return result
 
 
-# def ForwardFieldSvcCfg(ConfigFlags, name="ForwardField", **kwargs):
-#     result = ComponentAccumulator()
-
-#     #setup the field and add the magneticfield service
-#     acc = MagneticFieldSvcCfg(ConfigFlags)
-#     result.merge(acc)
-
-#     #FIXME Once it exists this version should use the new MagField Service defined in ForwardRegionMgField
-#     kwargs.setdefault("MagneticFieldSvc", result.getService("AtlasFieldSvc"))
-#     #kwargs.setdefault("FieldOn", True)
-
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-
-# def Q1FwdG4FieldSvcCfg(ConfigFlags, name='Q1FwdG4FieldSvc', **kwargs):
-#     result = ComponentAccumulator()
-
-#     result.addService( MagField__ForwardRegionFieldSvc("Q1", 
-#                                                         Magnet = 0, # FIXME find a better way to do this.
-#                                                         MQXA_DataFile = "MQXA_NOMINAL.dat"))
-
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q1"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q2FwdG4FieldSvcCfg(ConfigFlags, name='Q2FwdG4FieldSvc', **kwargs):
-#     result = ComponentAccumulator()
-
-#     result.addService( MagField__ForwardRegionFieldSvc("Q2", 
-#                                                         Magnet = 1, # FIXME find a better way to do this.
-#                                                         MQXA_DataFile = "MQXA_NOMINAL.dat"))
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q2"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q3FwdG4FieldSvcCfg(ConfigFlags, name='Q3FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-
-#     result.addService( MagField__ForwardRegionFieldSvc("Q3", 
-#                                                         Magnet = 2, # FIXME find a better way to do this.
-#                                                         MQXA_DataFile = "MQXA_NOMINAL.dat"))
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q3"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def D1FwdG4FieldSvcCfg(ConfigFlags, name='D1FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("D1", 
-#                                                         Magnet = 3))# FIXME find a better way to do this.
-                                                        
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("D1"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def D2FwdG4FieldSvcCfg(ConfigFlags, name='D2FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-
-#     result.addService( MagField__ForwardRegionFieldSvc("D2", 
-#                                                         Magnet = 4))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("D2"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q4FwdG4FieldSvcCfg(ConfigFlags, name='Q4FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q4", 
-#                                                         Magnet = 5))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q4"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q5FwdG4FieldSvcCfg(ConfigFlags, name='Q5FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q5", 
-#                                                         Magnet = 6))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q5"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q6FwdG4FieldSvcCfg(ConfigFlags, name='Q6FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q6", 
-#                                                         Magnet = 7))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q6"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q7FwdG4FieldSvcCfg(ConfigFlags, name='Q7FwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q7", 
-#                                                         Magnet = 8))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q7"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q1HKickFwdG4FieldSvcCfg(ConfigFlags, name='Q1HKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q1HKick", 
-#                                                         Magnet = 9))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q1HKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q1VKickFwdG4FieldSvcCfg(ConfigFlags, name='Q1VKickFwdG4FieldSvc', **kwargs): #note is lower case "v" in ForwardRegionMgFieldConfig.py
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q1VKick", 
-#                                                         Magnet = 10))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q1VKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q2HKickFwdG4FieldSvcCfg(ConfigFlags, name='Q2HKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q2HKick", 
-#                                                         Magnet = 11))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q2HKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q2VKickFwdG4FieldSvcCfg(ConfigFlags, name='Q2VKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q2VKick", 
-#                                                         Magnet = 12))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q2VKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q3HKickFwdG4FieldSvcCfg(ConfigFlags, name='Q3HKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q3HKick", 
-#                                                         Magnet = 13))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q3HKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q3VKickFwdG4FieldSvcCfg(ConfigFlags, name='Q3VKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q3VKick", 
-#                                                         Magnet = 14))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q3VKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q4VKickAFwdG4FieldSvcCfg(ConfigFlags, name='Q4VKickAFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q4VKickA", 
-#                                                         Magnet = 15))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q4VKickA"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q4HKickFwdG4FieldSvcCfg(ConfigFlags, name='Q4HKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q4HKick", 
-#                                                         Magnet = 16))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q4HKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q4VKickBFwdG4FieldSvcCfg(ConfigFlags, name='Q4VKickBFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q4VKickB", 
-#                                                         Magnet = 17))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q4VKickB"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q5HKickFwdG4FieldSvcCfg(ConfigFlags, name='Q5HKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q5HKick", 
-#                                                         Magnet = 18))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q5HKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
-# def Q6VKickFwdG4FieldSvcCfg(ConfigFlags, name='Q6VKickFwdG4FieldSvc', **kwargs): 
-#     result = ComponentAccumulator()
-#     result.addService( MagField__ForwardRegionFieldSvc("Q6VKick", 
-#                                                         Magnet = 19))# FIXME find a better way to do this.
-#     kwargs.setdefault("MagneticFieldSvc",           result.getService("Q6VKick"))
-#     result.addService(StandardFieldSvc(name, **kwargs))
-#     return result
diff --git a/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py b/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py
index 21357a02dc4298dc734f0dcbbc70d38f8b52b45b..839a4fda883d0f8e39f04f4efdc7a632918a6176 100644
--- a/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py
+++ b/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py
@@ -1,116 +1,21 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 from __future__ import print_function
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
 DetectorGeometrySvc, G4AtlasSvc, G4GeometryNotifierSvc, PhysicsListSvc=CompFactory.getComps("DetectorGeometrySvc","G4AtlasSvc","G4GeometryNotifierSvc","PhysicsListSvc",)
-#
-#  Physics region tools
-#
-from G4FaserTools.G4PhysicsRegionConfigNew import NeutrinoPhysicsRegionToolCfg, ScintillatorPhysicsRegionToolCfg, TrackerPhysicsRegionToolCfg, EcalPhysicsRegionToolCfg
-#
-#  Geometry tools
-#
-from G4FaserTools.G4GeometryToolConfig import MaterialDescriptionToolCfg, G4AtlasDetectorConstructionToolCfg, FASEREnvelopeCfg
-#
-#  Magnetic field tools - start simple
-#
-from G4FaserTools.G4FieldConfigNew import FASERFieldManagerToolCfg, EmulsionFieldManagerToolCfg, VetoFieldManagerToolCfg, TriggerFieldManagerToolCfg, PreshowerFieldManagerToolCfg
-#
-#  Future field managers (?)
-#
-# from G4FaserTools.G4FieldConfigNew import UpstreamDipoleFieldManagerToolCfg, CentralDipoleFieldManagerToolCfg, DownstreamDipleFieldManagerToolCfg, FaserCaloFieldManagerToolCfg
-from G4FaserTools.G4FieldConfigNew import TrackerFieldManagerToolCfg, DipoleFieldManagerToolCfg, EcalFieldManagerToolCfg
-#
-#
-#
-def getFASER_RegionCreatorList(ConfigFlags):
-    regionCreatorList = []
-
-    # from G4AtlasApps.SimFlags import simFlags
-    # Settings to widen the region of study - not yet supported by FASER
-    # if ConfigFlags.Beam.Type == 'cosmics' or ConfigFlags.Sim.CavernBG != 'Signal':
-    #     regionCreatorList += [SX1PhysicsRegionToolCfg(ConfigFlags), BedrockPhysicsRegionToolCfg(ConfigFlags), CavernShaftsConcretePhysicsRegionToolCfg(ConfigFlags)]
-
-    if ConfigFlags.Detector.EnableNeutrino:
-        regionCreatorList += [NeutrinoPhysicsRegionToolCfg(ConfigFlags)]
-
-    if ConfigFlags.Detector.EnableScintillator:
-        regionCreatorList += [ScintillatorPhysicsRegionToolCfg(ConfigFlags)]
-
-    if ConfigFlags.Detector.EnableTracker:
-        regionCreatorList += [TrackerPhysicsRegionToolCfg(ConfigFlags)]
-
-    if ConfigFlags.Detector.EnableEcal:
-        regionCreatorList += [EcalPhysicsRegionToolCfg(ConfigFlags)]
-
-    return regionCreatorList
-
-#########################################################################
-def FASER_FieldMgrListCfg(ConfigFlags):
-    result = ComponentAccumulator()
-    fieldMgrList = []
-
-    acc   = FASERFieldManagerToolCfg(ConfigFlags)
-    tool  = result.popToolsAndMerge(acc)
-    fieldMgrList += [tool]
-
-    if ConfigFlags.Detector.GeometryDipole:
-        acc = DipoleFieldManagerToolCfg(ConfigFlags)
-        tool  = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]    
-    if ConfigFlags.Detector.GeometryEmulsion:
-        acc = EmulsionFieldManagerToolCfg(ConfigFlags)
-        tool  = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-    if ConfigFlags.Detector.GeometryVeto:
-        acc = VetoFieldManagerToolCfg(ConfigFlags)
-        tool  = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-    if ConfigFlags.Detector.GeometryTrigger:
-        acc = TriggerFieldManagerToolCfg(ConfigFlags)
-        tool = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-    if ConfigFlags.Detector.GeometryPreshower:
-        acc = PreshowerFieldManagerToolCfg(ConfigFlags)
-        tool = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-    if ConfigFlags.Detector.GeometryTracker:
-        acc = TrackerFieldManagerToolCfg(ConfigFlags)
-        tool  = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-    if ConfigFlags.Detector.GeometryEcal:
-        acc = EcalFieldManagerToolCfg(ConfigFlags)
-        tool  = result.popToolsAndMerge(acc)
-        fieldMgrList += [tool]
-
-    result.setPrivateTools(fieldMgrList)
-    return result
-
-def getGeometryConfigurationTools(ConfigFlags):
-    geoConfigToolList = []
-    # The methods for these tools should be defined in the
-    # package containing each tool, so G4FaserTools in this case
-    geoConfigToolList += [MaterialDescriptionToolCfg(ConfigFlags)]
-    return geoConfigToolList
-
+from G4FaserTools.G4GeometryToolConfig import G4AtlasDetectorConstructionToolCfg
 
 def DetectorGeometrySvcCfg(ConfigFlags, name="DetectorGeometrySvc", **kwargs):
     result = ComponentAccumulator()
-    kwargs.setdefault("DetectorConstruction", G4AtlasDetectorConstructionToolCfg(ConfigFlags))
-    kwargs.setdefault("GeometryConfigurationTools", getGeometryConfigurationTools(ConfigFlags))
-
-    accGeo, toolGeo = FASEREnvelopeCfg(ConfigFlags)
-    kwargs.setdefault("World", toolGeo)
-    result.merge(accGeo)
-    kwargs.setdefault("RegionCreators", getFASER_RegionCreatorList(ConfigFlags))
-    acc = FASER_FieldMgrListCfg(ConfigFlags)
-    fieldMgrList = result.popToolsAndMerge(acc)
-    kwargs.setdefault("FieldManagers", fieldMgrList)
+    detConstTool = result.popToolsAndMerge(G4AtlasDetectorConstructionToolCfg(ConfigFlags))
+    result.addPublicTool(detConstTool)
+    kwargs.setdefault("DetectorConstruction", result.getPublicTool(detConstTool.name))
 
     result.addService(DetectorGeometrySvc(name, **kwargs))
     return result
 
+
 def G4AtlasSvcCfg(ConfigFlags, name="G4AtlasSvc", **kwargs):
     if ConfigFlags.Concurrency.NumThreads > 0:
         is_hive = True
@@ -126,6 +31,7 @@ def G4GeometryNotifierSvcCfg(ConfigFlags, name="G4GeometryNotifierSvc", **kwargs
     kwargs.setdefault("ActivatePVNotifier", False)
     return G4GeometryNotifierSvc(name, **kwargs)
 
+
 def PhysicsListSvcCfg(ConfigFlags, name="PhysicsListSvc", **kwargs):
     result = ComponentAccumulator()
     G4StepLimitationTool = CompFactory.G4StepLimitationTool
@@ -138,13 +44,19 @@ def PhysicsListSvcCfg(ConfigFlags, name="PhysicsListSvc", **kwargs):
     if 'PhysicsList' in kwargs:
         if kwargs['PhysicsList'].endswith('_EMV') or kwargs['PhysicsList'].endswith('_EMX'):
             raise RuntimeError( 'PhysicsList not allowed: '+kwargs['PhysicsList'] )
-    kwargs.setdefault("GeneralCut", 1.)
-    if ConfigFlags.Sim.NeutronTimeCut > 0.:
-        kwargs.setdefault("NeutronTimeCut", ConfigFlags.Sim.NeutronTimeCut)
-
-    if ConfigFlags.Sim.NeutronEnergyCut > 0.:
-        kwargs.setdefault("NeutronEnergyCut", ConfigFlags.Sim.NeutronEnergyCut)
 
+    kwargs.setdefault("GeneralCut", 1.)
+    kwargs.setdefault("NeutronTimeCut", ConfigFlags.Sim.NeutronTimeCut)
+    kwargs.setdefault("NeutronEnergyCut", ConfigFlags.Sim.NeutronEnergyCut)
     kwargs.setdefault("ApplyEMCuts", ConfigFlags.Sim.ApplyEMCuts)
+    ## from AthenaCommon.SystemOfUnits import eV, TeV
+    ## kwargs.setdefault("EMMaxEnergy"     , 7*TeV)
+    ## kwargs.setdefault("EMMinEnergy"     , 100*eV)
+    """ --- ATLASSIM-3967 ---
+        these two options are replaced by SetNumberOfBinsPerDecade
+        which now controls both values.
+    """
+    ## kwargs.setdefault("EMDEDXBinning"   , 77)
+    ## kwargs.setdefault("EMLambdaBinning" , 77)
     result.addService(PhysicsListSvc(name, **kwargs))
     return result
diff --git a/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py b/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py
index 6f3d50a2b91d255fa6ad1af6b9e73ad61ddb12ab..3520b26d0df3e3bc948c8b69cedf4de6cc5aecb6 100644
--- a/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py
+++ b/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py
@@ -6,6 +6,20 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaCommon import CfgMgr
 SensitiveDetectorMasterTool=CompFactory.SensitiveDetectorMasterTool
+FastSimulationMasterTool=CompFactory.FastSimulationMasterTool
+
+def generateFastSimulationListCfg(ConfigFlags):
+    result = ComponentAccumulator()
+    FastSimulationList = []
+    result.setPrivateTools(FastSimulationList)
+    return result
+
+def FastSimulationMasterToolCfg(ConfigFlags, **kwargs):
+    result = ComponentAccumulator()
+    FastSimulationList = result.popToolsAndMerge(generateFastSimulationListCfg(ConfigFlags))
+    kwargs.setdefault("FastSimulations", FastSimulationList)
+    result.setPrivateTools(FastSimulationMasterTool(name="FastSimulationMasterTool", **kwargs))
+    return result
 
 from EmulsionG4_SD.EmulsionG4_SDToolConfig import EmulsionSensorSDCfg
 from VetoG4_SD.VetoG4_SDToolConfig import VetoSensorSDCfg
@@ -72,12 +86,6 @@ def generateCaloSensitiveDetectorList(ConfigFlags):
     
     return result, SensitiveDetectorList #List of tools here now! (CALL IT TOOL LIST?)
 
-# def generateEnvelopeSensitiveDetectorList(ConfigFlags):
-#     SensitiveDetectorList=[]
-#     if ConfigFlags.Beam.Type == 'cosmics' and not ConfigFlags.Sim.ReadTR:
-#         SensitiveDetectorList+=['CosmicRecord']
-#     return SensitiveDetectorList
-
 def generateSensitiveDetectorList(ConfigFlags):
     result = ComponentAccumulator()
     SensitiveDetectorList=[]
@@ -108,7 +116,7 @@ def SensitiveDetectorMasterToolCfg(ConfigFlags, name="SensitiveDetectorMasterToo
     accSensitiveDetector = generateSensitiveDetectorList(ConfigFlags)
     kwargs.setdefault("SensitiveDetectors", result.popToolsAndMerge(accSensitiveDetector)) #list of tools
 
-    result.addPublicTool(SensitiveDetectorMasterTool(name, **kwargs)) #note -this is still a public tool
+    result.setPrivateTools(SensitiveDetectorMasterTool(name, **kwargs)) #note -this is still a public tool
     return result
 
 def getEmptySensitiveDetectorMasterTool(name="EmptySensitiveDetectorMasterTool", **kwargs):
diff --git a/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py b/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py
index 85b372fa30ee6bdb1b3b5015b7901d5db8792fe6..992cfbe4fe506841adbbaa052540dc50168f1155 100644
--- a/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py
+++ b/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py
@@ -3,11 +3,15 @@
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 
-GeoDetectorTool=CompFactory.GeoDetectorTool
+from AthenaCommon import Logging
 
-BoxEnvelope,MaterialDescriptionTool,G4AtlasDetectorConstructionTool=CompFactory.getComps("BoxEnvelope","MaterialDescriptionTool","G4AtlasDetectorConstructionTool",)
+#the physics region tools
+from G4FaserTools.G4PhysicsRegionConfigNew import NeutrinoPhysicsRegionToolCfg, TrackerPhysicsRegionToolCfg, ScintillatorPhysicsRegionToolCfg, EcalPhysicsRegionToolCfg
 
-from AthenaCommon.SystemOfUnits import mm
+#the field config tools
+from G4FaserTools.G4FieldConfigNew import FASERFieldManagerToolCfg, EmulsionFieldManagerToolCfg, VetoFieldManagerToolCfg, TriggerFieldManagerToolCfg, PreshowerFieldManagerToolCfg, TrackerFieldManagerToolCfg, DipoleFieldManagerToolCfg, EcalFieldManagerToolCfg
+
+GeoDetectorTool=CompFactory.GeoDetectorTool
 from EmulsionGeoModel.EmulsionGeoModelConfig import EmulsionGeometryCfg
 from VetoGeoModel.VetoGeoModelConfig import VetoGeometryCfg
 from TriggerGeoModel.TriggerGeoModelConfig import TriggerGeometryCfg
@@ -16,123 +20,249 @@ from FaserSCT_GeoModel.FaserSCT_GeoModelConfig import FaserSCT_GeometryCfg
 from DipoleGeoModel.DipoleGeoModelConfig import DipoleGeometryCfg
 from EcalGeoModel.EcalGeoModelConfig import EcalGeometryCfg
 
+BoxEnvelope, MaterialDescriptionTool, SmartlessnessTool, G4AtlasDetectorConstructionTool = CompFactory.getComps("BoxEnvelope", "MaterialDescriptionTool", "SmartlessnessTool", "G4AtlasDetectorConstructionTool",)
+
+from AthenaCommon.SystemOfUnits import mm
+
 #ToDo - finish migrating this (dnoel)
 #Todo - just return component accumulator
 #to still migrate: getCavernWorld, getCavernInfraGeoDetectorTool
 #from ForwardRegionProperties.ForwardRegionPropertiesToolConfig import ForwardRegionPropertiesCfg
 
+#put it here to avoid circular import?
+G4GeometryNotifierSvc=CompFactory.G4GeometryNotifierSvc
+def G4GeometryNotifierSvcCfg(ConfigFlags, name="G4GeometryNotifierSvc", **kwargs):
+    kwargs.setdefault("ActivateLVNotifier", True)
+    kwargs.setdefault("ActivatePVNotifier", False)
+    return G4GeometryNotifierSvc(name, **kwargs)
+
 def EmulsionGeoDetectorToolCfg(ConfigFlags, name='Emulsion', **kwargs):
     #set up geometry
     result=EmulsionGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Emulsion")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def VetoGeoDetectorToolCfg(ConfigFlags, name='Veto', **kwargs):
     #set up geometry
     result=VetoGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Veto")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def TriggerGeoDetectorToolCfg(ConfigFlags, name='Trigger', **kwargs):
     #set up geometry
     result=TriggerGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Trigger")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def PreshowerGeoDetectorToolCfg(ConfigFlags, name='Preshower', **kwargs):
     #set up geometry
     result=PreshowerGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Preshower")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def SCTGeoDetectorToolCfg(ConfigFlags, name='SCT', **kwargs):
     #set up geometry
     result=FaserSCT_GeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "SCT")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def DipoleGeoDetectorToolCfg(ConfigFlags, name='Dipole', **kwargs):
     #set up geometry
     result=DipoleGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Dipole")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def EcalGeoDetectorToolCfg(ConfigFlags, name='Ecal', **kwargs):
     #set up geometry
     result=EcalGeometryCfg(ConfigFlags)
     kwargs.setdefault("DetectorName", "Ecal")
-    return result, GeoDetectorTool(name, **kwargs)
+    #add the GeometryNotifierSvc
+    result.addService(G4GeometryNotifierSvcCfg(ConfigFlags))
+    kwargs.setdefault("GeometryNotifierSvc", result.getService("G4GeometryNotifierSvc"))
+    result.setPrivateTools(GeoDetectorTool(name, **kwargs))
+    return result
 
 def generateSubDetectorList(ConfigFlags):
     result = ComponentAccumulator()
     SubDetectorList=[]
 
     if ConfigFlags.Detector.GeometryEmulsion:
-        accEmulsion, toolEmulsion = EmulsionGeoDetectorToolCfg(ConfigFlags)
+        toolEmulsion = result.popToolsAndMerge(EmulsionGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolEmulsion ]
-        result.merge(accEmulsion)
 
     if ConfigFlags.Detector.GeometryVeto:
-        accVeto, toolVeto = VetoGeoDetectorToolCfg(ConfigFlags)
+        toolVeto = result.popToolsAndMerge(VetoGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolVeto ]
-        result.merge(accVeto)
 
     if ConfigFlags.Detector.GeometryTrigger:
-        accTrigger, toolTrigger = TriggerGeoDetectorToolCfg(ConfigFlags)
+        toolTrigger = result.popToolsAndMerge(TriggerGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolTrigger ]
-        result.merge(accTrigger)
 
     if ConfigFlags.Detector.GeometryPreshower:
-        accPreshower, toolPreshower = PreshowerGeoDetectorToolCfg(ConfigFlags)
+        toolPreshower = result.popToolsAndMerge(PreshowerGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolPreshower ]
-        result.merge(accPreshower)
 
     if ConfigFlags.Detector.GeometryFaserSCT:
-        accSCT, toolSCT = SCTGeoDetectorToolCfg(ConfigFlags)
+        toolSCT = result.popToolsAndMerge(SCTGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolSCT ]
-        result.merge(accSCT)
 
     if ConfigFlags.Detector.GeometryDipole:
-        accDipole, toolDipole = DipoleGeoDetectorToolCfg(ConfigFlags)
+        toolDipole = result.popToolsAndMerge(DipoleGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolDipole ]
-        result.merge(accDipole)
 
     if ConfigFlags.Detector.GeometryEcal:
-        accEcal, toolEcal = EcalGeoDetectorToolCfg(ConfigFlags)
+        toolEcal = result.popToolsAndMerge(EcalGeoDetectorToolCfg(ConfigFlags))
         SubDetectorList += [ toolEcal ]
-        result.merge(accEcal)
-
-    return result, SubDetectorList
+    result.setPrivateTools(SubDetectorList)
+    return result
 
 def FASEREnvelopeCfg(ConfigFlags, name="Faser", **kwargs):
     result = ComponentAccumulator()
 
-    kwargs.setdefault("DetectorName", "Faser")
-    accSubDetectors, SubDetectorList = generateSubDetectorList(ConfigFlags) 
-    result.merge(accSubDetectors)
-
     kwargs.setdefault("OffsetX", 0.0 * mm)
     kwargs.setdefault("OffsetY", 0.0 * mm)
     kwargs.setdefault("OffsetZ", 0.0 * mm)
-    # kwargs.setdefault("OffsetX", 0.0 * mm)
-    # kwargs.setdefault("OffsetY", 0.0 * mm)
-    # kwargs.setdefault("OffsetZ", -1650.0 * mm)
-    
-    # kwargs.setdefault("dX", 16.0 * mm) 
-    # kwargs.setdefault("dY", 16.0 * mm) 
-    # kwargs.setdefault("dZ", 33.0 * mm) 
     kwargs.setdefault("dX", 600.0 * mm) 
     kwargs.setdefault("dY", 600.0 * mm) 
     kwargs.setdefault("dZ", 4000.0 * mm) 
 
+    kwargs.setdefault("DetectorName", "Faser")
+    SubDetectorList = result.popToolsAndMerge(generateSubDetectorList(ConfigFlags))
     kwargs.setdefault("SubDetectors", SubDetectorList)
+    result.setPrivateTools(BoxEnvelope(name, **kwargs))
+    return result
 
-    return result, BoxEnvelope(name, **kwargs)
+def MaterialDescriptionToolCfg(ConfigFlags, name="MaterialDescriptionTool", **kwargs):
+    ## kwargs.setdefault("SomeProperty", aValue)
+    result = ComponentAccumulator()
+    result.setPrivateTools(MaterialDescriptionTool(name, **kwargs))
+    return result
 
-def G4AtlasDetectorConstructionToolCfg(ConfigFlags, name="G4FaserDetectorConstructionTool", **kwargs):
-    return G4AtlasDetectorConstructionTool(name, **kwargs)
 
-def MaterialDescriptionToolCfg(ConfigFlags, name="MaterialDescriptionTool", **kwargs):
+def SmartlessnessToolCfg(ConfigFlags, name="SmartlessnessTool", **kwargs):
     ## kwargs.setdefault("SomeProperty", aValue)
-    return MaterialDescriptionTool(name, **kwargs)
+    result = ComponentAccumulator()
+    result.setPrivateTools(SmartlessnessTool(name, **kwargs))
+    return result
+
+def getFASER_RegionCreatorList(ConfigFlags):
+    regionCreatorList = []
+
+    if ConfigFlags.Detector.GeometryNeutrino:
+        regionCreatorList += [NeutrinoPhysicsRegionToolCfg(ConfigFlags)]
+
+    if ConfigFlags.Detector.GeometryTracker:
+        regionCreatorList += [TrackerPhysicsRegionToolCfg(ConfigFlags)]
+
+    if ConfigFlags.Detector.GeometryScintillator:
+        regionCreatorList += [ScintillatorPhysicsRegionToolCfg(ConfigFlags)]
+
+    if ConfigFlags.Detector.GeometryFaserCalo:
+        regionCreatorList += [EcalPhysicsRegionToolCfg(ConfigFlags)]
+
+    return regionCreatorList
+
+def FASER_FieldMgrListCfg(ConfigFlags):
+    result = ComponentAccumulator()
+    fieldMgrList = []
+
+    acc   = FASERFieldManagerToolCfg(ConfigFlags)
+    tool  = result.popToolsAndMerge(acc)
+    fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryEmulsion:
+        acc = EmulsionFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryVeto:
+        acc = VetoFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryTrigger:
+        acc = TriggerFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryPreshower:
+        acc = PreshowerFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryTracker:
+        acc = TrackerFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryDipole:
+        acc = DipoleFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    if ConfigFlags.Detector.GeometryEcal:
+        acc = EcalFieldManagerToolCfg(ConfigFlags)
+        tool  = result.popToolsAndMerge(acc)
+        fieldMgrList += [tool]
+
+    result.setPrivateTools(fieldMgrList)
+    return result
+
+def getGeometryConfigurationTools(ConfigFlags):
+    geoConfigToolList = []
+    # The methods for these tools should be defined in the
+    # package containing each tool, so G4FaserTools in this case
+    result =ComponentAccumulator()
+    geoConfigToolList += [result.popToolsAndMerge(MaterialDescriptionToolCfg(ConfigFlags))]
+    geoConfigToolList += [result.popToolsAndMerge(SmartlessnessToolCfg(ConfigFlags))]
+    return result, geoConfigToolList
+
+
+def G4AtlasDetectorConstructionToolCfg(ConfigFlags, name="G4FaserDetectorConstructionTool", **kwargs):
+    result = ComponentAccumulator()
+
+    ## For now just have the same geometry configurations tools loaded for ATLAS and TestBeam
+    geoConfAcc, listOfGeoConfTools = getGeometryConfigurationTools(ConfigFlags)
+    result.merge(geoConfAcc)
+    kwargs.setdefault("GeometryConfigurationTools", listOfGeoConfTools)
+
+    # Getting this tool by name works, but not if you use getSensitiveDetectorMasterTool()
+    kwargs.setdefault('SenDetMasterTool', "SensitiveDetectorMasterTool" )
+
+    toolGeo = result.popToolsAndMerge(FASEREnvelopeCfg(ConfigFlags))
+    kwargs.setdefault("World", toolGeo)
+    kwargs.setdefault("RegionCreators", getFASER_RegionCreatorList(ConfigFlags))
+    #if hasattr(simFlags, 'MagneticField') and simFlags.MagneticField.statusOn:
+    if True:
+        acc = FASER_FieldMgrListCfg(ConfigFlags)
+        fieldMgrList = result.popToolsAndMerge(acc)
+        kwargs.setdefault("FieldManagers", fieldMgrList)
+    
+    result.setPrivateTools(G4AtlasDetectorConstructionTool(name, **kwargs))
+    return result
+
 
diff --git a/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py b/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py
index c910e2b8003df305b801f437257b0b44cbf937ec..040853dc2f46d08f0a92843d8b2f0dfef945ef11 100644
--- a/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py
+++ b/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py
@@ -2,65 +2,6 @@
 from AthenaConfiguration.ComponentFactory import CompFactory
 
 RegionCreator=CompFactory.RegionCreator
-# Beampipe Regions
-# def BeampipeFwdCutPhysicsRegionToolCfg(ConfigFlags, name='BeampipeFwdCutPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'BeampipeFwdCut')
-#     volumeList = ['BeamPipe::SectionF47', 'BeamPipe::SectionF48', 'BeamPipe::SectionF61']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     from G4AtlasApps.SimFlags import simFlags
-
-#     #if simFlags.BeamPipeSimMode() == "FastSim":
-#     if True:
-#         kwargs.setdefault("ElectronCut", 10.)
-#         kwargs.setdefault("PositronCut", 10.)
-#         kwargs.setdefault("GammaCut", 10.)
-#         print('Adding fast sim model to the beampipe!')
-#     else:
-#         assert simFlags.BeamPipeCut.statusOn
-#         if simFlags.BeamPipeCut() < 1:
-#             msg = "Setting the forward beam pipe range cuts to %e mm " % simFlags.BeamPipeCut()
-#             msg += "-- cut is < 1 mm, I hope you know what you're doing!"
-#             print(msg)
-#         if simFlags.BeamPipeSimMode() == "EGammaRangeCuts":
-#             kwargs.setdefault("ElectronCut", simFlags.BeamPipeCut())
-#             kwargs.setdefault("PositronCut", simFlags.BeamPipeCut())
-#             kwargs.setdefault("GammaCut", simFlags.BeamPipeCut())
-#         elif simFlags.BeamPipeSimMode() == "EGammaPRangeCuts":
-#             kwargs.setdefault("ElectronCut", simFlags.BeamPipeCut())
-#             kwargs.setdefault("PositronCut", simFlags.BeamPipeCut())
-#             kwargs.setdefault("GammaCut", simFlags.BeamPipeCut())
-#             kwargs.setdefault("ProtonCut", simFlags.BeamPipeCut())
-#     return RegionCreator(name, **kwargs)
-
-# def FWDBeamLinePhysicsRegionToolCfg(ConfigFlags, name='FWDBeamLinePhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'FWDBeamLine')
-#     volumeList = ['BeamPipe::SectionF46']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     return RegionCreator(name, **kwargs)
-
-# # Forward Regions
-# def FwdRegionPhysicsRegionToolCfg(ConfigFlags, name='FwdRegionPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'FwdRegion')
-#     volumeList = ['FwdRegion::ForwardRegionGeoModel']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 200.)
-#     kwargs.setdefault("PositronCut", 200.)
-#     kwargs.setdefault("GammaCut",    200.)
-#     return RegionCreator(name, **kwargs)
-
-# # Inner Detector Regions
-# def PixelPhysicsRegionToolCfg(ConfigFlags, name='PixelPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'Pixel')
-#     volumeList = ['Pixel::siLog', 'Pixel::siBLayLog']
-#     from AtlasGeoModel.CommonGMJobProperties import CommonGeometryFlags as commonGeoFlags
-#     from AtlasGeoModel.InDetGMJobProperties import InDetGeometryFlags as geoFlags
-#     if (ConfigFlags.GeoModel.Run in ["RUN2", "RUN3"]) or (commonGeoFlags.Run()=="UNDEFINED" and geoFlags.isIBL()):
-#         volumeList += ['Pixel::dbmDiamondLog']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.05)
-#     kwargs.setdefault("PositronCut", 0.05)
-#     kwargs.setdefault("GammaCut",    0.05)
-#     return RegionCreator(name, **kwargs)
 
 #  Values identical to ATLAS SCT
 
@@ -104,232 +45,3 @@ def EcalPhysicsRegionToolCfg(ConfigFlags, name='EcalPhysicsRegionTool', **kwargs
     kwargs.setdefault("PositronCut", rangeEMB)
     kwargs.setdefault("GammaCut",    rangeEMB)
     return RegionCreator(name, **kwargs)
-
-# def SCTPhysicsRegionToolCfg(ConfigFlags, name='SCTPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'SCT')
-#     volumeList = ['SCT::BRLSensor', 'SCT::BRLSensorSS', 'SCT::BRLSensorMS',
-#                    'SCT::ECSensor0', 'SCT::ECSensor1', 'SCT::ECSensor2',
-#                    'SCT::ECSensor3', 'SCT::ECSensor4', 'SCT::ECSensor5']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.05)
-#     kwargs.setdefault("PositronCut", 0.05)
-#     kwargs.setdefault("GammaCut",    0.05)
-#     return RegionCreator(name, **kwargs)
-
-# def TRTPhysicsRegionToolCfg(ConfigFlags, name='TRTPhysicsRegionTool', **kwargs):
-#     #rangeCut = simFlags.TRTRangeCut._Value()
-#     rangeCut = 30.0
-#     kwargs.setdefault("RegionName", 'TRT')
-#     volumeList = ['TRT::Gas', 'TRT::GasMA']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", rangeCut)
-#     kwargs.setdefault("PositronCut", rangeCut)
-#     # The photon range cut is meant to stay small
-#     kwargs.setdefault("GammaCut",    0.05)
-#     return RegionCreator(name, **kwargs)
-
-# def TRT_ArPhysicsRegionToolCfg(ConfigFlags, name='TRT_ArPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'TRT_Ar')
-#     volumeList = ['TRT::Gas_Ar', 'TRT::GasMA_Ar']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 30.0)
-#     kwargs.setdefault("PositronCut", 30.0)
-#     kwargs.setdefault("GammaCut",    0.05)
-#     return RegionCreator(name, **kwargs)
-
-# def TRT_KrPhysicsRegionToolCfg(ConfigFlags, name='TRT_KrPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'TRT_Kr')
-#     volumeList = ['TRT::Gas_Kr', 'TRT::GasMA_Kr']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 15.0)
-#     kwargs.setdefault("PositronCut", 15.0)
-#     kwargs.setdefault("GammaCut",    0.05)
-#     return RegionCreator(name, **kwargs)
-
-# # Calo Regions
-# def EMBPhysicsRegionToolCfg(ConfigFlags, name='EMBPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'EMB')
-#     volumeList = ['LArMgr::LAr::EMB::STAC']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     rangeEMB = 0.03
-#     from G4AtlasApps.SimFlags import simFlags
-#     if '_EMV' not in simFlags.PhysicsList() and '_EMX' not in simFlags.PhysicsList():
-#         rangeEMB = 0.1
-#     kwargs.setdefault("ElectronCut", rangeEMB)
-#     kwargs.setdefault("PositronCut", rangeEMB)
-#     kwargs.setdefault("GammaCut",    rangeEMB)
-#     return RegionCreator(name, **kwargs)
-
-# def EMECPhysicsRegionToolCfg(ConfigFlags, name='EMECPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'EMEC')
-#     volumeList = ['LArMgr::LAr::EMEC::Mother']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     rangeEMEC = 0.03
-#     from G4AtlasApps.SimFlags import simFlags
-#     if '_EMV' not in simFlags.PhysicsList() and '_EMX' not in simFlags.PhysicsList():
-#         rangeEMEC = 0.1
-#     kwargs.setdefault("ElectronCut", rangeEMEC)
-#     kwargs.setdefault("PositronCut", rangeEMEC)
-#     kwargs.setdefault("GammaCut",    rangeEMEC)
-#     return RegionCreator(name, **kwargs)
-
-# def HECPhysicsRegionToolCfg(ConfigFlags, name='HECPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'HEC')
-#     volumeList = ['LArMgr::LAr::HEC::LiquidArgon']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     rangeHEC = 0.03
-#     from G4AtlasApps.SimFlags import simFlags
-#     if '_EMV' not in simFlags.PhysicsList() and '_EMX' not in simFlags.PhysicsList():
-#         rangeHEC = 1.0
-#     kwargs.setdefault("ElectronCut", rangeHEC)
-#     kwargs.setdefault("PositronCut", rangeHEC)
-#     kwargs.setdefault("GammaCut",    rangeHEC)
-#     return RegionCreator(name, **kwargs)
-
-# def FCALPhysicsRegionToolCfg(ConfigFlags, name='FCALPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'FCAL')
-#     volumeList = ['LArMgr::LAr::FCAL::LiquidArgonC']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.03)
-#     kwargs.setdefault("PositronCut", 0.03)
-#     kwargs.setdefault("GammaCut",    0.03)
-#     return RegionCreator(name, **kwargs)
-
-# def EMECParaPhysicsRegionToolCfg(ConfigFlags, name='EMECParaPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'EMECPara')
-#     volumeList = ['LArMgr::LAr::EMEC::Pos::InnerWheel', 'LArMgr::LAr::EMEC::Pos::OuterWheel',
-#                   'LArMgr::LAr::EMEC::Neg::InnerWheel', 'LArMgr::LAr::EMEC::Neg::OuterWheel']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     rangeEMEC = 0.03
-#     from G4AtlasApps.SimFlags import simFlags
-#     if '_EMV' not in simFlags.PhysicsList() and '_EMX' not in simFlags.PhysicsList():
-#         rangeEMEC = 0.1
-#     kwargs.setdefault("ElectronCut", rangeEMEC)
-#     kwargs.setdefault("PositronCut", rangeEMEC)
-#     kwargs.setdefault("GammaCut",    rangeEMEC)
-#     return RegionCreator(name, **kwargs)
-
-# def FCALParaPhysicsRegionToolCfg(ConfigFlags, name='FCALParaPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'FCALPara')
-#     volumeList = ['LArMgr::LAr::FCAL::Module1::Absorber']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.03)
-#     kwargs.setdefault("PositronCut", 0.03)
-#     kwargs.setdefault("GammaCut",    0.03)
-#     return RegionCreator(name, **kwargs)
-
-# def FCAL2ParaPhysicsRegionToolCfg(ConfigFlags, name='FCAL2ParaPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'FCAL2Para')
-#     volumeList = ['LArMgr::LAr::FCAL::Module2::Absorber', 'LArMgr::LAr::FCAL::Module3::Absorber']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.03)
-#     kwargs.setdefault("PositronCut", 0.03)
-#     kwargs.setdefault("GammaCut",    0.03)
-#     return RegionCreator(name, **kwargs)
-
-# def PreSampLArPhysicsRegionToolCfg(ConfigFlags, name='PreSampLArPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'PreSampLAr')
-#     volumeList = ['LArMgr::LAr::Endcap::Presampler::LiquidArgon']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     return RegionCreator(name, **kwargs)
-
-# def DeadMaterialPhysicsRegionToolCfg(ConfigFlags, name='DeadMaterialPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'DeadMaterial')
-#     volumeList = []
-#     sectionList = range(16,49) # does not include 49
-#     sectionList += [ 51, 52, 53, 54 ]
-#     for section in sectionList:
-#         volumeList += ['BeamPipe::SectionF'+str(section)]
-#     volumeList += ['LArMgr::LAr::Endcap::Cryostat::Cylinder',
-#                    'LArMgr::LAr::Endcap::Cryostat::Cylinder::Mixed',
-#                    'LArMgr::LAr::Endcap::Cryostat::Cone::Mixed',
-#                    'LArMgr::LAr::Endcap::Cryostat::Cone',
-#                    'DiskShieldingPlugs', 'ToroidShieldingInnerPlugs',
-#                    'ForwardShieldingMainCylinder']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 1.0)
-#     kwargs.setdefault("PositronCut", 1.0)
-#     kwargs.setdefault("GammaCut",    1.0)
-#     return RegionCreator(name, **kwargs)
-
-# #Muon Regions
-# def DriftWallPhysicsRegionToolCfg(ConfigFlags, name='DriftWallPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'DriftWall')
-#     volumeList = ['Muon::MDTDriftWall']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.05)
-#     kwargs.setdefault("PositronCut", 0.05)
-#     return RegionCreator(name, **kwargs)
-
-# def DriftWall1PhysicsRegionToolCfg(ConfigFlags, name='DriftWall1PhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'DriftWall1')
-#     volumeList = ['Muon::Endplug']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 1.0)
-#     kwargs.setdefault("PositronCut", 1.0)
-#     return RegionCreator(name, **kwargs)
-
-# def DriftWall2PhysicsRegionToolCfg(ConfigFlags, name='DriftWall2PhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'DriftWall2')
-#     volumeList = ['Muon::SensitiveGas']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 1.0)
-#     kwargs.setdefault("PositronCut", 1.0)
-#     return RegionCreator(name, **kwargs)
-
-# def MuonSystemFastPhysicsRegionToolCfg(ConfigFlags, name='MuonSystemFastPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'MuonSystemFastRegion')
-#     volumeList = []
-#     if ConfigFlags.Sim.CavernBG  == 'World':
-#         volumeList += ['BeamPipe::BeamPipe', 'IDET::IDET']
-#     volumeList = ['Muon::MuonSys']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 1.0)
-#     kwargs.setdefault("PositronCut", 1.0)
-#     return RegionCreator(name, **kwargs)
-
-# def MuonPhysicsRegionToolCfg(ConfigFlags, name="MuonPhysicsRegionTool", **kwargs):
-#     kwargs.setdefault("RegionName", 'MuonSys')
-#     volumeList = ['Muon::MuonSys']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 0.1)
-#     kwargs.setdefault("PositronCut", 0.1)
-#     kwargs.setdefault("GammaCut",    0.1)
-#     return RegionCreator(name, **kwargs)
-
-# # Cavern Regions
-# def SX1PhysicsRegionToolCfg(ConfigFlags, name='SX1PhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'SX1')
-#     volumeList = ['CavernInfra::SX1Air']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 2000.)
-#     kwargs.setdefault("PositronCut", 2000.)
-#     kwargs.setdefault("GammaCut",    2000.)
-#     return RegionCreator(name, **kwargs)
-
-# def BedrockPhysicsRegionToolCfg(ConfigFlags, name='BedrockPhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'BEDROCK')
-#     volumeList = ['CavernInfra::BEDROCK']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 1000000.)
-#     kwargs.setdefault("PositronCut", 1000000.)
-#     kwargs.setdefault("GammaCut",    1000000.)
-#     return RegionCreator(name, **kwargs)
-
-# def CavernShaftsConcretePhysicsRegionToolCfg(ConfigFlags, name='CavernShaftsConcretePhysicsRegionTool', **kwargs):
-#     kwargs.setdefault("RegionName", 'CAV_SHAFTS_CONC')
-#     volumeList = ['CavernInfra::CAV_SHAFTS_CONC']
-#     kwargs.setdefault("VolumeList",  volumeList)
-#     kwargs.setdefault("ElectronCut", 150.)
-#     kwargs.setdefault("PositronCut", 150.)
-#     kwargs.setdefault("GammaCut",    150.)
-#     return RegionCreator(name, **kwargs)
-
-##def getCavernShaftsAirPhysicsRegionTool(name='CavernShaftsAirPhysicsRegionTool', **kwargs):
-##    kwargs.setdefault("RegionName", 'CAV_SHAFTS_AIR')
-##    volumeList = ['CavernInfra::CAV_SHAFTS_AIR']
-##    kwargs.setdefault("VolumeList",  volumeList)
-##    kwargs.setdefault("ElectronCut", 2000.)
-##    kwargs.setdefault("PositronCut", 2000.)
-##    kwargs.setdefault("GammaCut",    2000.)
-##    return CfgMgr.RegionCreator(name, **kwargs)
diff --git a/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesConfigNew.py b/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesConfigNew.py
index 6f7478c462fb631db72596e8d3ee9d0a220e3418..7260d59fc1e6df1b327196817f8a44c865d72a16 100644
--- a/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesConfigNew.py
+++ b/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesConfigNew.py
@@ -10,30 +10,10 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 
 from BarcodeServices.BarcodeServicesConfigNew import MC15aPlusBarcodeSvcCfg
 from ISF_HepMC_Tools.ISF_HepMC_ToolsConfigNew import ParticleFinalStateFilterCfg, GenParticleInteractingFilterCfg
-#from FaserISF_HepMC_Tools.FaserISF_HepMC_ToolsConfigNew import FaserParticlePositionFilterCfg, FaserParticleGenericFilterCfg
 from FaserISF_HepMC_Tools.FaserISF_HepMC_ToolsConfigNew import FaserTruthStrategyCfg, FaserDipoleTruthStrategyCfg
 
-# from ISF_HepMC_Tools.ISF_HepMC_ToolsConfigNew import TruthStrategyGroupID_MC15Cfg, TruthStrategyGroupCaloMuBremCfg, TruthStrategyGroupCaloDecay_MC15Cfg, TruthStrategyGroupIDHadInt_MC15Cfg, ParticleFinalStateFilterCfg, ParticlePositionFilterDynamicCfg, EtaPhiFilterCfg, GenParticleInteractingFilterCfg
-# from SubDetectorEnvelopes.SubDetectorEnvelopesConfigNew import EnvelopeDefSvcCfg
-
-
 ISF__FaserTruthSvc, ISF__FaserGeoIDSvc, ISF__FaserInputConverter = CompFactory.getComps("ISF::FaserTruthSvc","ISF::FaserGeoIDSvc","ISF::FaserInputConverter")
 
-#Functions yet to be migrated:
-#getParticleBrokerSvcNoOrdering, getParticleBrokerSvc, getAFIIParticleBrokerSvc, getAFIIEnvelopeDefSvc, getAFIIGeoIDSvc
-#getLongLivedInputConverter, getValidationTruthService, getMC12BeamPipeTruthStrategies, getMC12IDTruthStrategies
-#getMC12CaloTruthStrategies, getMC12MSTruthStrategies, getMC12TruthService, getTruthService, getMC12LLPTruthService, getMC12PlusTruthService,  getMC15IDTruthStrategies
-#getMC15CaloTruthStrategies
-
-
-def FaserGeoIDSvcCfg(ConfigFlags, name="ISF_FaserGeoIDSvc", **kwargs):
-    result = ComponentAccumulator()
-
-    result.addService(ISF__FaserGeoIDSvc(name, **kwargs))
-
-    return result
-
-
 def GenParticleFiltersToolCfg(ConfigFlags):
     result = ComponentAccumulator()
 
@@ -110,39 +90,3 @@ def FaserTruthServiceCfg(ConfigFlags, name="FaserISF_TruthService", **kwargs):
 
     result.addService(ISF__FaserTruthSvc(name, **kwargs))
     return result
-
-
-# def MC15TruthServiceCfg(ConfigFlags, name="ISF_MC15TruthService", **kwargs):
-#     result = ComponentAccumulator()
-#     # importing Reflex dictionary to access AtlasDetDescr::AtlasRegion enum
-#     import ROOT, cppyy
-#     cppyy.loadDictionary('AtlasDetDescrDict')
-#     AtlasRegion = ROOT.AtlasDetDescr
-
-#     acc1 = TruthStrategyGroupID_MC15Cfg(ConfigFlags)
-#     acc2 = TruthStrategyGroupIDHadInt_MC15Cfg(ConfigFlags)
-#     acc3 = TruthStrategyGroupCaloMuBremCfg(ConfigFlags)
-#     acc4 = TruthStrategyGroupCaloDecay_MC15Cfg(ConfigFlags)
-
-#     kwargs.setdefault('TruthStrategies', [result.popToolsAndMerge(acc1),
-#                                           result.popToolsAndMerge(acc2),
-#                                           result.popToolsAndMerge(acc3), #FIXME this should be ISF_MCTruthStrategyGroupCaloMuBrem_MC15!!
-#                                           result.popToolsAndMerge(acc4)])
-
-
-#     kwargs.setdefault('IgnoreUndefinedBarcodes', False)
-#     kwargs.setdefault('PassWholeVertices', False) # new for MC15 - can write out partial vertices.
-#     kwargs.setdefault('ForceEndVtxInRegions', [AtlasRegion.fAtlasID])
-#     accTruthService = GenericTruthServiceCfg(ConfigFlags, name, **kwargs)
-#     result.merge(accTruthService)
-#     return result
-
-
-# def MC15aPlusTruthServiceCfg(ConfigFlags, name="ISF_MC15aPlusTruthService", **kwargs):
-#     # importing Reflex dictionary to access AtlasDetDescr::AtlasRegion enum
-#     import ROOT, cppyy
-#     cppyy.loadDictionary('AtlasDetDescrDict')
-#     AtlasRegion = ROOT.AtlasDetDescr
-#     kwargs.setdefault('ForceEndVtxInRegions', [AtlasRegion.fAtlasID])
-#     result = MC15TruthServiceCfg(ConfigFlags, name, **kwargs)
-#     return result
diff --git a/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesCoreConfigNew.py b/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesCoreConfigNew.py
new file mode 100644
index 0000000000000000000000000000000000000000..569a51177d8144a328ffce9415bd6a7f5773b97f
--- /dev/null
+++ b/Simulation/ISF/ISF_Core/FaserISF_Services/python/FaserISF_ServicesCoreConfigNew.py
@@ -0,0 +1,9 @@
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+def FaserGeoIDSvcCfg(ConfigFlags, name="ISF_FaserGeoIDSvc", **kwargs):
+    result = ComponentAccumulator()
+
+    result.addService(CompFactory.ISF.FaserGeoIDSvc(name, **kwargs))
+
+    return result
diff --git a/Simulation/ISF/ISF_Geant4/FaserISF_Geant4Event/src/FaserISFG4GeoHelper.cxx b/Simulation/ISF/ISF_Geant4/FaserISF_Geant4Event/src/FaserISFG4GeoHelper.cxx
index 5dd4fa5d5b746700b47f384b058d2ae9af7955c3..6697607742a1a4cb0cdebf08aa138ba1fca4ba6c 100644
--- a/Simulation/ISF/ISF_Geant4/FaserISF_Geant4Event/src/FaserISFG4GeoHelper.cxx
+++ b/Simulation/ISF/ISF_Geant4/FaserISF_Geant4Event/src/FaserISFG4GeoHelper.cxx
@@ -139,7 +139,7 @@ bool iGeant4::FaserISFG4GeoHelper::checkVolumeDepth(G4LogicalVolume* lv, int vol
   } // Check of volume name
 
   // Going through the volume depth
-  for (int i=0; i<lv->GetNoDaughters(); ++i) {
+  for (size_t i=0; i<lv->GetNoDaughters(); ++i) {
     Cavern = Cavern || checkVolumeDepth( lv->GetDaughter(i)->GetLogicalVolume() , volLevel , depth+1 );
   }
   if (depth==0 && !Cavern && volLevel>1) {
diff --git a/Simulation/README.md b/Simulation/README.md
index 350d7ab9beb3eb94d7683c94d210d2e11d1fa90c..4b9556c73de0e240dc4c14d3d407712fc24ed20a 100644
--- a/Simulation/README.md
+++ b/Simulation/README.md
@@ -1,15 +1,14 @@
 To generate Calypso MC data from an installation (run) directory:
 
-1) edit the G4FaserAlg/test/runG4.py file to setup the job
+1) edit the G4FaserAlg/test/G4FaserAlgConfigNew_Test.py file to setup the job
 ....the default generator is particle-gun; it can also read EVNT files but note that the Veto is far away from (0,0,0) where most ATLAS generators put things by default
+....there are examples of single-particle (muon or electron), cosmic-rays and decay-in-flight.  The parameters of each can be changed by passing keyword arguments
 ....read the comments carefully as a few other things have to be changed in the job options to switch between internal generator and generator data-file
+....the geometry can be changed on the command line, using the GeoModel.FaserVersion flag and IOVDb.GlobalTag flags.  See the tests in the CMakeLists.txt file for examples
 
 2) source ./setup.sh
-3) runG4.py
+3) G4FaserAlgConfigNew_Test.py
 
 (setup.sh will put the script in your path)
 
-To generate events with the emulsion detector, use
-
-3a) runG4FaserNu.py
 
diff --git a/Tracker/TrackerDetDescr/DipoleGeoModel/src/DipoleTool.cxx b/Tracker/TrackerDetDescr/DipoleGeoModel/src/DipoleTool.cxx
index 535c63ef409ada5cac9b9ca7a49982d802c1afde..138deee6639c1248aae0dc2cb02fa946b0fa233a 100644
--- a/Tracker/TrackerDetDescr/DipoleGeoModel/src/DipoleTool.cxx
+++ b/Tracker/TrackerDetDescr/DipoleGeoModel/src/DipoleTool.cxx
@@ -83,7 +83,6 @@ StatusCode DipoleTool::create()
   }  
   
   std::string versionTag = m_rdbAccessSvc->getChildTag("Dipole", versionKey.tag(), versionKey.node(), "FASERDD");
-  msg(MSG::INFO) << "Dipole Package Version: " << PACKAGE_VERSION << endmsg;
   if(msgLvl(MSG::DEBUG)) msg() << "versionTag=" << versionTag <<" %%%"<< endmsg;
 
   // If versionTag is NULL then don't build.
diff --git a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/FaserSCT_DetectorTool.cxx b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/FaserSCT_DetectorTool.cxx
index 91958660cb9e1a8d697e7a59f6825f0539df7a14..456afc4ee1b9199a3ec62aac9a03b82a8b705d8d 100644
--- a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/FaserSCT_DetectorTool.cxx
+++ b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/FaserSCT_DetectorTool.cxx
@@ -63,7 +63,7 @@ FaserSCT_DetectorTool::create()
   ATH_CHECK(m_rdbAccessSvc.retrieve());
   // Print the SCT version tag:
   std::string sctVersionTag{m_rdbAccessSvc->getChildTag("SCT", versionKey.tag(), versionKey.node(),"FASERDD")};
-  ATH_MSG_INFO("SCT Version: " << sctVersionTag <<  "  Package Version: " << PACKAGE_VERSION);
+  ATH_MSG_INFO("SCT Version: " << sctVersionTag);
   // Check if version is empty. If so, then the SCT cannot be built. This may or may not be intentional. We
   // just issue an INFO message. 
   if (sctVersionTag.empty()) {
@@ -163,7 +163,7 @@ FaserSCT_DetectorTool::clear()
 StatusCode 
 FaserSCT_DetectorTool::registerCallback ATLAS_NOT_THREAD_SAFE ()
 {
-  StatusCode sc{StatusCode::FAILURE, true};
+  StatusCode sc{StatusCode::FAILURE};
   if (m_alignable.value()) {
     if (m_useDynamicAlignFolders.value()) {
       ATH_MSG_FATAL("Dynamic alignment not supported.");
diff --git a/Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictInterface_TB00.xml b/Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictInterface_TB00.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a75ccee6cfc5b0cbf46511c7ffa7ade10440b437
--- /dev/null
+++ b/Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictInterface_TB00.xml
@@ -0,0 +1,50 @@
+<IdDictionary name="Tracker" version="FaserNu">
+
+  <field name="part">
+    <label name="SCT"        value="1" />
+  </field>
+
+<!-- This file includes the Interface detector -->
+  <field name="station" >
+    <label name="Interface"  value="0" />
+  </field>
+
+  <field name="layer" >
+    <label name="Upstream"   value="0" />
+    <label name="Central"    value="1" />
+    <label name="Downstream" value="2" />
+  </field>
+
+  <field name="phi_module">
+    <label name="Bottom"       value="0" /> 
+    <label name="LowerMiddle"  value="1" />
+    <label name="UpperMiddle"  value="2" />
+    <label name="Top"          value="3" />
+  </field>
+
+  <field name="eta_module">
+  <!-- facing downstream (hence "starboard" and "port")
+       x must increase right to left for a right-handed
+       coordinate system -->
+  <!-- numbers straddle zero for consistency with ATLAS -->       
+    <label name="Starboard"   value="-1" />
+    <label name="Port"        value="+1" />
+  </field>
+
+  <field name="side">
+  <!-- The "upper" side is the side with the pigtail -->
+    <label name="Upper"    value="0" />
+    <label name="Lower"    value="1" />
+  </field>
+
+  <region>
+    <range field="part"       value="SCT" />
+    <range field="station"    values="Interface" />
+    <range field="layer"      values="Upstream Central Downstream" />
+    <range field="phi_module" values="Bottom LowerMiddle UpperMiddle Top" wraparound="FALSE" />
+    <range field="eta_module" values="Starboard Port" wraparound="FALSE" />
+    <range field="side"       values="Upper Lower" />
+    <range field="strip"      minvalue="0" maxvalue="767" />
+  </region>
+
+</IdDictionary>
\ No newline at end of file
diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
index ebb1b3151a2f4e96652b2b2598e66ccf8ffe1ba3..89fa0e161a3f73b06d54c5630dd7ac763b41bc69 100644
--- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
+++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
@@ -162,10 +162,10 @@ namespace TrackerDD {
     //@{
     
     /// identifier of this detector element (inline)
-    Identifier identify() const;
+    virtual Identifier identify() const override final;
     
     /// identifier hash (inline)
-    IdentifierHash identifyHash() const;
+    virtual IdentifierHash identifyHash() const override final;
     
     /// Returns the id helper (inline)
     const FaserDetectorID* getIdHelper() const;
@@ -201,20 +201,38 @@ namespace TrackerDD {
     /// @name Transformation/Orientation
     //
     ///////////////////////////////////////////////////////////////////
+    /**
+     * Element Surface
+     */
+    Trk::Surface& surface();
+    virtual const Trk::Surface& surface() const override final;
+    /**
+     * TrkDetElementBase interface (inline)
+     */
+    virtual const Trk::Surface& surface(const Identifier&) const override final;
     
     //@{
     // Position 
     /// Local (simulation/hit frame) to global transform
     virtual const GeoTrf::Transform3D& transformHit() const;
     /// Local (reconstruction frame) to global transform
-    const Amg::Transform3D& transform() const;
+    virtual const Amg::Transform3D& transform() const override final;
+    /**
+     * TrkDetElementBase interface (inline)
+     */
+    virtual const Amg::Transform3D& transform(const Identifier&) const override final;
+
     /// Default Local (reconstruction frame) to global transform
     /// ie with no misalignment. 
     const HepGeom::Transform3D defTransformCLHEP() const;
     const Amg::Transform3D defTransform() const;
     /// Center in global coordinates
-    const Amg::Vector3D& center() const;
-    
+    virtual const Amg::Vector3D& center() const override final;
+    /**
+     * TrkDetElementBase interface (inline)
+     */
+    virtual const Amg::Vector3D& center(const Identifier&) const override final;
+
     const HepGeom::Transform3D& transformCLHEP() const;
     
     /// Simulation/Hit local frame to reconstruction local frame. 2D.
@@ -254,8 +272,14 @@ namespace TrackerDD {
     /// In direction of increasing z in the barrel and increasing r in the endcap. 
     const Amg::Vector3D& etaAxis() const;
     const HepGeom::Vector3D<double>& etaAxisCLHEP() const;
-    /// Get reconstruction local normal axes in global frame. Choosen to give right-handed coordinate frame.
-    const Amg::Vector3D& normal() const;
+    /**
+     * Get reconstruction local normal axes in global frame. Choosen to give right-handed coordinate frame.
+     */
+    virtual const Amg::Vector3D& normal() const override final;
+    /**
+     * TrkDetElementBase interface (inline)
+     */
+    virtual const Amg::Vector3D& normal(const Identifier&) const override final;
      
     /// transform a hit local position into a global position (inline):
     HepGeom::Point3D<double> globalPositionHit(const HepGeom::Point3D<double>& simulationLocalPos) const;
@@ -298,8 +322,8 @@ namespace TrackerDD {
     double sinStereoLocal(const HepGeom::Point3D<double>& globalPos) const;
     
     /// Element Surface
-    virtual Trk::Surface& surface();
-    virtual const Trk::Surface& surface() const;
+    // virtual Trk::Surface& surface();
+    // virtual const Trk::Surface& surface() const;
     
     //@}
 
@@ -396,7 +420,11 @@ namespace TrackerDD {
     TrackerDD::CarrierType carrierType() const; // carrier type for readout. ie holes for SCT 
     // and electrons for pixels.
 
-    virtual const Trk::SurfaceBounds& bounds() const;
+    virtual const Trk::SurfaceBounds& bounds() const override final;
+    /**
+     * TrkDetElementBase interface (inline)
+     */
+    virtual const Trk::SurfaceBounds& bounds(const Identifier&) const override final;
     
     // Pitch 
     //
@@ -527,11 +555,11 @@ namespace TrackerDD {
     //
     ///////////////////////////////////////////////////////////////////
     //{@
-    virtual const Amg::Transform3D& transform(const Identifier&) const;
-    virtual const Trk::Surface& surface(const Identifier&) const;
-    virtual const Amg::Vector3D& center(const Identifier&) const;
-    virtual const Amg::Vector3D& normal(const Identifier&) const;
-    virtual const Trk::SurfaceBounds& bounds(const Identifier&) const;
+    // virtual const Amg::Transform3D& transform(const Identifier&) const;
+    // virtual const Trk::Surface& surface(const Identifier&) const;
+    // virtual const Amg::Vector3D& center(const Identifier&) const;
+    // virtual const Amg::Vector3D& normal(const Identifier&) const;
+    // virtual const Trk::SurfaceBounds& bounds(const Identifier&) const;
     //@}
     
     //////////////////////////////////////////////////////////////////////////////////////
@@ -553,7 +581,11 @@ namespace TrackerDD {
     //@}
 
     const SiCommonItems* getCommonItems() const;
-    
+
+    /** TrkDetElementBase interface detectorType
+     */
+     virtual Trk::DetectorElemType detectorType() const override final;
+
     ///////////////////////////////////////////////////////////////////
     // Private methods:
     ///////////////////////////////////////////////////////////////////
diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.icc b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.icc
index 5936a08d41b3bb58c0da56e42bcea1de5542dbad..33bd220bf0f135f9180b28f6e99c256bddb37e3f 100644
--- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.icc
+++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.icc
@@ -11,7 +11,11 @@ namespace TrackerDD {
   ///////////////////////////////////////////////////////////////////
   // Inline methods:
   ///////////////////////////////////////////////////////////////////
-    
+
+  inline Trk::DetectorElemType SiDetectorElement::detectorType() const{
+    return Trk::DetectorElemType::Silicon;
+  }
+
   inline Identifier SiDetectorElement::identify() const
   {
     return m_id;
diff --git a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
index db4f5e6f6f6063281465b12fea988ffb8ae0dc84..e3c2b07fddfdc0305326f11a27def61644e1b6d0 100644
--- a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
+++ b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
@@ -45,6 +45,9 @@ TrackerDataDecoderTool::initialize()
 
   ATH_CHECK(detStore()->retrieve(m_sctID, "FaserSCT_ID"));
 
+  auto first_wafer = m_sctID->wafer_begin();
+  m_trb0Station = m_sctID->station(*first_wafer);
+
   m_sctContext = m_sctID->wafer_context();
   m_phiReversed.resize(m_sctID->wafer_hash_max(), false);
 
@@ -113,8 +116,8 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
     if ((frag->source_id()&0xFFFF0000) != DAQFormats::SourceIDs::TrackerSourceID) continue;
     ATH_MSG_DEBUG("Fragment:\n" << *frag);
     uint32_t trb = frag->source_id() & 0x0000FFFF;
-    // FIXME: will need to be updated for interface detector
-    int station = 1 + trb / TrackerDataFragment::PLANES_PER_STATION; 
+    // FIXME: 1 by default; needs to be 0 for IFT
+    int station = m_trb0Station + trb / TrackerDataFragment::PLANES_PER_STATION; 
     int plane = trb % TrackerDataFragment::PLANES_PER_STATION;
     
     // Exceptions are a no-no in Athena/Calypso, so catch any thrown by faser-common
@@ -140,7 +143,7 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
       // auto bcid = trackFrag.bc_id();
       ATH_MSG_DEBUG("Processing tracker data fragment for TRB " << trb);
 
-      for (const SCTEvent* sctEvent : trackFrag)
+      for (auto sctEvent : trackFrag)
       {
         if (sctEvent != nullptr)
         {
@@ -241,7 +244,7 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
         }
       }
     } 
-    catch (const TrackerDataException& exc)
+    catch (const TrackerData::TrackerDataException& exc)
     {
       ATH_MSG_ERROR("TrackerDataException: " << exc.what());
       continue;
@@ -301,7 +304,7 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
   //   // Do the conversion here using whatever it takes
   //   // try {
   //   //  rdo->setData( fragment );
-  //   //} catch ( TrackerDataException& e ) {
+  //   //} catch ( TrackerData::TrackerDataException& e ) {
   //   //  ATH_MSG_INFO("TrackerDataDecoderTool:\n"
   //   //	   <<e.what()
   //   //		   << "\nTracker data not filled!\n");
diff --git a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.h b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.h
index 401c0ec5cb4fa857433e565383aef49a4072617b..1d9507c2b6d8ca77467e2685d26ff9d459f83b9f 100644
--- a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.h
+++ b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.h
@@ -41,6 +41,8 @@ private:
                                                         "ModuleMap", 
                                                         {7, 2, 5, 0, 3, 6, 1, 4}, 
                                                         "Mapping from online to offline module numbers" };
+  
+  Gaudi::Property<uint32_t>               m_trb0Station { this, "Trb0StationNumber", 1, "Station number for TRB #0" };
 };
 
 #endif  /* TRACKERBYTESTREAM_TRACKERDATADECODERTOOL_H */
diff --git a/Tracker/TrackerEventCnv/TrackerEventTPCnv/src/TrackerPrepRawData/FaserSCT_ClusterCnv_p3.cxx b/Tracker/TrackerEventCnv/TrackerEventTPCnv/src/TrackerPrepRawData/FaserSCT_ClusterCnv_p3.cxx
index 038542e50285a76e1a41fb77156b465bd96b4bb9..22879d7c4979c1254d49d6fc296a58b2ff2cccd6 100644
--- a/Tracker/TrackerEventCnv/TrackerEventTPCnv/src/TrackerPrepRawData/FaserSCT_ClusterCnv_p3.cxx
+++ b/Tracker/TrackerEventCnv/TrackerEventTPCnv/src/TrackerPrepRawData/FaserSCT_ClusterCnv_p3.cxx
@@ -49,11 +49,11 @@ FaserSCT_ClusterCnv_p3::createSCT_Cluster (const Tracker::FaserSCT_Cluster_p3* p
   m_swCnv.persToTrans(&persObj->m_width, &sw, log);
 
   // Error matrix
-  auto cmat = std::make_unique<Amg::MatrixX>(2,2);
-  (*cmat)(0,0) = static_cast<double>(persObj->m_mat00);
-  (*cmat)(1,0) = static_cast<double>(persObj->m_mat01);
-  (*cmat)(0,1) = static_cast<double>(persObj->m_mat01);
-  (*cmat)(1,1) = static_cast<double>(persObj->m_mat11);
+  auto cmat = Amg::MatrixX(2,2);
+  (cmat)(0,0) = static_cast<double>(persObj->m_mat00);
+  (cmat)(1,0) = static_cast<double>(persObj->m_mat01);
+  (cmat)(0,1) = static_cast<double>(persObj->m_mat01);
+  (cmat)(1,1) = static_cast<double>(persObj->m_mat11);
 
   Tracker::FaserSCT_Cluster clus (clusId,
                            localPos,
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx
index ab88bf504ec140e847eaed5e39eee664943ad164..6e955b6a250599eaaf33d12baf0e55369803fd39 100644
--- a/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx
@@ -378,12 +378,13 @@ ClusterFitAlg::AddTrack(std::unique_ptr<TrackCollection>& tracks,
     s->push_back( GetState(fitResult, fitCovariance, nullptr, station) );
 
     for (const clusterInfo* cInfo : fitClusters)
-      {
-	s->push_back( GetState(fitResult, fitCovariance, cInfo->cluster, station) );
-      }
+    {
+	      s->push_back( GetState(fitResult, fitCovariance, cInfo->cluster, station) );
+    }
 
     // Create and store track
-    tracks->push_back(new Trk::Track(i, s , q));
+    std::unique_ptr<DataVector<const Trk::TrackStateOnSurface>> sink(s);
+    tracks->push_back(new Trk::Track(i, std::move(*sink) , q));
     return StatusCode::SUCCESS;
 }
 
@@ -422,7 +423,7 @@ ClusterFitAlg::GetState( const Eigen::Matrix< double, 4, 1 >& fitResult,
                                            fitCluster->localCovariance(), 
                                            m_idHelper->wafer_hash(fitCluster->detectorElement()->identify())};
     }
-    std::unique_ptr<Trk::TrackParameters> p { new Trk::CurvilinearParameters { pos, phi, theta, qoverp, covPar5.release() } };
+    std::unique_ptr<Trk::TrackParameters> p { new Trk::CurvilinearParameters { pos, phi, theta, qoverp, *(covPar5.release()) } };
     return new Trk::TrackStateOnSurface { rot, p.release() };
 }
 
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TestBeamClusterFitDbg.py b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TestBeamClusterFitDbg.py
new file mode 100755
index 0000000000000000000000000000000000000000..d2d23810bcf69c1899cf26e9cd096e3cc009fc1b
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TestBeamClusterFitDbg.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+"""Test various ComponentAccumulator Digitization configuration modules
+
+Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+"""
+import sys
+from AthenaCommon.Logging import log, logging
+from AthenaCommon.Constants import DEBUG, VERBOSE, INFO
+from AthenaCommon.Configurable import Configurable
+from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+from AthenaConfiguration.TestDefaults import defaultTestFiles
+from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
+from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg
+from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+#from Digitization.DigitizationParametersConfig import writeDigitizationMetadata
+from ScintRecAlgs.ScintRecAlgsConfig import WaveformReconstructionCfg
+from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg
+from TrackerClusterFit.TrackerClusterFitConfig import ClusterFitAlgCfg
+from TrackerSpacePointFormation.TrackerSpacePointFormationConfig import TrackerSpacePointFinderCfg
+#from MCTruthSimAlgs.RecoTimingConfig import MergeRecoTimingObjCfg
+
+# Set up logging and new style config
+log.setLevel(DEBUG)
+Configurable.configurableRun3Behavior = True
+
+# Configure
+ConfigFlags.Input.Files = [
+    'tb.raw',
+    #'/eos/project-f/faser-commissioning/TI12Data/Run-001332/Faser-Physics-001332-00000.raw',
+    #'/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00000.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00001.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00002.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00003.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00004.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00005.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00006.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00007.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00008.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00009.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00010.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00011.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00012.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00013.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00014.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00015.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00016.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00017.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00018.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00019.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00020.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00021.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00022.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00023.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00024.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00025.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00026.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00027.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00028.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00029.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00030.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00031.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00032.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00033.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00034.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00035.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00036.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00037.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00038.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00039.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00040.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00041.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00042.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00043.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00044.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00045.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00046.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00047.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00048.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00049.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00050.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00051.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00052.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00053.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00054.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00055.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00056.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00057.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00058.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00059.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00060.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00061.raw',
+    # '/eos/project-f/faser-commissioning/winter2020CosmicsStand/Run-000608/Faser-Physics-000608-00062.raw'
+]
+#ConfigFlags.Output.ESDFileName = "run608.ESD.pool.root"
+#ConfigFlags.Output.ESDFileName = "run001332.ESD.pool.root"
+ConfigFlags.Output.ESDFileName = "tb.ESD.pool.root"
+ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02"             # Always needed; must match FaserVersion
+ConfigFlags.IOVDb.DatabaseInstance = "OFLP200"               # Use MC conditions for now
+ConfigFlags.Input.ProjectName = "data21"                     # Needed to bypass autoconfig
+ConfigFlags.Input.isMC = False                               # Needed to bypass autoconfig
+ConfigFlags.GeoModel.FaserVersion     = "FASER-TB00"         # FASER geometry
+ConfigFlags.Common.isOnline = False
+ConfigFlags.GeoModel.Align.Dynamic = False
+ConfigFlags.Beam.NumberOfCollisions = 0.
+
+ConfigFlags.Detector.GeometryFaserSCT = True
+
+ConfigFlags.lock()
+
+# Core components
+acc = MainServicesCfg(ConfigFlags)
+#acc.merge(PoolReadCfg(ConfigFlags))
+acc.merge(PoolWriteCfg(ConfigFlags))
+
+#acc.merge(writeDigitizationMetadata(ConfigFlags))
+
+from FaserByteStreamCnvSvc.FaserByteStreamCnvSvcConfig import FaserByteStreamCnvSvcCfg
+acc.merge(FaserByteStreamCnvSvcCfg(ConfigFlags))
+acc.merge(WaveformReconstructionCfg(ConfigFlags))
+acc.merge(FaserSCT_ClusterizationCfg(ConfigFlags, DataObjectName="SCT_EDGEMODE_RDOs"))
+acc.merge(ClusterFitAlgCfg(ConfigFlags))
+acc.merge(TrackerSpacePointFinderCfg(ConfigFlags))
+#acc.getEventAlgo("Tracker::ClusterFitAlg").OutputLevel = DEBUG
+
+from AthenaConfiguration.ComponentFactory import CompFactory
+decoderTool = CompFactory.ScintWaveformDecoderTool(name = "ScintWaveformDecoderTool", 
+                                                   CaloChannels = [0, 1, 2, 3, 4, 5], 
+                                                   PreshowerChannels = [6, 7], 
+                                                   TriggerChannels = [8, 9],
+                                                   VetoChannels=[])
+acc.addPublicTool(decoderTool)
+
+# explicitly save RDO information
+from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+itemList = [ "xAOD::EventInfo#*",
+             "xAOD::EventAuxInfo#*",
+             "FaserSCT_RDO_Container#*",
+             "xAOD::FaserTriggerData#*",
+             "xAOD::FaserTriggerDataAux#*",
+             "ScintWaveformContainer#*",
+             "TrackCollection#*",
+             "xAOD::WaveformHitContainer#*",
+             "xAOD::WaveformHitAuxContainer#*",
+             "xAOD::WaveformClock#*",
+             "xAOD::WaveformClockAuxInfo#*",
+           ]
+acc.merge(OutputStreamCfg(ConfigFlags, "ESD", itemList))
+acc.getEventAlgo("OutputStreamESD").AcceptAlgs = ["Tracker::ClusterFitAlg"] 
+# Timing
+#acc.merge(MergeRecoTimingObjCfg(ConfigFlags))
+
+# Dump config
+# logging.getLogger('forcomps').setLevel(VERBOSE)
+# acc.foreach_component("*").OutputLevel = VERBOSE
+# acc.foreach_component("*ClassID*").OutputLevel = INFO
+# acc.getCondAlgo("FaserSCT_AlignCondAlg").OutputLevel = VERBOSE
+# acc.getCondAlgo("FaserSCT_DetectorElementCondAlg").OutputLevel = VERBOSE
+# acc.getService("StoreGateSvc").Dump = True
+# acc.getService("ConditionStore").Dump = True
+# acc.printConfig(withDetails=True)
+# ConfigFlags.dump()
+
+# Execute and finish
+sc = acc.run(maxEvents=1000)
+
+# Success should be 0
+sys.exit(not sc.isSuccess())
diff --git a/Tracker/TrackerRecAlgs/TrackerSeedFinder/src/TrackerSeedFinder.cxx b/Tracker/TrackerRecAlgs/TrackerSeedFinder/src/TrackerSeedFinder.cxx
index f8aef6daed4a6d9af723ccd7ef7c4fc573c28c6c..53ffec6a238914461c8780138a4f36704c36f49c 100755
--- a/Tracker/TrackerRecAlgs/TrackerSeedFinder/src/TrackerSeedFinder.cxx
+++ b/Tracker/TrackerRecAlgs/TrackerSeedFinder/src/TrackerSeedFinder.cxx
@@ -138,7 +138,7 @@ namespace Tracker
     CHECK(m_thistSvc->regHist("/TrackerSeedFinder/sp/sp_dx_intercept_after",m_hist_dx_intercept_after));
     CHECK(m_thistSvc->regHist("/TrackerSeedFinder/sp/sp_line",m_hist_line));
 
-    ATH_MSG_INFO( "TrackerSeedFinder::initialized for package version " << PACKAGE_VERSION );
+    ATH_MSG_INFO( "TrackerSeedFinder::initialized" );
     return StatusCode::SUCCESS;
   }
 
diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/StatisticsAlg.cxx b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/StatisticsAlg.cxx
index bf8b17d4fc16103c45cb0256bd3d7c644a3afc9e..5589297e584762c57a6450790c2a6d65a170a50e 100755
--- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/StatisticsAlg.cxx
+++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/StatisticsAlg.cxx
@@ -114,7 +114,7 @@ StatusCode StatisticsAlg::initialize()
   CHECK(m_thistSvc->regHist("/StatisticsAlg/sp/sp_x_y_plane6",m_hist_x_y_plane6));
   CHECK(m_thistSvc->regHist("/StatisticsAlg/sp/sp_x_y_plane7",m_hist_x_y_plane7));
   CHECK(m_thistSvc->regHist("/StatisticsAlg/sp/sp_x_y_plane8",m_hist_x_y_plane8));
-  ATH_MSG_INFO( "StatisticsAlg::initialized for package version " << PACKAGE_VERSION );
+  ATH_MSG_INFO( "StatisticsAlg::initialized" );
   return StatusCode::SUCCESS;
 }
 
diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
index 5c9940aeaa3cef28e0631d9d6a6480c54f473b57..62f63d8db08a27d9c04a347347954e07e4ee8968 100755
--- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
+++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
@@ -95,7 +95,7 @@ StatusCode TrackerSpacePointFinder::initialize()
 
   if (!m_monTool.empty()) CHECK(m_monTool.retrieve());
 
-  ATH_MSG_INFO( "Initialized for package version " << PACKAGE_VERSION );
+  ATH_MSG_INFO( "Initialized" );
   return StatusCode::SUCCESS;
 }
 
diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx
index 90228db2ef2cf233968ae6a481df1e64858b5214..1094424fb0cbd11f0a9618aedbd2813bfca4ded8 100755
--- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx
+++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx
@@ -180,7 +180,7 @@ namespace Tracker
     CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/InitReso_py",m_hist_InitReso_py));
     CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/InitReso_pz",m_hist_InitReso_pz));
 	//!!!!!!!!!!!!!!!!!!!!
-    ATH_MSG_INFO( "TruthTrackSeeds::initialized for package version " << PACKAGE_VERSION );
+    ATH_MSG_INFO( "TruthTrackSeeds::initialized" );
     return StatusCode::SUCCESS;
   }
 
diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h
index 1e91539955a063585de8b823a30a5d28081acee4..bb09dfc937b252c2e4af9e4d8dd8e5e49e24358d 100755
--- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h
+++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h
@@ -69,7 +69,7 @@ class TruthSeededTrackFinder:public AthReentrantAlgorithm {
 
     SG::ReadCondHandleKey<TrackerDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"};
 
-    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "GEN_EVENT" };
+    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "BeamTruthEvent" };
     SG::ReadHandleKey<FaserSiHitCollection> m_faserSiHitKey { this, "FaserSiHitCollection", "SCT_Hits" };
     SG::ReadHandleKey<FaserSCT_RDO_Container> m_faserRdoKey { this, "FaserSCT_RDO_Container", "SCT_RDOs"};
     SG::ReadHandleKey<TrackerSimDataCollection> m_sctMap {this, "TrackerSimDataCollection", "SCT_SDO_Map"};
diff --git a/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/FaserSCT_Cluster.h b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/FaserSCT_Cluster.h
index 109d093c41099fee1a164c9dc38580fb9e2d292d..71412ba7aaa7bb44c863b1fb75ff92b50233bd13 100755
--- a/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/FaserSCT_Cluster.h
+++ b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/FaserSCT_Cluster.h
@@ -44,18 +44,16 @@ class FaserSCT_Cluster : public TrackerCluster {
                 const std::vector<Identifier>& rdoList,
                 const FaserSiWidth& width,
                 const TrackerDD::SiDetectorElement* detEl,
-                const Amg::MatrixX* locErrMat
+                const Amg::MatrixX& locErrMat
               );
 
   // For use by tp converter.
-  FaserSCT_Cluster( 
-                const Identifier& RDOId,
-                const Amg::Vector2D& locpos, 
-                std::vector<Identifier>&& rdoList,
-                const FaserSiWidth& width,
-                const TrackerDD::SiDetectorElement* detEl,
-                std::unique_ptr<const Amg::MatrixX> locErrMat
-              );
+  FaserSCT_Cluster(const Identifier& RDOId,
+              const Amg::Vector2D& locpos,
+              std::vector<Identifier>&& rdoList,
+              const FaserSiWidth& width,
+              const TrackerDD::SiDetectorElement* detEl,
+              Amg::MatrixX&& locErrMat);
 
     /** dump information about the PRD object. */
     virtual MsgStream&    dump( MsgStream&    stream) const;
diff --git a/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.h b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.h
index 75f3a09f89b70743cd00a5fe620d27ef99866607..79e3bf3031f8c08f34aca8dfd946b15219c850e1 100755
--- a/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.h
+++ b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.h
@@ -19,7 +19,6 @@
 // Base class
 #include "TrkPrepRawData/PrepRawData.h"
 
-#include "CxxUtils/CachedUniquePtr.h"
 #include "Identifier/Identifier.h"
 #include "TrackerPrepRawData/FaserSiWidth.h"
 #include "TrackerReadoutGeometry/SiDetectorElement.h" // cant be forward declared
@@ -51,34 +50,63 @@ namespace Tracker
 		public:
 		
 		/** Public, Copy, operator=, constructor*/
-		TrackerCluster();
-		TrackerCluster(const TrackerCluster &);
-		TrackerCluster(TrackerCluster &&);
-		TrackerCluster &operator=(const TrackerCluster &);
-		TrackerCluster &operator=(TrackerCluster &&);
+		TrackerCluster() = default;
+		TrackerCluster(const TrackerCluster &) = default;
+		TrackerCluster(TrackerCluster &&) = default;
+		TrackerCluster &operator=(const TrackerCluster &) = default;
+		TrackerCluster &operator=(TrackerCluster &&) = default;
 		
-			/** Only constructor for TrackerCluster.
-				Last datamember might not be always filled and will be 0 by default.
-				The others including SiDetectorElement have to be given!
-			*/
-
-			TrackerCluster( 
-					const Identifier& RDOId,
-					const Amg::Vector2D& locpos, 
+		/**
+		 * Constructor with parameters using ref or omitting  Amg::MatrixX.
+		 * If omitted we have any empty one.
+		 */
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
 					const std::vector<Identifier>& rdoList,
 					const FaserSiWidth& width,
 					const TrackerDD::SiDetectorElement* detEl,
-					const Amg::MatrixX* locErrMat = 0
-					);
+					const Amg::MatrixX& locErrMat);
 
-			TrackerCluster( 
-					const Identifier& RDOId,
-					const Amg::Vector2D& locpos, 
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
+					const std::vector<Identifier>& rdoList,
+					const FaserSiWidth& width,
+					const TrackerDD::SiDetectorElement* detEl);
+
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
+					const Amg::Vector3D& globpos,
+					const std::vector<Identifier>& rdoList,
+					const FaserSiWidth& width,
+					const TrackerDD::SiDetectorElement* detEl,
+					const Amg::MatrixX& locErrMat);
+
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
+					const Amg::Vector3D& globpos,
+					const std::vector<Identifier>& rdoList,
+					const FaserSiWidth& width,
+					const TrackerDD::SiDetectorElement* detEl);
+
+		/**
+		 * Constructor with parameters using r-value reference of Amg::MatrixX.
+		 * All parameters have to be given!
+		 */
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
 					std::vector<Identifier>&& rdoList,
 					const FaserSiWidth& width,
 					const TrackerDD::SiDetectorElement* detEl,
-					std::unique_ptr<const Amg::MatrixX> locErrMat
-					);
+					Amg::MatrixX&& locErrMat);
+
+		TrackerCluster(const Identifier& RDOId,
+					const Amg::Vector2D& locpos,
+					const Amg::Vector3D& globpos,
+					std::vector<Identifier>&& rdoList,
+					const FaserSiWidth& width,
+					const TrackerDD::SiDetectorElement* detEl,
+					Amg::MatrixX&& locErrMat);
+
 
 			// Destructor:
 		virtual ~TrackerCluster();
@@ -95,20 +123,25 @@ namespace Tracker
 		
 		/** return the detector element corresponding to this PRD
 		The pointer will be zero if the det el is not defined (i.e. it was not passed in by the ctor)*/
-		virtual const TrackerDD::SiDetectorElement* detectorElement() const override;
+		virtual const TrackerDD::SiDetectorElement* detectorElement() const override final;
 
 		/** Interface method checking the type*/
-		virtual bool type(Trk::PrepRawDataType::Type type) const final;
+		virtual bool type(Trk::PrepRawDataType type) const override final;
 
 		/** dump information about the SiCluster*/
 		virtual MsgStream&    dump( MsgStream&    stream) const override;
 		/** dump information about the SiCluster*/
 		virtual std::ostream& dump( std::ostream& stream) const override;
 
+		/// Set the m_detEl and calculate globalPostion
+		//used by TPCnv converters
+		void setDetectorElement(const TrackerDD::SiDetectorElement* detEl);
+
 		private:
+	    Amg::Vector3D m_globalPosition = Amg::Vector3D::Zero();
+  		/// col, row, and width in mm
 		FaserSiWidth m_width; //col, row, and width in mm
-		CxxUtils::CachedUniquePtr<const Amg::Vector3D> m_globalPosition;
-		const TrackerDD::SiDetectorElement* m_detEl;
+		const TrackerDD::SiDetectorElement* m_detEl = nullptr;
 
 		// Identifier m_clusId; 
 		// /**see derived classes for definition of meaning of LocalPosition*/
@@ -128,32 +161,6 @@ namespace Tracker
 	MsgStream&    operator << (MsgStream& stream,    const TrackerCluster& prd);
 	std::ostream& operator << (std::ostream& stream, const TrackerCluster& prd);
 
-	///////////////////////////////////////////////////////////////////
-	// Inline methods:
-	///////////////////////////////////////////////////////////////////
-
-	// return width:
-	inline const FaserSiWidth&  TrackerCluster::width() const
-	{
-		return m_width;
-	}
-	// return globalPosition:
-	inline const Amg::Vector3D& TrackerCluster::globalPosition() const
-	{
-	if (not m_globalPosition) {
-		m_globalPosition.set(std::unique_ptr<const Amg::Vector3D>(m_detEl->surface(identify()).localToGlobal(localPosition())));
-	}
-	return *m_globalPosition;
-	}
-
-	inline const TrackerDD::SiDetectorElement* TrackerCluster::detectorElement() const
-	{
-		return m_detEl;
-	}
-
-	inline bool TrackerCluster::type(Trk::PrepRawDataType::Type type) const
-	{
-  		return type == Trk::PrepRawDataType::SiCluster;
-	}
 }
+#include "TrackerCluster.icc"
 #endif // TRACKERPREPRAWDATA_TRACKERCLUSTER_H
diff --git a/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.icc b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.icc
new file mode 100644
index 0000000000000000000000000000000000000000..cf9a189464cfdb759ec9eb1441c84317c1750eac
--- /dev/null
+++ b/Tracker/TrackerRecEvent/TrackerPrepRawData/TrackerPrepRawData/TrackerCluster.icc
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+namespace Tracker
+{
+	// return width:
+	inline const FaserSiWidth&  TrackerCluster::width() const
+	{
+		return m_width;
+	}
+	// return globalPosition:
+	inline const Amg::Vector3D& TrackerCluster::globalPosition() const
+	{
+	return m_globalPosition;
+	}
+
+	inline const TrackerDD::SiDetectorElement* TrackerCluster::detectorElement() const
+	{
+		return m_detEl;
+	}
+
+	inline bool TrackerCluster::type(Trk::PrepRawDataType type) const
+	{
+  		return type == Trk::PrepRawDataType::SiCluster;
+	}
+    inline void
+    TrackerCluster::setDetectorElement(const TrackerDD::SiDetectorElement* detEl)
+    {
+        m_detEl = detEl;
+        if (m_detEl) {
+            m_globalPosition =
+            m_detEl->surface(identify()).localToGlobal(localPosition());
+        }
+    }
+}
\ No newline at end of file
diff --git a/Tracker/TrackerRecEvent/TrackerPrepRawData/src/FaserSCT_Cluster.cxx b/Tracker/TrackerRecEvent/TrackerPrepRawData/src/FaserSCT_Cluster.cxx
index 7c4b9f474e9166376c117be1b83d1386c69e4b60..8675b0129c7b9c5f7b68eb158f7e51dddd107faf 100755
--- a/Tracker/TrackerRecEvent/TrackerPrepRawData/src/FaserSCT_Cluster.cxx
+++ b/Tracker/TrackerRecEvent/TrackerPrepRawData/src/FaserSCT_Cluster.cxx
@@ -21,25 +21,27 @@ FaserSCT_Cluster::FaserSCT_Cluster(
     const std::vector<Identifier>& rdoList,
     const FaserSiWidth& width,
     const TrackerDD::SiDetectorElement* detEl,
-    const Amg::MatrixX* locErrMat
+    const Amg::MatrixX& locErrMat
     ) : TrackerCluster(RDOId, locpos, rdoList, width, detEl, locErrMat) 
 {
   m_hitsInThirdTimeBin=0;
 }
 
-FaserSCT_Cluster::FaserSCT_Cluster( 
-    const Identifier& RDOId,
-    const Amg::Vector2D& locpos, 
-    std::vector<Identifier>&& rdoList,
-    const FaserSiWidth& width,
-    const TrackerDD::SiDetectorElement* detEl,
-    std::unique_ptr<const Amg::MatrixX> locErrMat
-    ) : TrackerCluster(RDOId, locpos,
-      std::move(rdoList), width, detEl,
-      std::move(locErrMat)),
-    m_hitsInThirdTimeBin(0)
-{
-}
+FaserSCT_Cluster::FaserSCT_Cluster(const Identifier& RDOId,
+                         const Amg::Vector2D& locpos,
+                         std::vector<Identifier>&& rdoList,
+                         const FaserSiWidth& width,
+                         const TrackerDD::SiDetectorElement* detEl,
+                         Amg::MatrixX&& locErrMat)
+  : TrackerCluster(RDOId,
+              locpos,
+              std::move(rdoList),
+              width,
+              detEl,
+              std::move(locErrMat))
+  , m_hitsInThirdTimeBin(0)
+{}
+
 
 // Default constructor:
 FaserSCT_Cluster::FaserSCT_Cluster():TrackerCluster()
diff --git a/Tracker/TrackerRecEvent/TrackerPrepRawData/src/TrackerCluster.cxx b/Tracker/TrackerRecEvent/TrackerPrepRawData/src/TrackerCluster.cxx
index a590bf8d1bf31edec0023b52847096eecbca52ce..6a9d9adf9a7f64e91caa7504e83bb6f5a6243c48 100755
--- a/Tracker/TrackerRecEvent/TrackerPrepRawData/src/TrackerCluster.cxx
+++ b/Tracker/TrackerRecEvent/TrackerPrepRawData/src/TrackerCluster.cxx
@@ -16,96 +16,105 @@
 
 namespace Tracker {
 // Constructor for EF:
-TrackerCluster::TrackerCluster(
-    const Identifier &RDOId,
-    const Amg::Vector2D& locpos, 
-    const std::vector<Identifier>& rdoList, 
-    const FaserSiWidth& width,
-    const TrackerDD::SiDetectorElement* detEl,
-    const Amg::MatrixX* locErrMat
-    ) :
-    PrepRawData(RDOId, locpos, rdoList, locErrMat), //call base class constructor    
-  m_width(width),
-  m_globalPosition{},
-  m_detEl(detEl) {}
-
-  TrackerCluster::TrackerCluster(
-      const Identifier &RDOId,
-      const Amg::Vector2D& locpos, 
-      std::vector<Identifier>&& rdoList, 
-      const FaserSiWidth& width,
-      const TrackerDD::SiDetectorElement* detEl,
-      std::unique_ptr<const Amg::MatrixX> locErrMat
-      ) :
-      PrepRawData(RDOId, locpos,
-                  std::move(rdoList),
-                  std::move(locErrMat)), //call base class constructor
-    m_width(width),
-    m_globalPosition{},
-    m_detEl(detEl) {}
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    const std::vector<Identifier>& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl,
+                    const Amg::MatrixX& locErrMat)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, rdoList, locErrMat)
+  , m_width(width)
+  , m_detEl(detEl)
+{
+  if (m_detEl) {
+    m_globalPosition =
+      m_detEl->surface(identify()).localToGlobal(localPosition());
+  }
+}
 
-    // Destructor:
-TrackerCluster::~TrackerCluster()
+// Constructor for EF:
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    const std::vector<Identifier>& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, rdoList, {})
+  , m_width(width)
+  , m_detEl(detEl)
 {
-  // do not delete m_detEl since owned by DetectorStore
+  if (m_detEl) {
+    m_globalPosition =
+      m_detEl->surface(identify()).localToGlobal(localPosition());
+  }
 }
 
-// Default constructor:
-TrackerCluster::TrackerCluster():
-  m_globalPosition{},
-  m_detEl(0)
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    const Amg::Vector3D& globpos,
+                    const std::vector<Identifier>& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl,
+                    const Amg::MatrixX& locErrMat)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, rdoList, locErrMat)
+  , m_globalPosition(globpos)
+  , m_width(width)
+  , m_detEl(detEl)
 {}
 
-//copy constructor:
-TrackerCluster::TrackerCluster(const TrackerCluster& RIO):
-  PrepRawData( RIO ),
-  m_width( RIO.m_width ),
-  m_globalPosition{},
-  m_detEl( RIO.m_detEl )
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    const Amg::Vector3D& globpos,
+                    const std::vector<Identifier>& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, rdoList,{})
+  , m_globalPosition(globpos)
+  , m_width(width)
+  , m_detEl(detEl)
+{}
 
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    std::vector<Identifier>&& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl,
+                    Amg::MatrixX&& locErrMat)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, std::move(rdoList), std::move(locErrMat))
+  , m_width(width)
+  , m_detEl(detEl)
 {
-  // copy only if it exists
-  if (RIO.m_globalPosition) {
-    m_globalPosition.set(std::make_unique<Amg::Vector3D>(*RIO.m_globalPosition));
+  if (m_detEl) {
+    m_globalPosition =
+      m_detEl->surface(identify()).localToGlobal(localPosition());
   }
 }
 
-//move constructor:
-TrackerCluster::TrackerCluster(TrackerCluster&& RIO):
-  PrepRawData( std::move(RIO) ),
-  m_width( std::move(RIO.m_width) ),
-  m_globalPosition( std::move(RIO.m_globalPosition) ),
-  m_detEl( RIO.m_detEl )
+TrackerCluster::TrackerCluster(const Identifier& RDOId,
+                    const Amg::Vector2D& locpos,
+                    const Amg::Vector3D& globpos,
+                    std::vector<Identifier>&& rdoList,
+                    const FaserSiWidth& width,
+                    const TrackerDD::SiDetectorElement* detEl,
+                    Amg::MatrixX&& locErrMat)
+  : // call base class constructor
+  PrepRawData(RDOId, locpos, std::move(rdoList), std::move(locErrMat))
+  , m_globalPosition(globpos)
+  , m_width(width)
+  , m_detEl(detEl)
+{}
+
 
+    // Destructor:
+TrackerCluster::~TrackerCluster()
 {
+  // do not delete m_detEl since owned by DetectorStore
 }
 
-//assignment operator
-TrackerCluster& TrackerCluster::operator=(const TrackerCluster& RIO){
-  if (&RIO !=this) {
-    Trk::PrepRawData::operator= (RIO);
-    m_width = RIO.m_width;
-    if (RIO.m_globalPosition) {
-      m_globalPosition.set(std::make_unique<Amg::Vector3D>(*RIO.m_globalPosition));
-    } else if (m_globalPosition) {
-      m_globalPosition.release().reset();
-    }
-    m_detEl =  RIO.m_detEl ;
-  }
-  return *this;
-} 
-
-//move operator
-TrackerCluster& TrackerCluster::operator=(TrackerCluster&& RIO){
-  if (&RIO !=this) {
-    Trk::PrepRawData::operator= (std::move(RIO));
-    m_width = RIO.m_width;
-    m_globalPosition = std::move(RIO.m_globalPosition);
-    m_detEl =  RIO.m_detEl ;
-  }
-  return *this;
-} 
-
 MsgStream& TrackerCluster::dump( MsgStream&    stream) const
 {
   stream << "TrackerCluster object"<<std::endl;
diff --git a/Tracker/TrackerRecEvent/TrackerRIO_OnTrack/src/FaserSCT_ClusterOnTrack.cxx b/Tracker/TrackerRecEvent/TrackerRIO_OnTrack/src/FaserSCT_ClusterOnTrack.cxx
index 7964343741c0dadc9818b4792a8d17e56fe04d33..5567e5cf9ab507ce8e7f076917055adef219e8e8 100644
--- a/Tracker/TrackerRecEvent/TrackerRIO_OnTrack/src/FaserSCT_ClusterOnTrack.cxx
+++ b/Tracker/TrackerRecEvent/TrackerRIO_OnTrack/src/FaserSCT_ClusterOnTrack.cxx
@@ -29,7 +29,7 @@ Tracker::FaserSCT_ClusterOnTrack::FaserSCT_ClusterOnTrack(const Tracker::FaserSC
 
   // Set global position
   Amg::Vector2D lpos(localParameters().get(Trk::locX), m_positionAlongStrip);
-  m_globalPosition = detectorElement()->surface(identify()).localToGlobalPos(lpos);
+  m_globalPosition = detectorElement()->surface(identify()).localToGlobal(lpos);
 }
 
 // Constructor with parameters
@@ -45,8 +45,9 @@ Tracker::FaserSCT_ClusterOnTrack::FaserSCT_ClusterOnTrack(const Tracker::FaserSC
   m_rio.setElement(RIO);
 
   //constructing local position provided a global one  
-  std::unique_ptr<const Amg::Vector2D>
-    lpos{detectorElement()->surface( identify() ).positionOnSurface(globalPosition)};
+  std::optional<Amg::Vector2D> lpos{
+    detectorElement()->surface(identify()).positionOnSurface(globalPosition)
+  };
 					
   //storing the position along the strip if available
   m_positionAlongStrip = (lpos) ? (*lpos)[Trk::locY]:0.; 
@@ -94,7 +95,7 @@ void Tracker::FaserSCT_ClusterOnTrack::setValues(const Trk::TrkDetElementBase* d
       Amg::Vector2D lpos(localParameters().get(Trk::locX),
                          m_positionAlongStrip);
       m_globalPosition =
-        detectorElement()->surface(identify()).localToGlobalPos(lpos);
+        detectorElement()->surface(identify()).localToGlobal(lpos);
     }
 }
 
diff --git a/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/FaserSCT_SpacePoint.h b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/FaserSCT_SpacePoint.h
index 8a6b7aceb2b233388699f0b7d11f7e874599de44..28c5cc2663b61019656504e176ff273779bb4820 100755
--- a/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/FaserSCT_SpacePoint.h
+++ b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/FaserSCT_SpacePoint.h
@@ -46,23 +46,9 @@ namespace Tracker
        * on the surface associated to the FIRST member of the PRD-pair clusList.
        */
       //@{
-      FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList, 
-		     const Amg::Vector3D* position, 
-		     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) ;
-      
-      FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList, 
-		     const Amg::Vector3D* position,
-		     const Amg::MatrixX* loccov,//assumes ownership of loccov
-		     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) ;
-      
       FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList, 
 		     const Amg::Vector3D& position, 
-		     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) ;
-      
-      FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList, 
-		     const Amg::Vector3D& position,
-		     const Amg::MatrixX& loccov,//assumes ownership of loccov
-		     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) ;
+		     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>& clusList) ;
       //@}
 
       /** Copy Constructor */
@@ -91,7 +77,7 @@ namespace Tracker
       /** common method used in constructors. */
       void setup(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
 		 const Amg::Vector3D& position,
-		 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList);
+		 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>&clusList);
     };
   
   ///////////////////////////////////////////////////////////////////
diff --git a/Tracker/TrackerRecEvent/TrackerSpacePoint/src/FaserSCT_SpacePoint.cxx b/Tracker/TrackerRecEvent/TrackerSpacePoint/src/FaserSCT_SpacePoint.cxx
index ca62c4ab52f916db61d3c8676495b0b1990cb2e0..68554d010e724fbe59f5c07cbfbb2c02b64d97f9 100755
--- a/Tracker/TrackerRecEvent/TrackerSpacePoint/src/FaserSCT_SpacePoint.cxx
+++ b/Tracker/TrackerRecEvent/TrackerSpacePoint/src/FaserSCT_SpacePoint.cxx
@@ -20,37 +20,9 @@ namespace Tracker
 
   //-------------------------------------------------------------
 
-  FaserSCT_SpacePoint::FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
-				 const Amg::Vector3D* position,
-				 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) 
-    :
-    Trk::SpacePoint()
-  {
-    setup(elementIdList,*position,clusList);
-    setupLocalCovarianceSCT();
-    setupGlobalFromLocalCovariance();
-    delete position;
-  }
-
-  //-------------------------------------------------------------
-
-  FaserSCT_SpacePoint::FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
-				 const Amg::Vector3D* position,
-				 const Amg::MatrixX* loccov,
-				 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) 
-    :
-    Trk::SpacePoint()
-  {
-    Trk::MeasurementBase::m_localCovariance = *loccov;
-    setup(elementIdList,*position,clusList);
-    setupGlobalFromLocalCovariance();
-    delete loccov;
-    delete position;
-  }
-
   FaserSCT_SpacePoint::FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
 				 const Amg::Vector3D& position,
-				 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) 
+				 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>& clusList) 
     :
     Trk::SpacePoint()
   {
@@ -59,38 +31,23 @@ namespace Tracker
     setupGlobalFromLocalCovariance();
   }
 
-  //-------------------------------------------------------------
-
-  FaserSCT_SpacePoint::FaserSCT_SpacePoint(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
-				 const Amg::Vector3D& position,
-				 const Amg::MatrixX& loccov,
-				 const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList) 
-    :
-    Trk::SpacePoint()
-  {
-    Trk::MeasurementBase::m_localCovariance = loccov;
-    setup(elementIdList,position,clusList);
-    setupGlobalFromLocalCovariance();
-  }
-
-  
   //-------------------------------------------------------------
   
   void FaserSCT_SpacePoint::setup(const std::pair<IdentifierHash, IdentifierHash>& elementIdList,  		    
 			     const Amg::Vector3D& position,
-			     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>* clusList)
+			     const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>& clusList)
   {
-    m_clusList.first = clusList->first;
-    m_clusList.second = clusList->second;
+    m_clusList = clusList;
     m_position = position ;
     m_elemIdList.first = elementIdList.first ;
     m_elemIdList.second = elementIdList.second ;
-    assert( (clusList->first!=0) && (clusList->second!=0) );
+    assert( (clusList.first!=0) && (clusList.second!=0) );
     assert(clusList->first->detectorElement()) ;
-    const Amg::Vector2D* locpos = (clusList->first->detectorElement()->surface().globalToLocal(position)) ;  
+   std::optional<Amg::Vector2D> locpos{
+      clusList.first->detectorElement()->surface().globalToLocal(position)
+    };
     assert(locpos);
     Trk::MeasurementBase::m_localParams = Trk::LocalParameters(*locpos ) ;
-    delete locpos ;
 
   }
 
diff --git a/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/FaserSCT_ClusteringTool.cxx b/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/FaserSCT_ClusteringTool.cxx
index dece2904daf8acc0ac4ac9e2d71c681713df8353..2963d98dfdb966c92bf9541052bfe9d0e256b654 100644
--- a/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/FaserSCT_ClusteringTool.cxx
+++ b/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/FaserSCT_ClusteringTool.cxx
@@ -435,7 +435,7 @@ namespace Tracker
       const Tracker::FaserSiWidth siWidth(Amg::Vector2D(nStrips, 1), Amg::Vector2D(clusterDim.width, stripLength));
       
       Tracker::FaserSCT_Cluster* cluster = (m_clusterMaker) ? (m_clusterMaker->sctCluster(clusterId, localPos, stripGroup, siWidth, element, m_errorStrategy))
-        : (new Tracker::FaserSCT_Cluster(clusterId, localPos, stripGroup, siWidth, element, 0));
+        : (new Tracker::FaserSCT_Cluster(clusterId, localPos, stripGroup, siWidth, element, {}));
       cluster->setHashAndIndex(clusterCollection->identifyHash(), clusterCollection->size());
       if (tbinIter != tbinGroups.end()) {
         cluster->setHitsInThirdTimeBin(*tbinIter);
@@ -666,8 +666,8 @@ namespace Tracker
         V[3]           = sn2*v0+cs2*v1;
       }
 
-      Amg::MatrixX* errorMatrix(new Amg::MatrixX(2,2));
-      *errorMatrix<<V[0],V[1],V[2],V[3];
+      auto errorMatrix = Amg::MatrixX(2,2);
+      errorMatrix<<V[0],V[1],V[2],V[3];
 
       Tracker::FaserSiWidth siWidth{Amg::Vector2D(dnStrips,1.), Amg::Vector2D(width,stripL)};
 
diff --git a/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/TrackerClusterMakerTool.cxx b/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/TrackerClusterMakerTool.cxx
index 2313a1584a00f63827cbfd9183c5fbf9acd29feb..9b853f514ed2b561219528707a9d15d14d2600b8 100644
--- a/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/TrackerClusterMakerTool.cxx
+++ b/Tracker/TrackerRecTools/FaserSiClusterizationTool/src/TrackerClusterMakerTool.cxx
@@ -92,8 +92,8 @@ Tracker::FaserSCT_Cluster* TrackerClusterMakerTool::sctCluster(
 	const Amg::Vector2D& colRow = width.colRow();// made ref to avoid 
 	// unnecessary copy EJWM
 
-	Amg::MatrixX* errorMatrix = new Amg::MatrixX(2,2);
-	errorMatrix->setIdentity();
+	auto errorMatrix = Amg::MatrixX(2,2);
+	errorMatrix.setIdentity();
 
 	// switches are more readable **OPT**
 	// actually they're slower as well (so I'm told) so perhaps
@@ -101,37 +101,37 @@ Tracker::FaserSCT_Cluster* TrackerClusterMakerTool::sctCluster(
     
 	switch (errorStrategy){
 	case 0:
-	  errorMatrix->fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
-	  errorMatrix->fillSymmetric(1,1,square(width.z())*ONE_TWELFTH);
+	  errorMatrix.fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
+	  errorMatrix.fillSymmetric(1,1,square(width.z())*ONE_TWELFTH);
 	  break;
 	case 1:
 	  // mat(1,1) = pow(width.phiR()/colRow.x(),2)/12;
 	  // single strip - resolution close to pitch/sqrt(12)
 	  // two-strip hits: better resolution, approx. 40% lower
 	  if(colRow.x() == 1){
-	    errorMatrix->fillSymmetric(0,0,square(1.05*width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(1.05*width.phiR())*ONE_TWELFTH);
 	  }
 	  else if(colRow.x() == 2){
-	    errorMatrix->fillSymmetric(0,0,square(0.27*width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(0.27*width.phiR())*ONE_TWELFTH);
 	  }
 	  else{
-	    errorMatrix->fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
 	  }
-	  errorMatrix->fillSymmetric(1,1,square(width.z()/colRow.y())*ONE_TWELFTH);
+	  errorMatrix.fillSymmetric(1,1,square(width.z()/colRow.y())*ONE_TWELFTH);
 	  break;
 	default:
 	  // single strip - resolution close to pitch/sqrt(12)
 	  // two-strip hits: better resolution, approx. 40% lower
 	  if(colRow.x() == 1){
-	    errorMatrix->fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
 	  }
 	  else if(colRow.x() == 2){
-	    errorMatrix->fillSymmetric(0,0,square(0.27*width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(0.27*width.phiR())*ONE_TWELFTH);
 	  }
 	  else{
-	    errorMatrix->fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
+	    errorMatrix.fillSymmetric(0,0,square(width.phiR())*ONE_TWELFTH);
 	  }
-	  errorMatrix->fillSymmetric(1,1,square(width.z()/colRow.y())*ONE_TWELFTH);
+	  errorMatrix.fillSymmetric(1,1,square(width.z()/colRow.y())*ONE_TWELFTH);
 	  break;
 	}
 
diff --git a/Tracker/TrackerRecTools/FaserSiSpacePointTool/src/TrackerSpacePointMakerTool.cxx b/Tracker/TrackerRecTools/FaserSiSpacePointTool/src/TrackerSpacePointMakerTool.cxx
index a26a3c3460a48b131de633dbfe3b3e09f177f39d..d04d721c7a748433d02087fc9ac981e46eeb205d 100644
--- a/Tracker/TrackerRecTools/FaserSiSpacePointTool/src/TrackerSpacePointMakerTool.cxx
+++ b/Tracker/TrackerRecTools/FaserSiSpacePointTool/src/TrackerSpacePointMakerTool.cxx
@@ -183,10 +183,9 @@ Trk::SpacePoint* TrackerSpacePointMakerTool::makeSCT_SpacePoint(const Tracker::T
   }
   if (ok) {
     ATH_MSG_VERBOSE( "SpacePoint generated at: ( " <<  point.x() << " , " << point.y() << " , " << point.z() << " )   " );       
-    const std::pair<IdentifierHash,IdentifierHash> elementIdList( element1->identifyHash() , element2->identifyHash() ); 
-    const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>*
-      clusList = new std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>(&cluster1, &cluster2);
-    return new FaserSCT_SpacePoint(elementIdList, new Amg::Vector3D(point), clusList);
+    std::pair<IdentifierHash,IdentifierHash> elementIdList( element1->identifyHash() , element2->identifyHash() ); 
+    std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*> clusList {&cluster1, &cluster2 };
+    return new FaserSCT_SpacePoint(elementIdList, point, clusList);
   }
 
   return nullptr;
@@ -531,9 +530,8 @@ void TrackerSpacePointMakerTool::makeSCT_SpacePoints(const double stripLengthGap
 
       ATH_MSG_VERBOSE("SpacePoint generated at: ( " <<  point.x() << " , " << point.y() << " , " << point.z() << " )   ");
       const std::pair<IdentifierHash, IdentifierHash> elementIdList(ent->m_element0->identifyHash(), ent->m_element1->identifyHash());
-      const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>*
-	clusList = new std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>((*I).cluster(), (*J).cluster());
-      ent->m_tmpSpacePoints.push_back(new FaserSCT_SpacePoint(elementIdList, new Amg::Vector3D(point), clusList));
+      const std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*> clusList {(*I).cluster(), (*J).cluster()};
+      ent->m_tmpSpacePoints.push_back(new FaserSCT_SpacePoint(elementIdList, point, clusList));
     }
   }
 }
diff --git a/Tracking/Acts/ActsInterop/ActsInterop/Logger.h b/Tracking/Acts/ActsInterop/ActsInterop/Logger.h
index cf0b4a4f9af8ab364220d680882d3a01d9e9bfb2..e76b7d0e3136b4b0e1f9d08da56f196090d65d8e 100644
--- a/Tracking/Acts/ActsInterop/ActsInterop/Logger.h
+++ b/Tracking/Acts/ActsInterop/ActsInterop/Logger.h
@@ -20,7 +20,7 @@ public:
   ActsAthenaPrintPolicy(std::shared_ptr<MsgStream> msg) : m_msg(msg) {}
 
   void
-  flush(const Acts::Logging::Level& lvl, const std::ostringstream& input);
+  flush(const Acts::Logging::Level& lvl, const std::string& input);
 
 private:
   std::shared_ptr<MsgStream> m_msg;
diff --git a/Tracking/Acts/ActsInterop/src/Logger.cxx b/Tracking/Acts/ActsInterop/src/Logger.cxx
index e40f9e47943baee1e5a33f7b34d535008661285e..aec48aee54814c60cbb69cb0bfd1759dcb3689cb 100644
--- a/Tracking/Acts/ActsInterop/src/Logger.cxx
+++ b/Tracking/Acts/ActsInterop/src/Logger.cxx
@@ -29,10 +29,10 @@ namespace {
 }
 
 void
-ActsAthenaPrintPolicy::flush(const Acts::Logging::Level& lvl, const std::ostringstream& input)
+ActsAthenaPrintPolicy::flush(const Acts::Logging::Level& lvl, const std::string& input)
 {
   MSG::Level athLevel = athLevelVector[lvl];
-  (*m_msg) << athLevel << input.str() << endmsg;
+  (*m_msg) << athLevel << input << endmsg;
 }
   
 
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h
index 908c57444d5796b620ccd2f6f9c4dacf13045c6d..091cc8c2734df9a7eb787bf702f6773d805ed1bb 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h
@@ -12,55 +12,76 @@
 #include "Acts/Definitions/Algebra.hpp"
 #include "Acts/Definitions/Units.hpp"
 #include "Acts/MagneticField/MagneticFieldContext.hpp"
+#include "Acts/MagneticField/MagneticFieldProvider.hpp"
 
-class FASERMagneticFieldWrapper
-{
-
+class FASERMagneticFieldWrapper final : public Acts::MagneticFieldProvider {
 
   public:
 
     struct Cache {
 
-      Cache(std::reference_wrapper<const Acts::MagneticFieldContext> mctx) {
-        std::any_cast<const FaserFieldCacheCondObj*>(mctx)->getInitializedCache(fieldCache);
+      Cache(const Acts::MagneticFieldContext mctx) {
+        const auto* faserField = mctx.get<const FaserFieldCacheCondObj*>();
+        faserField->getInitializedCache(fieldCache);
       }
 
       MagField::FaserFieldCache fieldCache;
     };
 
-
     FASERMagneticFieldWrapper() = default;
 
-    Acts::Vector3
-    getField(const Acts::Vector3& pos, Cache& cache) const
-      {
-	double pos0[]{pos.x(), pos.y(), pos.z()};
-	double bfield0[]{0., 0., 0.};
-	cache.fieldCache.getField(pos0, bfield0);
-	Acts::Vector3 bfield(bfield0[0], bfield0[1], bfield0[2]);
 
-	bfield *= m_bFieldUnit; // kT -> T;
+    MagneticFieldProvider::Cache 
+    makeCache(const Acts::MagneticFieldContext& mctx) const override {
+      return Acts::MagneticFieldProvider::Cache::make<Cache>(mctx);
+    }
 
-	return bfield;
-      }
+    Acts::Result<Acts::Vector3>
+    getField(const Acts::Vector3& position, Acts::MagneticFieldProvider::Cache& gcache) const override {
+      Cache& cache = gcache.get<Cache>();
+      double posXYZ[3];
+      posXYZ[0] = position.x();
+      posXYZ[1] = position.y();
+      posXYZ[2] = position.z();
+      double BField[3];
 
-    Acts::Vector3
-    getFieldGradient(const Acts::Vector3& position, Acts::ActsMatrix<3, 3>& gradient, Cache& cache) const
-      {
-	double position0[]{position.x(), position.y(), position.z()};
-	double bfield0[]{0., 0., 0.};
-	double grad[9];
-	cache.fieldCache.getField(position0, bfield0, grad);
-	Acts::Vector3 bfield(bfield0[0], bfield0[1], bfield0[2]);
-        Acts::ActsMatrix<3, 3> tempGrad;
-	tempGrad << grad[0], grad[1], grad[2], grad[3], grad[4], grad[5], grad[6], grad[7], grad[8]; 
-	gradient = tempGrad;
-
-	bfield *= m_bFieldUnit; // kT -> T;
-	gradient *= m_bFieldUnit;
-
-	return bfield;
-      }
+      cache.fieldCache.getField(posXYZ, BField);
+
+      // Magnetic field
+      Acts::Vector3 bfield{BField[0],BField[1],BField[2]};
+
+      bfield *= m_bFieldUnit; // kT -> T;
+
+      return Acts::Result<Acts::Vector3>::success(bfield);
+    }
+
+    Acts::Result<Acts::Vector3>
+    getFieldGradient(const Acts::Vector3& position,
+                    Acts::ActsMatrix<3, 3>& gradient,
+                    Acts::MagneticFieldProvider::Cache& gcache) const override
+    {
+      Cache& cache = gcache.get<Cache>();
+      double posXYZ[3];
+      posXYZ[0] = position.x();
+      posXYZ[1] = position.y();
+      posXYZ[2] = position.z();
+      double BField[3];
+      double grad[9];
+
+      cache.fieldCache.getField(posXYZ, BField, grad);
+
+      // Magnetic field
+      Acts::Vector3 bfield{BField[0], BField[1],BField[2]};
+      Acts::ActsMatrix<3, 3> tempGrad;
+      tempGrad << grad[0], grad[1], grad[2], grad[3], grad[4], grad[5], grad[6], grad[7], grad[8]; 
+      gradient = tempGrad;
+
+
+      bfield *= m_bFieldUnit; // kT -> T;
+      gradient *= m_bFieldUnit;
+
+      return Acts::Result<Acts::Vector3>::success(bfield);
+    }
 
 
   private:
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h
index ee765dd235b4d139d336edabb21a1605169fc483..2f1d2e8aa2affce99cc187eca841aa085204021a 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h
@@ -11,6 +11,8 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "Gaudi/Property.h"
 #include "GaudiKernel/EventContext.h"
+#include "TrkEventPrimitives/ParticleHypothesis.h"
+#include "TrkEventPrimitives/PdgToParticleHypothesis.h"
 
 // Need to include this early; otherwise, we run into errors with
 // ReferenceWrapperAnyCompat in clang builds due the is_constructable
@@ -27,7 +29,6 @@
 #include "FaserActsGeometry/FASERMagneticFieldWrapper.h"
 
 // ACTS
-#include "Acts/Propagator/EigenStepper.hpp"
 #include "Acts/Propagator/detail/SteppingLogger.hpp"
 #include "Acts/Propagator/Navigator.hpp"
 #include "Acts/Propagator/StandardAborters.hpp"
@@ -111,11 +112,8 @@ public:
   getMagneticFieldContext(const EventContext& ctx) const override;
 
 
-
 private:
-
   std::unique_ptr<ActsExtrapolationDetail::VariantPropagator> m_varProp;
-
   std::unique_ptr<const Acts::Logger> m_logger{nullptr};
 
   // Read handle for conditions object to get the field cache
@@ -127,16 +125,14 @@ private:
   Gaudi::Property<std::vector<double>> m_constantFieldVector{this, "ConstantFieldVector", {0, 0, 0}};
 
   Gaudi::Property<double> m_ptLoopers{this, "PtLoopers", 300, "PT loop protection threshold. Will be converted to Acts MeV unit"};
-
   Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 10, "Max step size in Acts m unit"};
+  Gaudi::Property<double> m_maxStep{this, "MaxSteps", 4000, "Max number of steps"};
 
   // Material inteaction option
   Gaudi::Property<bool> m_interactionMultiScatering{this, "InteractionMultiScatering", false, "Whether to consider multiple scattering in the interactor"};
   Gaudi::Property<bool> m_interactionEloss{this, "InteractionEloss", false, "Whether to consider energy loss in the interactor"};
   Gaudi::Property<bool> m_interactionRecord{this, "InteractionRecord", false, "Whether to record all material interactions"};
-  
 };
 
 
-
 #endif
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h
index 6165e29203d93be6f4160ed54560d72a145faa3b..e88db406b4483580fe726c1976421fdb0d6a0beb 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h
@@ -23,9 +23,9 @@ struct FaserActsGeometryContext {
   const FaserActsAlignmentStore* alignmentStore{nullptr};
 
   Acts::GeometryContext
-  any() const
+  context() const
   {
-    return Acts::GeometryContext {this};
+    return Acts::GeometryContext(this);
   }
 };
 
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
index efd0afbdfb2b07f6c46332048d7ed5580121dca3..fbb91545d925fb04ea4e6ed03f9e0f9426881d46 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h
@@ -32,8 +32,11 @@ namespace TrackerDD {
 namespace Acts {
 class Surface;
 class LayerCreator;
+class GeometryIdentifier;
 }
 
+class Identifier;
+
 /// @class FaserActsLayerBuilder
 class FaserActsLayerBuilder
 {
@@ -50,6 +53,7 @@ public:
     const TrackerDD::SCT_DetectorManager*   mng;
     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;
     int station;
     int plane;
   };
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsMaterialJsonWriterTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsMaterialJsonWriterTool.h
index e3959e307137f5b49633a48f753b57d9d308e554..c29a42c5c2ccf21db1c4c86a4c8fb4defd82a2b9 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsMaterialJsonWriterTool.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsMaterialJsonWriterTool.h
@@ -15,9 +15,7 @@
 #include "FaserActsGeometryInterfaces/IFaserActsMaterialJsonWriterTool.h"
 
 // ACTS
-#include "Acts/Geometry/TrackingGeometry.hpp"
-#include "Acts/Plugins/Json/JsonGeometryConverter.hpp"
-#include "FaserActsGeometry/FaserActsJsonGeometryConverter.h"
+#include "Acts/Plugins/Json/MaterialMapJsonConverter.hpp"
 
 namespace Acts {
   class TrackingGeometry;
@@ -36,7 +34,7 @@ public:
 
   virtual
   void
-  write(const Acts::FaserActsJsonGeometryConverter::DetectorMaterialMaps& detMaterial) const override;
+  write(const Acts::MaterialMapJsonConverter::DetectorMaterialMaps& detMaterial) const override;
 
   virtual
   void
@@ -45,7 +43,7 @@ public:
 
 private:
 
-Acts::FaserActsJsonGeometryConverter::Config m_cfg;
+Acts::MaterialMapJsonConverter::Config m_cfg;
 
   Gaudi::Property<std::string> m_filePath{this, "OutputFile", "material-maps.json", "Output json file for the Material Map"};
   Gaudi::Property<bool> m_processSensitives{this, "processSensitives", true, "Write sensitive surface to the json file"};
@@ -54,7 +52,7 @@ Acts::FaserActsJsonGeometryConverter::Config m_cfg;
   Gaudi::Property<bool> m_processBoundaries{this, "processBoundaries", true, "Write boundary surface to the json file"};
   Gaudi::Property<bool> m_processVolumes{this, "processVolumes", true, "Write volume to the json file"};
   Gaudi::Property<bool> m_processDenseVolumes{this, "processDenseVolumes", false, "Write dense volume to the json file"};
-  Gaudi::Property<bool> m_processnonmaterial{this, "processnonmaterial", false, "Add proto material to all surfaces and volumes"};
+  Gaudi::Property<bool> m_processNonMaterial{this, "processnonmaterial", false, "Add proto material to all surfaces and volumes"};
 };
 
 #endif
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h
index 65d61f8b54563b098432351c78a0804536e0a467..65e21a130cc984d2533cf7e122629b18eb2cc4ba 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h
@@ -57,9 +57,15 @@ public:
   void
   populateAlignmentStore(FaserActsAlignmentStore *store) const override;
 
+  void
+  populateIdentifierMap(IdentifierMap *map) const override;
+
   const FaserActsAlignmentStore*
   getNominalAlignmentStore() const override;
 
+  std::shared_ptr<IdentifierMap>
+  getIdentifierMap() const override;
+
 private:
   std::shared_ptr<const Acts::ITrackingVolumeBuilder>
   makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager);
@@ -69,6 +75,7 @@ private:
 
   std::shared_ptr<std::vector<std::shared_ptr<const FaserActsDetectorElement>>> m_elementStore;
   std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
+  std::shared_ptr<std::map<Identifier, Acts::GeometryIdentifier>> m_identifierMap;
 
   std::unique_ptr<const FaserActsAlignmentStore> m_nominalAlignmentStore{nullptr};
 
diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h
index 7a32e70e994b29b5f2583d5104ad3b2cdd186c70..5150efec954ae285105056af92505d60eb864c88 100644
--- a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h
+++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h
@@ -48,6 +48,10 @@ public:
   FaserActsGeometryContext
   getNominalGeometryContext() const override;
 
+  virtual
+  const std::shared_ptr<std::map<Identifier, Acts::GeometryIdentifier>>
+  getIdentifierMap() const override;
+
 private:
   ServiceHandle<IFaserActsTrackingGeometrySvc> m_trackingGeometrySvc;
 
diff --git a/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py b/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py
index 84bfe224aad7f984ffa7ca1f712a2db5525e7427..a1c3c9f1f239befaaa4c10542706cacfdd18e4dd 100644
--- a/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py
+++ b/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py
@@ -5,7 +5,7 @@ FaserActsWriteTrackingGeometry,FaserActsTrackingGeometrySvc,FaserActsTrackingGeo
 
 
 
-def ActsTrackingGeometrySvcCfg(configFlags, name = "ActsTrackingGeometrySvc" ) :
+def ActsTrackingGeometrySvcCfg(configFlags, name = "ActsTrackingGeometrySvc" , **kwargs) :
   result = ComponentAccumulator()
   actsTrackingGeometrySvc = FaserActsTrackingGeometrySvc(name = "FaserActsTrackingGeometrySvc", **kwargs)
 
diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py
index 574f7f82273d076fd6b236488d9a443a17890b68..8720049d249df0064baddab4a91edea401ea2ae1 100644
--- a/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py
+++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py
@@ -3,7 +3,7 @@ Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 """
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
+# from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
 from FaserSCT_GeoModel.FaserSCT_GeoModelConfig import FaserSCT_GeometryCfg
 from MagFieldServices.MagFieldServicesConfig import MagneticFieldSvcCfg
 
diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
index 23270e4e9eeec0f6ddac95645749d3de1bf714c0..feb3b04d2f978297bfcbea4229d0ff35862d5aee 100644
--- a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
+++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py
@@ -1,3 +1,5 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FASER collaborations
+
 ###############################################################
 #
 # Map material from a Geantino scan onto the surfaces and 
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx
index b911380d6e579a90fd22f7da11a59df282a92ce1..2a790d184273f5aee8c69389500e6d1f94a9ab2d 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx
@@ -91,7 +91,7 @@ const Acts::Transform3&
 FaserActsDetectorElement::transform(const Acts::GeometryContext& anygctx) const
 {
   // any cast to known context type
-  const FaserActsGeometryContext* gctx = std::any_cast<const FaserActsGeometryContext*>(anygctx);
+  const FaserActsGeometryContext* gctx = anygctx.get<const FaserActsGeometryContext*>();
 
   // This is needed for initial geometry construction. At that point, we don't have a
   // consistent view of the geometry yet, and thus we can't populate an alignment store
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx
index 0fb4c07c6295d9c173cae6c5aff1fabf340d2c43..0eca15c20fcd100e2711573588e9c68a3fecf094 100755
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx
@@ -111,7 +111,7 @@ StatusCode FaserActsExtrapolationAlg::execute(const EventContext& ctx) const
       // Perigee, no alignment -> default geo context
       FaserActsGeometryContext gctx
         = m_extrapolationTool->trackingGeometryTool()->getNominalGeometryContext();
-      auto anygctx = gctx.any();
+      auto anygctx = gctx.context();
       Acts::BoundTrackParameters startParameters(std::move(surface), std::move(pars), std::move(cov));
       auto output = m_extrapolationTool->propagationSteps(ctx, startParameters);
       m_propStepWriterSvc->write(output.first);
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx
index e2235d1cd9d9d8ebac86dfa423e45ed350674bbf..e84a69c6a3fe54ee30ecb046a0606a1e264da5e5 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx
@@ -33,8 +33,8 @@
 
 namespace ActsExtrapolationDetail {
   using VariantPropagatorBase = boost::variant<
-    Acts::Propagator<Acts::EigenStepper<FASERMagneticFieldWrapper>, Acts::Navigator>,
-    Acts::Propagator<Acts::EigenStepper<Acts::ConstantBField>, Acts::Navigator>
+    Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>,
+    Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>
   >;
 
   class VariantPropagator : public VariantPropagatorBase
@@ -77,27 +77,33 @@ FaserActsExtrapolationTool::initialize()
   std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry
     = m_trackingGeometryTool->trackingGeometry();
 
-  Acts::Navigator navigator(trackingGeometry);
+  Acts::Navigator navigator( Acts::Navigator::Config{ trackingGeometry } );
 
   if (m_fieldMode == "FASER") {
     ATH_MSG_INFO("Using FASER magnetic field service");
-    using BField_t = FASERMagneticFieldWrapper;
     ATH_CHECK( m_fieldCondObjInputKey.initialize() );
-    BField_t bField;
-    auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
+    auto bField = std::make_shared<FASERMagneticFieldWrapper>();
+    auto stepper = Acts::EigenStepper<>(std::move(bField));
     auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
                                                                       std::move(navigator));
     m_varProp = std::make_unique<VariantPropagator>(propagator);
   }
   else if (m_fieldMode == "Constant") {
-    std::vector<double> constantFieldVector = m_constantFieldVector;
-    double Bx = constantFieldVector.at(0);
-    double By = constantFieldVector.at(1);
-    double Bz = constantFieldVector.at(2);
-    ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << Bx << ", " << By << ", " << Bz << ")");
-    using BField_t = Acts::ConstantBField;
-    BField_t bField(Bx, By, Bz);
-    auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
+    if (m_constantFieldVector.value().size() != 3)
+    {
+      ATH_MSG_ERROR("Incorrect field vector size. Using empty field.");
+      return StatusCode::FAILURE; 
+    }
+    
+    Acts::Vector3 constantFieldVector = Acts::Vector3(m_constantFieldVector[0], 
+                                                      m_constantFieldVector[1], 
+                                                      m_constantFieldVector[2]);
+
+    ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << m_constantFieldVector[0] << ", " 
+                                                                   << m_constantFieldVector[1] << ", " 
+                                                                   << m_constantFieldVector[2] << ")");
+    auto bField = std::make_shared<Acts::ConstantBField>(constantFieldVector);
+    auto stepper = Acts::EigenStepper<>(std::move(bField));
     auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
                                                                       std::move(navigator));
     m_varProp = std::make_unique<VariantPropagator>(propagator);
@@ -122,7 +128,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
       //= m_trackingGeometryTool->getGeometryContext(ctx);
       = m_trackingGeometryTool->getNominalGeometryContext();
 
-    auto anygctx = gctx.any();
+    auto anygctx = gctx.context();
 
     // Action list and abort list
     using ActionList = Acts::ActionList<SteppingLogger, Acts::MaterialInteractor>;
@@ -138,6 +144,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
           < m_ptLoopers * 1_MeV);
 
     options.maxStepSize = m_maxStepSize * 1_m;
+    options.maxSteps = m_maxStep;
     options.direction = navDir;
 
     auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
@@ -150,7 +157,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
     auto res = boost::apply_visitor([&](const auto& propagator) -> ResultType {
         auto result = propagator.propagate(startParameters, options);
         if (!result.ok()) {
-        return result.error();
+          return result.error();
         }
         auto& propRes = *result;
 
@@ -160,17 +167,19 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
         output.second = std::move(materialResult);
         // try to force return value optimization, not sure this is necessary
         return std::move(output);
-        }, *m_varProp);
+    }, *m_varProp);
 
     if (!res.ok()) {
-      ATH_MSG_ERROR("Got error during propagation:" << res.error() << " " << res.error().message()
-          << ". Returning empty step vector.");
+      ATH_MSG_ERROR("Got error during propagation: "
+  		  << res.error() << " " << res.error().message()
+                    << ". Returning empty step vector.");
       return {};
     }
+    output = std::move(*res);
 
     ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps");
-    if (output.first.size() == 0) {
-       ATH_MSG_WARNING("ZERO steps returned by stepper, that is not typically a good sign");
+    if(output.first.size() == 0) {
+      ATH_MSG_WARNING("ZERO steps returned by stepper, that is not typically a good sign");
     }
 
     ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " end");
@@ -193,7 +202,7 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx,
       //= m_trackingGeometryTool->getGeometryContext(ctx);
       = m_trackingGeometryTool->getNominalGeometryContext();
 
-  auto anygctx = gctx.any();
+  auto anygctx = gctx.context();
 
   // Action list and abort list
   using ActionList = Acts::ActionList<Acts::MaterialInteractor>;
@@ -207,6 +216,7 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx,
     = (Acts::VectorHelpers::perp(startParameters.momentum())
        < m_ptLoopers * 1_MeV);
   options.maxStepSize = m_maxStepSize * 1_m;
+  options.maxSteps = m_maxStep;
   options.direction = navDir;
 
   auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
@@ -242,7 +252,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
     //= m_trackingGeometryTool->getGeometryContext(ctx);
     = m_trackingGeometryTool->getGeometryContext(ctx );
 
-  auto anygctx = gctx.any();
+  auto anygctx = gctx.context();
 
   // Action list and abort list
   using ActionList = Acts::ActionList<SteppingLogger, Acts::MaterialInteractor>;
@@ -256,6 +266,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
     = (Acts::VectorHelpers::perp(startParameters.momentum())
        < m_ptLoopers * 1_MeV);
   options.maxStepSize = m_maxStepSize * 1_m;
+  options.maxSteps = m_maxStep;
   options.direction = navDir;
 
   auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
@@ -284,6 +295,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx,
                   << ". Returning empty step vector.");
     return {};
   }
+  output = std::move(*res);
 
   ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps");
   if (output.first.size() == 0) {
@@ -307,10 +319,9 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx,
 
   Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx);
   const FaserActsGeometryContext& gctx
-    //= m_trackingGeometryTool->getGeometryContext(ctx);
     = m_trackingGeometryTool->getGeometryContext(ctx);
 
-  auto anygctx = gctx.any();
+  auto anygctx = gctx.context();
 
   // Action list and abort list
   using ActionList = Acts::ActionList<Acts::MaterialInteractor>;
@@ -324,6 +335,7 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx,
     = (Acts::VectorHelpers::perp(startParameters.momentum())
        < m_ptLoopers * 1_MeV);
   options.maxStepSize = m_maxStepSize * 1_m;
+  options.maxSteps = m_maxStep;
   options.direction = navDir;
 
   auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
@@ -355,4 +367,3 @@ Acts::MagneticFieldContext FaserActsExtrapolationTool::getMagneticFieldContext(c
 
   return Acts::MagneticFieldContext(fieldCondObj);
 }
-
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialJsonWriterTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialJsonWriterTool.cxx
index fe033f8eba019c77761c8edb6f8e89501f31bd89..feeb6f7a79425845048565d73f47f044dad45ccf 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialJsonWriterTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsMaterialJsonWriterTool.cxx
@@ -34,16 +34,16 @@ FaserActsMaterialJsonWriterTool::initialize()
   m_cfg.processBoundaries = m_processBoundaries;
   m_cfg.processVolumes = m_processVolumes;
   m_cfg.processDenseVolumes = m_processDenseVolumes;
-  m_cfg.processnonmaterial = m_processnonmaterial;
+  m_cfg.processNonMaterial = m_processNonMaterial;
   
   return StatusCode::SUCCESS;
 }
 
 void
-FaserActsMaterialJsonWriterTool::write(const Acts::FaserActsJsonGeometryConverter::DetectorMaterialMaps& detMaterial) const
+FaserActsMaterialJsonWriterTool::write(const Acts::MaterialMapJsonConverter::DetectorMaterialMaps& detMaterial) const
 {
   // Evoke the converter
-  Acts::FaserActsJsonGeometryConverter jmConverter(m_cfg);
+  Acts::MaterialMapJsonConverter jmConverter(m_cfg);
   auto jout = jmConverter.materialMapsToJson(detMaterial);
   // And write the file
   std::ofstream ofj(m_filePath);
@@ -54,7 +54,7 @@ void
 FaserActsMaterialJsonWriterTool::write(const Acts::TrackingGeometry& tGeometry) const
 {
   // Evoke the converter
-  Acts::FaserActsJsonGeometryConverter jmConverter(m_cfg);
+  Acts::MaterialMapJsonConverter jmConverter(m_cfg);
   auto jout = jmConverter.trackingGeometryToJson(tGeometry);
   // And write the file
   std::ofstream ofj(m_filePath);
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx
index 61a84e4c5d2617225261c85fdbb0a3195340c21b..35da191fc41ab08138a469e2abce9756d5886c53 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx
@@ -82,5 +82,5 @@ FaserActsObjWriterTool::write(const FaserActsGeometryContext& gctx, const Acts::
   auto tgObjWriter
     = std::make_shared<Acts::ObjTrackingGeometryWriter>(tgObjWriterConfig);
 
-  tgObjWriter->write(gctx.any(), tg);
+  tgObjWriter->write(gctx.context(), tg);
 }
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsSurfaceMappingTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsSurfaceMappingTool.cxx
index e2ff5c10694dab663d896a1440e4355606edcaf2..ac647013bd177fb74ec5eaa1d26ae74935b3cfb1 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsSurfaceMappingTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsSurfaceMappingTool.cxx
@@ -38,7 +38,7 @@ FaserActsSurfaceMappingTool::initialize()
 
   m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
 
-  Acts::Navigator navigator(m_trackingGeometry);
+  Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometry } );
   // Make stepper and propagator
   SlStepper stepper;
   StraightLinePropagator propagator = StraightLinePropagator(std::move(stepper), std::move(navigator));
@@ -51,7 +51,7 @@ FaserActsSurfaceMappingTool::initialize()
       std::move(propagator),
       makeActsAthenaLogger(this, "SurfaceMaterialMapper"));
 
-  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().any();
+  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().context();
 
   ATH_MSG_INFO("ACTS Surface Mapper successfully initialized");
   return StatusCode::SUCCESS;
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
index 744700aa995f525914b84d257e7be4ba936f3f80..f32a02990835e96bc0d56bfe887604bf3667a4eb 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx
@@ -41,6 +41,7 @@ FaserActsTrackingGeometrySvc::FaserActsTrackingGeometrySvc(const std::string& na
    m_detStore("StoreGateSvc/DetectorStore", name)
 {
   m_elementStore = std::make_shared<std::vector<std::shared_ptr<const FaserActsDetectorElement>>>();
+  m_identifierMap = std::make_shared<std::map<Identifier, Acts::GeometryIdentifier>>();
 }
 
 StatusCode
@@ -97,12 +98,13 @@ FaserActsTrackingGeometrySvc::initialize()
   constructionContext.construction = true;
 
   m_trackingGeometry = trackingGeometryBuilder
-    ->trackingGeometry(constructionContext.any());
+    ->trackingGeometry(constructionContext.context());
 
   ATH_MSG_VERBOSE("Building nominal alignment store");
   FaserActsAlignmentStore* nominalAlignmentStore = new FaserActsAlignmentStore();
 
   populateAlignmentStore(nominalAlignmentStore);
+  populateIdentifierMap(m_identifierMap.get());
 
   // manage ownership
   m_nominalAlignmentStore = std::unique_ptr<const FaserActsAlignmentStore>(nominalAlignmentStore);
@@ -130,6 +132,7 @@ FaserActsTrackingGeometrySvc::makeVolumeBuilder(const Acts::GeometryContext& gct
   cfg.subdetector = FaserActsDetectorElement::Subdetector::SCT;
   cfg.mng = static_cast<const TrackerDD::SCT_DetectorManager*>(manager);
   cfg.elementStore = m_elementStore;
+  cfg.identifierMap = m_identifierMap;
   gmLayerBuilder = std::make_shared<FaserActsLayerBuilder>(cfg,
       makeActsAthenaLogger(this, "GMLayBldr", "ActsTGSvc"));
   auto cvbConfig = gmLayerBuilder->buildVolume(gctx);
@@ -155,3 +158,20 @@ FaserActsTrackingGeometrySvc::getNominalAlignmentStore() const
 {
   return m_nominalAlignmentStore.get();
 }
+
+void
+FaserActsTrackingGeometrySvc::populateIdentifierMap(IdentifierMap *map) const
+{
+  m_trackingGeometry->visitSurfaces(
+    [map](const Acts::Surface* srf) {
+    const Acts::DetectorElementBase* detElem = srf->associatedDetectorElement();
+    const auto* faserDetElem = dynamic_cast<const FaserActsDetectorElement*>(detElem);
+    map->insert(std::make_pair(faserDetElem->identify(), srf->geometryId()));
+  });
+}
+
+std::shared_ptr<IdentifierMap>
+FaserActsTrackingGeometrySvc::getIdentifierMap() const
+{
+  return m_identifierMap;
+}
\ No newline at end of file
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx
index ae50ea2756e3c705f6eb9f1942849c6c9ec5b331..aae04e8fae2a775d9dc9a6bb5536ffb5f820c39f 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx
@@ -62,3 +62,9 @@ FaserActsTrackingGeometryTool::getNominalGeometryContext() const
 
   return gctx;
 }
+
+const std::shared_ptr<std::map<Identifier, Acts::GeometryIdentifier>>
+FaserActsTrackingGeometryTool::getIdentifierMap() const
+{
+  return m_trackingGeometrySvc->getIdentifierMap();
+}
diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsVolumeMappingTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsVolumeMappingTool.cxx
index 234a7f2be7741ed7e41f56cc43338702418cff35..796ad74e4878cd72e6eae62cfea7333b94bcdc11 100644
--- a/Tracking/Acts/FaserActsGeometry/src/FaserActsVolumeMappingTool.cxx
+++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsVolumeMappingTool.cxx
@@ -40,7 +40,7 @@ FaserActsVolumeMappingTool::initialize()
 
   m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
 
-  Acts::Navigator navigator(m_trackingGeometry);
+  Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometry } );
   // Make stepper and propagator
   SlStepper stepper;
   StraightLinePropagator propagator = StraightLinePropagator(std::move(stepper), std::move(navigator));
@@ -53,7 +53,7 @@ FaserActsVolumeMappingTool::initialize()
       std::move(propagator),
       makeActsAthenaLogger(this, "VolumeMaterialMapper"));
 
-  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().any();
+  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().context();
 
   ATH_MSG_INFO("ACTS Surface Mapper successfully initialized");
   return StatusCode::SUCCESS;
diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
index 899134b324e2975bb78e33361b6ea974a5aa68f7..61f1e62490ee5d50a9f4d20f0e23a4d5dc55646a 100644
--- a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
+++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py
@@ -44,7 +44,7 @@ acc.merge(FaserActsWriteTrackingGeometryCfg(ConfigFlags))
 #oStream = acc.getEventAlgo("OutputStreamRDO")
 #oStream.ItemList += ["EventInfo#*",
 #                     "McEventCollection#TruthEvent",
-#                     "McEventCollection#GEN_EVENT"
+#                     "McEventCollection#BeamTruthEvent"
 #                    ]
                     
 # Timing
diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h
index 89ec77aa9598f49ac0660379862921ba7ca48901..05b16956611affd2a69a1301693db36a9be3aa12 100644
--- a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h
+++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h
@@ -9,6 +9,7 @@
 #include "GaudiKernel/IInterface.h"
 #include "GaudiKernel/IAlgTool.h"
 #include "GaudiKernel/EventContext.h"
+#include "TrkEventPrimitives/ParticleHypothesis.h"
 
 #include "Acts/Propagator/detail/SteppingLogger.hpp"
 #include "Acts/EventData/TrackParameters.hpp"
@@ -72,7 +73,6 @@ class IFaserActsExtrapolationTool : virtual public IAlgTool {
 
   virtual 
   Acts::MagneticFieldContext getMagneticFieldContext(const EventContext& ctx) const = 0;
-
 };
 
 #endif
diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsMaterialJsonWriterTool.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsMaterialJsonWriterTool.h
index 7fe13c593aaee7207a8da54909ee1e21eba09564..940cad83644a311bf30b5977c87a37ce17200678 100644
--- a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsMaterialJsonWriterTool.h
+++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsMaterialJsonWriterTool.h
@@ -9,9 +9,7 @@
 #include "GaudiKernel/IInterface.h"
 #include "GaudiKernel/IAlgTool.h"
 
-#include "Acts/Geometry/TrackingGeometry.hpp"
-#include "Acts/Plugins/Json/JsonGeometryConverter.hpp"
-#include "FaserActsGeometry/FaserActsJsonGeometryConverter.h"
+#include "Acts/Plugins/Json/MaterialMapJsonConverter.hpp"
 
 namespace Acts {
   class TrackingGeometry;
@@ -24,7 +22,7 @@ public:
 
   virtual
   void
-  write(const Acts::FaserActsJsonGeometryConverter::DetectorMaterialMaps& detMaterial) const = 0;
+  write(const Acts::MaterialMapJsonConverter::DetectorMaterialMaps& detMaterial) const = 0;
 
   virtual
   void
diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h
index 1c7798352d663f87435d00f12337cee263b0cb4e..ecae533f37d46551bcefd0a8e6592b538370b568 100644
--- a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h
+++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h
@@ -9,12 +9,16 @@
 
 class EventContext;
 class FaserActsAlignmentStore;
+class Identifier;
 
 namespace Acts {
   class TrackingGeometry;
+  class GeometryIdentifier;
 }
 
 
+using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>;
+
 class IFaserActsTrackingGeometrySvc : virtual public IInterface {
   public:
 
@@ -32,6 +36,13 @@ class IFaserActsTrackingGeometrySvc : virtual public IInterface {
   const FaserActsAlignmentStore*
   getNominalAlignmentStore() const = 0;
 
+  virtual
+  void
+  populateIdentifierMap(IdentifierMap *map) const = 0;
+
+  virtual
+  std::shared_ptr<IdentifierMap>
+  getIdentifierMap() const = 0;
 };
 
 #endif
diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h
index 823279417d1ef87d8ca00287a36214aabf7d623c..1e88ecbe5cf561abda0cc9217f283976dea89ef6 100644
--- a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h
+++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h
@@ -11,8 +11,11 @@
 #include "GaudiKernel/EventContext.h"
 #include "FaserActsGeometry/FaserActsGeometryContext.h"
 
+class Identifier;
+
 namespace Acts {
   class TrackingGeometry;
+  class GeometryIdentifier;
 }
 
 
@@ -32,6 +35,10 @@ class IFaserActsTrackingGeometryTool : virtual public IAlgTool {
   virtual
   FaserActsGeometryContext
   getNominalGeometryContext() const = 0;
+
+  virtual
+  const std::shared_ptr<std::map<Identifier, Acts::GeometryIdentifier>>
+  getIdentifierMap() const = 0;
 };
 
 #endif
diff --git a/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt.disabled b/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt
similarity index 100%
rename from Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt.disabled
rename to Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d147019b115c7d7f6818bb06c7aef1c65c6bfec
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h
@@ -0,0 +1,46 @@
+#ifndef COMBINATORIALKALMANFILTERALG_H
+#define COMBINATORIALKALMANFILTERALG_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "TrkSpacePoint/SpacePointContainer.h"
+#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h"
+#include "FaserActsKalmanFilter/TruthBasedInitialParameterTool.h"
+#include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp"
+#include "Acts/TrackFinding/MeasurementSelector.hpp"
+#include "FaserActsKalmanFilter/Measurement.h"
+#include "MagFieldConditions/FaserFieldCacheCondObj.h"
+#include "FaserActsKalmanFilter/TrajectoryWriterTool.h"
+
+
+class CombinatorialKalmanFilterAlg : public AthReentrantAlgorithm { 
+ public:
+  CombinatorialKalmanFilterAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~CombinatorialKalmanFilterAlg() = default;
+
+  StatusCode initialize() override;
+  StatusCode execute(const EventContext& ctx) const override;
+  StatusCode finalize() override;
+
+  using TrackFinderOptions =
+      Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor, MeasurementCalibrator, Acts::MeasurementSelector>;
+  using TrackFinderResult = std::vector<
+      Acts::Result<Acts::CombinatorialKalmanFilterResult<IndexSourceLink>>>;
+  using TrackFinderFunction = std::function<TrackFinderResult(
+      const IndexSourceLinkContainer&, const std::vector<Acts::CurvilinearTrackParameters>&,
+      const TrackFinderOptions&)>;
+
+  static TrackFinderFunction makeTrackFinderFunction(
+      std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry);
+
+  Acts::MagneticFieldContext getMagneticFieldContext(const EventContext& ctx) const;
+
+
+ private:
+  ToolHandle<IFaserActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "FaserActsTrackingGeometryTool"};
+  ToolHandle<TruthBasedInitialParameterTool> m_initialParameterTool{this, "InitialParameterTool", "TruthBasedInitialParameterTool"};
+  ToolHandle<TrajectoryWriterTool> m_trajectoryWriterTool{this, "OutputTool", "TrajectoryWriterTool"};
+  SG::ReadCondHandleKey<FaserFieldCacheCondObj> m_fieldCondObjInputKey {this, "FaserFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+  SG::ReadHandleKey<SpacePointContainer> m_SpacePointContainerKey{this, "SpacePointsSCTName", "SCT_SpacePointContainer", "SCT space point container"};
+};
+
+#endif // COMBINATORIALKALMANFILTERALG_H
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsGeometryContainers.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsGeometryContainers.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f049c7d6429d5d40c6656bb43240950ea19261a
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsGeometryContainers.h
@@ -0,0 +1,120 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2017-2020 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "Acts/Geometry/GeometryIdentifier.hpp"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+
+namespace detail {
+// extract the geometry identifier from a variety of types
+    struct GeometryIdGetter {
+        // explicit geometry identifier are just forwarded
+        constexpr Acts::GeometryIdentifier operator()(
+                Acts::GeometryIdentifier geometryId) const {
+            return geometryId;
+        }
+        // encoded geometry ids are converted back to geometry identifiers.
+        constexpr Acts::GeometryIdentifier operator()(
+                Acts::GeometryIdentifier::Value encoded) const {
+            return Acts::GeometryIdentifier(encoded);
+        }
+        // support elements in map-like structures.
+        template <typename T>
+        constexpr Acts::GeometryIdentifier operator()(
+                const std::pair<Acts::GeometryIdentifier, T>& mapItem) const {
+            return mapItem.first;
+        }
+        // support elements that implement `.geometryId()`.
+        template <typename T>
+        inline auto operator()(const T& thing) const
+        -> decltype(thing.geometryId(), Acts::GeometryIdentifier()) {
+            return thing.geometryId();
+        }
+    };
+
+    struct CompareGeometryId {
+        // indicate that comparisons between keys and full objects are allowed.
+        using is_transparent = void;
+        // compare two elements using the automatic key extraction.
+        template <typename Left, typename Right>
+        constexpr bool operator()(Left&& lhs, Right&& rhs) const {
+            return GeometryIdGetter()(lhs) < GeometryIdGetter()(rhs);
+        }
+    };
+
+}  // namespace detail
+
+/// Store elements that know their detector geometry id, e.g. simulation hits.
+///
+/// @tparam T type to be stored, must be compatible with `CompareGeometryId`
+///
+/// The container stores an arbitrary number of elements for any geometry
+/// id. Elements can be retrieved via the geometry id; elements can be selected
+/// for a specific geometry id or for a larger range, e.g. a volume or a layer
+/// within the geometry hierachy using the helper functions below. Elements can
+/// also be accessed by index that uniquely identifies each element regardless
+/// of geometry id.
+template <typename T>
+using GeometryIdMultiset =
+boost::container::flat_multiset<T, detail::CompareGeometryId>;
+
+/// Store elements indexed by an geometry id.
+///
+/// @tparam T type to be stored
+///
+/// The behaviour is the same as for the `GeometryIdMultiset` except that the
+/// stored elements do not know their geometry id themself. When iterating
+/// the iterator elements behave as for the `std::map`, i.e.
+///
+///     for (const auto& entry: elements) {
+///         auto id = entry.first; // geometry id
+///         const auto& el = entry.second; // stored element
+///     }
+///
+template <typename T>
+using GeometryIdMultimap =
+GeometryIdMultiset<std::pair<Acts::GeometryIdentifier, T>>;
+
+/// The accessor for the GeometryIdMultiset container
+///
+/// It wraps up a few lookup methods to be used in the Combinatorial Kalman
+/// Filter
+template <typename T>
+struct GeometryIdMultisetAccessor {
+  using Container = GeometryIdMultiset<T>;
+  using Key = Acts::GeometryIdentifier;
+  using Value = typename GeometryIdMultiset<T>::value_type;
+  using Iterator = typename GeometryIdMultiset<T>::const_iterator;
+
+  // pointer to the container
+  const Container* container = nullptr;
+
+  // count the number of elements with requested geoId
+  size_t count(const Acts::GeometryIdentifier& geoId) const {
+    assert(container != nullptr);
+    return container->count(geoId);
+  }
+
+  // get the range of elements with requested geoId
+  std::pair<Iterator, Iterator> range(
+      const Acts::GeometryIdentifier& geoId) const {
+    assert(container != nullptr);
+    return container->equal_range(geoId);
+  }
+
+  // get the element using the iterator
+  const Value& at(const Iterator& it) const { return *it; }
+};
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h
index b007b6054c41028b6dac7ef7d5773423add1bcb2..fd7801c9eef4aa76b4f71215996983cc1a9efd5e 100755
--- a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h
@@ -43,8 +43,9 @@
 #include "FaserActsGeometry/FaserActsTrackingGeometryTool.h"
 #include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h"
 #include "FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h"
-#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h"
 #include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h"
+#include "FaserActsKalmanFilter/IndexSourceLink.h"
+#include "FaserActsKalmanFilter/Measurement.h"
 
 // STL
 #include <memory>
@@ -66,6 +67,7 @@ namespace TrackerDD {
 }
 
 using TrajectoryContainer = std::vector<FaserActsRecMultiTrajectory>;
+using BField_t = FASERMagneticFieldWrapper;
 
 //class FaserActsKalmanFilterAlg : public AthReentrantAlgorithm {
 class FaserActsKalmanFilterAlg : public AthAlgorithm {
@@ -75,19 +77,22 @@ public:
   //StatusCode execute(const EventContext& ctx) const override;
   StatusCode execute() override;
   StatusCode finalize() override;
- 
-  using FitterResult = Acts::Result<Acts::KalmanFitterResult<RecSourceLink>>;
+
+  using FitterResult = Acts::Result<Acts::KalmanFitterResult<IndexSourceLink>>;
   // Fit function that takes input measurements, initial trackstate and fitter
   // options and returns some fit-specific result.
   using FitterFunction = std::function<FitterResult(
-     const std::vector<RecSourceLink>&,
-     const Acts::CurvilinearTrackParameters&,
-     const Acts::KalmanFitterOptions<Acts::VoidOutlierFinder>&)>;
+      const std::vector<IndexSourceLink>&,
+      const Acts::CurvilinearTrackParameters&,
+      const Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder>&,
+      const std::vector<const Acts::Surface*>&)>;
+
+  using BoundVector = Acts::ActsVector<6>;
 
   // Create the fitter function implementation.
   static FitterFunction
   makeFitterFunction(
-     ActsExtrapolationDetail::VariantPropagator* varProp);
+      ActsExtrapolationDetail::VariantPropagator* varProp);
 
   virtual
   Acts::MagneticFieldContext
@@ -113,14 +118,19 @@ private:
 
   SG::ReadHandleKey<SpacePointForSeedCollection>  m_seed_spcollectionKey{this, "FaserSpacePointsSeedsName", "SpacePointForSeedCollection", "SpacePointForSeedCollection"};
 
-    SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "GEN_EVENT" };
-    SG::ReadHandleKey<TrackerSimDataCollection> m_sctMap {this, "TrackerSimDataCollection", "SCT_SDO_Map"};
-    const TrackerDD::SCT_DetectorManager* m_detManager{nullptr};
+  SG::ReadHandleKey<McEventCollection> m_mcEventKey       { this, "McEventCollection", "BeamTruthEvent" };
+  SG::ReadHandleKey<TrackerSimDataCollection> m_sctMap {this, "TrackerSimDataCollection", "SCT_SDO_Map"};
+  const TrackerDD::SCT_DetectorManager* m_detManager{nullptr};
 
   ServiceHandle<ITHistSvc> m_thistSvc;
 
   TTree *m_trackTree{nullptr};
 
+  Acts::GeometryIdentifier getGeometryIdentifier(const Identifier id);
+  int getGeometryIdentifierVolume(int station);
+  int getGeometryIdentifierLayer(int layer);
+  int getGeometryIdentifierSensitive(int row, int column);
+
   /// Acts tree values
   int m_eventNr{0};
   int m_trajNr{0};
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h
index 928261e6ed9bbdd155a50a919de4c4fa58ca34fa..35baa239600d5f273dd91c2145eecfd8e1c8b52a 100644
--- a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h
@@ -14,7 +14,7 @@
 #include "Acts/EventData/TrackParameters.hpp"
 
 // PACKAGE
-#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h"
+#include "FaserActsKalmanFilter/IndexSourceLink.h"
 
 using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>;
 
@@ -23,7 +23,7 @@ struct FaserActsRecMultiTrajectory
  public:
   FaserActsRecMultiTrajectory() = default;
 
-  FaserActsRecMultiTrajectory(const Acts::MultiTrajectory<RecSourceLink>& multiTraj,
+  FaserActsRecMultiTrajectory(const Acts::MultiTrajectory<IndexSourceLink>& multiTraj,
                      const std::vector<size_t>& tTips,
                      const IndexedParams& parameters)
       : m_multiTrajectory(multiTraj),
@@ -64,7 +64,7 @@ struct FaserActsRecMultiTrajectory
     return m_trackParameters.count(entryIndex) > 0;
   }
 
-  std::pair<std::vector<size_t>, Acts::MultiTrajectory<RecSourceLink>>
+  std::pair<std::vector<size_t>, Acts::MultiTrajectory<IndexSourceLink>>
   trajectory() const {
     return std::make_pair(m_trackTips, m_multiTrajectory);
   }
@@ -81,7 +81,7 @@ struct FaserActsRecMultiTrajectory
   }
 
  private:
-  Acts::MultiTrajectory<RecSourceLink> m_multiTrajectory;
+  Acts::MultiTrajectory<IndexSourceLink> m_multiTrajectory;
   std::vector<size_t> m_trackTips = {};
   IndexedParams m_trackParameters = {};
 };
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h
deleted file mode 100644
index 4e0cbe7e62e601126d86a46f1ac73fc666bea2ea..0000000000000000000000000000000000000000
--- a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h
+++ /dev/null
@@ -1,54 +0,0 @@
-# pragma once
-
-// ACTS
-#include "Acts/EventData/Measurement.hpp"
-#include "TrackParameterization.hpp"
-
-// ATHENA
-#include "TrkSpacePoint/SpacePoint.h"
-
-
-class RecSourceLink {
-public:
-    // TODO convert Trk::LocalParameters to acts::BoundVector and Amg::MatrixX& to ACTS::BoundMatrix
-    RecSourceLink(const Acts::Surface& surface, const Trk::SpacePoint& spacePoint)
-        : m_values(spacePoint.localParameters()),
-          m_cov(spacePoint.localCovariance()),
-          m_surface(&surface),
-          m_spacePoint(&spacePoint) {}
-
-    RecSourceLink() = default;
-
-    constexpr const Acts::Surface& referenceSurface() const { return *m_surface; }
-    constexpr const Trk::SpacePoint& spacePoint() const { return *m_spacePoint; }
-
-    Acts::FittableMeasurement<RecSourceLink> operator*() const {
-        return Acts::Measurement<RecSourceLink, Acts::BoundIndices, Acts::eBoundLoc0, Acts::eBoundLoc1> {
-            m_surface->getSharedPtr(),
-            *this,
-            m_cov.topLeftCorner<2, 2>(),
-            m_values[0],
-            m_values[1]
-        };
-    }
-
-    Acts::GeometryIdentifier geometryId() const
-    {
-        return m_surface->geometryId();
-    }
-
-private:
-    Acts::BoundVector m_values;
-    Acts::BoundMatrix m_cov;
-    const Acts::Surface* m_surface;
-    const Trk::SpacePoint* m_spacePoint;
-
-    friend constexpr bool operator==(const RecSourceLink& lhs, const RecSourceLink& rhs) {
-        return lhs.m_spacePoint == rhs.m_spacePoint;
-    }
-    friend constexpr bool operator!=(const RecSourceLink& lhs, const RecSourceLink& rhs) {
-        return !(lhs == rhs);
-    }
-
-
-};
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/IndexSourceLink.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/IndexSourceLink.h
new file mode 100644
index 0000000000000000000000000000000000000000..99d101519030fca1d4fd7904bc7549b22a39a6c2
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/IndexSourceLink.h
@@ -0,0 +1,77 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2020 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "Acts/Geometry/GeometryIdentifier.hpp"
+
+#include <cassert>
+
+#include <boost/container/flat_map.hpp>
+
+#include "FaserActsKalmanFilter/FaserActsGeometryContainers.h"
+
+/// Index type to reference elements in a container.
+///
+/// We do not expect to have more than 2^32 elements in any given container so a
+/// fixed sized integer type is sufficient.
+using Index = uint32_t;
+
+/// A source link that stores just an index.
+///
+/// This is intentionally kept as barebones as possible. The source link
+/// is just a reference and will be copied, moved around, etc. often.
+/// Keeping it small and separate from the actual, potentially large,
+/// measurement data should result in better overall performance.
+/// Using an index instead of e.g. a pointer, means source link and
+/// measurement are decoupled and the measurement represenation can be
+/// easily changed without having to also change the source link.
+class IndexSourceLink final {
+public:
+    /// Construct from geometry identifier and index.
+    constexpr IndexSourceLink(Acts::GeometryIdentifier gid, Index idx)
+            : m_geometryId(gid), m_index(idx) {}
+
+    // Construct an invalid source link. Must be default constructible to
+    /// satisfy SourceLinkConcept.
+    IndexSourceLink() = default;
+    IndexSourceLink(const IndexSourceLink&) = default;
+    IndexSourceLink(IndexSourceLink&&) = default;
+    IndexSourceLink& operator=(const IndexSourceLink&) = default;
+    IndexSourceLink& operator=(IndexSourceLink&&) = default;
+
+    /// Access the geometry identifier.
+    constexpr Acts::GeometryIdentifier geometryId() const { return m_geometryId; }
+    /// Access the index.
+    constexpr Index index() const { return m_index; }
+
+private:
+    Acts::GeometryIdentifier m_geometryId;
+    Index m_index;
+
+    friend constexpr bool operator==(const IndexSourceLink& lhs,
+                                     const IndexSourceLink& rhs) {
+        return (lhs.m_geometryId == rhs.m_geometryId) and
+               (lhs.m_index == rhs.m_index);
+    }
+    friend constexpr bool operator!=(const IndexSourceLink& lhs,
+                                     const IndexSourceLink& rhs) {
+        return not(lhs == rhs);
+    }
+};
+
+/// Container of index source links.
+///
+/// Since the source links provide a `.geometryId()` accessor, they can be
+/// stored in an ordered geometry container.
+using IndexSourceLinkContainer = GeometryIdMultiset<IndexSourceLink>;
+/// Accessor for the above source link container
+///
+/// It wraps up a few lookup methods to be used in the Combinatorial Kalman
+/// Filter
+using IndexSourceLinkAccessor = GeometryIdMultisetAccessor<IndexSourceLink>;
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/Measurement.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/Measurement.h
new file mode 100644
index 0000000000000000000000000000000000000000..3defe818047153794f33d86af76cb2592e882797
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/Measurement.h
@@ -0,0 +1,53 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2020 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "Acts/EventData/Measurement.hpp"
+#include "FaserActsKalmanFilter/IndexSourceLink.h"
+
+#include <cassert>
+#include <vector>
+
+/// Variable measurement type that can contain all possible combinations.
+using Measurement = Acts::BoundVariantMeasurement<IndexSourceLink>;
+/// Container of measurements.
+///
+/// In contrast to the source links, the measurements themself must not be
+/// orderable. The source links stored in the measurements are treated
+/// as opaque here and no ordering is enforced on the stored measurements.
+using MeasurementContainer = std::vector<Measurement>;
+
+/// Calibrator to convert an index source link to a measurement.
+class MeasurementCalibrator {
+public:
+    /// Construct an invalid calibrator. Required to allow copying.
+    MeasurementCalibrator() = default;
+    /// Construct using a user-provided container to chose measurements from.
+    MeasurementCalibrator(const MeasurementContainer& measurements)
+            : m_measurements(&measurements) {}
+
+    /// Find the measurement corresponding to the source link.
+    ///
+    /// @tparam parameters_t Track parameters type
+    /// @param sourceLink Input source link
+    /// @param parameters Input track parameters (unused)
+    template <typename parameters_t>
+    const Measurement& operator()(const IndexSourceLink& sourceLink,
+                                  const parameters_t& ) const {
+        assert(m_measurements and
+               "Undefined measurement container in DigitizedCalibrator");
+        assert((sourceLink.index() < m_measurements->size()) and
+               "Source link index is outside the container bounds");
+        return (*m_measurements)[sourceLink.index()];
+    }
+
+private:
+    // use pointer so the calibrator is copyable and default constructible.
+    const MeasurementContainer* m_measurements = nullptr;
+};
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/SimWriterTool.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/SimWriterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0ab6f7dbe0479a4321eff3dd2be7e68e3bea70c
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/SimWriterTool.h
@@ -0,0 +1,37 @@
+#ifndef SIMWRITERTOOL_H
+#define SIMWRITERTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "Acts/Definitions/Algebra.hpp"
+class TFile;
+class TTree;
+
+
+class SimWriterTool : public AthAlgTool {
+ public:
+  SimWriterTool(const std::string& type,
+      const std::string& name, const IInterface* parent);
+
+  virtual ~SimWriterTool() = default;
+
+  virtual StatusCode initialize() override;
+  virtual StatusCode finalize() override;
+
+  void writeout(Acts::Vector3 vertex, Acts::Vector3 momentum) const;
+
+ private:
+  Gaudi::Property<std::string> m_filePath{this, "FilePath", "SimData.root", "Output root file for simulated data"};
+  Gaudi::Property<std::string> m_treeName{this, "TreeName", "tree", ""};
+  TFile* m_file;
+  TTree* m_tree;
+
+  mutable int m_eventNumber;
+  mutable double m_x;
+  mutable double m_y;
+  mutable double m_z;
+  mutable double m_px;
+  mutable double m_py;
+  mutable double m_pz;
+};
+
+#endif // SIMWRITERTOOL_H
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TrajectoryWriterTool.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TrajectoryWriterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a3f348b0b467348eb9924c3e93b1c6482922bad
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TrajectoryWriterTool.h
@@ -0,0 +1,167 @@
+#ifndef TRAJECTORYWRITERTOOL_H
+#define TRAJECTORYWRITERTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "Acts/Geometry/GeometryContext.hpp"
+
+class TFile;
+class TTree;
+class FaserActsRecMultiTrajectory;
+using TrajectoriesContainer = std::vector<FaserActsRecMultiTrajectory>;
+
+class TrajectoryWriterTool : public AthAlgTool {
+ public:
+  TrajectoryWriterTool(const std::string& type, 
+      const std::string& name, const IInterface* parent);
+  
+  virtual ~TrajectoryWriterTool() = default;
+
+  virtual StatusCode initialize() override;
+  virtual StatusCode finalize() override;
+
+  void writeout(TrajectoriesContainer trajectories,
+      Acts::GeometryContext geoContext) const;
+  
+  void clearVariables() const;
+
+ private:
+  void initializeTree();
+  Gaudi::Property<std::string> m_filePath{this, "FilePath", "Trajectories.root", "Output root file for CKF Tracks"};
+  Gaudi::Property<std::string> m_treeName{this, "TreeName", "tree", ""};
+  TFile* m_file;
+  TTree* m_tree;
+
+  mutable int m_eventNumber;
+  mutable int m_trajNumber;
+  mutable int m_trackNumber;
+
+  mutable bool m_hasFittedParams{false};
+  mutable std::vector<bool> m_prt;
+  mutable std::vector<bool> m_flt;
+  mutable std::vector<bool> m_smt;
+
+  mutable int m_nPredicted{0};
+  mutable int m_nFiltered{0};
+  mutable int m_nSmoothed{0};
+
+  mutable int m_nMeasurements{0};
+  mutable int m_nStates{0};
+  mutable int m_nOutliers{0};
+  mutable int m_nHoles{0};
+  mutable float m_chi2_fit{-99.};
+  mutable float m_ndf_fit{-99.};
+
+  mutable std::vector<int> m_volumeID;
+  mutable std::vector<int> m_layerID;
+  mutable std::vector<int> m_moduleID;
+  mutable std::vector<float> m_lx_hit;
+  mutable std::vector<float> m_ly_hit;
+  mutable std::vector<float> m_x_hit;
+  mutable std::vector<float> m_y_hit;
+  mutable std::vector<float> m_z_hit;
+  mutable std::vector<float> m_res_x_hit;
+  mutable std::vector<float> m_res_y_hit;
+  mutable std::vector<float> m_err_x_hit;
+  mutable std::vector<float> m_err_y_hit;
+  mutable std::vector<float> m_pull_x_hit;
+  mutable std::vector<float> m_pull_y_hit;
+  mutable std::vector<int> m_dim_hit;
+
+  mutable int m_charge_fit{-99};
+  mutable float m_eLOC0_fit{-99.};
+  mutable float m_eLOC1_fit{-99.};
+  mutable float m_ePHI_fit{-99.};
+  mutable float m_eTHETA_fit{-99.};
+  mutable float m_eQOP_fit{-99.};
+  mutable float m_eT_fit{-99.};
+  mutable float m_err_eLOC0_fit{-99.};
+  mutable float m_err_eLOC1_fit{-99.};
+  mutable float m_err_ePHI_fit{-99.};
+  mutable float m_err_eTHETA_fit{-99.};
+  mutable float m_err_eQOP_fit{-99.};
+  mutable float m_err_eT_fit{-99.};
+  mutable float m_px_fit{-99.};
+  mutable float m_py_fit{-99.};
+  mutable float m_pz_fit{-99.};
+  mutable float m_x_fit{-99.};
+  mutable float m_y_fit{-99.};
+  mutable float m_z_fit{-99.};
+
+  mutable std::vector<float> m_eLOC0_prt;
+  mutable std::vector<float> m_eLOC1_prt;
+  mutable std::vector<float> m_ePHI_prt;
+  mutable std::vector<float> m_eTHETA_prt;
+  mutable std::vector<float> m_eQOP_prt;
+  mutable std::vector<float> m_eT_prt;
+  mutable std::vector<float> m_res_eLOC0_prt;
+  mutable std::vector<float> m_res_eLOC1_prt;
+  mutable std::vector<float> m_err_eLOC0_prt;
+  mutable std::vector<float> m_err_eLOC1_prt;
+  mutable std::vector<float> m_err_ePHI_prt;
+  mutable std::vector<float> m_err_eTHETA_prt;
+  mutable std::vector<float> m_err_eQOP_prt;
+  mutable std::vector<float> m_err_eT_prt;
+  mutable std::vector<float> m_pull_eLOC0_prt;
+  mutable std::vector<float> m_pull_eLOC1_prt;
+  mutable std::vector<float> m_x_prt;
+  mutable std::vector<float> m_y_prt;
+  mutable std::vector<float> m_z_prt;
+  mutable std::vector<float> m_px_prt;
+  mutable std::vector<float> m_py_prt;
+  mutable std::vector<float> m_pz_prt;
+  mutable std::vector<float> m_eta_prt;
+  mutable std::vector<float> m_pT_prt;
+
+  mutable std::vector<float> m_eLOC0_flt;
+  mutable std::vector<float> m_eLOC1_flt;
+  mutable std::vector<float> m_ePHI_flt;
+  mutable std::vector<float> m_eTHETA_flt;
+  mutable std::vector<float> m_eQOP_flt;
+  mutable std::vector<float> m_eT_flt;
+  mutable std::vector<float> m_res_eLOC0_flt;
+  mutable std::vector<float> m_res_eLOC1_flt;
+  mutable std::vector<float> m_err_eLOC0_flt;
+  mutable std::vector<float> m_err_eLOC1_flt;
+  mutable std::vector<float> m_err_ePHI_flt;
+  mutable std::vector<float> m_err_eTHETA_flt;
+  mutable std::vector<float> m_err_eQOP_flt;
+  mutable std::vector<float> m_err_eT_flt;
+  mutable std::vector<float> m_pull_eLOC0_flt;
+  mutable std::vector<float> m_pull_eLOC1_flt;
+  mutable std::vector<float> m_x_flt;
+  mutable std::vector<float> m_y_flt;
+  mutable std::vector<float> m_z_flt;
+  mutable std::vector<float> m_px_flt;
+  mutable std::vector<float> m_py_flt;
+  mutable std::vector<float> m_pz_flt;
+  mutable std::vector<float> m_eta_flt;
+  mutable std::vector<float> m_pT_flt;
+  mutable std::vector<float> m_chi2;
+
+  mutable std::vector<float> m_eLOC0_smt;
+  mutable std::vector<float> m_eLOC1_smt;
+  mutable std::vector<float> m_ePHI_smt;
+  mutable std::vector<float> m_eTHETA_smt;
+  mutable std::vector<float> m_eQOP_smt;
+  mutable std::vector<float> m_eT_smt;
+  mutable std::vector<float> m_res_eLOC0_smt;
+  mutable std::vector<float> m_res_eLOC1_smt;
+  mutable std::vector<float> m_err_eLOC0_smt;
+  mutable std::vector<float> m_err_eLOC1_smt;
+  mutable std::vector<float> m_err_ePHI_smt;
+  mutable std::vector<float> m_err_eTHETA_smt;
+  mutable std::vector<float> m_err_eQOP_smt;
+  mutable std::vector<float> m_err_eT_smt;
+  mutable std::vector<float> m_pull_eLOC0_smt;
+  mutable std::vector<float> m_pull_eLOC1_smt;
+  mutable std::vector<float> m_x_smt;
+  mutable std::vector<float> m_y_smt;
+  mutable std::vector<float> m_z_smt;
+  mutable std::vector<float> m_px_smt;
+  mutable std::vector<float> m_py_smt;
+  mutable std::vector<float> m_pz_smt;
+  mutable std::vector<float> m_eta_smt;
+  mutable std::vector<float> m_pT_smt;
+};
+
+#endif // TRAJECTORYWRITERTOOL_H
diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TruthBasedInitialParameterTool.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TruthBasedInitialParameterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b94890f311f2661ba90fd69498330adb1573ee4
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/TruthBasedInitialParameterTool.h
@@ -0,0 +1,33 @@
+#ifndef TRUTHBASEDINITIALPARAMETERTOOL_H
+#define TRUTHBASEDINITIALPARAMETERTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "TrackerSimData/TrackerSimDataCollection.h"
+#include "FaserActsKalmanFilter/SimWriterTool.h"
+
+
+namespace Acts {
+  struct SinglyCharged;
+  template <typename charge_t> class SingleCurvilinearTrackParameters;
+  using CurvilinearTrackParameters =
+    SingleCurvilinearTrackParameters<SinglyCharged>;
+}
+
+
+class TruthBasedInitialParameterTool : public AthAlgTool {
+ public:
+  TruthBasedInitialParameterTool (const std::string& type, 
+      const std::string& name, const IInterface* parent);
+  ~TruthBasedInitialParameterTool() = default;
+
+  virtual StatusCode initialize() override;
+  virtual StatusCode finalize() override;
+
+  Acts::CurvilinearTrackParameters getInitialParameters(std::vector<Identifier> ids) const;
+
+ private:
+  SG::ReadHandleKey<TrackerSimDataCollection> m_simDataCollectionKey {this, "TrackerSimDataCollection", "SCT_SDO_Map"};
+  ToolHandle<SimWriterTool> m_simWriterTool{this, "OutputTool", "SimWriterTool"};
+};
+
+#endif  // TRUTHBASEDINITIALPARAMETERTOOL_H
diff --git a/Tracking/Acts/FaserActsKalmanFilter/python/CombinatorialKalmanFilterConfig.py b/Tracking/Acts/FaserActsKalmanFilter/python/CombinatorialKalmanFilterConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4bef9af0883abd8219a5d908e3c39603674da55
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/python/CombinatorialKalmanFilterConfig.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS and FASER collaborations
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+
+
+def CombinatorialKalmanFilter_OutputCfg(flags):
+    acc = ComponentAccumulator()
+    acc.merge(OutputStreamCfg(flags, "ESD"))
+    ostream = acc.getEventAlgo("OutputStreamESD")
+    ostream.TakeItemsFromInput = True
+    return acc
+
+
+def CombinatorialKalmanFilterCfg(flags, **kwargs):
+    acc = ComponentAccumulator()
+    kwargs.setdefault("SpacePointsSCTName", "SCT_SpacePointContainer")
+    combinatorialKalmanFilterAlg = CompFactory.CombinatorialKalmanFilterAlg(**kwargs)
+    acc.addEventAlgo(combinatorialKalmanFilterAlg)
+    acc.merge(CombinatorialKalmanFilter_OutputCfg(flags))
+    return acc
diff --git a/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py b/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py
index 0a955d80a50c7fcb5de8878841404565cd870f1b..6d6167c051b868d6032355e5bfd58d2a0f8296bd 100644
--- a/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py
+++ b/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py
@@ -1,3 +1,5 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS and FASER collaborations
+
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/CombinatorialKalmbanFilterAlg.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/CombinatorialKalmbanFilterAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..564760f72f7e5a502d4e21f9474a1f00c9e52221
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/CombinatorialKalmbanFilterAlg.cxx
@@ -0,0 +1,171 @@
+#include "FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h"
+
+#include "StoreGate/ReadHandle.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "TrkSpacePoint/SpacePointCollection.h"
+#include "TrkSpacePoint/SpacePoint.h"
+#include "TrkPrepRawData/PrepRawData.h"
+#include "TrkSurfaces/Surface.h"
+#include "Identifier/Identifier.h"
+#include "Acts/Geometry/GeometryIdentifier.hpp"
+#include "Acts/EventData/TrackParameters.hpp"
+#include "FaserActsKalmanFilter/IndexSourceLink.h"
+#include "FaserActsKalmanFilter/Measurement.h"
+#include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h"
+#include "Acts/Surfaces/PerigeeSurface.hpp"
+#include "Acts/MagneticField/MagneticFieldContext.hpp"
+
+using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>;
+using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, 2>;
+using TrajectoriesContainer = std::vector<FaserActsRecMultiTrajectory>;
+std::array<Acts::BoundIndices, 2> indices = {Acts::eBoundLoc0, Acts::eBoundLoc1};
+
+
+CombinatorialKalmanFilterAlg::CombinatorialKalmanFilterAlg(
+    const std::string& name, ISvcLocator* pSvcLocator)
+    : AthReentrantAlgorithm(name, pSvcLocator) {}
+
+
+StatusCode CombinatorialKalmanFilterAlg::initialize() {
+  ATH_MSG_INFO("CombinatorialKalmanFilterAlg::initialize");
+
+  ATH_CHECK(m_trackingGeometryTool.retrieve());
+  ATH_CHECK(m_initialParameterTool.retrieve());
+  ATH_CHECK(m_trajectoryWriterTool.retrieve());
+
+  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+
+  if (m_SpacePointContainerKey.key().empty()) {
+    ATH_MSG_FATAL("empty space point container key");
+    return StatusCode::FAILURE;
+  }
+  ATH_CHECK(m_SpacePointContainerKey.initialize());
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode CombinatorialKalmanFilterAlg::execute(const EventContext& ctx) const {
+  ATH_MSG_INFO("CombinatorialKalmanFilterAlg::execute");
+
+  SG::ReadHandle<SpacePointContainer> spcontainer(m_SpacePointContainerKey, ctx);
+  if (!spcontainer.isValid()) {
+    ATH_MSG_FATAL( "Could not find the data object "<< spcontainer.name());
+    return StatusCode::FAILURE;
+  }
+
+  const std::shared_ptr<IdentifierMap> identifierMap
+      = m_trackingGeometryTool->getIdentifierMap();
+
+  // Create measurement and source link containers
+  IndexSourceLinkContainer sourceLinks;
+  MeasurementContainer measurements;
+  std::vector<Identifier> sp_ids;
+
+  SpacePointContainer::const_iterator coll_it = spcontainer->begin();
+  SpacePointContainer::const_iterator coll_itend = spcontainer->end();
+  for (; coll_it != coll_itend; ++coll_it) {
+    const SpacePointCollection* spcollection = *coll_it;
+    SpacePointCollection::const_iterator sp_it = spcollection->begin();
+    SpacePointCollection::const_iterator sp_end = spcollection->end();
+    for (; sp_it != sp_end; ++sp_it) {
+      const Trk::SpacePoint* sp = *sp_it;
+      Identifier id = sp->associatedSurface().associatedDetectorElementIdentifier();
+      Acts::GeometryIdentifier geoId = identifierMap->at(id);
+      IndexSourceLink sourceLink(geoId, measurements.size());
+      sourceLinks.emplace_hint(sourceLinks.end(), std::move(sourceLink));
+      ThisMeasurement meas(sourceLink, indices, sp->localParameters(), sp->localCovariance());
+      measurements.emplace_back(std::move(meas));
+
+      sp_ids.push_back(sp->clusterList().first->identify());
+    }
+  }
+
+  // Get initial parameters
+  // FIXME: Get initial parameters from clusterFitter or SeedFinder not MC!
+  std::vector<Acts::CurvilinearTrackParameters> initialParameters;
+  auto initialParameter = m_initialParameterTool->getInitialParameters(sp_ids);
+  initialParameters.push_back(initialParameter);
+
+  // Prepare the output data with MultiTrajectory
+  TrajectoriesContainer trajectories;
+  trajectories.reserve(initialParameters.size());
+
+  // Construct a perigee surface as the target surface
+  auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
+      Acts::Vector3{0., 0., 0.});
+
+  Acts::PropagatorPlainOptions pOptions;
+  pOptions.maxSteps = 10000;
+
+  Acts::GeometryContext geoContext = m_trackingGeometryTool->getNominalGeometryContext().context();
+  Acts::MagneticFieldContext magFieldContext = getMagneticFieldContext(ctx);
+  Acts::CalibrationContext calibContext;
+  double chi2Max = 15;
+  size_t nMax = 10;
+  Acts::MeasurementSelector::Config measurementSelectorCfg = {
+    {Acts::GeometryIdentifier(), {chi2Max, nMax}},
+  };
+  std::unique_ptr<const Acts::Logger> logger
+      = Acts::getDefaultLogger("CombinatorialKalmanFilter", Acts::Logging::VERBOSE);
+
+  // Set the CombinatorialKalmanFilter options
+  CombinatorialKalmanFilterAlg::TrackFinderOptions options(
+      geoContext, magFieldContext, calibContext,
+      IndexSourceLinkAccessor(), MeasurementCalibrator(measurements),
+      Acts::MeasurementSelector(measurementSelectorCfg),
+      Acts::LoggerWrapper{*logger}, pOptions, &(*pSurface));
+
+  std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry
+      = m_trackingGeometryTool->trackingGeometry();
+
+  // Get track finder function
+  auto trackFinderFunction = makeTrackFinderFunction(trackingGeometry);
+
+  // Perform the track finding for all initial parameters
+  ATH_MSG_DEBUG("Invoke track finding with " << initialParameters.size()
+                                          << " seeds.");
+  auto results = trackFinderFunction(sourceLinks, initialParameters, options);
+  // Loop over the track finding results for all initial parameters
+  for (std::size_t iseed = 0; iseed < initialParameters.size(); ++iseed) {
+    // The result for this seed
+    auto& result = results[iseed];
+    if (result.ok()) {
+      // Get the track finding output object
+      const auto& trackFindingOutput = result.value();
+      // Create a Trajectories result struct
+      trajectories.emplace_back(std::move(trackFindingOutput.fittedStates),
+                                std::move(trackFindingOutput.lastMeasurementIndices),
+                                std::move(trackFindingOutput.fittedParameters));
+    } else {
+      ATH_MSG_WARNING("Track finding failed for seed " << iseed << " with error"
+                                                       << result.error());
+      // Track finding failed. Add an empty result so the output container has
+      // the same number of entries as the input.
+      trajectories.push_back(FaserActsRecMultiTrajectory());
+    }
+  }
+
+  m_trajectoryWriterTool->writeout(trajectories, geoContext);
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode CombinatorialKalmanFilterAlg::finalize() {
+  ATH_MSG_INFO("CombinatorialKalmanFilterAlg::finalize");
+  return StatusCode::SUCCESS;
+}
+
+
+Acts::MagneticFieldContext CombinatorialKalmanFilterAlg::getMagneticFieldContext(const EventContext& ctx) const {
+  SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  if (!readHandle.isValid()) {
+    std::stringstream msg;
+    msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << ".";
+    throw std::runtime_error(msg.str());
+  }
+  const FaserFieldCacheCondObj* fieldCondObj{*readHandle};
+
+  return Acts::MagneticFieldContext(fieldCondObj);
+}
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx
index 9374b5dd74f01fffd0efad57e016d504337dd118..9d11c2f800b559ebb694765e7286cea85d62ee8d 100755
--- a/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx
@@ -38,11 +38,12 @@
 #include "Acts/Utilities/detail/periodic.hpp"
 #include "Acts/Definitions/Common.hpp"
 #include "Acts/Definitions/Algebra.hpp"
-#include "Acts/Definitions/TrackParameterization.hpp"
+#include "Acts/Definitions/TrackParametrization.hpp"
 #include "Acts/Utilities/CalibrationContext.hpp"
 #include "Acts/EventData/TrackParameters.hpp"
 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
 #include "Acts/EventData/Measurement.hpp"
+#include "Acts/Geometry/GeometryIdentifier.hpp"
 
 
 // PACKAGE
@@ -51,8 +52,6 @@
 #include "FaserActsGeometry/FaserActsGeometryContext.h"
 #include "FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h"
 #include "FaserActsGeometry/FaserActsDetectorElement.h"
-#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h"
-#include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h"
 
 //ROOT
 #include <TTree.h>
@@ -60,7 +59,7 @@
 // BOOST
 #include <boost/variant/variant.hpp>
 #include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/static_visitor.hpp>
+// #include <boost/variant/static_visitor.hpp>
 
 // STL
 #include <string>
@@ -75,13 +74,17 @@ using Acts::VectorHelpers::eta;
 using Acts::VectorHelpers::perp;
 using Acts::VectorHelpers::phi;
 using Acts::VectorHelpers::theta;
-using Measurement = Acts::Measurement<RecSourceLink, Acts::BoundIndices, Acts::eBoundLoc0,
-                                      Acts::eBoundLoc1>;
+using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, 2>;
+using Updater = Acts::GainMatrixUpdater;
+using Smoother = Acts::GainMatrixSmoother;
+using Stepper = Acts::EigenStepper<FASERMagneticFieldWrapper>;
+using Propagator = Acts::Propagator<Stepper, Acts::DirectNavigator>;
+using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>;
 
 namespace ActsExtrapolationDetail {
   using VariantPropagatorBase = boost::variant<
-    Acts::Propagator<Acts::EigenStepper<FASERMagneticFieldWrapper>, Acts::Navigator>,
-    Acts::Propagator<Acts::EigenStepper<Acts::ConstantBField>, Acts::Navigator>
+    Acts::Propagator<Acts::EigenStepper<>, Acts::DirectNavigator>,
+    Acts::Propagator<Acts::EigenStepper<>, Acts::DirectNavigator>
   >;
 
   class VariantPropagator : public VariantPropagatorBase
@@ -94,13 +97,76 @@ namespace ActsExtrapolationDetail {
 
 using ActsExtrapolationDetail::VariantPropagator;
 
+FaserActsKalmanFilterAlg::FaserActsKalmanFilterAlg(const std::string& name, ISvcLocator* pSvcLocator)
+    : AthAlgorithm(name, pSvcLocator) , m_thistSvc("THistSvc", name)
+{
+}
 
-FaserActsKalmanFilterAlg::FaserActsKalmanFilterAlg(const std::string& name,
-                                 ISvcLocator* pSvcLocator)
-    //: AthReentrantAlgorithm(name, pSvcLocator)
-    : AthAlgorithm(name, pSvcLocator)
-      , m_thistSvc("THistSvc", name)
+// FixMe the Identifier to GeometryIdentfier mapping should not be hardcoded.
+int FaserActsKalmanFilterAlg::getGeometryIdentifierVolume(int station)
 {
+  switch(station)
+  {
+    case 1:
+      return 2;
+    case 2:
+      return 3;
+    case 3:
+      return 4;
+    default:
+      ATH_MSG_ERROR("Received unexpected station. Check detector geometry");
+      return 0;
+  }
+}
+
+int FaserActsKalmanFilterAlg::getGeometryIdentifierLayer(int layer)
+{
+  switch(layer)
+  {
+    case 0:
+      return 2;
+    case 1:
+      return 4;
+    case 2:
+      return 6;
+    default:
+      ATH_MSG_ERROR("Received unexpected layer. Check detector geometry");
+      return 0;
+  }
+}
+
+int FaserActsKalmanFilterAlg::getGeometryIdentifierSensitive(int row, int column)
+{
+  if (row == 0 && column == -1)
+    return 2;
+  else if (row == 0 && column == 1)
+    return 4;
+  else if (row == 1 && column == -1)
+    return 5;
+  else if (row == 1 && column == 1)
+    return 7;
+  else if (row == 2 && column == -1)
+    return 10;
+  else if (row == 2 && column == 1)
+    return 12;
+  else if (row == 3 && column == -1)
+    return 13;
+  else if (row ==3 && column == 1)
+    return 15;
+  else
+  {
+    ATH_MSG_ERROR("Received unexpected row or column. Check detector geometry");
+    return 0;
+  }
+}
+
+Acts::GeometryIdentifier FaserActsKalmanFilterAlg::getGeometryIdentifier(const Identifier id)
+{
+  Acts::GeometryIdentifier geoId = Acts::GeometryIdentifier();
+  geoId.setVolume(getGeometryIdentifierVolume(m_idHelper->station(id)));
+  geoId.setLayer(getGeometryIdentifierLayer(m_idHelper->layer(id)));
+  geoId.setSensitive(getGeometryIdentifierSensitive(m_idHelper->phi_module(id), m_idHelper->eta_module(id)));
+  return geoId;
 }
 
 StatusCode FaserActsKalmanFilterAlg::initialize() {
@@ -109,31 +175,31 @@ StatusCode FaserActsKalmanFilterAlg::initialize() {
 
   ATH_MSG_INFO("Initializing ACTS kalman filter");
 
-  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+      ATH_CHECK( m_fieldCondObjInputKey.initialize() );
 
-  ATH_CHECK( m_extrapolationTool.retrieve() );
+      ATH_CHECK( m_extrapolationTool.retrieve() );
 
   if ( m_seed_spcollectionKey.key().empty()){
     ATH_MSG_FATAL( "SCTs selected and no name set for SCT clusters");
     return StatusCode::FAILURE;
   }
 
-  ATH_CHECK( m_seed_spcollectionKey.initialize() );
+      ATH_CHECK( m_seed_spcollectionKey.initialize() );
+
+      ATH_CHECK( m_mcEventKey.initialize() );
 
-  ATH_CHECK( m_mcEventKey.initialize() );
+      ATH_CHECK( m_sctMap.initialize());
 
-  ATH_CHECK( m_sctMap.initialize());
+      ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID"));
 
-  ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID"));
-	
-  ATH_CHECK(detStore()->retrieve(m_detManager, "SCT"));
+      ATH_CHECK(detStore()->retrieve(m_detManager, "SCT"));
 
-  ATH_CHECK(m_thistSvc.retrieve());
+      ATH_CHECK(m_thistSvc.retrieve());
 
   m_trackTree = new TTree("tracks", "");
 
-  ATH_CHECK(m_thistSvc->regTree("/KalmanTracks/tracks", m_trackTree));
-  
+      ATH_CHECK(m_thistSvc->regTree("/KalmanTracks/tracks", m_trackTree));
+
   if (m_trackTree) {
     initializeTree();
   }
@@ -162,15 +228,12 @@ StatusCode FaserActsKalmanFilterAlg::execute()
 
   const FaserActsGeometryContext& gctx
       = m_extrapolationTool->trackingGeometryTool()->getNominalGeometryContext();
-  auto geoctx = gctx.any();
+  auto geoctx = gctx.context();
   Acts::MagneticFieldContext magctx = getMagneticFieldContext();
   Acts::CalibrationContext calctx;
 
   std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry
       = m_extrapolationTool->trackingGeometryTool()->trackingGeometry();
-  const Acts::TrackingVolume* tVolume = trackingGeometry->highestTrackingVolume();
-
-  std::vector<RecSourceLink> sourceLinks;
 
   std::shared_ptr<const Acts::Surface> pSurface;
 
@@ -182,311 +245,351 @@ StatusCode FaserActsKalmanFilterAlg::execute()
   }
 
 
-	//!!!!!!!!!!!!!!!!!!!!
-    static const TrackerDD::SCT_DetectorManager     *s_sct;
-    if(detStore()->retrieve(s_sct,"SCT").isFailure()) s_sct = 0;
-	int N_1_0=0, N_1_1=0, N_1_2=0, N_2_0=0, N_2_1=0, N_2_2=0;
+  static const TrackerDD::SCT_DetectorManager     *s_sct;
+  if(detStore()->retrieve(s_sct,"SCT").isFailure()) s_sct = 0;
+  int N_1_0=0, N_1_1=0, N_1_2=0, N_2_0=0, N_2_1=0, N_2_2=0;
   Acts::Vector3 pos1_0(0., 0., 0.);
   Acts::Vector3 pos1_1(0., 0., 0.);
   Acts::Vector3 pos1_2(0., 0., 0.);
   Acts::Vector3 pos2_0(0., 0., 0.);
   Acts::Vector3 pos2_1(0., 0., 0.);
   Acts::Vector3 pos2_2(0., 0., 0.);
-        HepMC::FourVector truthmom;
-        HepMC::FourVector pv;
-	//!!!!!!!!!!!!!!!!!!!!
+  HepMC::FourVector truthmom;
+  HepMC::FourVector pv;
+
+  // create source links and measurements
+  std::vector<IndexSourceLink> sourceLinks;
+  std::vector<const Acts::Surface*> surfSequence;
+  MeasurementContainer measurements;
 
-  // Make the source links
   SpacePointForSeedCollection::const_iterator it = seed_spcollection->begin();
   SpacePointForSeedCollection::const_iterator itend = seed_spcollection->end();
   for (; it != itend; ++it){
-    const SpacePointForSeed *seed_sp = &(**it);
-    const Trk::SpacePoint *sp = seed_sp->SpacePoint();
-    auto faserSp = (Tracker::FaserSCT_SpacePoint*)sp;
-        ATH_MSG_DEBUG("TruthSeededTrack: SapcePoint test");
-    faserSp->dump(msg(MSG::INFO));
-    // ATH_MSG_DEBUG("TruthSeededTrack: SapcePoint " << *sp);
-    const Identifier id = sp->clusterList().first->identify();
+    const Trk::SpacePoint *sp = (&(**it))->SpacePoint();
 
+    const Identifier id = sp->clusterList().first->identify();
     const TrackerDD::SiDetectorElement* siSpElement = m_detManager->getDetectorElement(id);
     auto spElement = static_cast<const FaserActsDetectorElement>(siSpElement);
-
-	//!!!!!!!!!!!!!!!!!!!!
-	  // Get the truth position and momentum
-          //SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey, ctx);
-	  //SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap, ctx);
-          SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey);
-	  SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap);
-	  const auto& simdata = h_collectionMap->find(id)->second;
-	  const auto& deposits = simdata.getdeposits();
-	  for( const auto& depositPair : deposits)
-	  {
-		if (depositPair.first->pdg_id() == -13) {
-		pv = depositPair.first->production_vertex()->position();
-	        truthmom = depositPair.first->momentum();
-	        std::cout<<"!!!!!!!!!!!  production_vertex: ( "<<pv.x()<<",  "<<pv.y()<<",  "<<pv.z()<<" )  "<<std::endl;
-		}
-	  }
-
-	  // Get the measurements
-	Amg::Vector3D gloPos=sp->globalPosition();
-	int station = m_idHelper->station(id);
-	int plane = m_idHelper->layer(id);
-	if (station==1 && plane==0) { 
-		N_1_0++;
-	 pos1_0 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-           // Construct a plane surface as the target surface
-           const TrackerDD::SiDetectorDesign &design = siSpElement->design();
-           double hlX = design.width()/2. * 1_mm;
-           double hlY = design.length()/2. * 1_mm;
-           auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
-	   Amg::Transform3D g2l = siSpElement->getMaterialGeom()->getDefAbsoluteTransform()
-			           * Amg::CLHEPTransformToEigen(siSpElement->recoToHitTransform());
-           pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( g2l, rectangleBounds );
-	   
-	}
-	if (station==1 && plane==1) {
-		N_1_1++;
-	 pos1_1 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-	}
-	if (station==1 && plane==2) {
-		N_1_2++;
-	 pos1_2 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-	}
-	if (station==2 && plane==0) {
-		N_2_0++;
-	 pos2_0 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-	}
-	if (station==2 && plane==1) {
-		N_2_1++;
-	 pos2_1 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-	}
-	if (station==2 && plane==2) {
-		N_2_2++;
-	 pos2_2 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
-	}
-	//!!!!!!!!!!!!!!!!!!!!
-	
-  if (tVolume->confinedVolumes()) {
-    for (auto volume : tVolume->confinedVolumes()->arrayObjects()) {
-    if (volume->confinedLayers()) {
-      for (const auto& layer : volume->confinedLayers()->arrayObjects()) {
-        if (layer->layerType() == Acts::navigation) continue;
-        for (auto surface : layer->surfaceArray()->surfaces()) {
-          if (surface) {
-            const Acts::DetectorElementBase *detElement = surface->associatedDetectorElement();
-            const auto *faserDetElement = dynamic_cast<const FaserActsDetectorElement*>(detElement);
-            auto* tmp = const_cast<FaserActsDetectorElement*>(faserDetElement);
-            if (*tmp == spElement) {
-              sourceLinks.emplace_back(*const_cast<Acts::Surface*>(surface), *const_cast<Trk::SpacePoint*>(sp));
+    // Acts::GeometryIdentifier geoId = getGeometryIdentifier(id);
+    Acts::GeometryIdentifier geoId;
+
+    const Acts::TrackingVolume* tVolume = trackingGeometry->highestTrackingVolume();
+    if (tVolume->confinedVolumes()) {
+      for (auto volume : tVolume->confinedVolumes()->arrayObjects()) {
+        if (volume->confinedLayers()) {
+          for (const auto& layer : volume->confinedLayers()->arrayObjects()) {
+            if (layer->layerType() == Acts::navigation) continue;
+            for (auto surface : layer->surfaceArray()->surfaces()) {
+              if (surface) {
+                const Acts::DetectorElementBase *detElement = surface->associatedDetectorElement();
+                const auto *faserDetElement = dynamic_cast<const FaserActsDetectorElement*>(detElement);
+                auto* tmp = const_cast<FaserActsDetectorElement*>(faserDetElement);
+                if (*tmp == spElement) {
+                  geoId = surface->geometryId();
+                }
+              }
             }
           }
         }
       }
     }
+
+    const Acts::Surface* surfacePtr = trackingGeometry->findSurface(geoId);
+    surfSequence.push_back(surfacePtr);
+    if (not surfacePtr) {
+      ATH_MSG_ERROR("Could not find surface " << geoId);
+      return StatusCode::FAILURE;
+    }
+
+    Index spIdx = measurements.size();
+    IndexSourceLink sourceLink(geoId, spIdx);
+
+
+    auto par = sp->localParameters();
+    auto cov = sp->localCovariance();
+    std::array<Acts::BoundIndices, 2> indices = {Acts::eBoundLoc0, Acts::eBoundLoc1};
+    ThisMeasurement meas(sourceLink, indices, par, cov);
+    sourceLinks.push_back(std::move(sourceLink));
+    measurements.emplace_back(std::move(meas));
+
+
+    // Get the truth position and momentum
+    SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey);
+    SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap);
+    const auto& simdata = h_collectionMap->find(id)->second;
+    const auto& deposits = simdata.getdeposits();
+    for( const auto& depositPair : deposits)
+    {
+      if (depositPair.first->pdg_id() == -13) {
+        pv = depositPair.first->production_vertex()->position();
+        truthmom = depositPair.first->momentum();
+      }
+    }
+
+    // Get the measurements
+    Amg::Vector3D gloPos=sp->globalPosition();
+    int station = m_idHelper->station(id);
+    int plane = m_idHelper->layer(id);
+    if (station==1 && plane==0) {
+      N_1_0++;
+      pos1_0 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+
+      // Construct a plane surface as the target surface
+      const TrackerDD::SiDetectorDesign &design = siSpElement->design();
+      double hlX = design.width()/2. * 1_mm;
+      double hlY = design.length()/2. * 1_mm;
+      auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
+      Amg::Transform3D g2l = siSpElement->getMaterialGeom()->getDefAbsoluteTransform()
+                             * Amg::CLHEPTransformToEigen(siSpElement->recoToHitTransform());
+      pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( g2l, rectangleBounds );
+    }
+    if (station==1 && plane==1) {
+      N_1_1++;
+      pos1_1 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+    }
+    if (station==1 && plane==2) {
+      N_1_2++;
+      pos1_2 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+    }
+    if (station==2 && plane==0) {
+      N_2_0++;
+      pos2_0 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+    }
+    if (station==2 && plane==1) {
+      N_2_1++;
+      pos2_1 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+    }
+    if (station==2 && plane==2) {
+      N_2_2++;
+      pos2_2 = Acts::Vector3(gloPos.x(), gloPos.y(), gloPos.z());
+    }
   }
+
+  for (auto sl : sourceLinks)
+  {
+    std::cout << "??volume=" << sl.geometryId().volume() << std::endl;
+    std::cout << "??layer=" << sl.geometryId().layer() << std::endl;
+    std::cout << "??sensitive=" << sl.geometryId().sensitive() << std::endl;
   }
- }
 
   // Calculate the initial track parameters
   if ( (N_1_0==1) && (N_1_1==1) && (N_1_2==1) && (N_2_0==1) && (N_2_1==1) && (N_2_2==1)) {
-  std::cout<<"!!!!!!!!!!!  pos1_0 = ("<<pos1_0.x()<<", "<<pos1_0.y()<<", "<<pos1_0.z()<<") "<<std::endl; 
-  std::cout<<"!!!!!!!!!!!  pos1_1 = ("<<pos1_1.x()<<", "<<pos1_1.y()<<", "<<pos1_1.z()<<") "<<std::endl;
-  std::cout<<"!!!!!!!!!!!  pos1_2 = ("<<pos1_2.x()<<", "<<pos1_2.y()<<", "<<pos1_2.z()<<") "<<std::endl;
-  std::cout<<"!!!!!!!!!!!  pos2_0 = ("<<pos2_0.x()<<", "<<pos2_0.y()<<", "<<pos2_0.z()<<") "<<std::endl; 
-  std::cout<<"!!!!!!!!!!!  pos2_1 = ("<<pos2_1.x()<<", "<<pos2_1.y()<<", "<<pos2_1.z()<<") "<<std::endl;
-  std::cout<<"!!!!!!!!!!!  pos2_2 = ("<<pos2_2.x()<<", "<<pos2_2.y()<<", "<<pos2_2.z()<<") "<<std::endl;
-  //@FIXME: change the hard codes in future 
-  double charge = 1;
-  double B = 0.55;
-  //const Acts::Vector3 pos = pos1_0;
-  const Acts::Vector3 pos(pos1_0.x(), pos1_0.y(), pos1_0.z()-1);
-  Acts::Vector3 d1 = pos1_2 - pos1_0;
-  Acts::Vector3 d2 = pos2_2 - pos2_0;
-  // the direction of momentum in the first station
-  Acts::Vector3 direct1 = d1.normalized();
-  // the direction of momentum in the second station
-  Acts::Vector3 direct2 = d2.normalized();
-  // the vector pointing from the center of circle to the particle at layer 2 in Y-Z plane
-  double R1_z = charge * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
-  // double R1_y = -charge * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
-  // the vector pointing from the center of circle to the particle at layer 3 in Y-Z plane
-  double R2_z = charge * direct2.y() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z());
-  // double R2_y = -charge * direct2.z() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z());
-  // the norm of radius
-  double R = (pos2_0.z() - pos1_2.z()) / (R2_z - R1_z);
-  // the norm of momentum in Y-Z plane
-  double p_yz = 0.3*B*R / 1000.0;  // R(mm), p(GeV), B(T)
-  double p_z = p_yz * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
-  double p_y = p_yz * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
-  double p_x = direct1.x() * p_z / direct1.z();
-  // total momentum at the layer 0
-  const Acts::Vector3 mom(p_x, p_y, p_z);
-  double p = mom.norm();
-  std::cout<<"!!!!!!!!!!!  InitTrack momentum on layer 0: ( "<<mom.x()*1000<<",  "<<mom.y()*1000<<",  "<<mom.z()*1000<<",  "<<p*1000<<")  "<<std::endl;
-  // build the track covariance matrix using the smearing sigmas
-  double sigmaU = 200_um;
-  double sigmaV = 200_um;
-  double sigmaPhi = 1_degree;
-  double sigmaTheta = 1_degree;
-  double sigmaQOverP = 0.01*p / (p*p);
-  double sigmaT0 = 1_ns;
-  Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero();
-  cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = sigmaU * sigmaU;
-  cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = sigmaV * sigmaV;
-  cov(Acts::eBoundPhi, Acts::eBoundPhi) = sigmaPhi * sigmaPhi;
-  cov(Acts::eBoundTheta, Acts::eBoundTheta) = sigmaTheta * sigmaTheta;
-  cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = sigmaQOverP * sigmaQOverP;
-  cov(Acts::eBoundTime, Acts::eBoundTime) = sigmaT0 * sigmaT0;
-  double time =0;
-  //Acts::CurvilinearTrackParameters InitTrackParam(std::make_optional(std::move(cov)), pos, mom, charge, time); // calculated initial parameters
-	 
-  // Smearing truth parameters as initial parameters
-  Acts::Vector3 pPos(pv.x(), pv.y(), pv.z());	 
-  Acts::Vector3 pMom(truthmom.x()/1000., truthmom.y()/1000., truthmom.z()/1000.);
-  std::random_device rd;
-  std::default_random_engine rng {rd()};
-  std::normal_distribution<> norm; // mu: 0 sigma: 1
-  Acts::Vector3 deltaPos(sigmaU*norm(rng), sigmaU*norm(rng), sigmaU*norm(rng));
-  auto theta = Acts::VectorHelpers::theta(pMom.normalized());
-  auto phi = Acts::VectorHelpers::phi(pMom.normalized());
-  auto angles = Acts::detail::ensureThetaBounds(phi + sigmaPhi*norm(rng), theta + sigmaTheta*norm(rng));
-  Acts::Vector3 dir(std::sin(angles.second) * std::cos(angles.first),
-                     std::sin(angles.second) * std::sin(angles.first),
-                     std::cos(angles.second));
-  const Acts::Vector3 deltaMom = ( pMom.norm()*(1 + 0.01*norm(rng)) ) * dir - pMom;
-  std::cout << "deltaPos: " << deltaPos << std::endl;
-  std::cout << "deltaMom: " << deltaMom << std::endl;
-  const Acts::Vector4D posTime ((pPos+deltaPos).x(), (pPos+deltaPos).y(), (pPos+deltaPos).z(), time);
-  const Acts::Vector3 momentum = pMom+deltaMom;
-  const Acts::Vector3 momentum_dir = momentum.normalized();
-  double momentum_abs = momentum.norm();
-  Acts::CurvilinearTrackParameters InitTrackParam(posTime, momentum_dir, momentum_abs, charge, std::make_optional(std::move(cov))); 
-      
-  // the surface which the production point is bound to 
-  Acts::Vector3 center(0, 0, pPos.z());
-  Acts::Vector3 normal(0, 0, 1);
-  std::shared_ptr<const Acts::Surface> initSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
-  // extrapolate the particle from production point to the first layer
-  const Acts::Vector4D truthPosTime (pPos.x(), pPos.y(), pPos.z(), time);
-  const Acts::Vector3 truthMomentum_dir = pMom.normalized(); 
-  double truthMomentum_abs = pMom.norm();
-  Acts::BoundTrackParameters startParameters(initSurface, geoctx, truthPosTime, truthMomentum_dir, truthMomentum_abs, charge, std::nullopt);
-  auto truthParam = m_extrapolationTool->propagate(Gaudi::Hive::currentContext(), startParameters, *pSurface);
-  std::cout << "truth pos on 1st layer: " << truthParam->position(geoctx) << std::endl;
-  std::cout << "truth mom on 1st layer: " << truthParam->momentum() << std::endl;
-  std::cout << "truth parameters on 1st layer: " << truthParam->parameters() << std::endl;
-
-
-  // Call the Acts Kalman Filter
-  // Prepare the output data with MultiTrajectory
-  TrajectoryContainer trajectories;
-  trajectories.reserve(1);
-
-  // Construct a perigee surface as the target surface
-  //auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
-  //                Acts::Vector3{0., 0., 0.});
-
-  // Set the KalmanFitter options
-  std::unique_ptr<const Acts::Logger> logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::VERBOSE);
-  Acts::KalmanFitterOptions<Acts::VoidOutlierFinder> kfOptions(
-           geoctx,
-           magctx,
-           calctx,
-           Acts::VoidOutlierFinder(),
-	         Acts::LoggerWrapper{*logger},
-           Acts::PropagatorPlainOptions(),
-           &(*pSurface),
-	   true, // scattering
-	   true, // energy loss
-	   false  // backward filtering
-	   );
-
-  ATH_MSG_DEBUG("Invoke fitter");
-  
-  Acts::Navigator     navigator(trackingGeometry);
-  navigator.resolvePassive   = false;
-  navigator.resolveMaterial  = true;
-  navigator.resolveSensitive = true;
-
-  ActsExtrapolationDetail::VariantPropagator* varProp {nullptr};
-
-  if (m_fieldMode == "FASER") {
-    ATH_MSG_INFO("Using FASER magnetic field service");
-    using BField_t = FASERMagneticFieldWrapper;
-    BField_t bField;
-    auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
-    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
-                                                                      std::move(navigator));
-    varProp = new VariantPropagator(propagator);
-  }
-  else if (m_fieldMode == "Constant") {
-    std::vector<double> constantFieldVector = m_constantFieldVector;
-    double Bx = constantFieldVector.at(0);
-    double By = constantFieldVector.at(1);
-    double Bz = constantFieldVector.at(2);
-    ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << Bx << ", " << By << ", " << Bz << ")");
-    using BField_t = Acts::ConstantBField;
-    BField_t bField(Bx, By, Bz);
-    auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
-    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
-                                                                      std::move(navigator));
-    varProp = new VariantPropagator(propagator);
-  }
+    std::cout<<"!!!!!!!!!!!  pos1_0 = ("<<pos1_0.x()<<", "<<pos1_0.y()<<", "<<pos1_0.z()<<") "<<std::endl;
+    std::cout<<"!!!!!!!!!!!  pos1_1 = ("<<pos1_1.x()<<", "<<pos1_1.y()<<", "<<pos1_1.z()<<") "<<std::endl;
+    std::cout<<"!!!!!!!!!!!  pos1_2 = ("<<pos1_2.x()<<", "<<pos1_2.y()<<", "<<pos1_2.z()<<") "<<std::endl;
+    std::cout<<"!!!!!!!!!!!  pos2_0 = ("<<pos2_0.x()<<", "<<pos2_0.y()<<", "<<pos2_0.z()<<") "<<std::endl;
+    std::cout<<"!!!!!!!!!!!  pos2_1 = ("<<pos2_1.x()<<", "<<pos2_1.y()<<", "<<pos2_1.z()<<") "<<std::endl;
+    std::cout<<"!!!!!!!!!!!  pos2_2 = ("<<pos2_2.x()<<", "<<pos2_2.y()<<", "<<pos2_2.z()<<") "<<std::endl;
+    //@FIXME: change the hard codes in future
+    double charge = 1;
+    double B = 0.55;
+    //const Acts::Vector3 pos = pos1_0;
+    const Acts::Vector3 pos(pos1_0.x(), pos1_0.y(), pos1_0.z()-1);
+    Acts::Vector3 d1 = pos1_2 - pos1_0;
+    Acts::Vector3 d2 = pos2_2 - pos2_0;
+    // the direction of momentum in the first station
+    Acts::Vector3 direct1 = d1.normalized();
+    // the direction of momentum in the second station
+    Acts::Vector3 direct2 = d2.normalized();
+    // the vector pointing from the center of circle to the particle at layer 2 in Y-Z plane
+    double R1_z = charge * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
+    // double R1_y = -charge * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
+    // the vector pointing from the center of circle to the particle at layer 3 in Y-Z plane
+    double R2_z = charge * direct2.y() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z());
+    // double R2_y = -charge * direct2.z() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z());
+    // the norm of radius
+    double R = (pos2_0.z() - pos1_2.z()) / (R2_z - R1_z);
+    // the norm of momentum in Y-Z plane
+    double p_yz = 0.3*B*R / 1000.0;  // R(mm), p(GeV), B(T)
+    double p_z = p_yz * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
+    double p_y = p_yz * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z());
+    double p_x = direct1.x() * p_z / direct1.z();
+    // total momentum at the layer 0
+    const Acts::Vector3 mom(p_x, p_y, p_z);
+    double p = mom.norm();
+    std::cout<<"!!!!!!!!!!!  InitTrack momentum on layer 0: ( "<<mom.x()*1000<<",  "<<mom.y()*1000<<",  "<<mom.z()*1000<<",  "<<p*1000<<")  "<<std::endl;
+    // build the track covariance matrix using the smearing sigmas
+    double sigmaU = 200_um;
+    double sigmaV = 200_um;
+    double sigmaPhi = 1_degree;
+    double sigmaTheta = 1_degree;
+    double sigmaQOverP = 0.01*p / (p*p);
+    double sigmaT0 = 1_ns;
+    Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero();
+    cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = sigmaU * sigmaU;
+    cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = sigmaV * sigmaV;
+    cov(Acts::eBoundPhi, Acts::eBoundPhi) = sigmaPhi * sigmaPhi;
+    cov(Acts::eBoundTheta, Acts::eBoundTheta) = sigmaTheta * sigmaTheta;
+    cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = sigmaQOverP * sigmaQOverP;
+    cov(Acts::eBoundTime, Acts::eBoundTime) = sigmaT0 * sigmaT0;
+    double time =0;
+    //Acts::CurvilinearTrackParameters InitTrackParam(std::make_optional(std::move(cov)), pos, mom, charge, time); // calculated initial parameters
+
+    // Smearing truth parameters as initial parameters
+    Acts::Vector3 pPos(pv.x(), pv.y(), pv.z());
+    Acts::Vector3 pMom(truthmom.x()/1000., truthmom.y()/1000., truthmom.z()/1000.);
+    std::random_device rd;
+    std::default_random_engine rng {rd()};
+    std::normal_distribution<> norm; // mu: 0 sigma: 1
+    Acts::Vector3 deltaPos(sigmaU*norm(rng), sigmaU*norm(rng), sigmaU*norm(rng));
+    auto theta = Acts::VectorHelpers::theta(pMom.normalized());
+    auto phi = Acts::VectorHelpers::phi(pMom.normalized());
+    auto angles = Acts::detail::normalizePhiTheta(phi + sigmaPhi*norm(rng), theta + sigmaTheta*norm(rng));
+    Acts::Vector3 dir(std::sin(angles.second) * std::cos(angles.first),
+                      std::sin(angles.second) * std::sin(angles.first),
+                      std::cos(angles.second));
+    const Acts::Vector3 deltaMom = ( pMom.norm()*(1 + 0.01*norm(rng)) ) * dir - pMom;
+    std::cout << "deltaPos: " << deltaPos << std::endl;
+    std::cout << "deltaMom: " << deltaMom << std::endl;
+    const Acts::Vector4 posTime ((pPos+deltaPos).x(), (pPos+deltaPos).y(), (pPos+deltaPos).z(), time);
+    const Acts::Vector3 momentum = pMom+deltaMom;
+    const Acts::Vector3 momentum_dir = momentum.normalized();
+    double momentum_abs = momentum.norm();
+    Acts::CurvilinearTrackParameters InitTrackParam(posTime, momentum_dir, momentum_abs, charge, std::make_optional(std::move(cov)));
+
+    // the surface which the production point is bound to
+    Acts::Vector3 center(0, 0, pPos.z());
+    Acts::Vector3 normal(0, 0, 1);
+    std::shared_ptr<const Acts::Surface> initSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
+    // extrapolate the particle from production point to the first layer
+    const Acts::Vector4 truthPosTime (pPos.x(), pPos.y(), pPos.z(), time);
+    const Acts::Vector3 truthMomentum_dir = pMom.normalized();
+    double truthMomentum_abs = pMom.norm();
+
+    BoundVector params = BoundVector::Zero();
+    params[Acts::eBoundLoc0] = pPos.x();
+    params[Acts::eBoundLoc1] = pPos.y();
+    params[Acts::eBoundPhi] = Acts::VectorHelpers::phi(pMom.normalized());
+    params[Acts::eBoundTheta] = Acts::VectorHelpers::theta(pMom.normalized());
+    params[Acts::eBoundQOverP] = charge/p;
+    params[Acts::eBoundTime] = time;
+
+    Acts::BoundTrackParameters startParameters(initSurface, params, charge, std::nullopt);
+    auto truthParam = m_extrapolationTool->propagate(Gaudi::Hive::currentContext(), startParameters, *pSurface);
+    std::cout << "truth pos on 1st layer: " << truthParam->position(geoctx) << std::endl;
+    std::cout << "truth mom on 1st layer: " << truthParam->momentum() << std::endl;
+    std::cout << "truth parameters on 1st layer: " << truthParam->parameters() << std::endl;
+
+
+    // Call the Acts Kalman Filter
+    // Prepare the output data with MultiTrajectory
+    TrajectoryContainer trajectories;
+    trajectories.reserve(1);
+
+    // Construct a perigee surface as the target surface
+    //auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
+    //                Acts::Vector3{0., 0., 0.});
+
+    // Set the KalmanFitter options
+    std::unique_ptr<const Acts::Logger> logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::VERBOSE);
+    Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder> kfOptions(
+        geoctx,
+        magctx,
+        calctx,
+        MeasurementCalibrator(measurements),
+        Acts::VoidOutlierFinder(),
+        Acts::LoggerWrapper{*logger},
+        Acts::PropagatorPlainOptions(),
+        &(*pSurface),
+        true, // scattering
+        true, // energy loss
+        false  // backward filtering
+    );
+
+    ATH_MSG_DEBUG("Invoke fitter");
+
+    // Acts::Navigator     navigator(trackingGeometry);
+    Acts::DirectNavigator     navigator;
+    // navigator.resolvePassive   = false;
+    // navigator.resolveMaterial  = true;
+    // navigator.resolveSensitive = true;
+
+    std::unique_ptr<ActsExtrapolationDetail::VariantPropagator> varProp;
+
+    if (m_fieldMode == "FASER") {
+      ATH_MSG_INFO("Using FASER magnetic field service");
+      ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+      auto bField = std::make_shared<FASERMagneticFieldWrapper>();
+      auto stepper = Acts::EigenStepper<>(std::move(bField));
+      auto propagator = Acts::Propagator<decltype(stepper), Acts::DirectNavigator>(std::move(stepper),
+                                                                                   std::move(navigator));
+      varProp = std::make_unique<VariantPropagator>(propagator);
+    }
+    else if (m_fieldMode == "Constant") {
+      if (m_constantFieldVector.value().size() != 3)
+      {
+        ATH_MSG_ERROR("Incorrect field vector size. Using empty field.");
+        return StatusCode::FAILURE; 
+      }
 
-     auto fit = makeFitterFunction(varProp);
-     auto result = fit(sourceLinks, InitTrackParam, kfOptions);
-
-     ATH_MSG_VERBOSE("Size of sourceLinks: " << sourceLinks.size());
-
-     int itrack = 0;
-     if (result.ok()) {
-       // Get the fit output object
-       const auto& fitOutput = result.value();
-       
-       // The track entry indices container. One element here.
-       std::vector<size_t> trackTips;
-       trackTips.reserve(1);
-       trackTips.emplace_back(fitOutput.trackTip);
-       // The fitted parameters container. One element (at most) here.
-       IndexedParams indexedParams;
-
-       if (fitOutput.fittedParameters) {
-         const auto& params = fitOutput.fittedParameters.value();
-         ATH_MSG_VERBOSE("Fitted paramemeters for track " << itrack);
-         ATH_MSG_VERBOSE("  parameters: " << params);
-	 ATH_MSG_VERBOSE("  position: " << params.position(geoctx).transpose());
-	 ATH_MSG_VERBOSE("  momentum: " << params.momentum().transpose());
-	 // Push the fitted parameters to the container
-	 indexedParams.emplace(fitOutput.trackTip, std::move(params));
-        } else {
-          ATH_MSG_DEBUG("No fitted paramemeters for track " << itrack);
-        }
-        // Create a SimMultiTrajectory
-	trajectories.emplace_back(std::move(fitOutput.fittedStates),
-	                          std::move(trackTips), std::move(indexedParams));
+      Acts::Vector3 constantFieldVector = Acts::Vector3(m_constantFieldVector[0], 
+                                                        m_constantFieldVector[1], 
+                                                        m_constantFieldVector[2]);
+
+      ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << m_constantFieldVector[0] << ", " 
+                                                                     << m_constantFieldVector[1] << ", " 
+                                                                     << m_constantFieldVector[2] << ")");
+      auto bField = std::make_shared<Acts::ConstantBField>(constantFieldVector);
+      auto stepper = Acts::EigenStepper<>(std::move(bField));
+      auto propagator = Acts::Propagator<decltype(stepper), Acts::DirectNavigator>(std::move(stepper),
+                                                                                   std::move(navigator));
+      varProp = std::make_unique<VariantPropagator>(propagator);
+    }
+
+    auto fit = makeFitterFunction(varProp.get());
+    auto result = fit(sourceLinks, InitTrackParam, kfOptions, surfSequence);
+
+    ATH_MSG_VERBOSE("Size of sourceLinks: " << sourceLinks.size());
+
+    int itrack = 0;
+    if (result.ok()) {
+      // Get the fit output object
+      const auto& fitOutput = result.value();
+
+      // The track entry indices container. One element here.
+      std::vector<size_t> trackTips;
+      trackTips.reserve(1);
+      trackTips.emplace_back(fitOutput.lastMeasurementIndex);
+      // The fitted parameters container. One element (at most) here.
+      IndexedParams indexedParams;
+
+      if (fitOutput.fittedParameters) {
+        const auto& params = fitOutput.fittedParameters.value();
+        ATH_MSG_VERBOSE("Fitted paramemeters for track " << itrack);
+        ATH_MSG_VERBOSE("  parameters: " << params);
+        ATH_MSG_VERBOSE("  position: " << params.position(geoctx).transpose());
+        ATH_MSG_VERBOSE("  momentum: " << params.momentum().transpose());
+        // Push the fitted parameters to the container
+        indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params));
       } else {
-            ATH_MSG_WARNING("Fit failed for track " << itrack << " with error"
-               << result.error());
-            // Fit failed, but still create a empty truth fit track
-            trajectories.push_back(FaserActsRecMultiTrajectory());
+        ATH_MSG_DEBUG("No fitted paramemeters for track " << itrack);
       }
-  
+      // Create a SimMultiTrajectory
+      trajectories.emplace_back(std::move(fitOutput.fittedStates),
+                                std::move(trackTips), std::move(indexedParams));
+    } else {
+      ATH_MSG_WARNING("Fit failed for track " << itrack << " with error"
+                                              << result.error());
+      // Fit failed, but still create a empty truth fit track
+      trajectories.push_back(FaserActsRecMultiTrajectory());
+    }
 
-  fillFitResult(geoctx, trajectories, *truthParam);
+
+    fillFitResult(geoctx, trajectories, *truthParam);
 
   }
   return StatusCode::SUCCESS;
 }
 
-StatusCode FaserActsKalmanFilterAlg::finalize() 
+StatusCode FaserActsKalmanFilterAlg::finalize()
 {
   return StatusCode::SUCCESS;
 }
 
+namespace {
 
-template <typename Fitter>
-struct FitterFunctionImpl
+  template <typename Fitter>
+  struct FitterFunctionImpl
   {
     Fitter fitter;
 
@@ -494,39 +597,41 @@ struct FitterFunctionImpl
 
     FaserActsKalmanFilterAlg::FitterResult
     operator()(
-      const std::vector<RecSourceLink>&    sourceLinks,
-      const Acts::CurvilinearTrackParameters&   initialParameters,
-      const Acts::KalmanFitterOptions<Acts::VoidOutlierFinder>& options) const
+        const std::vector<IndexSourceLink>&    sourceLinks,
+        const Acts::CurvilinearTrackParameters&   initialParameters,
+        const Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder>& options,
+        const std::vector<const Acts::Surface*>& sSequence) const
     {
-        return fitter.fit(sourceLinks, initialParameters, options);
+      return fitter.fit(sourceLinks, initialParameters, options, sSequence);
     };
   };
+}
 
 FaserActsKalmanFilterAlg::FitterFunction
 FaserActsKalmanFilterAlg::makeFitterFunction(
-     ActsExtrapolationDetail::VariantPropagator* varProp)
+    ActsExtrapolationDetail::VariantPropagator* varProp)
 {
 
   return boost::apply_visitor([&](const auto& propagator) -> FitterFunction {
     using Updater  = Acts::GainMatrixUpdater;
     using Smoother = Acts::GainMatrixSmoother;
-    using Fitter        = Acts::KalmanFitter<typename std::decay_t<decltype(propagator)>, Updater, Smoother>;
+    using Fitter = Acts::KalmanFitter<typename std::decay_t<decltype(propagator)>, Updater, Smoother>;
 
     Fitter     fitter(std::move(propagator));
     // build the fitter functions. owns the fitter object.
     return FitterFunctionImpl<Fitter>(std::move(fitter));
-    }, *varProp);
+  }, *varProp);
 
 }
 
 //Acts::MagneticFieldContext FaserActsKalmanFilterAlg::getMagneticFieldContext(const EventContext& ctx) const {
-  //SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+//SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
 Acts::MagneticFieldContext FaserActsKalmanFilterAlg::getMagneticFieldContext() const {
   SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey};
   if (!readHandle.isValid()) {
-     std::stringstream msg;
-     msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << ".";
-     throw std::runtime_error(msg.str());
+    std::stringstream msg;
+    msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << ".";
+    throw std::runtime_error(msg.str());
   }
   const FaserFieldCacheCondObj* fieldCondObj{*readHandle};
 
@@ -680,10 +785,10 @@ void FaserActsKalmanFilterAlg::initializeTree()
 }
 
 void FaserActsKalmanFilterAlg::fillFitResult(
-		const Acts::GeometryContext& geoctx,
-		const TrajectoryContainer& trajectories, 
-		const Acts::BoundTrackParameters& truthParam
-		)
+    const Acts::GeometryContext& geoctx,
+    const TrajectoryContainer& trajectories,
+    const Acts::BoundTrackParameters& truthParam
+)
 {
   m_t_eLOC0 = truthParam.parameters()[Acts::eBoundLoc0];
   m_t_eLOC1 = truthParam.parameters()[Acts::eBoundLoc1];
@@ -728,380 +833,381 @@ void FaserActsKalmanFilterAlg::fillFitResult(
     m_chi2_fit = trajState.chi2Sum;
     m_ndf_fit = trajState.NDF;
     std::cout << "Track has " << trajState.nMeasurements
-	      << " measurements and " << trajState.nHoles
-	      << " holes and " << trajState.nOutliers 
-	      << " outliers and " << trajState.nStates
-	      << " states " << std::endl;
-  
-  /// If it has track parameters, fill the values
-  if (traj.hasTrackParameters(trackTip))
-  {
-    m_hasFittedParams = true;
-    const auto &boundParam = traj.trackParameters(trackTip);
-    const auto &parameter = boundParam.parameters();
-    const auto &covariance = *boundParam.covariance();
-    m_charge_fit = boundParam.charge();
-    m_eLOC0_fit = parameter[Acts::eBoundLoc0];
-    m_eLOC1_fit = parameter[Acts::eBoundLoc1];
-    m_ePHI_fit = parameter[Acts::eBoundPhi];
-    m_eTHETA_fit = parameter[Acts::eBoundTheta];
-    m_eQOP_fit = parameter[Acts::eBoundQOverP];
-    m_eT_fit = parameter[Acts::eBoundTime];
-    m_err_eLOC0_fit =
-        sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0));
-    m_err_eLOC1_fit =
-        sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1));
-    m_err_ePHI_fit = sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi));
-    m_err_eTHETA_fit =
-        sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta));
-    m_err_eQOP_fit = sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP));
-    m_err_eT_fit = sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime));
-
-    m_px_fit = boundParam.momentum()(0);
-    m_py_fit = boundParam.momentum()(1);
-    m_pz_fit = boundParam.momentum()(2);
-    m_x_fit  = boundParam.position(geoctx)(0);
-    m_y_fit  = boundParam.position(geoctx)(1);
-    m_z_fit  = boundParam.position(geoctx)(2);
-  }
-   
-  m_nPredicted = 0; 
-  m_nFiltered = 0; 
-  m_nSmoothed = 0; 
-
-  mj.visitBackwards(trackTip, [&](const auto &state) {
-    /// Only fill the track states with non-outlier measurement
-    auto typeFlags = state.typeFlags();
-    if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag))
-    {
-      return true;
-    }
+              << " measurements and " << trajState.nHoles
+              << " holes and " << trajState.nOutliers
+              << " outliers and " << trajState.nStates
+              << " states " << std::endl;
 
-    /// Get the geometry ID
-    auto geoID = state.referenceSurface().geometryId();
-    m_volumeID.push_back(geoID.volume());
-    m_layerID.push_back(geoID.layer());
-    m_moduleID.push_back(geoID.sensitive());
-
-    auto meas = std::get<Measurement>(*state.uncalibrated());
-
-    /// Get local position
-    Acts::Vector2D local(meas.parameters()[Acts::eBoundLoc0],
-                         meas.parameters()[Acts::eBoundLoc1]);
-    /// Get global position
-    Acts::Vector3 global(0, 0, 0);
-    /// This is an arbitrary vector. Doesn't matter in coordinate transformation
-    /// in Acts code
-    Acts::Vector3 mom(1, 1, 1);
-    global = meas.referenceObject().localToGlobal(geoctx, local, mom);
-
-    /// Get measurement covariance
-    auto cov = meas.covariance();
-
-    m_lx_hit.push_back(local.x());
-    m_ly_hit.push_back(local.y());
-    m_x_hit.push_back(global.x());
-    m_y_hit.push_back(global.y());
-    m_z_hit.push_back(global.z());
-
-    /// Get the predicted parameter for this state
-    bool predicted = false;
-    if (state.hasPredicted())
+    /// If it has track parameters, fill the values
+    if (traj.hasTrackParameters(trackTip))
     {
-      predicted = true;
-      m_nPredicted++;
-      Acts::BoundTrackParameters parameter(
-          state.referenceSurface().getSharedPtr(),
-          state.predicted(),
-          state.predictedCovariance());
-      auto covariance = state.predictedCovariance();
-
-      /// Local hit residual info
-      auto H = meas.projector();
-      auto resCov = cov + H * covariance * H.transpose();
-      auto residual = meas.residual(state.predicted());
-
-      /// Predicted residual
-      m_res_eLOC0_prt.push_back(residual(Acts::eBoundLoc0));
-      m_res_eLOC1_prt.push_back(residual(Acts::eBoundLoc1));
-
-      /// Predicted parameter pulls
-      m_pull_eLOC0_prt.push_back(
-          residual(Acts::eBoundLoc0) /
-          sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_pull_eLOC1_prt.push_back(
-          residual(Acts::eBoundLoc1) /
-          sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-
-
-      /// Predicted parameter
-      m_eLOC0_prt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
-      m_eLOC1_prt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
-      m_ePHI_prt.push_back(parameter.parameters()[Acts::eBoundPhi]);
-      m_eTHETA_prt.push_back(parameter.parameters()[Acts::eBoundTheta]);
-      m_eQOP_prt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
-      m_eT_prt.push_back(parameter.parameters()[Acts::eBoundTime]);
-
-      /// Predicted parameter Uncertainties
-      m_err_eLOC0_prt.push_back(
-          sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_err_eLOC1_prt.push_back(
-          sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-      m_err_ePHI_prt.push_back(
-          sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
-      m_err_eTHETA_prt.push_back(
-          sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
-      m_err_eQOP_prt.push_back(
-          sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
-      m_err_eT_prt.push_back(
-          sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
-
-      m_x_prt.push_back(parameter.position(geoctx).x());
-      m_y_prt.push_back(parameter.position(geoctx).y());
-      m_z_prt.push_back(parameter.position(geoctx).z());
-      m_px_prt.push_back(parameter.momentum().x());
-      m_py_prt.push_back(parameter.momentum().y());
-      m_pz_prt.push_back(parameter.momentum().z());
-      m_pT_prt.push_back(parameter.transverseMomentum());
-      m_eta_prt.push_back(eta(parameter.position(geoctx)));
-    }
-    else
-    {
-      /// Push bad values if no predicted parameter
-      m_eLOC0_prt.push_back(-9999);
-      m_eLOC1_prt.push_back(-9999);
-      m_ePHI_prt.push_back(-9999);
-      m_eTHETA_prt.push_back(-9999);
-      m_eQOP_prt.push_back(-9999);
-      m_eT_prt.push_back(-9999);
-      m_res_eLOC0_prt.push_back(-9999);
-      m_res_eLOC1_prt.push_back(-9999);
-      m_err_eLOC0_prt.push_back(-9999);
-      m_err_eLOC1_prt.push_back(-9999);
-      m_err_ePHI_prt.push_back(-9999);
-      m_err_eTHETA_prt.push_back(-9999);
-      m_err_eQOP_prt.push_back(-9999);
-      m_err_eT_prt.push_back(-9999);
-      m_pull_eLOC0_prt.push_back(-9999);
-      m_pull_eLOC1_prt.push_back(-9999);
-      m_x_prt.push_back(-9999);
-      m_y_prt.push_back(-9999);
-      m_z_prt.push_back(-9999);
-      m_px_prt.push_back(-9999);
-      m_py_prt.push_back(-9999);
-      m_pz_prt.push_back(-9999);
-      m_pT_prt.push_back(-9999);
-      m_eta_prt.push_back(-9999);
+      m_hasFittedParams = true;
+      const auto &boundParam = traj.trackParameters(trackTip);
+      const auto &parameter = boundParam.parameters();
+      const auto &covariance = *boundParam.covariance();
+      m_charge_fit = boundParam.charge();
+      m_eLOC0_fit = parameter[Acts::eBoundLoc0];
+      m_eLOC1_fit = parameter[Acts::eBoundLoc1];
+      m_ePHI_fit = parameter[Acts::eBoundPhi];
+      m_eTHETA_fit = parameter[Acts::eBoundTheta];
+      m_eQOP_fit = parameter[Acts::eBoundQOverP];
+      m_eT_fit = parameter[Acts::eBoundTime];
+      m_err_eLOC0_fit =
+          sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0));
+      m_err_eLOC1_fit =
+          sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1));
+      m_err_ePHI_fit = sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi));
+      m_err_eTHETA_fit =
+          sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta));
+      m_err_eQOP_fit = sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP));
+      m_err_eT_fit = sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime));
+
+      m_px_fit = boundParam.momentum()(0);
+      m_py_fit = boundParam.momentum()(1);
+      m_pz_fit = boundParam.momentum()(2);
+      m_x_fit  = boundParam.position(geoctx)(0);
+      m_y_fit  = boundParam.position(geoctx)(1);
+      m_z_fit  = boundParam.position(geoctx)(2);
     }
 
-    bool filtered = false;
-    if (state.hasFiltered())
-    {
-      filtered = true;
-      m_nFiltered++;
-      Acts::BoundTrackParameters parameter(
-          state.referenceSurface().getSharedPtr(),
-          state.filtered(),
-          state.filteredCovariance());
-      auto covariance = state.filteredCovariance();
-
-      /// Local hit residual info
-      auto H = meas.projector();
-      auto resCov = cov + H * covariance * H.transpose();
-      auto residual = meas.residual(state.filtered());
-
-      /// Filtered residual
-      m_res_eLOC0_flt.push_back(residual(Acts::eBoundLoc0));
-      m_res_eLOC1_flt.push_back(residual(Acts::eBoundLoc1));
-
-      /// Filtered parameter pulls
-      m_pull_eLOC0_flt.push_back(
-          residual(Acts::eBoundLoc0) /
-          sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_pull_eLOC1_flt.push_back(
-          residual(Acts::eBoundLoc1) /
-          sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-
-      /// Filtered parameter
-      m_eLOC0_flt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
-      m_eLOC1_flt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
-      m_ePHI_flt.push_back(parameter.parameters()[Acts::eBoundPhi]);
-      m_eTHETA_flt.push_back(parameter.parameters()[Acts::eBoundTheta]);
-      m_eQOP_flt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
-      m_eT_flt.push_back(parameter.parameters()[Acts::eBoundTime]);
-
-      /// Filtered parameter uncertainties
-      m_err_eLOC0_flt.push_back(
-          sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_err_eLOC1_flt.push_back(
-          sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-      m_err_ePHI_flt.push_back(
-          sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
-      m_err_eTHETA_flt.push_back(
-          sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
-      m_err_eQOP_flt.push_back(
-          sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
-      m_err_eT_flt.push_back(
-          sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
-
-      /// Other filtered parameter info
-      m_x_flt.push_back(parameter.position(geoctx).x());
-      m_y_flt.push_back(parameter.position(geoctx).y());
-      m_z_flt.push_back(parameter.position(geoctx).z());
-      m_px_flt.push_back(parameter.momentum().x());
-      m_py_flt.push_back(parameter.momentum().y());
-      m_pz_flt.push_back(parameter.momentum().z());
-      m_pT_flt.push_back(parameter.transverseMomentum());
-      m_eta_flt.push_back(eta(parameter.position(geoctx)));
-      m_chi2.push_back(state.chi2());
-      
-    }
-    else
-    {
-      /// Push bad values if no filtered parameter
-      m_eLOC0_flt.push_back(-9999);
-      m_eLOC1_flt.push_back(-9999);
-      m_ePHI_flt.push_back(-9999);
-      m_eTHETA_flt.push_back(-9999);
-      m_eQOP_flt.push_back(-9999);
-      m_eT_flt.push_back(-9999);
-      m_res_eLOC0_flt.push_back(-9999);
-      m_res_eLOC1_flt.push_back(-9999);
-      m_err_eLOC0_flt.push_back(-9999);
-      m_err_eLOC1_flt.push_back(-9999);
-      m_err_ePHI_flt.push_back(-9999);
-      m_err_eTHETA_flt.push_back(-9999);
-      m_err_eQOP_flt.push_back(-9999);
-      m_err_eT_flt.push_back(-9999);
-      m_pull_eLOC0_flt.push_back(-9999);
-      m_pull_eLOC1_flt.push_back(-9999);
-      m_x_flt.push_back(-9999);
-      m_y_flt.push_back(-9999);
-      m_z_flt.push_back(-9999);
-      m_py_flt.push_back(-9999);
-      m_pz_flt.push_back(-9999);
-      m_pT_flt.push_back(-9999);
-      m_eta_flt.push_back(-9999);
-      m_chi2.push_back(-9999);
-    }
-  
-    bool smoothed = false;
-    if (state.hasSmoothed())
-    {
-      smoothed = true;
-      m_nSmoothed++;
-      Acts::BoundTrackParameters parameter(
-          state.referenceSurface().getSharedPtr(),
-          state.smoothed(),
-          state.smoothedCovariance());
-      auto covariance = state.smoothedCovariance();
-
-      /// Local hit residual info
-      auto H = meas.projector();
-      auto resCov = cov + H * covariance * H.transpose();
-      auto residual = meas.residual(state.smoothed());
-
-      m_res_x_hit.push_back(residual(Acts::eBoundLoc0));
-      m_res_y_hit.push_back(residual(Acts::eBoundLoc1));
-      m_err_x_hit.push_back(
-          sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_err_y_hit.push_back(
-          sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-      m_pull_x_hit.push_back(
-          residual(Acts::eBoundLoc0) /
-          sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_pull_y_hit.push_back(
-          residual(Acts::eBoundLoc1) /
-          sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-      m_dim_hit.push_back(state.calibratedSize());
-
-      /// Smoothed residual
-      m_res_eLOC0_smt.push_back(residual(Acts::eBoundLoc0));
-      m_res_eLOC1_smt.push_back(residual(Acts::eBoundLoc1));
-
-      /// Smoothed parameter pulls
-      m_pull_eLOC0_smt.push_back(
-          residual(Acts::eBoundLoc0) /
-          sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_pull_eLOC1_smt.push_back(
-          residual(Acts::eBoundLoc1) /
-          sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-
-      /// Smoothed parameter
-      m_eLOC0_smt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
-      m_eLOC1_smt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
-      m_ePHI_smt.push_back(parameter.parameters()[Acts::eBoundPhi]);
-      m_eTHETA_smt.push_back(parameter.parameters()[Acts::eBoundTheta]);
-      m_eQOP_smt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
-      m_eT_smt.push_back(parameter.parameters()[Acts::eBoundTime]);
-
-      /// Smoothed parameter uncertainties
-      m_err_eLOC0_smt.push_back(
-          sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
-      m_err_eLOC1_smt.push_back(
-          sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
-      m_err_ePHI_smt.push_back(
-          sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
-      m_err_eTHETA_smt.push_back(
-          sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
-      m_err_eQOP_smt.push_back(
-          sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
-      m_err_eT_smt.push_back(
-          sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
-
-      m_x_smt.push_back(parameter.position(geoctx).x());
-      m_y_smt.push_back(parameter.position(geoctx).y());
-      m_z_smt.push_back(parameter.position(geoctx).z());
-      m_px_smt.push_back(parameter.momentum().x());
-      m_py_smt.push_back(parameter.momentum().y());
-      m_pz_smt.push_back(parameter.momentum().z());
-      m_pT_smt.push_back(parameter.transverseMomentum());
-      m_eta_smt.push_back(eta(parameter.position(geoctx)));
-    }
-    else
-    {
-      /// Push bad values if no smoothed parameter
-      m_eLOC0_smt.push_back(-9999);
-      m_eLOC1_smt.push_back(-9999);
-      m_ePHI_smt.push_back(-9999);
-      m_eTHETA_smt.push_back(-9999);
-      m_eQOP_smt.push_back(-9999);
-      m_eT_smt.push_back(-9999);
-      m_res_eLOC0_smt.push_back(-9999);
-      m_res_eLOC1_smt.push_back(-9999);
-      m_err_eLOC0_smt.push_back(-9999);
-      m_err_eLOC1_smt.push_back(-9999);
-      m_err_ePHI_smt.push_back(-9999);
-      m_err_eTHETA_smt.push_back(-9999);
-      m_err_eQOP_smt.push_back(-9999);
-      m_err_eT_smt.push_back(-9999);
-      m_pull_eLOC0_smt.push_back(-9999);
-      m_pull_eLOC1_smt.push_back(-9999);
-      m_x_smt.push_back(-9999);
-      m_y_smt.push_back(-9999);
-      m_z_smt.push_back(-9999);
-      m_px_smt.push_back(-9999);
-      m_py_smt.push_back(-9999);
-      m_pz_smt.push_back(-9999);
-      m_pT_smt.push_back(-9999);
-      m_eta_smt.push_back(-9999);
-      m_res_x_hit.push_back(-9999);
-      m_res_y_hit.push_back(-9999);
-      m_err_x_hit.push_back(-9999);
-      m_err_y_hit.push_back(-9999);
-      m_pull_x_hit.push_back(-9999);
-      m_pull_y_hit.push_back(-9999);
-      m_dim_hit.push_back(-9999);
-    }
+    m_nPredicted = 0;
+    m_nFiltered = 0;
+    m_nSmoothed = 0;
+
+    mj.visitBackwards(trackTip, [&](const auto &state) {
+      /// Only fill the track states with non-outlier measurement
+      auto typeFlags = state.typeFlags();
+      if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag))
+      {
+        return true;
+      }
+
+      const auto& surface = state.referenceSurface();
+
+      /// Get the geometry ID
+      auto geoID = state.referenceSurface().geometryId();
+      m_volumeID.push_back(geoID.volume());
+      m_layerID.push_back(geoID.layer());
+      m_moduleID.push_back(geoID.sensitive());
+
+      // expand the local measurements into the full bound space
+      Acts::BoundVector meas =
+          state.projector().transpose() * state.calibrated();
+
+      // extract local and global position
+      Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]);
+      Acts::Vector3 mom(1, 1, 1);
+      Acts::Vector3 global =
+          surface.localToGlobal(geoctx, local, mom);
+
+      // fill the measurement info
+      m_lx_hit.push_back(local[Acts::ePos0]);
+      m_ly_hit.push_back(local[Acts::ePos1]);
+      m_x_hit.push_back(global[Acts::ePos0]);
+      m_y_hit.push_back(global[Acts::ePos1]);
+      m_z_hit.push_back(global[Acts::ePos2]);
+
+      /// Get the predicted parameter for this state
+      bool predicted = false;
+      if (state.hasPredicted())
+      {
+        predicted = true;
+        m_nPredicted++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.predicted(),
+            state.predictedCovariance());
+        auto covariance = state.predictedCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.predicted();
+
+        /// Predicted residual
+        m_res_eLOC0_prt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_prt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Predicted parameter pulls
+        m_pull_eLOC0_prt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_prt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+
+        /// Predicted parameter
+        m_eLOC0_prt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_prt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_prt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_prt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_prt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_prt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Predicted parameter Uncertainties
+        m_err_eLOC0_prt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_prt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_prt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_prt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_prt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_prt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        m_x_prt.push_back(parameter.position(geoctx).x());
+        m_y_prt.push_back(parameter.position(geoctx).y());
+        m_z_prt.push_back(parameter.position(geoctx).z());
+        m_px_prt.push_back(parameter.momentum().x());
+        m_py_prt.push_back(parameter.momentum().y());
+        m_pz_prt.push_back(parameter.momentum().z());
+        m_pT_prt.push_back(parameter.transverseMomentum());
+        m_eta_prt.push_back(eta(parameter.position(geoctx)));
+      }
+      else
+      {
+        /// Push bad values if no predicted parameter
+        m_eLOC0_prt.push_back(-9999);
+        m_eLOC1_prt.push_back(-9999);
+        m_ePHI_prt.push_back(-9999);
+        m_eTHETA_prt.push_back(-9999);
+        m_eQOP_prt.push_back(-9999);
+        m_eT_prt.push_back(-9999);
+        m_res_eLOC0_prt.push_back(-9999);
+        m_res_eLOC1_prt.push_back(-9999);
+        m_err_eLOC0_prt.push_back(-9999);
+        m_err_eLOC1_prt.push_back(-9999);
+        m_err_ePHI_prt.push_back(-9999);
+        m_err_eTHETA_prt.push_back(-9999);
+        m_err_eQOP_prt.push_back(-9999);
+        m_err_eT_prt.push_back(-9999);
+        m_pull_eLOC0_prt.push_back(-9999);
+        m_pull_eLOC1_prt.push_back(-9999);
+        m_x_prt.push_back(-9999);
+        m_y_prt.push_back(-9999);
+        m_z_prt.push_back(-9999);
+        m_px_prt.push_back(-9999);
+        m_py_prt.push_back(-9999);
+        m_pz_prt.push_back(-9999);
+        m_pT_prt.push_back(-9999);
+        m_eta_prt.push_back(-9999);
+      }
+
+      bool filtered = false;
+      if (state.hasFiltered())
+      {
+        filtered = true;
+        m_nFiltered++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.filtered(),
+            state.filteredCovariance());
+        auto covariance = state.filteredCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.filtered();
+
+        /// Filtered residual
+        m_res_eLOC0_flt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_flt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Filtered parameter pulls
+        m_pull_eLOC0_flt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_flt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+        /// Filtered parameter
+        m_eLOC0_flt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_flt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_flt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_flt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_flt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_flt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Filtered parameter uncertainties
+        m_err_eLOC0_flt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_flt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_flt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_flt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_flt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_flt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        /// Other filtered parameter info
+        m_x_flt.push_back(parameter.position(geoctx).x());
+        m_y_flt.push_back(parameter.position(geoctx).y());
+        m_z_flt.push_back(parameter.position(geoctx).z());
+        m_px_flt.push_back(parameter.momentum().x());
+        m_py_flt.push_back(parameter.momentum().y());
+        m_pz_flt.push_back(parameter.momentum().z());
+        m_pT_flt.push_back(parameter.transverseMomentum());
+        m_eta_flt.push_back(eta(parameter.position(geoctx)));
+        m_chi2.push_back(state.chi2());
+
+      }
+      else
+      {
+        /// Push bad values if no filtered parameter
+        m_eLOC0_flt.push_back(-9999);
+        m_eLOC1_flt.push_back(-9999);
+        m_ePHI_flt.push_back(-9999);
+        m_eTHETA_flt.push_back(-9999);
+        m_eQOP_flt.push_back(-9999);
+        m_eT_flt.push_back(-9999);
+        m_res_eLOC0_flt.push_back(-9999);
+        m_res_eLOC1_flt.push_back(-9999);
+        m_err_eLOC0_flt.push_back(-9999);
+        m_err_eLOC1_flt.push_back(-9999);
+        m_err_ePHI_flt.push_back(-9999);
+        m_err_eTHETA_flt.push_back(-9999);
+        m_err_eQOP_flt.push_back(-9999);
+        m_err_eT_flt.push_back(-9999);
+        m_pull_eLOC0_flt.push_back(-9999);
+        m_pull_eLOC1_flt.push_back(-9999);
+        m_x_flt.push_back(-9999);
+        m_y_flt.push_back(-9999);
+        m_z_flt.push_back(-9999);
+        m_py_flt.push_back(-9999);
+        m_pz_flt.push_back(-9999);
+        m_pT_flt.push_back(-9999);
+        m_eta_flt.push_back(-9999);
+        m_chi2.push_back(-9999);
+      }
 
-    /// Save whether or not states had various KF steps
-    m_prt.push_back(predicted);
-    m_flt.push_back(filtered);
-    m_smt.push_back(smoothed);
+      bool smoothed = false;
+      if (state.hasSmoothed())
+      {
+        smoothed = true;
+        m_nSmoothed++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.smoothed(),
+            state.smoothedCovariance());
+        auto covariance = state.smoothedCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.smoothed();
+
+        m_res_x_hit.push_back(residual(Acts::eBoundLoc0));
+        m_res_y_hit.push_back(residual(Acts::eBoundLoc1));
+        m_err_x_hit.push_back(
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_y_hit.push_back(
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_pull_x_hit.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_y_hit.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_dim_hit.push_back(state.calibratedSize());
+
+        /// Smoothed residual
+        m_res_eLOC0_smt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_smt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Smoothed parameter pulls
+        m_pull_eLOC0_smt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_smt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+        /// Smoothed parameter
+        m_eLOC0_smt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_smt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_smt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_smt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_smt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_smt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Smoothed parameter uncertainties
+        m_err_eLOC0_smt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_smt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_smt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_smt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_smt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_smt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        m_x_smt.push_back(parameter.position(geoctx).x());
+        m_y_smt.push_back(parameter.position(geoctx).y());
+        m_z_smt.push_back(parameter.position(geoctx).z());
+        m_px_smt.push_back(parameter.momentum().x());
+        m_py_smt.push_back(parameter.momentum().y());
+        m_pz_smt.push_back(parameter.momentum().z());
+        m_pT_smt.push_back(parameter.transverseMomentum());
+        m_eta_smt.push_back(eta(parameter.position(geoctx)));
+      }
+      else
+      {
+        /// Push bad values if no smoothed parameter
+        m_eLOC0_smt.push_back(-9999);
+        m_eLOC1_smt.push_back(-9999);
+        m_ePHI_smt.push_back(-9999);
+        m_eTHETA_smt.push_back(-9999);
+        m_eQOP_smt.push_back(-9999);
+        m_eT_smt.push_back(-9999);
+        m_res_eLOC0_smt.push_back(-9999);
+        m_res_eLOC1_smt.push_back(-9999);
+        m_err_eLOC0_smt.push_back(-9999);
+        m_err_eLOC1_smt.push_back(-9999);
+        m_err_ePHI_smt.push_back(-9999);
+        m_err_eTHETA_smt.push_back(-9999);
+        m_err_eQOP_smt.push_back(-9999);
+        m_err_eT_smt.push_back(-9999);
+        m_pull_eLOC0_smt.push_back(-9999);
+        m_pull_eLOC1_smt.push_back(-9999);
+        m_x_smt.push_back(-9999);
+        m_y_smt.push_back(-9999);
+        m_z_smt.push_back(-9999);
+        m_px_smt.push_back(-9999);
+        m_py_smt.push_back(-9999);
+        m_pz_smt.push_back(-9999);
+        m_pT_smt.push_back(-9999);
+        m_eta_smt.push_back(-9999);
+        m_res_x_hit.push_back(-9999);
+        m_res_y_hit.push_back(-9999);
+        m_err_x_hit.push_back(-9999);
+        m_err_y_hit.push_back(-9999);
+        m_pull_x_hit.push_back(-9999);
+        m_pull_y_hit.push_back(-9999);
+        m_dim_hit.push_back(-9999);
+      }
 
-    return true;
-  }   /// Finish lambda function
-  );  /// Finish multi trajectory visitBackwards call
+      /// Save whether or not states had various KF steps
+      m_prt.push_back(predicted);
+      m_flt.push_back(filtered);
+      m_smt.push_back(smoothed);
+
+      return true;
+    }   /// Finish lambda function
+    );  /// Finish multi trajectory visitBackwards call
 
     iTraj++;
 
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/SimWriterTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/SimWriterTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0e9a39a11391c8d2a67a487151b60ee6a075b9ef
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/SimWriterTool.cxx
@@ -0,0 +1,58 @@
+#include "FaserActsKalmanFilter/SimWriterTool.h"
+
+#include "TFile.h"
+#include "TTree.h"
+
+SimWriterTool::SimWriterTool(const std::string& type,
+   const std::string& name, const IInterface* parent)
+   : AthAlgTool(type, name, parent) {}
+
+
+StatusCode SimWriterTool::initialize() {
+  ATH_MSG_INFO("SimWriterTool::initialize");
+
+  std::string filePath = m_filePath;
+  std::string treeName = m_treeName;
+
+  m_file = TFile::Open(filePath.c_str(), "RECREATE");
+  if (m_file == nullptr) {
+    ATH_MSG_ERROR("Unable to open output file at " << m_filePath);
+    return StatusCode::FAILURE;
+  }
+  m_file->cd();
+  m_tree = new TTree(treeName.c_str(), "tree");
+  if (m_tree == nullptr) {
+    ATH_MSG_ERROR("Unable to create TTree");
+    return StatusCode::FAILURE;
+  }
+
+  m_tree->Branch("event_number", &m_eventNumber);
+  m_tree->Branch("x", &m_x);
+  m_tree->Branch("y", &m_y);
+  m_tree->Branch("z", &m_z);
+  m_tree->Branch("px", &m_px);
+  m_tree->Branch("py", &m_py);
+  m_tree->Branch("pz", &m_pz);
+  
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode SimWriterTool::finalize() {
+  ATH_MSG_INFO("finalize SimWriterTool::finalize");
+  m_file->cd();
+  m_tree->Write();
+  return StatusCode::SUCCESS;
+}
+
+
+void SimWriterTool::writeout(Acts::Vector3 vertex, Acts::Vector3 momentum) const {
+  m_eventNumber = Gaudi::Hive::currentContext().eventID().event_number();
+  m_x = vertex.x();
+  m_y = vertex.y();
+  m_z = vertex.z();
+  m_px = momentum.x();
+  m_py = momentum.y();
+  m_pz = momentum.z();
+  m_tree->Fill();
+}
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/TrackFindingAlgorithmFunction.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/TrackFindingAlgorithmFunction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..954906a0f4263c6e17f17143b23d4639c5d1107a
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/TrackFindingAlgorithmFunction.cxx
@@ -0,0 +1,99 @@
+#include "FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h"
+#include "FaserActsGeometry/FASERMagneticFieldWrapper.h"
+
+#include "Acts/Propagator/EigenStepper.hpp"
+#include "Acts/Propagator/Navigator.hpp"
+#include "Acts/Propagator/Propagator.hpp"
+#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
+#include "Acts/TrackFitting/GainMatrixUpdater.hpp"
+#include "Acts/MagneticField/ConstantBField.hpp"
+#include "Acts/MagneticField/InterpolatedBFieldMap.hpp"
+#include "Acts/MagneticField/SharedBField.hpp"
+
+#include <boost/variant/variant.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+
+
+using Updater = Acts::GainMatrixUpdater;
+using Smoother = Acts::GainMatrixSmoother;
+using Stepper = Acts::EigenStepper<>;
+using Propagator = Acts::Propagator<Stepper, Acts::Navigator>;
+
+namespace ActsExtrapolationDetail {
+  using VariantPropagatorBase = boost::variant<
+      Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>,
+      Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>
+  >;
+
+  class VariantPropagator : public VariantPropagatorBase
+  {
+  public:
+    using VariantPropagatorBase::VariantPropagatorBase;
+  };
+
+}
+
+using ActsExtrapolationDetail::VariantPropagator;
+
+
+template <typename TrackFinder>
+struct TrackFinderFunctionImpl {
+  TrackFinder trackFinder;
+
+  TrackFinderFunctionImpl(TrackFinder&& f) : trackFinder(std::move(f)) {}
+
+  CombinatorialKalmanFilterAlg::TrackFinderResult operator()(
+      const IndexSourceLinkContainer& sourceLinks,
+      const std::vector<Acts::CurvilinearTrackParameters>& initialParameters,
+      const CombinatorialKalmanFilterAlg::TrackFinderOptions& options) const
+  {
+    return trackFinder.findTracks(sourceLinks, initialParameters, options);
+  }
+};
+
+
+CombinatorialKalmanFilterAlg::TrackFinderFunction 
+CombinatorialKalmanFilterAlg::makeTrackFinderFunction(
+    std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry)
+{
+  const std::string fieldMode = "FASER";
+  const std::vector<double> constantFieldVector = {0., 0., 0.55};
+
+  Acts::Navigator::Config cfg{trackingGeometry};
+  cfg.resolvePassive   = false;
+  cfg.resolveMaterial  = true;
+  cfg.resolveSensitive = true;
+  Acts::Navigator navigator( cfg );
+
+  std::unique_ptr<ActsExtrapolationDetail::VariantPropagator> varProp;
+
+  if (fieldMode == "FASER") {
+    auto bField = std::make_shared<FASERMagneticFieldWrapper>();
+    auto stepper = Acts::EigenStepper<>(std::move(bField));
+    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
+                                                                      std::move(navigator));
+    varProp = std::make_unique<VariantPropagator>(propagator);
+  }
+  else if (fieldMode == "Constant") {
+    Acts::Vector3 constantFieldVector = Acts::Vector3(constantFieldVector[0], 
+                                                      constantFieldVector[1], 
+                                                      constantFieldVector[2]);
+
+    auto bField = std::make_shared<Acts::ConstantBField>(constantFieldVector);
+    auto stepper = Acts::EigenStepper<>(std::move(bField));
+    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
+                                                                      std::move(navigator));
+    varProp = std::make_unique<VariantPropagator>(propagator);
+  }
+
+  return boost::apply_visitor([&](const auto& propagator) -> TrackFinderFunction {
+    using Updater  = Acts::GainMatrixUpdater;
+    using Smoother = Acts::GainMatrixSmoother;
+    using CKF = Acts::CombinatorialKalmanFilter<typename std::decay_t<decltype(propagator)>, Updater, Smoother>;
+
+    CKF trackFinder(std::move(propagator));
+
+    return TrackFinderFunctionImpl<CKF>(std::move(trackFinder));
+  }, *varProp);
+}
\ No newline at end of file
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/TrajectoryWriterTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/TrajectoryWriterTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5eaf25b910681d92dd53a31975c6f451037f13cc
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/TrajectoryWriterTool.cxx
@@ -0,0 +1,680 @@
+#include "FaserActsKalmanFilter/TrajectoryWriterTool.h"
+#include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h"
+#include "Acts/EventData/MultiTrajectoryHelpers.hpp"
+#include "TFile.h"
+#include "TTree.h"
+
+using Acts::VectorHelpers::eta;
+using Acts::VectorHelpers::perp;
+using Acts::VectorHelpers::phi;
+using Acts::VectorHelpers::theta;
+
+
+TrajectoryWriterTool::TrajectoryWriterTool(const std::string& type, 
+    const std::string& name, const IInterface* parent)
+    : AthAlgTool( type, name, parent ) {}
+
+
+StatusCode TrajectoryWriterTool::initialize() {
+  ATH_MSG_INFO("TrajectoryWriterTool::initialize");
+
+  std::string filePath = m_filePath;
+  std::string treeName = m_treeName;
+
+  m_file = TFile::Open(filePath.c_str(), "RECREATE");
+  if (m_file == nullptr) {
+    ATH_MSG_ERROR("Unable to open output file at " << m_filePath);
+    return StatusCode::FAILURE;
+  }
+  m_file->cd();
+  m_tree = new TTree(treeName.c_str(), "tree");
+  if (m_tree == nullptr) {
+    ATH_MSG_ERROR("Unable to create TTree");
+    return StatusCode::FAILURE;
+  }
+
+  TrajectoryWriterTool::initializeTree();
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TrajectoryWriterTool::finalize() {
+  ATH_MSG_INFO("finalize WriteOutInitialParameterTool");
+
+  m_file->cd();
+  m_tree->Write();
+
+  return StatusCode::SUCCESS;
+}
+
+
+void TrajectoryWriterTool::initializeTree() {
+  m_tree->Branch("event_number", &m_eventNumber);
+  m_tree->Branch("traj_number", &m_trajNumber);
+
+  m_tree->Branch("nMeasurements", &m_nMeasurements);
+  m_tree->Branch("nStates", &m_nStates);
+  m_tree->Branch("nOutliers", &m_nOutliers);
+  m_tree->Branch("nHoles", &m_nHoles);
+
+  m_tree->Branch("hasFittedParams", &m_hasFittedParams);
+  m_tree->Branch("chi2_fit", &m_chi2_fit);
+  m_tree->Branch("ndf_fit", &m_ndf_fit);
+  m_tree->Branch("eLOC0_fit", &m_eLOC0_fit);
+  m_tree->Branch("eLOC1_fit", &m_eLOC1_fit);
+  m_tree->Branch("ePHI_fit", &m_ePHI_fit);
+  m_tree->Branch("eTHETA_fit", &m_eTHETA_fit);
+  m_tree->Branch("eQOP_fit", &m_eQOP_fit);
+  m_tree->Branch("eT_fit", &m_eT_fit);
+  m_tree->Branch("charge_fit", &m_charge_fit);
+  m_tree->Branch("err_eLOC0_fit", &m_err_eLOC0_fit);
+  m_tree->Branch("err_eLOC1_fit", &m_err_eLOC1_fit);
+  m_tree->Branch("err_ePHI_fit", &m_err_ePHI_fit);
+  m_tree->Branch("err_eTHETA_fit", &m_err_eTHETA_fit);
+  m_tree->Branch("err_eQOP_fit", &m_err_eQOP_fit);
+  m_tree->Branch("err_eT_fit", &m_err_eT_fit);
+  m_tree->Branch("g_px_fit", &m_px_fit);
+  m_tree->Branch("g_py_fit", &m_py_fit);
+  m_tree->Branch("g_pz_fit", &m_pz_fit);
+  m_tree->Branch("g_x_fit" , &m_x_fit);
+  m_tree->Branch("g_y_fit" , &m_y_fit);
+  m_tree->Branch("g_z_fit" , &m_z_fit);
+
+  m_tree->Branch("nPredicted", &m_nPredicted);
+  m_tree->Branch("predicted", &m_prt);
+  m_tree->Branch("eLOC0_prt", &m_eLOC0_prt);
+  m_tree->Branch("eLOC1_prt", &m_eLOC1_prt);
+  m_tree->Branch("ePHI_prt", &m_ePHI_prt);
+  m_tree->Branch("eTHETA_prt", &m_eTHETA_prt);
+  m_tree->Branch("eQOP_prt", &m_eQOP_prt);
+  m_tree->Branch("eT_prt", &m_eT_prt);
+  m_tree->Branch("res_eLOC0_prt", &m_res_eLOC0_prt);
+  m_tree->Branch("res_eLOC1_prt", &m_res_eLOC1_prt);
+  m_tree->Branch("err_eLOC0_prt", &m_err_eLOC0_prt);
+  m_tree->Branch("err_eLOC1_prt", &m_err_eLOC1_prt);
+  m_tree->Branch("err_ePHI_prt", &m_err_ePHI_prt);
+  m_tree->Branch("err_eTHETA_prt", &m_err_eTHETA_prt);
+  m_tree->Branch("err_eQOP_prt", &m_err_eQOP_prt);
+  m_tree->Branch("err_eT_prt", &m_err_eT_prt);
+  m_tree->Branch("pull_eLOC0_prt", &m_pull_eLOC0_prt);
+  m_tree->Branch("pull_eLOC1_prt", &m_pull_eLOC1_prt);
+  m_tree->Branch("g_x_prt", &m_x_prt);
+  m_tree->Branch("g_y_prt", &m_y_prt);
+  m_tree->Branch("g_z_prt", &m_z_prt);
+  m_tree->Branch("px_prt", &m_px_prt);
+  m_tree->Branch("py_prt", &m_py_prt);
+  m_tree->Branch("pz_prt", &m_pz_prt);
+  m_tree->Branch("eta_prt", &m_eta_prt);
+  m_tree->Branch("pT_prt", &m_pT_prt);
+
+  m_tree->Branch("nFiltered", &m_nFiltered);
+  m_tree->Branch("filtered", &m_flt);
+  m_tree->Branch("eLOC0_flt", &m_eLOC0_flt);
+  m_tree->Branch("eLOC1_flt", &m_eLOC1_flt);
+  m_tree->Branch("ePHI_flt", &m_ePHI_flt);
+  m_tree->Branch("eTHETA_flt", &m_eTHETA_flt);
+  m_tree->Branch("eQOP_flt", &m_eQOP_flt);
+  m_tree->Branch("eT_flt", &m_eT_flt);
+  m_tree->Branch("res_eLOC0_flt", &m_res_eLOC0_flt);
+  m_tree->Branch("res_eLOC1_flt", &m_res_eLOC1_flt);
+  m_tree->Branch("err_eLOC0_flt", &m_err_eLOC0_flt);
+  m_tree->Branch("err_eLOC1_flt", &m_err_eLOC1_flt);
+  m_tree->Branch("err_ePHI_flt", &m_err_ePHI_flt);
+  m_tree->Branch("err_eTHETA_flt", &m_err_eTHETA_flt);
+  m_tree->Branch("err_eQOP_flt", &m_err_eQOP_flt);
+  m_tree->Branch("err_eT_flt", &m_err_eT_flt);
+  m_tree->Branch("pull_eLOC0_flt", &m_pull_eLOC0_flt);
+  m_tree->Branch("pull_eLOC1_flt", &m_pull_eLOC1_flt);
+  m_tree->Branch("g_x_flt", &m_x_flt);
+  m_tree->Branch("g_y_flt", &m_y_flt);
+  m_tree->Branch("g_z_flt", &m_z_flt);
+  m_tree->Branch("px_flt", &m_px_flt);
+  m_tree->Branch("py_flt", &m_py_flt);
+  m_tree->Branch("pz_flt", &m_pz_flt);
+  m_tree->Branch("eta_flt", &m_eta_flt);
+  m_tree->Branch("pT_flt", &m_pT_flt);
+  m_tree->Branch("chi2", &m_chi2);
+
+  m_tree->Branch("nSmoothed", &m_nSmoothed);
+  m_tree->Branch("smoothed", &m_smt);
+  m_tree->Branch("eLOC0_smt", &m_eLOC0_smt);
+  m_tree->Branch("eLOC1_smt", &m_eLOC1_smt);
+  m_tree->Branch("ePHI_smt", &m_ePHI_smt);
+  m_tree->Branch("eTHETA_smt", &m_eTHETA_smt);
+  m_tree->Branch("eQOP_smt", &m_eQOP_smt);
+  m_tree->Branch("eT_smt", &m_eT_smt);
+  m_tree->Branch("res_eLOC0_smt", &m_res_eLOC0_smt);
+  m_tree->Branch("res_eLOC1_smt", &m_res_eLOC1_smt);
+  m_tree->Branch("err_eLOC0_smt", &m_err_eLOC0_smt);
+  m_tree->Branch("err_eLOC1_smt", &m_err_eLOC1_smt);
+  m_tree->Branch("err_ePHI_smt", &m_err_ePHI_smt);
+  m_tree->Branch("err_eTHETA_smt", &m_err_eTHETA_smt);
+  m_tree->Branch("err_eQOP_smt", &m_err_eQOP_smt);
+  m_tree->Branch("err_eT_smt", &m_err_eT_smt);
+  m_tree->Branch("pull_eLOC0_smt", &m_pull_eLOC0_smt);
+  m_tree->Branch("pull_eLOC1_smt", &m_pull_eLOC1_smt);
+  m_tree->Branch("g_x_smt", &m_x_smt);
+  m_tree->Branch("g_y_smt", &m_y_smt);
+  m_tree->Branch("g_z_smt", &m_z_smt);
+  m_tree->Branch("px_smt", &m_px_smt);
+  m_tree->Branch("py_smt", &m_py_smt);
+  m_tree->Branch("pz_smt", &m_pz_smt);
+  m_tree->Branch("eta_smt", &m_eta_smt);
+  m_tree->Branch("pT_smt", &m_pT_smt);
+}
+
+
+void TrajectoryWriterTool::writeout(TrajectoriesContainer trajectories,
+    Acts::GeometryContext geoContext) const {
+    
+  m_eventNumber = Gaudi::Hive::currentContext().eventID().event_number();
+
+
+  // Loop over the trajectories
+  int iTraj = 0;
+  for (const auto& traj : trajectories) {
+    m_trajNumber = iTraj;
+
+    // The trajectory entry indices and the multiTrajectory
+    const auto& [trackTips, mj] = traj.trajectory();
+    if (trackTips.empty()) {
+      ATH_MSG_WARNING("Empty multiTrajectory.");
+      continue;
+    }
+
+    // Get the entry index for the single trajectory
+    auto& trackTip = trackTips.front();
+    std::cout<<"trackTip = "<<trackTip<<std::endl;
+
+    // Collect the trajectory summary info
+    auto trajState =
+        Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip);
+
+    m_nMeasurements = trajState.nMeasurements;
+    m_nStates = trajState.nStates;
+    m_nOutliers = trajState.nOutliers;
+    m_nHoles = trajState.nHoles;
+    m_chi2_fit = trajState.chi2Sum;
+    m_ndf_fit = trajState.NDF;
+    std::cout << "Track has " << trajState.nMeasurements
+              << " measurements and " << trajState.nHoles
+              << " holes and " << trajState.nOutliers
+              << " outliers and " << trajState.nStates
+              << " states " << std::endl;
+    
+    /// If it has track parameters, fill the values
+    if (traj.hasTrackParameters(trackTip))
+    {
+      m_hasFittedParams = true;
+      const auto &boundParam = traj.trackParameters(trackTip);
+      const auto &parameter = boundParam.parameters();
+      const auto &covariance = *boundParam.covariance();
+      m_charge_fit = boundParam.charge();
+      m_eLOC0_fit = parameter[Acts::eBoundLoc0];
+      m_eLOC1_fit = parameter[Acts::eBoundLoc1];
+      m_ePHI_fit = parameter[Acts::eBoundPhi];
+      m_eTHETA_fit = parameter[Acts::eBoundTheta];
+      m_eQOP_fit = parameter[Acts::eBoundQOverP];
+      m_eT_fit = parameter[Acts::eBoundTime];
+      m_err_eLOC0_fit =
+          sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0));
+      m_err_eLOC1_fit =
+          sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1));
+      m_err_ePHI_fit = sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi));
+      m_err_eTHETA_fit =
+          sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta));
+      m_err_eQOP_fit = sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP));
+      m_err_eT_fit = sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime));
+
+      m_px_fit = boundParam.momentum()(0);
+      m_py_fit = boundParam.momentum()(1);
+      m_pz_fit = boundParam.momentum()(2);
+      m_x_fit  = boundParam.position(geoContext)(0);
+      m_y_fit  = boundParam.position(geoContext)(1);
+      m_z_fit  = boundParam.position(geoContext)(2);
+    }
+
+    m_nPredicted = 0;
+    m_nFiltered = 0;
+    m_nSmoothed = 0;
+
+    mj.visitBackwards(trackTip, [&](const auto &state) {
+      /// Only fill the track states with non-outlier measurement
+      auto typeFlags = state.typeFlags();
+      if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag))
+      {
+        return true;
+      }
+
+      const auto& surface = state.referenceSurface();
+
+      /// Get the geometry ID
+      auto geoID = state.referenceSurface().geometryId();
+      m_volumeID.push_back(geoID.volume());
+      m_layerID.push_back(geoID.layer());
+      m_moduleID.push_back(geoID.sensitive());
+
+      // expand the local measurements into the full bound space
+      Acts::BoundVector meas =
+          state.projector().transpose() * state.calibrated();
+
+      // extract local and global position
+      Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]);
+      Acts::Vector3 mom(1, 1, 1);
+      Acts::Vector3 global =
+          surface.localToGlobal(geoContext, local, mom);
+
+      // fill the measurement info
+      m_lx_hit.push_back(local[Acts::ePos0]);
+      m_ly_hit.push_back(local[Acts::ePos1]);
+      m_x_hit.push_back(global[Acts::ePos0]);
+      m_y_hit.push_back(global[Acts::ePos1]);
+      m_z_hit.push_back(global[Acts::ePos2]);
+
+      /// Get the predicted parameter for this state
+      bool predicted = false;
+      if (state.hasPredicted())
+      {
+        predicted = true;
+        m_nPredicted++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.predicted(),
+            state.predictedCovariance());
+        auto covariance = state.predictedCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.predicted();
+
+        /// Predicted residual
+        m_res_eLOC0_prt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_prt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Predicted parameter pulls
+        m_pull_eLOC0_prt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_prt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+        /// Predicted parameter
+        m_eLOC0_prt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_prt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_prt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_prt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_prt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_prt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Predicted parameter Uncertainties
+        m_err_eLOC0_prt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_prt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_prt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_prt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_prt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_prt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        m_x_prt.push_back(parameter.position(geoContext).x());
+        m_y_prt.push_back(parameter.position(geoContext).y());
+        m_z_prt.push_back(parameter.position(geoContext).z());
+        m_px_prt.push_back(parameter.momentum().x());
+        m_py_prt.push_back(parameter.momentum().y());
+        m_pz_prt.push_back(parameter.momentum().z());
+        m_pT_prt.push_back(parameter.transverseMomentum());
+        m_eta_prt.push_back(eta(parameter.position(geoContext)));
+      }
+      else
+      {
+        /// Push bad values if no predicted parameter
+        m_eLOC0_prt.push_back(-9999);
+        m_eLOC1_prt.push_back(-9999);
+        m_ePHI_prt.push_back(-9999);
+        m_eTHETA_prt.push_back(-9999);
+        m_eQOP_prt.push_back(-9999);
+        m_eT_prt.push_back(-9999);
+        m_res_eLOC0_prt.push_back(-9999);
+        m_res_eLOC1_prt.push_back(-9999);
+        m_err_eLOC0_prt.push_back(-9999);
+        m_err_eLOC1_prt.push_back(-9999);
+        m_err_ePHI_prt.push_back(-9999);
+        m_err_eTHETA_prt.push_back(-9999);
+        m_err_eQOP_prt.push_back(-9999);
+        m_err_eT_prt.push_back(-9999);
+        m_pull_eLOC0_prt.push_back(-9999);
+        m_pull_eLOC1_prt.push_back(-9999);
+        m_x_prt.push_back(-9999);
+        m_y_prt.push_back(-9999);
+        m_z_prt.push_back(-9999);
+        m_px_prt.push_back(-9999);
+        m_py_prt.push_back(-9999);
+        m_pz_prt.push_back(-9999);
+        m_pT_prt.push_back(-9999);
+        m_eta_prt.push_back(-9999);
+      }
+
+      bool filtered = false;
+      if (state.hasFiltered())
+      {
+        filtered = true;
+        m_nFiltered++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.filtered(),
+            state.filteredCovariance());
+        auto covariance = state.filteredCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.filtered();
+
+        /// Filtered residual
+        m_res_eLOC0_flt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_flt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Filtered parameter pulls
+        m_pull_eLOC0_flt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_flt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+        /// Filtered parameter
+        m_eLOC0_flt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_flt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_flt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_flt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_flt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_flt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Filtered parameter uncertainties
+        m_err_eLOC0_flt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_flt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_flt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_flt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_flt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_flt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        /// Other filtered parameter info
+        m_x_flt.push_back(parameter.position(geoContext).x());
+        m_y_flt.push_back(parameter.position(geoContext).y());
+        m_z_flt.push_back(parameter.position(geoContext).z());
+        m_px_flt.push_back(parameter.momentum().x());
+        m_py_flt.push_back(parameter.momentum().y());
+        m_pz_flt.push_back(parameter.momentum().z());
+        m_pT_flt.push_back(parameter.transverseMomentum());
+        m_eta_flt.push_back(eta(parameter.position(geoContext)));
+        m_chi2.push_back(state.chi2());
+
+      }
+      else
+      {
+        /// Push bad values if no filtered parameter
+        m_eLOC0_flt.push_back(-9999);
+        m_eLOC1_flt.push_back(-9999);
+        m_ePHI_flt.push_back(-9999);
+        m_eTHETA_flt.push_back(-9999);
+        m_eQOP_flt.push_back(-9999);
+        m_eT_flt.push_back(-9999);
+        m_res_eLOC0_flt.push_back(-9999);
+        m_res_eLOC1_flt.push_back(-9999);
+        m_err_eLOC0_flt.push_back(-9999);
+        m_err_eLOC1_flt.push_back(-9999);
+        m_err_ePHI_flt.push_back(-9999);
+        m_err_eTHETA_flt.push_back(-9999);
+        m_err_eQOP_flt.push_back(-9999);
+        m_err_eT_flt.push_back(-9999);
+        m_pull_eLOC0_flt.push_back(-9999);
+        m_pull_eLOC1_flt.push_back(-9999);
+        m_x_flt.push_back(-9999);
+        m_y_flt.push_back(-9999);
+        m_z_flt.push_back(-9999);
+        m_py_flt.push_back(-9999);
+        m_pz_flt.push_back(-9999);
+        m_pT_flt.push_back(-9999);
+        m_eta_flt.push_back(-9999);
+        m_chi2.push_back(-9999);
+      }
+
+      bool smoothed = false;
+      if (state.hasSmoothed())
+      {
+        smoothed = true;
+        m_nSmoothed++;
+        Acts::BoundTrackParameters parameter(
+            state.referenceSurface().getSharedPtr(),
+            state.smoothed(),
+            state.smoothedCovariance());
+        auto covariance = state.smoothedCovariance();
+
+        /// Local hit residual info
+        auto H = state.effectiveProjector();
+        auto resCov = state.effectiveCalibratedCovariance() +
+                      H * covariance * H.transpose();
+        auto residual = state.effectiveCalibrated() - H * state.smoothed();
+
+        m_res_x_hit.push_back(residual(Acts::eBoundLoc0));
+        m_res_y_hit.push_back(residual(Acts::eBoundLoc1));
+        m_err_x_hit.push_back(
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_y_hit.push_back(
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_pull_x_hit.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_y_hit.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_dim_hit.push_back(state.calibratedSize());
+
+        /// Smoothed residual
+        m_res_eLOC0_smt.push_back(residual(Acts::eBoundLoc0));
+        m_res_eLOC1_smt.push_back(residual(Acts::eBoundLoc1));
+
+        /// Smoothed parameter pulls
+        m_pull_eLOC0_smt.push_back(
+            residual(Acts::eBoundLoc0) /
+            sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_pull_eLOC1_smt.push_back(
+            residual(Acts::eBoundLoc1) /
+            sqrt(resCov(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+
+        /// Smoothed parameter
+        m_eLOC0_smt.push_back(parameter.parameters()[Acts::eBoundLoc0]);
+        m_eLOC1_smt.push_back(parameter.parameters()[Acts::eBoundLoc1]);
+        m_ePHI_smt.push_back(parameter.parameters()[Acts::eBoundPhi]);
+        m_eTHETA_smt.push_back(parameter.parameters()[Acts::eBoundTheta]);
+        m_eQOP_smt.push_back(parameter.parameters()[Acts::eBoundQOverP]);
+        m_eT_smt.push_back(parameter.parameters()[Acts::eBoundTime]);
+
+        /// Smoothed parameter uncertainties
+        m_err_eLOC0_smt.push_back(
+            sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
+        m_err_eLOC1_smt.push_back(
+            sqrt(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
+        m_err_ePHI_smt.push_back(
+            sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
+        m_err_eTHETA_smt.push_back(
+            sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
+        m_err_eQOP_smt.push_back(
+            sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
+        m_err_eT_smt.push_back(
+            sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)));
+
+        m_x_smt.push_back(parameter.position(geoContext).x());
+        m_y_smt.push_back(parameter.position(geoContext).y());
+        m_z_smt.push_back(parameter.position(geoContext).z());
+        m_px_smt.push_back(parameter.momentum().x());
+        m_py_smt.push_back(parameter.momentum().y());
+        m_pz_smt.push_back(parameter.momentum().z());
+        m_pT_smt.push_back(parameter.transverseMomentum());
+        m_eta_smt.push_back(eta(parameter.position(geoContext)));
+      }
+      else
+      {
+        /// Push bad values if no smoothed parameter
+        m_eLOC0_smt.push_back(-9999);
+        m_eLOC1_smt.push_back(-9999);
+        m_ePHI_smt.push_back(-9999);
+        m_eTHETA_smt.push_back(-9999);
+        m_eQOP_smt.push_back(-9999);
+        m_eT_smt.push_back(-9999);
+        m_res_eLOC0_smt.push_back(-9999);
+        m_res_eLOC1_smt.push_back(-9999);
+        m_err_eLOC0_smt.push_back(-9999);
+        m_err_eLOC1_smt.push_back(-9999);
+        m_err_ePHI_smt.push_back(-9999);
+        m_err_eTHETA_smt.push_back(-9999);
+        m_err_eQOP_smt.push_back(-9999);
+        m_err_eT_smt.push_back(-9999);
+        m_pull_eLOC0_smt.push_back(-9999);
+        m_pull_eLOC1_smt.push_back(-9999);
+        m_x_smt.push_back(-9999);
+        m_y_smt.push_back(-9999);
+        m_z_smt.push_back(-9999);
+        m_px_smt.push_back(-9999);
+        m_py_smt.push_back(-9999);
+        m_pz_smt.push_back(-9999);
+        m_pT_smt.push_back(-9999);
+        m_eta_smt.push_back(-9999);
+        m_res_x_hit.push_back(-9999);
+        m_res_y_hit.push_back(-9999);
+        m_err_x_hit.push_back(-9999);
+        m_err_y_hit.push_back(-9999);
+        m_pull_x_hit.push_back(-9999);
+        m_pull_y_hit.push_back(-9999);
+        m_dim_hit.push_back(-9999);
+      }
+
+      /// Save whether or not states had various KF steps
+      m_prt.push_back(predicted);
+      m_flt.push_back(filtered);
+      m_smt.push_back(smoothed);
+
+      return true;
+    } // Finish lambda function
+    ); // Finish multi trajectory visitBackwards call
+
+    iTraj++;
+  }
+  m_tree->Fill();
+
+  clearVariables();
+}
+
+
+void TrajectoryWriterTool::clearVariables() const {
+  m_volumeID.clear();
+  m_layerID.clear();
+  m_moduleID.clear();
+  m_lx_hit.clear();
+  m_ly_hit.clear();
+  m_x_hit.clear();
+  m_y_hit.clear();
+  m_z_hit.clear();
+  m_res_x_hit.clear();
+  m_res_y_hit.clear();
+  m_err_x_hit.clear();
+  m_err_y_hit.clear();
+  m_pull_x_hit.clear();
+  m_pull_y_hit.clear();
+  m_dim_hit.clear();
+
+  m_prt.clear();
+  m_eLOC0_prt.clear();
+  m_eLOC1_prt.clear();
+  m_ePHI_prt.clear();
+  m_eTHETA_prt.clear();
+  m_eQOP_prt.clear();
+  m_eT_prt.clear();
+  m_res_eLOC0_prt.clear();
+  m_res_eLOC1_prt.clear();
+  m_err_eLOC0_prt.clear();
+  m_err_eLOC1_prt.clear();
+  m_err_ePHI_prt.clear();
+  m_err_eTHETA_prt.clear();
+  m_err_eQOP_prt.clear();
+  m_err_eT_prt.clear();
+  m_pull_eLOC0_prt.clear();
+  m_pull_eLOC1_prt.clear();
+  m_x_prt.clear();
+  m_y_prt.clear();
+  m_z_prt.clear();
+  m_px_prt.clear();
+  m_py_prt.clear();
+  m_pz_prt.clear();
+  m_eta_prt.clear();
+  m_pT_prt.clear();
+
+  m_flt.clear();
+  m_eLOC0_flt.clear();
+  m_eLOC1_flt.clear();
+  m_ePHI_flt.clear();
+  m_eTHETA_flt.clear();
+  m_eQOP_flt.clear();
+  m_eT_flt.clear();
+  m_res_eLOC0_flt.clear();
+  m_res_eLOC1_flt.clear();
+  m_err_eLOC0_flt.clear();
+  m_err_eLOC1_flt.clear();
+  m_err_ePHI_flt.clear();
+  m_err_eTHETA_flt.clear();
+  m_err_eQOP_flt.clear();
+  m_err_eT_flt.clear();
+  m_pull_eLOC0_flt.clear();
+  m_pull_eLOC1_flt.clear();
+  m_x_flt.clear();
+  m_y_flt.clear();
+  m_z_flt.clear();
+  m_px_flt.clear();
+  m_py_flt.clear();
+  m_pz_flt.clear();
+  m_eta_flt.clear();
+  m_pT_flt.clear();
+  m_chi2.clear();
+
+  m_smt.clear();
+  m_eLOC0_smt.clear();
+  m_eLOC1_smt.clear();
+  m_ePHI_smt.clear();
+  m_eTHETA_smt.clear();
+  m_eQOP_smt.clear();
+  m_eT_smt.clear();
+  m_res_eLOC0_smt.clear();
+  m_res_eLOC1_smt.clear();
+  m_err_eLOC0_smt.clear();
+  m_err_eLOC1_smt.clear();
+  m_err_ePHI_smt.clear();
+  m_err_eTHETA_smt.clear();
+  m_err_eQOP_smt.clear();
+  m_err_eT_smt.clear();
+  m_pull_eLOC0_smt.clear();
+  m_pull_eLOC1_smt.clear();
+  m_x_smt.clear();
+  m_y_smt.clear();
+  m_z_smt.clear();
+  m_px_smt.clear();
+  m_py_smt.clear();
+  m_pz_smt.clear();
+  m_eta_smt.clear();
+  m_pT_smt.clear();
+
+}
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/TruthBasedInitialParameterTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/TruthBasedInitialParameterTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..85b1036e415fb3f28f9f6b8ee37679afb60304bd
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/TruthBasedInitialParameterTool.cxx
@@ -0,0 +1,100 @@
+#include "FaserActsKalmanFilter/TruthBasedInitialParameterTool.h"
+
+#include "StoreGate/ReadHandle.h"
+#include "HepMC/GenVertex.h"
+#include "Acts/EventData/TrackParameters.hpp"
+#include "Acts/Definitions/Units.hpp"
+#include <random>
+#include <cmath>
+
+
+using namespace Acts::UnitLiterals;
+
+TruthBasedInitialParameterTool::TruthBasedInitialParameterTool(
+    const std::string& type, const std::string& name, const IInterface* parent) :
+    AthAlgTool(type, name, parent) {}
+
+
+StatusCode TruthBasedInitialParameterTool::initialize() {
+  ATH_MSG_INFO("TruthBasedInitialParameterTool::initialize");
+  ATH_CHECK(m_simDataCollectionKey.initialize());
+  ATH_CHECK(m_simWriterTool.retrieve());
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TruthBasedInitialParameterTool::finalize() {
+  ATH_MSG_INFO("TruthBasedInitialParameterTool::finalize");
+  return StatusCode::SUCCESS;
+}
+
+
+Acts::CurvilinearTrackParameters TruthBasedInitialParameterTool::getInitialParameters(std::vector<Identifier> ids) const {
+  SG::ReadHandle<TrackerSimDataCollection> simDataCollection(m_simDataCollectionKey);
+
+  // get simulated vertex and momentum of the HepMcParticle with the highest energy deposit
+  float highestDep = 0;
+  HepMC::FourVector vertex;
+  HepMC::FourVector momentum;
+
+  for (Identifier id : ids) {
+    if( simDataCollection->count(id) == 0)
+      continue;
+
+    const auto& deposits = simDataCollection->at(id).getdeposits();
+    for( const auto& depositPair : deposits) {
+      if( std::abs(depositPair.first->pdg_id()) == 13 && depositPair.second > highestDep) {
+        highestDep = depositPair.second;
+        vertex = depositPair.first->production_vertex()->position();
+        momentum = depositPair.first->momentum();
+      }
+    }
+  }
+
+  std::cout << "?? px = " << momentum.x() << " py = " << momentum.y() << " pz = " << momentum.z() << std::endl;
+
+  Acts::Vector3 truthVertex = {vertex.x(), vertex.y(), vertex.z()}; // in mm
+  Acts::Vector3 truthMomentum = {momentum.x() / 1000, momentum.y() / 1000, momentum.z() / 1000}; // in GeV
+  m_simWriterTool->writeout(truthVertex, truthMomentum);
+
+  // smearing parameters
+  double sigmaU = 200_um;
+  double sigmaV = 200_um;
+  double sigmaPhi = 1_degree;
+  double sigmaTheta = 1_degree;
+  double sigmaQOverP = 0.1 * truthVertex.norm() / (truthMomentum.norm() * truthMomentum.norm());
+  double sigmaT0 = 1_ns;
+
+  // create covariance matrix
+  Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero();
+  cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = sigmaU * sigmaU;
+  cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = sigmaV * sigmaV;
+  cov(Acts::eBoundPhi, Acts::eBoundPhi) = sigmaPhi * sigmaPhi;
+  cov(Acts::eBoundTheta, Acts::eBoundTheta) = sigmaTheta * sigmaTheta;
+  cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = sigmaQOverP * sigmaQOverP;
+  cov(Acts::eBoundTime, Acts::eBoundTime) = sigmaT0 * sigmaT0;
+   
+  // smear truth parameters
+  std::random_device rd;
+  std::default_random_engine rng {rd()};
+  std::normal_distribution<> norm; // mu: 0 sigma: 1
+  double charge = 1;
+  double time =0;
+  Acts::Vector3 deltaPos(sigmaU*norm(rng), sigmaU*norm(rng), sigmaU*norm(rng));
+  Acts::Vector4 posTime = {(truthVertex+deltaPos).x(), (truthVertex+deltaPos).y(), (truthVertex+deltaPos).z(), time};
+  auto theta = Acts::VectorHelpers::theta(truthMomentum.normalized());
+  auto phi = Acts::VectorHelpers::phi(truthMomentum.normalized());
+  auto angles = Acts::detail::normalizePhiTheta(phi + sigmaPhi*norm(rng), theta + sigmaTheta*norm(rng));
+  Acts::Vector3 dir(std::sin(angles.second) * std::cos(angles.first),
+                    std::sin(angles.second) * std::sin(angles.first),
+                    std::cos(angles.second));
+  const Acts::Vector3 initMomentum = ( truthMomentum.norm()*(1 + 0.1*norm(rng)) ) * dir;
+  const Acts::Vector3 momentum_dir = initMomentum.normalized();
+  double momentum_abs = initMomentum.norm();
+
+  ATH_MSG_DEBUG("x: " << posTime.x() << ", y: " << posTime.y() << ", z: " << posTime.z());
+  ATH_MSG_DEBUG("p: " << momentum_abs << ", px: " << momentum_dir.x() << ", py: " << momentum_dir.y() << ", pz: " << momentum_dir.z());
+  
+  Acts::CurvilinearTrackParameters initialTrackParameters(posTime, momentum_dir, momentum_abs, charge, std::make_optional(std::move(cov)));
+  return initialTrackParameters;
+}
\ No newline at end of file
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx
index 59a385596f4fad95415b5d6291ab3901482e7b1f..d933e0f480d2c488361f93f2dee2c9087c2e5c79 100755
--- a/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx
+++ b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx
@@ -3,6 +3,14 @@
 */
 
 #include "FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h"
+#include "FaserActsKalmanFilter/CombinatorialKalmanFilterAlg.h"
+#include "FaserActsKalmanFilter/TruthBasedInitialParameterTool.h"
+#include "FaserActsKalmanFilter/TrajectoryWriterTool.h"
+#include "FaserActsKalmanFilter/SimWriterTool.h"
 
 
-DECLARE_COMPONENT( FaserActsKalmanFilterAlg )
+DECLARE_COMPONENT(FaserActsKalmanFilterAlg)
+DECLARE_COMPONENT(CombinatorialKalmanFilterAlg)
+DECLARE_COMPONENT(TruthBasedInitialParameterTool)
+DECLARE_COMPONENT(TrajectoryWriterTool)
+DECLARE_COMPONENT(SimWriterTool)
diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx
deleted file mode 100644
index 4634ae05271a0d4b4dbbb6c24d39d313b60a8ba6..0000000000000000000000000000000000000000
--- a/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h"
-
-DECLARE_COMPONENT( FaserActsKalmanFilterAlg )
\ No newline at end of file
diff --git a/Tracking/Acts/FaserActsKalmanFilter/test/CombinatorialKalmanFilterAlg.py b/Tracking/Acts/FaserActsKalmanFilter/test/CombinatorialKalmanFilterAlg.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a18e531c7a862da30939e0fc03bbbd9dee99fa4
--- /dev/null
+++ b/Tracking/Acts/FaserActsKalmanFilter/test/CombinatorialKalmanFilterAlg.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+import sys
+from AthenaCommon.Logging import log, logging
+from AthenaCommon.Constants import DEBUG, VERBOSE, INFO
+from AthenaCommon.Configurable import Configurable
+from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
+from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+# from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg
+from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg
+from TrackerSpacePointFormation.TrackerSpacePointFormationConfig import TrackerSpacePointFinderCfg
+from FaserActsKalmanFilter.CombinatorialKalmanFilterConfig import CombinatorialKalmanFilterCfg
+
+log.setLevel(DEBUG)
+Configurable.configurableRun3Behavior = True
+
+ConfigFlags.Input.Files = ['my.RDO.pool.root']
+ConfigFlags.Output.ESDFileName = "myCKF.ESD.pool.root"
+ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01"
+# ConfigFlags.GeoModel.FaserVersion = "FASER-01"
+ConfigFlags.GeoModel.Align.Dynamic = False
+ConfigFlags.Beam.NumberOfCollisions = 0.
+ConfigFlags.lock()
+
+acc = MainServicesCfg(ConfigFlags)
+acc.merge(PoolReadCfg(ConfigFlags))
+# acc.merge(PoolWriteCfg(ConfigFlags))
+
+acc.merge(FaserSCT_ClusterizationCfg(ConfigFlags))
+acc.merge(TrackerSpacePointFinderCfg(ConfigFlags))
+acc.merge(CombinatorialKalmanFilterCfg(ConfigFlags))
+
+logging.getLogger('forcomps').setLevel(VERBOSE)
+acc.foreach_component("*").OutputLevel = VERBOSE
+acc.foreach_component("*ClassID*").OutputLevel = INFO
+acc.getService("StoreGateSvc").Dump = True
+acc.getService("ConditionStore").Dump = True
+acc.printConfig(withDetails=True)
+ConfigFlags.dump()
+
+sc = acc.run(maxEvents=-1)
+
+sys.exit(not sc.isSuccess())
diff --git a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/DetElementSurface.h b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/DetElementSurface.h
index 3f734e18539c905ba35dd824b3f61c18dfb0b42d..d8da8531253883eb19265ff95b798a3db1164f34 100644
--- a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/DetElementSurface.h
+++ b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/DetElementSurface.h
@@ -47,7 +47,7 @@ class DetElementSurface : public Surface
     std::ostream &              dump (std::ostream &sl) const { return sl;};
     const Identifier            associatedDetectorElementIdentifier() const {return m_id;}
     bool                        isFree() {return true;}// To avoid memory leaks
-    Surface::SurfaceType        type() const {return Surface::Other;}
+    SurfaceType                 type() const {return SurfaceType::Other;}
     void                        localToGlobal(const Amg::Vector2D&, const Amg::Vector3D&, Amg::Vector3D&) const {}
     bool                        globalToLocal(const Amg::Vector3D&, const Amg::Vector3D&, Amg::Vector2D&) const {return false;}
     std::string                 name() const { return "Trk::DetElementSurface";}
@@ -58,7 +58,7 @@ class DetElementSurface : public Surface
                                 double,
                                 double,
                                 double,
-                                AmgSymMatrix(5) *) const
+                                std::optional<AmgSymMatrix(5)> = std::nullopt) const
     {
       return nullptr;
     }
@@ -66,7 +66,7 @@ class DetElementSurface : public Surface
     createUniqueTrackParameters(const Amg::Vector3D&,
                                 const Amg::Vector3D&,
                                 double,
-                                AmgSymMatrix(5) *) const
+                                std::optional<AmgSymMatrix(5)> = std::nullopt) const
     {
       return nullptr;
     }
@@ -77,7 +77,7 @@ class DetElementSurface : public Surface
                                   double,
                                   double,
                                   double,
-                                  AmgSymMatrix(5) *) const
+                                  std::optional<AmgSymMatrix(5)> = std::nullopt) const
     {
       return nullptr;
     }
@@ -85,7 +85,7 @@ class DetElementSurface : public Surface
     createUniqueNeutralParameters(const Amg::Vector3D&,
                                   const Amg::Vector3D&,
                                   double,
-                                  AmgSymMatrix(5) *) const
+                                  std::optional<AmgSymMatrix(5)> = std::nullopt) const
     {
       return nullptr;
     }
@@ -99,7 +99,7 @@ class DetElementSurface : public Surface
     virtual Trk::DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D&,
                                            const Amg::Vector3D&, bool) const {return 0;}
 
-    virtual bool isOnSurface(const Amg::Vector3D&, Trk::BoundaryCheck, double, double) const {return false;}
+    virtual bool isOnSurface(const Amg::Vector3D&, const Trk::BoundaryCheck&, double, double) const {return false;}
 
 private:
     Identifier  m_id;
diff --git a/Tracking/TrkEventCnv/TrkEventCnvTools/python/TrkEventCnvToolsConfig.py b/Tracking/TrkEventCnv/TrkEventCnvTools/python/TrkEventCnvToolsConfig.py
index 272de9158e9e65da5bbbfe6aa911abaa6c424ed3..6a30a71bd796ec8f56834aeccd258eb235dd4de6 100644
--- a/Tracking/TrkEventCnv/TrkEventCnvTools/python/TrkEventCnvToolsConfig.py
+++ b/Tracking/TrkEventCnv/TrkEventCnvTools/python/TrkEventCnvToolsConfig.py
@@ -3,7 +3,7 @@
 # default configuration of TrkEventCnvTools
 # example of a configuration in class deriving from a Configurable
 
-from AthenaCommon.DetFlags import DetFlags
+# from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.AppMgr import ToolSvc
 # from RecExConfig import RecFlags as rec
 
diff --git a/faser-common b/faser-common
index a6e556e2b868059d1ef34a5a63075ba1d31c7e6c..89ce6a07128eb2ebc367b6b68f29c9c88220e3e6 160000
--- a/faser-common
+++ b/faser-common
@@ -1 +1 @@
-Subproject commit a6e556e2b868059d1ef34a5a63075ba1d31c7e6c
+Subproject commit 89ce6a07128eb2ebc367b6b68f29c9c88220e3e6
diff --git a/graphics/VTI12/README.md b/graphics/VTI12/README.md
index 20b87b07520403e8b69da9e888f6fb588154a092..d6e0311a08559002da6f750fb31e984be5a42564 100644
--- a/graphics/VTI12/README.md
+++ b/graphics/VTI12/README.md
@@ -8,6 +8,8 @@ To run on Calypso MC data (from an installation (run) directory):
 
 Note that VP1PLUGINPATH can be ninja-changed by asetup, and if it does not include the Calypso installation library folder, nothing will work.  Also note that it must be an ABSOLUTE (not relative) path!
 
-You can also give the -detdescr="FASER-01" or -detdescr="FASER-02" and -globcond="OFLCOND-FASER-01" or -globcond="OFLCOND-FASER-02" flags to specify the detector geometry and conditions.  
+You can also give the -detdescr="FASER-01" (baseline detector), -detdescr="FASER-02" (baseline + IFT), -detdescr="FASERNU-02" (baseline + IFT + emulsion) or -detdescr="FASER-TB00" (2021 Test-beam) to specify the geometry.
+
+You also need either -globcond="OFLCOND-FASER-01" (baseline) or -globcond="OFLCOND-FASER-02" (IFT with or without emulsion, or Test-beam) flags to specify the conditions.  
 
 The event display has no way to determine the right values for these settings (it defaults to FASER-01 and OFLCOND-FASER-01).
\ No newline at end of file
diff --git a/graphics/VTI12/VTI12Algs/share/vti12 b/graphics/VTI12/VTI12Algs/share/vti12
index 803466b4e18a0e5c2de706db1e774f717c11c7fa..ee3cf7c0f5f1afd20895c475e6a42f7f7d7d9caa 100644
--- a/graphics/VTI12/VTI12Algs/share/vti12
+++ b/graphics/VTI12/VTI12Algs/share/vti12
@@ -715,7 +715,7 @@ if [ "x$FLAG_HELP" != "x0" ]; then
     echo "                                (default mode when running over data files)"
     echo
     echo "  -fatras                     : Use Fatras (in single-track-simulation mode if no input file with generated event)"
-    echo "  -fatraskey=KEY              : Optionally override truth key used by Fatras (typical values are GEN_EVENT or TruthEvent)"
+    echo "  -fatraskey=KEY              : Optionally override truth key used by Fatras (typical values are BeamTruthEvent or TruthEvent)"
     echo
     echo "  -eventsrc=DIR               : Directory to take single event files from (do not specify input files in this case)."
     echo "                                To get files from a web server (i.e. live events), put instead the url to the file"
diff --git a/graphics/VTI12/VTI12Gui/src/VP1MainWindow.cxx b/graphics/VTI12/VTI12Gui/src/VP1MainWindow.cxx
index f86ddf08faf1fead9da2cfc4964a92514a57c5ed..f3f4dbe1b6de67bd31b732b0a5bf1b292c45018b 100644
--- a/graphics/VTI12/VTI12Gui/src/VP1MainWindow.cxx
+++ b/graphics/VTI12/VTI12Gui/src/VP1MainWindow.cxx
@@ -251,7 +251,7 @@ VP1MainWindow::VP1MainWindow(VP1ExecutionScheduler*sched,VP1AvailEvents * ae,QWi
 	// connect(pushButton_quicksetup_trackingstudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
 	// connect(pushButton_quicksetup_calostudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
 	connect(pushButton_quicksetup_geometrystudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
-	connect(pushButton_quicksetup_analysisstudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
+	connect(pushButton_quicksetup_waveformstudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
 
 	//Default application font:
 	m_defaultfont = QApplication::font();
@@ -284,7 +284,7 @@ VP1MainWindow::VP1MainWindow(VP1ExecutionScheduler*sched,VP1AvailEvents * ae,QWi
 	// connect(action_quicklaunch_Tracking_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
 	// connect(action_quicklaunch_Calo_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
 	connect(action_quicklaunch_Geometry_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
-	connect(action_quicklaunch_analysisstudies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
+	connect(action_quicklaunch_waveformstudies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
 	connect(action_quicklaunch_Storegate_browser,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
 	connect(action_quicklaunch_faser,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
 	// connect(action_quicklaunch_trackcalo_commis,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
@@ -1747,7 +1747,7 @@ void VP1MainWindow::quickSetupTriggered()
     plugfile="libVP13DCocktailPlugin.so";
     channelname="TrackCalo";
     tabname = "Track/Calo"; 
-  } */else if (sender()==pushButton_quicksetup_analysisstudies||sender()==action_quicklaunch_analysisstudies) {
+  } */else if (sender()==pushButton_quicksetup_waveformstudies||sender()==action_quicklaunch_waveformstudies) {
 
     //Open AOD file selection dialog for VP1Light
 #ifdef BUILDVP1LIGHT
@@ -1761,9 +1761,9 @@ void VP1MainWindow::quickSetupTriggered()
     pushButton_eventselect->setEnabled(true);
 #endif // BUILDVP1LIGHT
 
-    plugfile="libVP1AODPlugin.so";
-    channelname="AOD";
-    tabname = "Analysis";
+    plugfile="libVTI12WaveformPlugin.so";
+    channelname="Waveform";
+    tabname = "Waveforms";
   } else {
     addToMessageBox("quickSetupTriggered() Error: Unknown sender");
     return;
diff --git a/graphics/VTI12/VTI12Gui/src/vp1mainwindow.ui b/graphics/VTI12/VTI12Gui/src/vp1mainwindow.ui
index 6a0b7eef4a03747b6838a76330c7b3edc03e59e3..e23575d74bba2348b6c69f2b80883a9125227d60 100644
--- a/graphics/VTI12/VTI12Gui/src/vp1mainwindow.ui
+++ b/graphics/VTI12/VTI12Gui/src/vp1mainwindow.ui
@@ -608,12 +608,12 @@ p, li { white-space: pre-wrap; }
                       </widget>
                      </item>
                      <item row="2" column="0" colspan="3">
-                      <widget class="QPushButton" name="pushButton_quicksetup_analysisstudies">
+                      <widget class="QPushButton" name="pushButton_quicksetup_waveformstudies">
                        <property name="toolTip">
-                        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Launch the Analysis Object (AOD) plugin within a new tab.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+                        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Launch the VP1Waveform plugin within a new tab.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
                        </property>
                        <property name="text">
-                        <string>Unused</string>
+                        <string>Waveform studies</string>
                        </property>
                       </widget>
                      </item>
@@ -764,7 +764,7 @@ p, li { white-space: pre-wrap; }
     <addaction name="action_quicklaunch_Calo_studies"/> -->
     <addaction name="action_quicklaunch_Geometry_studies"/>
     <!-- <addaction name="action_quicklaunch_trackcalo_commis"/> -->
-    <addaction name="action_quicklaunch_analysisstudies"/>
+    <addaction name="action_quicklaunch_waveformstudies"/>
     <addaction name="action_quicklaunch_Storegate_browser"/>
     <addaction name="separator"/>
     <addaction name="action_exit_VP1"/>
@@ -880,9 +880,9 @@ p, li { white-space: pre-wrap; }
     <string>Open additional settings</string>
    </property>
   </action>
-  <action name="action_quicklaunch_analysisstudies">
+  <action name="action_quicklaunch_waveformstudies">
    <property name="text">
-    <string>A&amp;nalysis Studies</string>
+    <string>&amp;Waveform Studies</string>
    </property>
   </action>
  </widget>
diff --git a/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/CMakeLists.txt b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2cf1077d7b27e87550349271d7a5ee6d2237cec9
--- /dev/null
+++ b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/CMakeLists.txt
@@ -0,0 +1,19 @@
+################################################################################
+# Package: VTI12WaveformPlugin
+################################################################################
+
+# Declare the package name:
+atlas_subdir( VTI12WaveformPlugin )
+
+# External dependencies:
+find_package( Qt5 COMPONENTS Core Gui Widgets )
+
+# Generate MOC files automatically:
+set( CMAKE_AUTOMOC TRUE )
+
+# Build the library.
+atlas_add_library( VTI12WaveformPlugin
+   VTI12WaveformPlugin/*.h src/*.cxx src/*.qrc 
+   PUBLIC_HEADERS VTI12WaveformPlugin
+   LINK_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets 
+   PRIVATE_LINK_LIBRARIES VP1Base VTI12WaveformSystems )
diff --git a/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformChannel.h b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformChannel.h
new file mode 100755
index 0000000000000000000000000000000000000000..b764e096df8aa3e1aceb462e3939534713b6b691
--- /dev/null
+++ b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformChannel.h
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Header file for class VP1GeometryChannel               //
+//                                                         //
+//  Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch>  //
+//                                                         //
+//  Initial version: May 2007                              //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+#ifndef VP1GEOMETRYCHANNEL_H
+#define VP1GEOMETRYCHANNEL_H
+
+#include "VP1Base/IVP12DStandardChannelWidget.h"
+
+class VP1WaveformChannel : public IVP12DStandardChannelWidget {
+
+  Q_OBJECT
+
+public:
+
+  VP1WaveformChannel();
+  void init();
+  virtual ~VP1WaveformChannel(){}
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformPlugin_VP1AutoFactory.h b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformPlugin_VP1AutoFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..77bc35b8f4374618287a617cf4dd18a6431429e3
--- /dev/null
+++ b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/VTI12WaveformPlugin/VP1WaveformPlugin_VP1AutoFactory.h
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+//Autogenerated VP1 Factory Code Header File (Fri Aug 19 13:36:52 CEST 2016)
+
+#ifndef VP1WaveformPlugin_VP1AutoFactory_H
+#define VP1WaveformPlugin_VP1AutoFactory_H
+
+#include <QObject>
+#include <QStringList>
+
+#include "VP1Base/IVP1ChannelWidgetFactory.h"
+
+class VP1WaveformPlugin_VP1AutoFactory : public QObject, public IVP1ChannelWidgetFactory
+{
+  Q_OBJECT
+  Q_PLUGIN_METADATA(IID "VP1WaveformPlugin" )
+  Q_INTERFACES(IVP1ChannelWidgetFactory)
+
+public:
+  virtual QStringList channelWidgetsProvided() const;
+  virtual IVP1ChannelWidget * getChannelWidget(const QString & channelwidget);
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformChannel.cxx b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformChannel.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..de7dda032b9eeaee1087a3e57c4015ccd615a429
--- /dev/null
+++ b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformChannel.cxx
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Implementation of class VP1WaveformChannel             //
+//                                                         //
+//  Author: Dave Casper <dcasper@uci.edu>                  //
+//                                                         //
+//  Initial version: August 2021                           //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+#include "VTI12WaveformPlugin/VP1WaveformChannel.h"
+#include "VTI12WaveformSystems/VP1WaveformSystem.h"
+#include "VTI12WaveformSystems/VP1WaveformHitSystem.h"
+#include "VP1Base/VP1QtUtils.h"
+
+VP1WaveformChannel::VP1WaveformChannel()
+  : IVP12DStandardChannelWidget(VP1CHANNELNAMEINPLUGIN(VP1WaveformChannel,"Waveform"),
+				"This channel shows the FASER waveform data.",
+				"dcasper@uci.edu")
+{
+}
+
+void VP1WaveformChannel::init()
+{
+  addSystem(new VP1WaveformSystem);
+  addSystem(new VP1WaveformHitSystem);
+  // addSystem(new VP1GeometrySystem);
+  // if (VP1QtUtils::environmentVariableIsOn("VP1_SECOND_GEOMSYS"))
+  //   addSystem(new VP1GeometrySystem(VP1GeoFlags::None,"AltGeo"),IVP13DStandardChannelWidget::StartDisabled);
+}
diff --git a/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformPlugin_VP1AutoFactory.cxx b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformPlugin_VP1AutoFactory.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7bd05df24f18c8415cdec79123915e2910453eb2
--- /dev/null
+++ b/graphics/VTI12/VTI12Plugins/VTI12WaveformPlugin/src/VP1WaveformPlugin_VP1AutoFactory.cxx
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+//Autogenerated VP1 Factory Code Implementation File (Fri Aug 19 13:36:52 CEST 2016)
+
+#include <QtPlugin>
+#include "VTI12WaveformPlugin/VP1WaveformPlugin_VP1AutoFactory.h"
+#include "VTI12WaveformPlugin/VP1WaveformChannel.h"
+
+QStringList VP1WaveformPlugin_VP1AutoFactory::channelWidgetsProvided() const
+{
+  return QStringList()
+        << "Waveform"
+         ;
+}
+
+IVP1ChannelWidget * VP1WaveformPlugin_VP1AutoFactory::getChannelWidget(const QString & channelwidget)
+{
+  if (channelwidget == "Waveform")
+    return new VP1WaveformChannel();
+
+  return 0;
+}
+
diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx
index e1df8c9ac21df05d3728942d5bdf0b4f07bbc816..82825c71806f9cddaef0e065a30086fffae4e270 100644
--- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx
@@ -160,23 +160,7 @@ DetVisAttributes::DetVisAttributes() {
     material->specularColor.setValue(.915152, .915152, .915152);
     material->shininess.setValue(0.642424);
     add("Veto",material);
-  }
-
-  {
-    SoMaterial *material = new SoMaterial;
-    material->ambientColor.setValue(0, .157811, .187004);
-    material->diffuseColor.setValue(.40, .631244, .748016);
-    material->specularColor.setValue(.915152, .915152, .915152);
-    material->shininess.setValue(0.642424);
     add("Trigger",material);
-  }
-
-  {
-    SoMaterial *material = new SoMaterial;
-    material->ambientColor.setValue(0, .157811, .187004);
-    material->diffuseColor.setValue(1, .8, .7);
-    material->specularColor.setValue(.915152, .915152, .915152);
-    material->shininess.setValue(0.642424);
     add("Preshower",material);
   }
 
@@ -283,14 +267,14 @@ DetVisAttributes::DetVisAttributes() {
     material->shininess.setValue(1.0);
     add("SCT",material);
   }
-    {
+  {
       SoMaterial *material = new SoMaterial;
-      material->ambientColor.setValue(0, .157811, .187004);
-      material->diffuseColor.setValue(1, .5, .5);
+      material->ambientColor.setValue(23, 170, 62);
+      material->diffuseColor.setValue(24, 145, 175);
       material->specularColor.setValue(.915152, .915152, .915152);
-      material->shininess.setValue(0.3);
+      material->shininess.setValue(0.5);
       add("Dipole",material);
-    }
+  }
 
   // {
   //   SoMaterial *material = new SoMaterial;
@@ -507,6 +491,15 @@ MatVisAttributes::MatVisAttributes() {
     add("Stainless",m);
     add("_dd_Materials_Ecal_EcalSteel",m);
   }
+  {
+      SoMaterial *material = new SoMaterial;
+      material->ambientColor.setValue(0.09, 0.67, 0.24);
+      material->diffuseColor.setValue(0.1, 0.57, 0.69);
+      material->specularColor.setValue(.915152, .915152, .915152);
+      material->shininess.setValue(0.4);
+      add("Nd2Fe14B",material);
+  }
+
   {
     // Liquid Argon
     SoMaterial *m = new SoMaterial;
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/AscObj_TSOS.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/AscObj_TSOS.cxx
index 7e96708b11b6bad45ecf793de1683e2ec828cebc..2c767c0c206fc6acd18301e993a075c1252fa9ff 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/AscObj_TSOS.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/AscObj_TSOS.cxx
@@ -196,8 +196,8 @@ const Trk::MeasurementBase * AscObj_TSOS::measurement() const
 SoTranslation* AscObj_TSOS::getZTranslationTube( const Trk::Surface * theSurface,
                          const double& maxTrans ) const
 {
-  const Amg::Vector3D* origo = theSurface->localToGlobal(Amg::Vector2D(0,0));
-  const Amg::Vector3D* unitz = theSurface->localToGlobal(Amg::Vector2D(0,1));
+  const Amg::Vector3D origo = theSurface->localToGlobal(Amg::Vector2D(0,0));
+  const Amg::Vector3D unitz = theSurface->localToGlobal(Amg::Vector2D(0,1));
 
   std::vector< Amg::Vector3D > * points = trackHandle()->hackGetPointsPropagated();//FIXME
 
@@ -208,7 +208,7 @@ SoTranslation* AscObj_TSOS::getZTranslationTube( const Trk::Surface * theSurface
   for ( size_t i = 0; i<points->size(); i++)
   {
     double s;
-    double dist = VP1LinAlgUtils::distPointLine2( (*points)[i], *origo, *unitz, s );
+    double dist = VP1LinAlgUtils::distPointLine2( (*points)[i], origo, unitz, s );
     if (dist < min)
     {
       min = dist;
@@ -226,16 +226,16 @@ SoTranslation* AscObj_TSOS::getZTranslationTube( const Trk::Surface * theSurface
     double sp,tp,sm,tm;
     if (imin+1 < points->size() && imin >= 1)
     {
-      VP1LinAlgUtils::distLineLineParam((*points).at(imin),(*points).at(imin+1),*origo,*unitz,tp,sp);
-      VP1LinAlgUtils::distLineLineParam((*points).at(imin-1),(*points).at(imin),*origo,*unitz,tm,sm);
+      VP1LinAlgUtils::distLineLineParam((*points).at(imin),(*points).at(imin+1),origo,unitz,tp,sp);
+      VP1LinAlgUtils::distLineLineParam((*points).at(imin-1),(*points).at(imin),origo,unitz,tm,sm);
       smin = fabs(tm - 0.5) < fabs(tp - 0.5) ? sm : sp;
     } else if (imin+1 >= points->size() && imin >= 1 )
     {
-      VP1LinAlgUtils::distLineLineParam((*points).at(imin-1),(*points).at(imin),*origo,*unitz,tm,sm);
+      VP1LinAlgUtils::distLineLineParam((*points).at(imin-1),(*points).at(imin),origo,unitz,tm,sm);
       smin = sm;
     } else
     {
-      VP1LinAlgUtils::distLineLineParam((*points).at(imin),(*points).at(imin+1),*origo,*unitz,tp,sp);
+      VP1LinAlgUtils::distLineLineParam((*points).at(imin),(*points).at(imin+1),origo,unitz,tp,sp);
       smin = sp;
     }
   } else {
@@ -389,13 +389,12 @@ void AscObj_TSOS::addErrors(const Trk::Surface& theSurface, const AmgSymMatrix(5
     // Shift from Surface centre to correct position
     if (applyLocalTrans) {
       SoTranslation * theTransform = new SoTranslation;
-      const Amg::Vector2D* locPosTmp = surface()->globalToLocal(p1);
+      std::optional<Amg::Vector2D> locPosTmp = surface()->globalToLocal(p1);
       if (locPosTmp) {
         theTransform->translation.setValue(locPosTmp->x(),locPosTmp->y(),0.0); 
         // std::cout<<"applyLocalTrans & Offset=("<<locPosTmp->x()<<","<<locPosTmp->y()<<std::endl;
         errSimple->addChild(theTransform);
         errDetailed->addChild(theTransform);
-        delete locPosTmp;
       } else {
         VP1Msg::message("AscObj_TSOS::addErrors - failed to get tmp position");  
       }
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_TrackRecord.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_TrackRecord.cxx
index 816c08f3ebdc3c3571a0cc549a16d921c6f5ce49..4cc6d5e0f292ed8e122f8ae20dc1facf91279bcf 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_TrackRecord.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_TrackRecord.cxx
@@ -43,7 +43,7 @@ Trk::TrackParameters * SimHitHandle_TrackRecord::createTrackParameters() const
 	Amg::Transform3D transf =  Amg::CLHEPTranslate3DToEigen(HepGeom::Translate3D(m_trkrecord->GetPosition().x(),m_trkrecord->GetPosition().y(),m_trkrecord->GetPosition().z()));
   //Surface:
   const Trk::PlaneSurface * surf
-    = new Trk::PlaneSurface( &transf );
+    = new Trk::PlaneSurface( transf );
   //Fixme: surface and transform ever DELETED??
 
   //Fixme: Don't do this in every simhit!!:
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackHandle_TruthTrack.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackHandle_TruthTrack.cxx
index 1d003ab384abc7102e77de3121bc77c906614079..d800a49d65814f78553a2a77622fae7cebf8cbf3 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackHandle_TruthTrack.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackHandle_TruthTrack.cxx
@@ -80,7 +80,7 @@ public:
     Amg::Vector3D pos(v->point3d().x(),v->point3d().y(),v->point3d().z());
 
     Amg::Translation3D amgtranslation(pos.x(),pos.y(),pos.z());
-    Amg::Transform3D* amgTransf = new Amg::Transform3D(amgtranslation * Amg::RotationMatrix3D::Identity());
+    Amg::Transform3D amgTransf { amgtranslation * Amg::RotationMatrix3D::Identity() };
 
     return new Trk::AtaPlane(pos,mom,charge, *(new Trk::PlaneSurface(amgTransf)));
   }
@@ -116,7 +116,10 @@ public:
     }
 
     Trk::TrackInfo ti(Trk::TrackInfo::Unknown,theclass->extrapolationParticleHypothesis());
-    trkTrack = new Trk::Track(ti,trackStateOnSurfaces/*track assumes ownership*/,0/*fitquality*/);
+    std::unique_ptr<DataVector<const Trk::TrackStateOnSurface>> sink(trackStateOnSurfaces);
+    trkTrack = new Trk::Track(ti,
+                              std::move(*sink),
+                              nullptr /*fitquality*/);
 
 //     if (VP1Msg::verbose())
 //       VP1Msg::messageVerbose("TrackHandle_TruthTrack created track with "
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackPropagationHelper.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackPropagationHelper.cxx
index 60a4efb144bf327cb35d9e27890a5a6513256a6b..f5545c729ec9007f9f2823ec2f5e968ceac35b17 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackPropagationHelper.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackPropagationHelper.cxx
@@ -367,7 +367,7 @@ const Trk::TrackParameters * TrackPropagationHelper::Imp::extrapolateToNewPar( T
   Trk::CurvilinearUVT uvt(prevpars->momentum().unit());
   
   
-  Amg::Transform3D*  t  = new Amg::Transform3D(uvt.curvU(),uvt.curvV(),uvt.curvT(), prevpars->position()+(prevpars->momentum().unit()*dist));
+  Amg::Transform3D  t  {uvt.curvU(),uvt.curvV(),uvt.curvT(), prevpars->position()+(prevpars->momentum().unit()*dist)};
   
   Trk::PlaneSurface surf(t);
   
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/CMakeLists.txt b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dacc9d7703d3b1fdf61aa50a4f020bf40a3ffe2e
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/CMakeLists.txt
@@ -0,0 +1,24 @@
+################################################################################
+# Package: VTI12WaveformSystems
+################################################################################
+
+# Declare the package name:
+atlas_subdir( VTI12WaveformSystems )
+
+# External dependencies:
+find_package( Coin3D )
+find_package( Qt5 COMPONENTS Core Gui Widgets Charts )
+
+# Generate UI files automatically:
+set( CMAKE_AUTOUIC TRUE )
+# Generate MOC files automatically:
+set( CMAKE_AUTOMOC TRUE )
+
+# Component(s) in the package:
+atlas_add_library( VTI12WaveformSystems VTI12WaveformSystems/*.h src/*.cxx
+   PUBLIC_HEADERS VTI12WaveformSystems
+   INCLUDE_DIRS ${COIN3D_INCLUDE_DIRS} ${QT5_INCLUDE_DIRS}
+   LINK_LIBRARIES ${COIN3D_LIBRARIES} GeoPrimitives VP1Base VTI12Utils ScintRawEvent xAODFaserWaveform
+   Qt5::Core Qt5::Gui Qt5::Charts
+   PRIVATE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
+   PRIVATE_LINK_LIBRARIES GaudiKernel VP1HEPVis )
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformHitSystem.h b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformHitSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa0831b3f579c8c052fd3d38639da1a491888d7c
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformHitSystem.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef VP1WAVEFORMHITSYSTEM_H
+#define VP1WAVEFORMHITSYSTEM_H
+
+/////////////////////////////////////////////////////////////////////////
+//                                                                     //
+//  Header file for class VP1WaveformHitSystem                         //
+//                                                                     //
+//  Author: Dave Casper <dcasper@uci.edu>                              //
+//                                                                     //
+//  Initial version: August 2021                                       //
+//                                                                     //
+/////////////////////////////////////////////////////////////////////////
+
+#include "VP1Base/IVP12DSystemSimple.h"
+#include <QColor>//Fixme obsolete
+
+class VP1WaveformHitSystem : public IVP12DSystemSimple {
+
+  Q_OBJECT
+
+public:
+
+  ///////////////////
+  //  Constructor  //
+  ///////////////////
+
+  VP1WaveformHitSystem();
+
+  //////////////////////////////////////////
+  //  Reimplementations from base class:  //
+  //////////////////////////////////////////
+
+  virtual ~VP1WaveformHitSystem();
+  void buildPermanentItemCollection(StoreGateSvc* detstore, VP1GraphicsItemCollection *root);
+  void buildEventItemCollection(StoreGateSvc*, VP1GraphicsItemCollection *root);
+  void systemuncreate();
+  QWidget * buildController();
+  QByteArray saveState();
+  void restoreFromState(QByteArray ba);
+
+public slots:
+
+  void updateVetoElements(bool);
+  void updateTriggerElements(bool);
+  void updatePreshowerElements(bool);
+  void updateCalorimeterElements(bool);
+  // void updateClockElements(bool);
+  void updateTestElements(bool);
+
+private:
+  class Imp;
+  Imp * m_d;
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformSystem.h b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..d17e3b60f5e58fc5709064be6c77215c21d7a5b4
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/VP1WaveformSystem.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef VP1WAVEFORMSYSTEM_H
+#define VP1WAVEFORMSYSTEM_H
+
+/////////////////////////////////////////////////////////////////////////
+//                                                                     //
+//  Header file for class VP1WaveformSystem                            //
+//                                                                     //
+//  Author: Dave Casper <dcasper@uci.edu>                              //
+//                                                                     //
+//  Initial version: August 2021                                       //
+//                                                                     //
+/////////////////////////////////////////////////////////////////////////
+
+#include "VP1Base/IVP12DSystemSimple.h"
+#include <QColor>//Fixme obsolete
+
+class VP1WaveformSystem : public IVP12DSystemSimple {
+
+  Q_OBJECT
+
+public:
+
+  ///////////////////
+  //  Constructor  //
+  ///////////////////
+
+  VP1WaveformSystem();
+
+  //////////////////////////////////////////
+  //  Reimplementations from base class:  //
+  //////////////////////////////////////////
+
+  virtual ~VP1WaveformSystem();
+  void buildPermanentItemCollection(StoreGateSvc* detstore, VP1GraphicsItemCollection *root);
+  void buildEventItemCollection(StoreGateSvc*, VP1GraphicsItemCollection *root);
+  void systemuncreate();
+  QWidget * buildController();
+  QByteArray saveState();
+  void restoreFromState(QByteArray ba);
+
+public slots:
+
+  void updateVetoElements(bool);
+  void updateTriggerElements(bool);
+  void updatePreshowerElements(bool);
+  void updateCalorimeterElements(bool);
+  void updateClockElements(bool);
+  void updateTestElements(bool);
+
+private:
+  class Imp;
+  Imp * m_d;
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/WaveformSysController.h b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/WaveformSysController.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebb3c4c34ca693d245a300b2f47813ce738b4597
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/VTI12WaveformSystems/WaveformSysController.h
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class WaveformSysController               //
+//                                                            //
+//  Description: Waveform system controller.                  //
+//                                                            //
+//  Author: Dave Casper (dcasper@uci.edu)                     //
+//  Initial version: August 2021                              //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef WAVEFORMSYSCONTROLLER_H
+#define WAVEFORMSYSCONTROLLER_H
+
+#include "VP1Base/VP1Controller.h"
+#include <Inventor/C/errors/debugerror.h>
+#include <Inventor/SbColor4f.h>
+class SoMaterial;
+
+class WaveformSysController : public VP1Controller {
+
+  Q_OBJECT
+
+public:
+
+  WaveformSysController(IVP1System * sys);
+  virtual ~WaveformSysController();
+
+  void actualRestoreSettings(VP1Deserialise&);
+  int currentSettingsVersion() const;
+  void actualSaveSettings(VP1Serialise&) const;
+
+  ///////////////////////////////////
+  //  Access Methods for settings  //
+  ///////////////////////////////////
+
+  bool vetoEnabled() const;
+  bool triggerEnabled() const;
+  bool preshowerEnabled() const;
+  bool calorimeterEnabled() const;
+  bool clockEnabled() const;
+  bool testEnabled() const;
+
+
+  ///////////////////////////////////////
+  //  Signals for changes in settings  //
+  ///////////////////////////////////////
+signals:
+  void vetoEnabledChanged(bool);
+  void triggerEnabledChanged(bool);
+  void preshowerEnabledChanged(bool);
+  void calorimeterEnabledChanged(bool);
+  void clockEnabledChanged(bool);
+  void testEnabledChanged(bool);
+
+private:
+
+  class Imp;
+  Imp * m_d;
+
+private slots:
+  void possibleChange_vetoEnabled();
+  void possibleChange_triggerEnabled();
+  void possibleChange_preshowerEnabled();
+  void possibleChange_calorimeterEnabled();
+  void possibleChange_clockEnabled();
+  void possibleChange_testEnabled();
+
+};
+
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformHitSystem.cxx b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformHitSystem.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7d0c07c942414273964ffed851b27b745cca2756
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformHitSystem.cxx
@@ -0,0 +1,402 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+/////////////////////////////////////////////////////////////////////////
+//                                                                     //
+//  Implementation of class VP1WaveformHitSystem                       //
+//                                                                     //
+//  Author: Dave Casper <dcasper@uci.edu>                              //
+//                                                                     //
+//  Initial version: August 2021                                       //
+//                                                                     //
+/////////////////////////////////////////////////////////////////////////
+
+#include "VTI12WaveformSystems/VP1WaveformHitSystem.h"
+#include "VTI12WaveformSystems/WaveformSysController.h"
+
+#include "VP1Base/VP1GraphicsItemCollection.h"
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1Deserialise.h"
+#include "VP1Base/VP1Msg.h"
+
+#include "StoreGate/StoreGateSvc.h"
+
+#include "xAODFaserWaveform/WaveformHitContainer.h"
+#include "xAODFaserWaveform/WaveformHit.h"
+
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoPickStyle.h>
+#include <Inventor/nodes/SoComplexity.h>
+#include <Inventor/SbVec3f.h>
+
+#include <QtCharts>
+#include <QtWidgets>
+#include <QGraphicsEllipseItem>
+
+using namespace QtCharts;
+
+#include <map>
+
+class VP1WaveformHitSystem::Imp {
+public:
+  Imp(VP1WaveformHitSystem*tc) : theclass(tc),
+			       controller(0) {}
+  VP1WaveformHitSystem *theclass;
+  WaveformSysController * controller;
+  std::vector<QChart*> vetoCharts;
+  std::vector<QChart*> triggerCharts;
+  std::vector<QChart*> preshowerCharts;
+  std::vector<QChart*> calorimeterCharts;
+  // std::vector<QChart*> clockCharts;
+  std::vector<QChart*> testCharts;
+  std::vector<QChart*> visibleCharts;
+  void fillFit(const std::vector<float>& time, std::vector<float>& fit, float peak, float mean, float width, float alpha, float n);
+  QChart* createChart(const std::vector<float>& time, const std::vector<float>& data, const std::vector<float>& spline, QGraphicsItem* parent = nullptr, const QString& title = "Default title");
+  void createCharts(StoreGateSvc* sg, VP1GraphicsItemCollection* items, bool visible, std::vector<QChart*>& list, const std::string& collectionName);
+  void getVisible(const std::vector<QChart*>& list);
+  void getVisible();
+  void layoutCharts();
+
+};
+
+//_____________________________________________________________________________________
+VP1WaveformHitSystem::VP1WaveformHitSystem()
+  : IVP12DSystemSimple("Waveform Hits",
+		       "System displaying reconstructed waveform data",
+		       "dcasper@uci.edu"), m_d(new Imp(this))
+{
+}
+
+
+//_____________________________________________________________________________________
+VP1WaveformHitSystem::~VP1WaveformHitSystem()
+{
+  delete m_d;
+}
+
+//_____________________________________________________________________________________
+QWidget * VP1WaveformHitSystem::buildController()
+{
+  m_d->controller = new WaveformSysController(this);
+
+  connect(m_d->controller,SIGNAL(vetoEnabledChanged(bool)),this,SLOT(updateVetoElements(bool)));
+  connect(m_d->controller,SIGNAL(triggerEnabledChanged(bool)),this,SLOT(updateTriggerElements(bool)));
+  connect(m_d->controller,SIGNAL(preshowerEnabledChanged(bool)),this,SLOT(updatePreshowerElements(bool)));
+  connect(m_d->controller,SIGNAL(calorimeterEnabledChanged(bool)),this,SLOT(updateCalorimeterElements(bool)));
+  // connect(m_d->controller,SIGNAL(clockEnabledChanged(bool)),this,SLOT(updateClockElements(bool)));
+  connect(m_d->controller,SIGNAL(testEnabledChanged(bool)),this,SLOT(updateTestElements(bool)));
+
+  return m_d->controller;
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformHitSystem::buildEventItemCollection(StoreGateSvc* sg, VP1GraphicsItemCollection* root)
+{
+  if(VP1Msg::verbose() || true){
+    messageVerbose("buildEventItemCollection");
+  }
+
+  m_d->vetoCharts.clear();
+  m_d->triggerCharts.clear();
+  m_d->preshowerCharts.clear();
+  m_d->calorimeterCharts.clear();
+  // m_d->clockCharts.clear();
+  m_d->testCharts.clear();
+//   m_d->nCharts = 0;
+
+  m_d->createCharts(sg, root, m_d->controller->vetoEnabled(), m_d->vetoCharts, "VetoWaveformHits");
+  m_d->createCharts(sg, root, m_d->controller->triggerEnabled(), m_d->triggerCharts, "TriggerWaveformHits");
+  m_d->createCharts(sg, root, m_d->controller->preshowerEnabled(), m_d->preshowerCharts, "PreshowerWaveformHits");
+  m_d->createCharts(sg, root, m_d->controller->calorimeterEnabled(), m_d->calorimeterCharts, "CaloWaveformHits");
+  // m_d->createCharts(sg, root, m_d->controller->clockEnabled(), m_d->clockCharts, "ClockWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->testEnabled(), m_d->testCharts, "TestWaveformHits");
+  
+  m_d->layoutCharts();
+}
+
+void VP1WaveformHitSystem::Imp::createCharts(StoreGateSvc* sg, 
+                                             VP1GraphicsItemCollection* items, 
+                                             bool visible, 
+                                             std::vector<QChart*>& list, 
+                                             const std::string& collectionName)
+{
+    const xAOD::WaveformHitContainer* p_container {nullptr};
+    if(sg->retrieve(p_container, collectionName)==StatusCode::SUCCESS)
+    {
+      for(xAOD::WaveformHitContainer::const_iterator i_wf=p_container->begin(); i_wf!=p_container->end(); ++i_wf)
+      {
+        const xAOD::WaveformHit* hit = (*i_wf);
+        if (hit->time_vector().size() > 0 && hit->wave_vector().size() == hit->time_vector().size())
+        {
+          QString title { collectionName.c_str() };
+          title.append(" ").append(QString::number(hit->channel()));
+
+          std::vector<float> cb;
+          if (!hit->status_bit(xAOD::WaveformStatus::CBFIT_FAILED) && hit->width() > 0 && hit->alpha() != 0 && hit->nval() != 0)
+          {
+            fillFit(hit->time_vector(), cb, hit->peak(), hit->mean(), hit->width(), hit->alpha(), hit->nval());
+          }
+          QChart* chart = createChart((*i_wf)->time_vector(), (*i_wf)->wave_vector(), cb, nullptr, title);
+
+          QFont fitFont;
+          fitFont.setPixelSize(18);
+
+          QGraphicsTextItem* meanText = new QGraphicsTextItem("Mean: " + QString::number(hit->mean(),'f',1), chart);
+          meanText->setFont(fitFont);
+          meanText->setDefaultTextColor(QRgb(0xb157fd));
+          meanText->setPos(290, 75);
+
+          QGraphicsTextItem* peakText = new QGraphicsTextItem("Peak: " + QString::number(hit->peak(),'f',1), chart);
+          peakText->setFont(fitFont);
+          peakText->setDefaultTextColor(QRgb(0xb157fd));
+          peakText->setPos(290, 100);
+
+          QGraphicsTextItem* intText = new QGraphicsTextItem("Integral: " + QString::number(hit->integral(),'f',1), chart);
+          intText->setFont(fitFont);
+          intText->setDefaultTextColor(QRgb(0xb157fd));
+          intText->setPos(290, 125);
+
+
+          chart->setVisible(visible);
+          list.push_back(chart);
+          items->addItem(chart, true, true);
+        }
+      }
+    }
+    else
+    {
+      QString errorMsg {"Unable to retrieve "};
+      theclass->message(errorMsg.append(collectionName.c_str()));
+    }
+}
+
+void VP1WaveformHitSystem::Imp::fillFit(const std::vector<float>& time, 
+                                        std::vector<float>& fit, 
+                                        float peak, 
+                                        float mean, 
+                                        float width, 
+                                        float alpha, 
+                                        float nval)
+{
+    for (size_t i = 0; i < time.size(); i++)
+    {
+      float z = (time[i] - mean)/width;
+      if (alpha < 0) z = -z;
+      if (z > -fabs(alpha))
+      {
+        fit.push_back(peak * std::exp(-z*z/2));
+      }
+      else
+      {
+        fit.push_back(peak * std::pow((nval/fabs(alpha))/(((nval/fabs(alpha)-fabs(alpha)) - z)), nval) * std::exp(-alpha*alpha/2));
+      }
+    }
+}
+
+QChart* VP1WaveformHitSystem::Imp::createChart(const std::vector<float>& times, 
+                                               const std::vector<float>& data, 
+                                               const std::vector<float>& spline,
+                                               QGraphicsItem* parent, const QString& title) 
+{
+  
+  QChart* chart = new QChart(parent);
+  QLineSeries *series = new QLineSeries();
+  // unsigned int maxEntry = 0;
+  for (size_t i = 0; i < data.size(); i++)
+  {
+      // maxEntry = std::max(maxEntry, data[i]);
+      series->append(times[i], data[i]);
+  }
+
+  QPen pen(QRgb(0xfdb157));
+  pen.setWidth(1);
+  series->setPen(pen);
+  chart->addSeries(series);
+
+  if (spline.size() == times.size())
+  {
+    QSplineSeries* fit = new QSplineSeries();
+    for (size_t i = 0; i < spline.size(); i++)
+    {
+      fit->append(times[i], spline[i]);
+    }
+    QPen fitPen(QRgb(0xb157fd));
+    fitPen.setWidth(2);
+    fit->setPen(fitPen);
+    chart->addSeries(fit);
+  }
+
+  chart->legend()->hide();
+
+  chart->createDefaultAxes();
+
+  QFont font;
+  font.setPixelSize(24);
+  chart->setTitleFont(font);
+  chart->setTitleBrush(QBrush(Qt::blue));
+  chart->setTitle(title);
+  // QValueAxis* axisX = new QValueAxis();
+  QAbstractAxis* axisX = chart->axes(Qt::Horizontal)[0];
+  QFont labelsFont;
+  labelsFont.setPixelSize(8);
+  QPen axisPen(QRgb(0xd18952));
+  axisPen.setWidth(2);
+  // axisX->setRange(times[0]-2.0, times[times.size()-1]+2.0);
+  // axisX->setTickCount(13);
+  axisX->setLabelsFont(labelsFont);
+  axisX->setLinePen(axisPen);
+  // chart->addAxis(axisX, Qt::AlignBottom);
+  // series->attachAxis(axisX);
+  // QValueAxis* axisY = new QValueAxis();
+  QAbstractAxis* axisY = chart->axes(Qt::Vertical)[0];
+  // axisY->setRange(-256, 0x4000);
+  // axisY->setTickCount(17);
+  axisY->setLabelsFont(labelsFont);
+  axisY->setLinePen(axisPen);
+  // chart->addAxis(axisY, Qt::AlignLeft);
+  // series->attachAxis(axisY);
+
+  return chart;
+}
+
+void VP1WaveformHitSystem::Imp::getVisible()
+{
+    visibleCharts.clear();
+    getVisible(vetoCharts);
+    getVisible(triggerCharts);
+    getVisible(preshowerCharts);
+    getVisible(calorimeterCharts);
+    // getVisible(clockCharts);
+    getVisible(testCharts);
+}
+
+void VP1WaveformHitSystem::Imp::getVisible(const std::vector<QChart*>& list)
+{
+    for (QChart* c : list)
+    {
+        if (c != nullptr && c->isVisible()) 
+        {
+            visibleCharts.push_back(c);
+        }
+    }
+}
+
+void VP1WaveformHitSystem::Imp::layoutCharts()
+{
+    getVisible();
+    unsigned int nVisible = visibleCharts.size();
+    if (nVisible == 0) return;
+    // unsigned int nRows = (nVisible - 1)/5 + 1;
+    for (unsigned int i = 0; i < nVisible; i++)
+    {
+        qreal x = i%6 * 550.0;
+        // qreal y = ( (i/5) - nRows ) * 550.0;
+        qreal y = ( i/6 ) * 550.0 + 550.0*2;
+        visibleCharts[i]->setGeometry(x, y, 500.0, 500.0);
+    }
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformHitSystem::buildPermanentItemCollection(StoreGateSvc* /*detstore*/, VP1GraphicsItemCollection* /*root*/)
+{
+  if(VP1Msg::verbose() || true){
+    messageVerbose("buildPermanentItemCollection");
+  }
+
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformHitSystem::systemuncreate()
+{
+  m_d->controller=0;
+}
+
+
+//_____________________________________________________________________________________
+QByteArray VP1WaveformHitSystem::saveState() {
+
+  if (m_d->controller == nullptr) buildController();
+
+  VP1Serialise serialise(0/*version*/,this);
+  serialise.save(IVP12DSystemSimple::saveState());
+  serialise.save(m_d->controller->saveSettings());
+  serialise.disableUnsavedChecks();//We do the testing in the controller
+  return serialise.result();
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformHitSystem::restoreFromState(QByteArray ba) {
+
+  VP1Deserialise state(ba,this);
+  if (state.version() != 0) {
+    message("Warning: State data in .vp1 file is in wrong format - ignoring!");
+    state.disableUnrestoredChecks();//We do the testing in the controller
+    return;
+  }
+//   if (state.version() > 0 &&state.version()<=3) {
+//     message("Warning: State data in .vp1 file is in obsolete format - ignoring!");
+//     state.disableUnrestoredChecks();//We do the testing in the controller
+//     return;
+//   }
+  if (m_d->controller == nullptr) buildController();
+
+  IVP12DSystemSimple::restoreFromState(state.restoreByteArray());
+  m_d->controller->restoreSettings(state.restoreByteArray());
+  state.disableUnrestoredChecks();//We do the testing in the controller
+}
+
+void VP1WaveformHitSystem::updateVetoElements(bool enabled)
+{
+    for (QChart* c : m_d->vetoCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformHitSystem::updateTriggerElements(bool enabled)
+{
+    for (QChart* c : m_d->triggerCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformHitSystem::updatePreshowerElements(bool enabled)
+{
+    for (QChart* c : m_d->preshowerCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformHitSystem::updateCalorimeterElements(bool enabled)
+{
+    for (QChart* c : m_d->calorimeterCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+// void VP1WaveformHitSystem::updateClockElements(bool enabled)
+// {
+//     for (QChart* c : m_d->clockCharts)
+//     {
+//         c->setVisible(enabled);
+//     }
+//     m_d->layoutCharts();
+// }
+
+void VP1WaveformHitSystem::updateTestElements(bool enabled)
+{
+    for (QChart* c : m_d->testCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformSystem.cxx b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformSystem.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5551a33cf4b50233704cc0b7d46e65a45047f399
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/VP1WaveformSystem.cxx
@@ -0,0 +1,332 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+/////////////////////////////////////////////////////////////////////////
+//                                                                     //
+//  Implementation of class VP1WaveformSystem                          //
+//                                                                     //
+//  Author: Dave Casper <dcasper@uci.edu>                              //
+//                                                                     //
+//  Initial version: August 2021                                       //
+//                                                                     //
+/////////////////////////////////////////////////////////////////////////
+
+#include "VTI12WaveformSystems/VP1WaveformSystem.h"
+#include "VTI12WaveformSystems/WaveformSysController.h"
+
+#include "VP1Base/VP1GraphicsItemCollection.h"
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1Deserialise.h"
+#include "VP1Base/VP1Msg.h"
+
+#include "StoreGate/StoreGateSvc.h"
+
+#include "ScintRawEvent/ScintWaveformContainer.h"
+
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoPickStyle.h>
+#include <Inventor/nodes/SoComplexity.h>
+#include <Inventor/SbVec3f.h>
+
+#include <QtCharts>
+#include <QtWidgets>
+#include <QGraphicsEllipseItem>
+
+using namespace QtCharts;
+
+#include <map>
+
+class VP1WaveformSystem::Imp {
+public:
+  Imp(VP1WaveformSystem*tc) : theclass(tc),
+			       controller(0) {}
+  VP1WaveformSystem *theclass;
+  WaveformSysController * controller;
+  std::vector<QChart*> vetoCharts;
+  std::vector<QChart*> triggerCharts;
+  std::vector<QChart*> preshowerCharts;
+  std::vector<QChart*> calorimeterCharts;
+  std::vector<QChart*> clockCharts;
+  std::vector<QChart*> testCharts;
+  std::vector<QChart*> visibleCharts;
+  QChart* createChart(const std::vector<unsigned int>& data, QGraphicsItem* parent = nullptr, const QString& title = "Default title");
+  void createCharts(StoreGateSvc* sg, VP1GraphicsItemCollection* items, bool visible, std::vector<QChart*>& list, const std::string& collectionName);
+  void getVisible(const std::vector<QChart*>& list);
+  void getVisible();
+  void layoutCharts();
+
+};
+
+//_____________________________________________________________________________________
+VP1WaveformSystem::VP1WaveformSystem()
+  : IVP12DSystemSimple("Raw Waveforms",
+		       "System displaying raw waveform data",
+		       "dcasper@uci.edu"), m_d(new Imp(this))
+{
+}
+
+
+//_____________________________________________________________________________________
+VP1WaveformSystem::~VP1WaveformSystem()
+{
+  delete m_d;
+}
+
+//_____________________________________________________________________________________
+QWidget * VP1WaveformSystem::buildController()
+{
+  m_d->controller = new WaveformSysController(this);
+
+  connect(m_d->controller,SIGNAL(vetoEnabledChanged(bool)),this,SLOT(updateVetoElements(bool)));
+  connect(m_d->controller,SIGNAL(triggerEnabledChanged(bool)),this,SLOT(updateTriggerElements(bool)));
+  connect(m_d->controller,SIGNAL(preshowerEnabledChanged(bool)),this,SLOT(updatePreshowerElements(bool)));
+  connect(m_d->controller,SIGNAL(calorimeterEnabledChanged(bool)),this,SLOT(updateCalorimeterElements(bool)));
+  connect(m_d->controller,SIGNAL(clockEnabledChanged(bool)),this,SLOT(updateClockElements(bool)));
+  connect(m_d->controller,SIGNAL(testEnabledChanged(bool)),this,SLOT(updateTestElements(bool)));
+
+  return m_d->controller;
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformSystem::buildEventItemCollection(StoreGateSvc* sg, VP1GraphicsItemCollection* root)
+{
+  if(VP1Msg::verbose() || true){
+    messageVerbose("buildEventItemCollection");
+  }
+
+  m_d->vetoCharts.clear();
+  m_d->triggerCharts.clear();
+  m_d->preshowerCharts.clear();
+  m_d->calorimeterCharts.clear();
+  m_d->clockCharts.clear();
+  m_d->testCharts.clear();
+//   m_d->nCharts = 0;
+
+  m_d->createCharts(sg, root, m_d->controller->vetoEnabled(), m_d->vetoCharts, "VetoWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->triggerEnabled(), m_d->triggerCharts, "TriggerWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->preshowerEnabled(), m_d->preshowerCharts, "PreshowerWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->calorimeterEnabled(), m_d->calorimeterCharts, "CaloWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->clockEnabled(), m_d->clockCharts, "ClockWaveforms");
+  m_d->createCharts(sg, root, m_d->controller->testEnabled(), m_d->testCharts, "TestWaveforms");
+  
+  m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::Imp::createCharts(StoreGateSvc* sg, 
+                                          VP1GraphicsItemCollection* items, 
+                                          bool visible, 
+                                          std::vector<QChart*>& list, 
+                                          const std::string& collectionName)
+{
+    typedef DataVector<ScintWaveform>::const_iterator ScintWaveformConstIterator;
+
+    const ScintWaveformContainer* p_container {nullptr};
+    if(sg->retrieve(p_container, collectionName)==StatusCode::SUCCESS)
+    {
+      for(ScintWaveformConstIterator i_wf=p_container->begin(); i_wf!=p_container->end(); ++i_wf)
+      {
+        if ((*i_wf)->n_samples() > 0)
+        {
+          QString title { collectionName.c_str() };
+          title.append(" ").append(QString::number((*i_wf)->channel()));
+          QChart* chart = createChart((*i_wf)->adc_counts(), nullptr, title);
+          chart->setVisible(visible);
+          list.push_back(chart);
+          items->addItem(chart, true, true);
+        }
+      }
+    }
+    else
+    {
+      QString errorMsg {"Unable to retrieve "};
+      theclass->message(errorMsg.append(collectionName.c_str()));
+    }
+}
+
+QChart* VP1WaveformSystem::Imp::createChart(const std::vector<unsigned int>& data, QGraphicsItem* parent, const QString& title) 
+{
+  
+  QChart* chart = new QChart(parent);
+  QLineSeries *series = new QLineSeries();
+  unsigned int maxEntry = 0;
+  for (size_t i = 0; i < data.size(); i++)
+  {
+      maxEntry = std::max(maxEntry, data[i]);
+      series->append(i, data[i]);
+  }
+
+  QPen pen(QRgb(0xfdb157));
+  pen.setWidth(1);
+  series->setPen(pen);
+  chart->legend()->hide();
+  chart->addSeries(series);
+
+  QFont font;
+  font.setPixelSize(24);
+  chart->setTitleFont(font);
+  chart->setTitleBrush(QBrush(Qt::blue));
+  chart->setTitle(title);
+  QValueAxis* axisX = new QValueAxis();
+  QFont labelsFont;
+  labelsFont.setPixelSize(8);
+  QPen axisPen(QRgb(0xd18952));
+  axisPen.setWidth(2);
+  axisX->setRange(0, data.size());
+  axisX->setTickCount(13);
+  axisX->setLabelsFont(labelsFont);
+  axisX->setLinePen(axisPen);
+  chart->addAxis(axisX, Qt::AlignBottom);
+  series->attachAxis(axisX);
+  QValueAxis* axisY = new QValueAxis();
+  axisY->setRange(0, 0x4000);
+  axisY->setTickCount(9);
+  axisY->setLabelsFont(labelsFont);
+  axisY->setLinePen(axisPen);
+  chart->addAxis(axisY, Qt::AlignLeft);
+  series->attachAxis(axisY);
+
+  return chart;
+}
+
+void VP1WaveformSystem::Imp::getVisible()
+{
+    visibleCharts.clear();
+    getVisible(vetoCharts);
+    getVisible(triggerCharts);
+    getVisible(preshowerCharts);
+    getVisible(calorimeterCharts);
+    getVisible(clockCharts);
+    getVisible(testCharts);
+}
+
+void VP1WaveformSystem::Imp::getVisible(const std::vector<QChart*>& list)
+{
+    for (QChart* c : list)
+    {
+        if (c != nullptr && c->isVisible()) 
+        {
+            visibleCharts.push_back(c);
+        }
+    }
+}
+
+void VP1WaveformSystem::Imp::layoutCharts()
+{
+    getVisible();
+    unsigned int nVisible = visibleCharts.size();
+    std::cout << "Laying out " << nVisible << " raw hits" << std::endl;
+    if (nVisible == 0) return;
+    // unsigned int nRows = (nVisible - 1)/5 + 1;
+    for (unsigned int i = 0; i < nVisible; i++)
+    {
+        qreal x = i%6 * 550.0;
+        // qreal y = ( (i/5) - nRows ) * 550.0;
+        qreal y = ( i/6 ) * 550.0;
+        visibleCharts[i]->setGeometry(x, y, 500.0, 500.0);
+    }
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformSystem::buildPermanentItemCollection(StoreGateSvc* /*detstore*/, VP1GraphicsItemCollection* /*root*/)
+{
+  if(VP1Msg::verbose() || true){
+    messageVerbose("buildPermanentItemCollection");
+  }
+
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformSystem::systemuncreate()
+{
+  m_d->controller=0;
+}
+
+
+//_____________________________________________________________________________________
+QByteArray VP1WaveformSystem::saveState() {
+
+  if (m_d->controller == nullptr) buildController();
+
+  VP1Serialise serialise(0/*version*/,this);
+  serialise.save(IVP12DSystemSimple::saveState());
+  serialise.save(m_d->controller->saveSettings());
+  serialise.disableUnsavedChecks();//We do the testing in the controller
+  return serialise.result();
+}
+
+//_____________________________________________________________________________________
+void VP1WaveformSystem::restoreFromState(QByteArray ba) {
+
+  VP1Deserialise state(ba,this);
+  if (state.version() != 0) {
+    message("Warning: State data in .vp1 file is in wrong format - ignoring!");
+    state.disableUnrestoredChecks();//We do the testing in the controller
+    return;
+  }
+//   if (state.version() > 0 &&state.version()<=3) {
+//     message("Warning: State data in .vp1 file is in obsolete format - ignoring!");
+//     state.disableUnrestoredChecks();//We do the testing in the controller
+//     return;
+//   }
+  if (m_d->controller == nullptr) buildController();
+
+  IVP12DSystemSimple::restoreFromState(state.restoreByteArray());
+  m_d->controller->restoreSettings(state.restoreByteArray());
+  state.disableUnrestoredChecks();//We do the testing in the controller
+}
+
+void VP1WaveformSystem::updateVetoElements(bool enabled)
+{
+    for (QChart* c : m_d->vetoCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::updateTriggerElements(bool enabled)
+{
+    for (QChart* c : m_d->triggerCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::updatePreshowerElements(bool enabled)
+{
+    for (QChart* c : m_d->preshowerCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::updateCalorimeterElements(bool enabled)
+{
+    for (QChart* c : m_d->calorimeterCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::updateClockElements(bool enabled)
+{
+    for (QChart* c : m_d->clockCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
+
+void VP1WaveformSystem::updateTestElements(bool enabled)
+{
+    for (QChart* c : m_d->testCharts)
+    {
+        c->setVisible(enabled);
+    }
+    m_d->layoutCharts();
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/WaveformSysController.cxx b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/WaveformSysController.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..765ce0d4d702245b2c2733f4003824b21a150ba2
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/WaveformSysController.cxx
@@ -0,0 +1,164 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class WaveformSysController             //
+//                                                            //
+//  Author: Dave Casper (dcasper@uci.edu)                     //
+//  Initial version: August 2021                              //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#define VP1IMPVARNAME m_d
+
+#include "VTI12WaveformSystems/WaveformSysController.h"
+#include "ui_waveformcontrollerform.h"
+
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1Deserialise.h"
+
+// System of units
+#ifdef BUILDVP1LIGHT
+	#include "GeoModelKernel/Units.h"
+	#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm'
+#else
+  #include "GaudiKernel/SystemOfUnits.h"
+  #define SYSTEM_OF_UNITS Gaudi::Units // --> 'Gaudi::Units::cm'
+#endif
+
+#include <cmath>
+
+//____________________________________________________________________
+class WaveformSysController::Imp {
+public:
+  WaveformSysController * theclass;
+  Ui::VP1WaveformControllerForm ui;
+
+  static SbColor4f color4f(const QColor& col, int transp_int) {
+    return SbColor4f(std::max<float>(0.0f,std::min<float>(1.0f,col.redF())),
+		     std::max<float>(0.0f,std::min<float>(1.0f,col.greenF())),
+		     std::max<float>(0.0f,std::min<float>(1.0f,col.blueF())),
+		     std::max<float>(0.0f,std::min<float>(1.0f,1.0-transp_int/100.0)));
+  }
+
+  bool last_vetoEnabled;
+  bool last_triggerEnabled;
+  bool last_preshowerEnabled;
+  bool last_calorimeterEnabled;
+  bool last_clockEnabled;
+  bool last_testEnabled;
+};
+
+//____________________________________________________________________
+WaveformSysController::WaveformSysController(IVP1System * sys)
+  : VP1Controller(sys,"WaveformSysController"), m_d(new Imp)
+{
+  m_d->theclass = this;
+  m_d->ui.setupUi(this);
+
+  addUpdateSlot(SLOT(possibleChange_vetoEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_vetoEnabled);
+
+  addUpdateSlot(SLOT(possibleChange_triggerEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_triggerEnabled);
+
+  addUpdateSlot(SLOT(possibleChange_preshowerEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_preshowerEnabled);
+
+  addUpdateSlot(SLOT(possibleChange_calorimeterEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_calorimeterEnabled);
+
+  addUpdateSlot(SLOT(possibleChange_clockEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_clockEnabled);
+
+  addUpdateSlot(SLOT(possibleChange_testEnabled()));
+  connectToLastUpdateSlot(m_d->ui.checkBox_testEnabled);
+
+  initLastVars();
+}
+
+//____________________________________________________________________
+WaveformSysController::~WaveformSysController()
+{
+  delete m_d;
+}
+
+bool WaveformSysController::vetoEnabled() const
+{
+  return m_d->ui.checkBox_vetoEnabled->isChecked();
+}
+
+bool WaveformSysController::triggerEnabled() const
+{
+  return m_d->ui.checkBox_triggerEnabled->isChecked();
+}
+
+bool WaveformSysController::preshowerEnabled() const
+{
+  return m_d->ui.checkBox_preshowerEnabled->isChecked();
+}
+
+bool WaveformSysController::calorimeterEnabled() const
+{
+  return m_d->ui.checkBox_calorimeterEnabled->isChecked();
+}
+
+bool WaveformSysController::clockEnabled() const
+{
+  return m_d->ui.checkBox_clockEnabled->isChecked();
+}
+
+bool WaveformSysController::testEnabled() const
+{
+  return m_d->ui.checkBox_testEnabled->isChecked();
+}
+
+int WaveformSysController::currentSettingsVersion() const
+{
+  return 0;
+}
+
+//____________________________________________________________________
+void WaveformSysController::actualSaveSettings(VP1Serialise&s) const
+{
+
+  s.save(m_d->ui.checkBox_vetoEnabled);
+  s.save(m_d->ui.checkBox_triggerEnabled);
+  s.save(m_d->ui.checkBox_preshowerEnabled);
+  s.save(m_d->ui.checkBox_calorimeterEnabled);
+  s.save(m_d->ui.checkBox_clockEnabled);
+  s.save(m_d->ui.checkBox_testEnabled);
+
+}
+
+//____________________________________________________________________
+void WaveformSysController::actualRestoreSettings(VP1Deserialise& s)
+{
+  if (s.version() != 0) {
+    message("Warning: State data in .vp1 file has unsupported version ("+str(s.version())+")");
+    return;
+  }
+
+  s.restore(m_d->ui.checkBox_vetoEnabled);
+  s.restore(m_d->ui.checkBox_triggerEnabled);
+  s.restore(m_d->ui.checkBox_preshowerEnabled);
+  s.restore(m_d->ui.checkBox_calorimeterEnabled);
+  s.restore(m_d->ui.checkBox_clockEnabled);
+  s.restore(m_d->ui.checkBox_testEnabled);
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Test for possible changes in values and emit signals as appropriate:
+// (possibleChange_XXX() slots code provided by macros)
+#define VP1CONTROLLERCLASSNAME WaveformSysController
+#include "VP1Base/VP1ControllerMacros.h"
+POSSIBLECHANGE_IMP(vetoEnabled)
+POSSIBLECHANGE_IMP(triggerEnabled)
+POSSIBLECHANGE_IMP(preshowerEnabled)
+POSSIBLECHANGE_IMP(calorimeterEnabled)
+POSSIBLECHANGE_IMP(clockEnabled)
+POSSIBLECHANGE_IMP(testEnabled)
diff --git a/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/waveformcontrollerform.ui b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/waveformcontrollerform.ui
new file mode 100644
index 0000000000000000000000000000000000000000..cb854170cb4351c4f61e0672cd51cf6853af6fe2
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12WaveformSystems/src/waveformcontrollerform.ui
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VP1WaveformControllerForm</class>
+ <widget class="QWidget" name="VP1WaveformControllerForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>267</width>
+    <height>182</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout">
+   <property name="rightMargin">
+    <number>1</number>
+   </property>
+   <property name="bottomMargin">
+    <number>1</number>
+   </property>
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <item row="0" column="0">
+    <layout class="QGridLayout">
+     <property name="horizontalSpacing">
+      <number>2</number>
+     </property>
+     <property name="verticalSpacing">
+      <number>0</number>
+     </property>
+     <item row="0" column="0">
+      <widget class="QCheckBox" name="checkBox_vetoEnabled">
+       <property name="text">
+        <string>Veto</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QCheckBox" name="checkBox_triggerEnabled">
+       <property name="text">
+        <string>Trigger</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QCheckBox" name="checkBox_preshowerEnabled">
+       <property name="text">
+        <string>Preshower</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QCheckBox" name="checkBox_calorimeterEnabled">
+       <property name="text">
+        <string>Calorimeter</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="0">
+      <widget class="QCheckBox" name="checkBox_clockEnabled">
+       <property name="text">
+        <string>Clock</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="0">
+      <widget class="QCheckBox" name="checkBox_testEnabled">
+       <property name="text">
+        <string>Test</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="0" column="1">
+    <spacer>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>1</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="1" column="0">
+    <spacer>
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>1</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/VTI12/VTI12Utils/src/HitToSodeNode.cxx b/graphics/VTI12/VTI12Utils/src/HitToSodeNode.cxx
index 9bb096aa783f217b1dcdb1f0c2cd18c0d4509fb6..6aaef646fe42edd3c232cfd690121eafb39d04ce 100644
--- a/graphics/VTI12/VTI12Utils/src/HitToSodeNode.cxx
+++ b/graphics/VTI12/VTI12Utils/src/HitToSodeNode.cxx
@@ -129,7 +129,7 @@ void HitToSoNode::buildStripShapes(const Trk::RIO_OnTrack& rio, SoSeparator*&sha
 
 
     double stripLength =100.0, stripWidth = 10.0, stripThickness=1.0;
-    const Amg::Vector2D* localposROT=0;
+    std::optional<Amg::Vector2D> localposROT=std::nullopt;
     Amg::Vector2D* localposStrip=0;
     Identifier id=rio.identify();
     fillValues(id, rio.detectorElement(), stripLength, stripWidth, stripThickness, localposStrip);
@@ -144,7 +144,7 @@ void HitToSoNode::buildStripShapes(const Trk::RIO_OnTrack& rio, SoSeparator*&sha
 
     if( !localposROT )
     {
-        localposROT = new Amg::Vector2D;
+        localposROT = Amg::Vector2D{};
         VP1Msg::message("Warning: Local hit position was NULL");
     }
 
@@ -181,7 +181,6 @@ void HitToSoNode::buildStripShapes(const Trk::RIO_OnTrack& rio, SoSeparator*&sha
     shape_detailed->addChild(localtrans1);
 
     delete localposStrip;
-    delete localposROT;    
 }
 
 void HitToSoNode::fillValues(Identifier& id, const Trk::TrkDetElementBase* baseDetEl, double& striplength, double& stripWidth, double& stripThickness, Amg::Vector2D*& localposStrip){
diff --git a/version.txt b/version.txt
index e5078b479cf7c53b9a657a8440d822748ade1826..cdbc15874e55b47fb45012cbf75daefe3196299b 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-22.0.31
+22.0.40