diff --git a/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py b/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py
index 91a59126c80bf50c9654183262c9bd3d8715145c..096aacdd81ce9316862a5b1c5ff06ab16a476087 100644
--- a/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py
+++ b/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py
@@ -51,7 +51,8 @@ if __name__ == "__main__":
 
     from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
     itemList = [ "xAOD::EventInfo#*",
-                 "xAOD::EventAuxInfo#*"
+                 "xAOD::EventAuxInfo#*",
+                 "ScintWaveformContainer#*"
                ]
     acc.merge(OutputStreamCfg(ConfigFlags, "RDO", itemList))
     ostream = acc.getEventAlgo("OutputStreamRDO")
diff --git a/MagneticField/MagFieldServices/src/FaserFieldCacheCondAlg.cxx b/MagneticField/MagFieldServices/src/FaserFieldCacheCondAlg.cxx
index 9ec8b8413268294c99b00d21f527391ce5035630..0ce2635e82d9d42e2b011989268a573b8f81743a 100644
--- a/MagneticField/MagFieldServices/src/FaserFieldCacheCondAlg.cxx
+++ b/MagneticField/MagFieldServices/src/FaserFieldCacheCondAlg.cxx
@@ -62,7 +62,7 @@ MagField::FaserFieldCacheCondAlg::initialize() {
 StatusCode
 MagField::FaserFieldCacheCondAlg::execute(const EventContext& ctx) const {
 
-    ATH_MSG_INFO ( "execute: entering");
+    ATH_MSG_DEBUG ( "execute: entering");
 
     // Check if output conditions object with field cache object is still valid, if not replace it
     // with new current scale factors
diff --git a/MagneticField/MagFieldServices/src/FaserFieldMapCondAlg.cxx b/MagneticField/MagFieldServices/src/FaserFieldMapCondAlg.cxx
index c1246f85b0bc8a33cd7f0922136784d66c085757..d2c761d5b898f7b088a08c96be9ae9df819c6095 100644
--- a/MagneticField/MagFieldServices/src/FaserFieldMapCondAlg.cxx
+++ b/MagneticField/MagFieldServices/src/FaserFieldMapCondAlg.cxx
@@ -64,7 +64,7 @@ MagField::FaserFieldMapCondAlg::initialize() {
 StatusCode
 MagField::FaserFieldMapCondAlg::execute(const EventContext& ctx) const {
 
-    ATH_MSG_INFO ( "execute: entering  ");
+    ATH_MSG_DEBUG ( "execute: entering  ");
 
     // Check if output conditions object with field map object is still valid, if not replace it
     // with new map
diff --git a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
index d7012c1389e5c4a0ea3e46d338d37d6de28a49e1..85a353a09cdab3ecdf23fc8e8ecedad51e345ad9 100644
--- a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
+++ b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
@@ -135,7 +135,7 @@ ScintWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
 
     // Check if this has data
     if (!digitizer->channel_has_data(channel)) {
-      ATH_MSG_INFO("Channel " << channel << " has no data - skipping!");
+      ATH_MSG_DEBUG("Channel " << channel << " has no data - skipping!");
       continue;
     } 
 
diff --git a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
index 55ce336f657700e577b822cccfc289ab7fbfacfd..9db3a1255fa8e91865bb09757ca04d91810a02a5 100644
--- a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
+++ b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
@@ -36,8 +36,8 @@ ScintWaveformContainerCnv_p0::persToTrans(const ScintWaveformContainer_p0* persC
 
 void
 ScintWaveformContainerCnv_p0::transToPers(const ScintWaveformContainer* transCont,ScintWaveformContainer_p0* persCont, MsgStream& log) {
-
-  log << MSG::DEBUG << "ScintWaveformContainerCnv_p0::transToPers preparing " << transCont->size() << " waveforms" << endmsg;
+  log << MSG::ALWAYS << "transCont = " << transCont << " / persCont = " << persCont << endmsg;
+  log << MSG::ALWAYS << "ScintWaveformContainerCnv_p0::transToPers preparing " << transCont->size() << " waveforms" << endmsg;
 
   // If trans container is empty, nothing else to do
   if (!transCont->size()) {
diff --git a/Scintillator/ScintRecAlgs/src/ScintClockRecAlg.cxx b/Scintillator/ScintRecAlgs/src/ScintClockRecAlg.cxx
index 45ceaa30ba91d814072a02d312755d03d3bd1b85..11ccfa9640a912e74bb7b8ecbb639adbd3ca2a98 100644
--- a/Scintillator/ScintRecAlgs/src/ScintClockRecAlg.cxx
+++ b/Scintillator/ScintRecAlgs/src/ScintClockRecAlg.cxx
@@ -30,7 +30,7 @@ ScintClockRecAlg::finalize() {
 
 StatusCode 
 ScintClockRecAlg::execute(const EventContext& ctx) const {
-  ATH_MSG_INFO("Executing");
+  ATH_MSG_DEBUG("Executing");
 
   ATH_MSG_DEBUG("Run: " << ctx.eventID().run_number() 
 		<< " Event: " << ctx.eventID().event_number());
@@ -42,7 +42,7 @@ ScintClockRecAlg::execute(const EventContext& ctx) const {
   ATH_MSG_DEBUG("Found ReadHandle for Waveforms");
 
   if (waveformHandle->size() == 0) {
-    ATH_MSG_INFO("Waveform container found with zero length!");
+    ATH_MSG_DEBUG("Waveform container found with zero length!");
     return StatusCode::SUCCESS;
   }
 
diff --git a/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx b/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
index 36d05aa36a81d89cd3b79cdc1d9492dea62d6b56..c4e04b2e62e84df576de0a1d6769a28a149ed5a1 100644
--- a/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
+++ b/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
@@ -34,7 +34,7 @@ ScintWaveformRecAlg::finalize() {
 
 StatusCode 
 ScintWaveformRecAlg::execute(const EventContext& ctx) const {
-  ATH_MSG_INFO("Executing");
+  ATH_MSG_DEBUG("Executing");
 
   ATH_MSG_DEBUG("Run: " << ctx.eventID().run_number() 
 		<< " Event: " << ctx.eventID().event_number());
@@ -46,7 +46,7 @@ ScintWaveformRecAlg::execute(const EventContext& ctx) const {
   ATH_MSG_DEBUG("Found ReadHandle for ScintWaveformContainer " << m_waveformContainerKey);
 
   if (waveformHandle->size() == 0) {
-    ATH_MSG_INFO("Waveform container found with zero length!");
+    ATH_MSG_DEBUG("Waveform container found with zero length!");
     return StatusCode::SUCCESS;
   }
 
diff --git a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/SCT_Frame.cxx b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/SCT_Frame.cxx
index 23a50ad35ddc5447451b116f0e079011dc5a8f0e..273e8c278d7d43e0800603b9065a2728b25794fe 100644
--- a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/SCT_Frame.cxx
+++ b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/src/SCT_Frame.cxx
@@ -58,11 +58,11 @@ SCT_Frame::getParameters()
   m_stagger = 0.0;
   if (getName().find("Central") != std::string::npos)
   {
-      m_stagger = -barrelParameters->phiStagger();
+      m_stagger = barrelParameters->phiStagger();
   }
   else if (getName().find("Downstream") != std::string::npos)
   {
-      m_stagger = barrelParameters->phiStagger();
+      m_stagger = -barrelParameters->phiStagger();
   }
 
   m_booleans  = barrelParameters->frameBooleanVolumes();
diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
index 893845c56afbc19809969baeaa19428f7bef977f..d9325aabfe527c2d3df54ebe24a3e8d29c762582 100644
--- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
+++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
@@ -602,7 +602,7 @@ namespace TrackerDD {
     //           = -(center cross etaAxis) . zAxis
     //           = (etaAxis cross center). z() 
     double sinStereo = 0.;
-    sinStereo = m_phiAxis.z();
+    sinStereo = -m_etaAxis.y();
     return sinStereo;
   }
 
@@ -634,7 +634,7 @@ namespace TrackerDD {
     //
     double sinStereo = 0.;
     if (m_design->shape() != TrackerDD::Trapezoid) {
-      sinStereo = m_phiAxis.z();
+      sinStereo = -m_etaAxis.y();
     } else { // trapezoid
       assert (minWidth() != maxWidth());
       double radius = width() * length() / (maxWidth() - minWidth());
diff --git a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
index b84a5fd143526685012b5058426e4a30a0976358..db4f5e6f6f6063281465b12fea988ffb8ae0dc84 100644
--- a/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
+++ b/Tracker/TrackerEventCnv/TrackerByteStream/src/TrackerDataDecoderTool.cxx
@@ -145,7 +145,7 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
         if (sctEvent != nullptr)
         {
           unsigned short onlineModuleID = sctEvent->GetModuleID(); 
-          if (plane == 2) onlineModuleID = (onlineModuleID + 4) % 8;
+          // if (plane == 2) onlineModuleID = (onlineModuleID + 4) % 8;
           if (onlineModuleID >= TrackerDataFragment::MODULES_PER_FRAGMENT)
           {
             // FIXME: Should we return failure here?
@@ -250,8 +250,8 @@ TrackerDataDecoderTool::convert(const DAQFormats::EventFull* re,
 
   if (validFragments == 0) 
   {
-    ATH_MSG_ERROR("Failed to find any valid Tracker fragments in raw event!");
-    return StatusCode::FAILURE;
+    ATH_MSG_DEBUG("Failed to find any valid Tracker fragments in raw event!");
+    return StatusCode::SUCCESS;
   }
 
   for (auto& [hash, collection] : collectionMap)
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/CMakeLists.txt b/Tracker/TrackerRecAlgs/TrackerClusterFit/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..254b5a4054a316406c3d065f4546d80e0b4a8bbd
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/CMakeLists.txt
@@ -0,0 +1,24 @@
+################################################################################
+# Package: TrackerClusterFIt
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrackerClusterFit )
+
+# External dependencies
+find_package( Eigen )
+
+# Component(s) in the package:
+atlas_add_component( TrackerClusterFit
+                    src/*.cxx src/*.h
+                    src/components/*.cxx
+                    INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+                    LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps AthViews StoreGateLib SGtests Identifier GaudiKernel TrackerRawData TrackerPrepRawData FaserDetDescr TrackerIdentifier TrackerReadoutGeometry xAODFaserTrigger 
+                                                      TrkTrack TrkEventPrimitives TrkRIO_OnTrack )
+
+# Install files from the package:
+#atlas_install_headers( TrackerPrepRawDataFormation )
+
+atlas_install_python_modules( python/*.py )
+
+atlas_install_scripts( test/*.py )
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/python/TrackerClusterFitConfig.py b/Tracker/TrackerRecAlgs/TrackerClusterFit/python/TrackerClusterFitConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfeb2517763b8c3b0be0fcab43fef99d92db6f5f
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/python/TrackerClusterFitConfig.py
@@ -0,0 +1,30 @@
+"""Define methods to construct configured SCT Cluster Fit tools and algorithms
+
+Copyright (C) 2021 CERN for the benefit of the FASER collaboration
+"""
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+# from FaserGeoModel.SCTGMConfig import SctGeometryCfg
+
+def ClusterFitAlgBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator for Tracker ClusterFitAlg"""
+    acc = ComponentAccumulator()
+    # clusterTool = acc.popToolsAndMerge(FaserSCT_ClusterizationToolCfg(flags))
+    # kwargs.setdefault("SCT_ClusteringTool", clusterTool)
+    # kwargs.setdefault("DataObjectName", "SCT_RDOs")
+    kwargs.setdefault("ClustersName", "SCT_ClusterContainer")
+    # kwargs.setdefault("SCT_FlaggedCondData", "SCT_Flags")
+    Tracker__ClusterFitAlg=CompFactory.Tracker.ClusterFitAlg
+    acc.addEventAlgo(Tracker__ClusterFitAlg(**kwargs))
+    
+    thistSvc = CompFactory.THistSvc()
+    thistSvc.Output += ["HIST DATAFILE='ClusterFitHistograms.root' OPT='RECREATE'"]
+    acc.addService(thistSvc)
+    return acc
+
+# with output defaults
+def ClusterFitAlgCfg(flags, **kwargs):
+    """Return ComponentAccumulator for Tracker ClusterFitAlg and Output"""
+    acc = ClusterFitAlgBasicCfg(flags, **kwargs)
+    # acc.merge(ClusterFitAlgOutputCfg(flags))
+    return acc
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/python/__init__.py b/Tracker/TrackerRecAlgs/TrackerClusterFit/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e59672072be6bba12b3256e39a9d507c021b3bf7
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/python/__init__.py
@@ -0,0 +1 @@
+#TrackerClusterFit
\ No newline at end of file
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e8daf6cea653aac8a9793fb493d7e0d40ebd01b2
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.cxx
@@ -0,0 +1,410 @@
+/*
+   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+   */
+
+/**   @file ClusterFitAlg.cxx
+ *   Implementation file for the ClusterFitAlg class.
+ *   @author Dave Casper
+ *   @date 28 February 2021
+ */
+
+#include "ClusterFitAlg.h"
+
+#include "TrackerPrepRawData/FaserSCT_Cluster.h"
+#include "FaserDetDescr/FaserDetectorID.h"    
+#include "TrackerIdentifier/FaserSCT_ID.h"
+#include "TrkEventPrimitives/FitQuality.h"
+#include "TrkEventPrimitives/ParticleHypothesis.h"
+#include "TrkEventPrimitives/LocalParameters.h"
+#include "TrkRIO_OnTrack/RIO_OnTrack.h"
+#include "StoreGate/ReadHandle.h"
+#include <TH1F.h>
+#include <TTree.h>
+#include <TBranch.h>
+
+
+namespace Tracker
+{
+
+static const std::string moduleFailureReason{"ClusterFitAlg: Exceeds max clusters"};
+
+// Constructor with parameters:
+ClusterFitAlg::ClusterFitAlg(const std::string& name, ISvcLocator* pSvcLocator) :
+  AthReentrantAlgorithm(name, pSvcLocator), 
+  AthHistogramming( name ),
+  m_idHelper{nullptr},
+  m_histSvc ( "THistSvc/THistSvc", name )
+{
+}
+
+// Initialize method:
+StatusCode ClusterFitAlg::initialize() {
+  ATH_MSG_INFO("ClusterFitAlg::initialize()");
+
+  ATH_CHECK(m_faserTriggerDataKey.initialize());
+  ATH_CHECK(m_clusterContainerKey.initialize());
+  ATH_CHECK(m_trackCollection.initialize());
+
+  // Get the SCT ID helper
+  ATH_CHECK(detStore()->retrieve(m_idHelper, "FaserSCT_ID"));
+
+
+  // Histograms
+  m_chi2 = new TH1F("chi2", "Fit #chi^2;#chi^2;Events/bin", 100, 0, 50);
+
+  // Tree
+  m_tree = new TTree("residTree","Cosmics residuals");
+  m_tree->Branch("id", &m_hash, "id/I");
+  m_tree->Branch("residual", &m_residual, "residual/F");
+  m_tree->Branch("pull", &m_pull, "pull/F");
+  m_tree->Branch("chi2", &m_refitChi2, "chi2/F");
+
+  ATH_CHECK(histSvc()->regHist("/HIST/chi2", m_chi2));
+  ATH_CHECK(histSvc()->regTree("/HIST/residTree", m_tree));
+
+  return StatusCode::SUCCESS;
+}
+
+// Execute method:
+StatusCode ClusterFitAlg::execute(const EventContext& ctx) const
+{
+  ++m_numberOfEvents;  
+  setFilterPassed(false, ctx);
+
+  SG::WriteHandle trackContainer{m_trackCollection, ctx};
+  std::unique_ptr<TrackCollection> outputTracks = std::make_unique<TrackCollection>();
+
+  SG::ReadHandle<xAOD::FaserTriggerData> triggerContainer{m_faserTriggerDataKey, ctx};
+  ATH_CHECK(triggerContainer.isValid());
+
+  uint8_t triggerBits = triggerContainer->tap();
+  if (m_triggerMask != 0 && ((triggerBits & m_triggerMask) == 0))
+  {
+      ATH_CHECK(trackContainer.record(std::move(outputTracks)));
+      return StatusCode::SUCCESS;
+  }
+  ++m_numberOfTriggeredEvents;
+
+  SG::ReadHandle<FaserSCT_ClusterContainer> clusterContainer{m_clusterContainerKey, ctx};
+  ATH_CHECK(clusterContainer.isValid());
+
+  // Tabulate cluster info by wafer
+
+  std::map<IdentifierHash, std::pair<std::vector<clusterInfo*>, std::vector<clusterInfo*>>> clusterMap; 
+  std::set<int> stations {};
+
+  FaserSCT_ClusterContainer::const_iterator clusterCollections {clusterContainer->begin()};
+  FaserSCT_ClusterContainer::const_iterator clusterCollectionsEnd {clusterContainer->end()};
+  for (; clusterCollections != clusterCollectionsEnd; ++clusterCollections) 
+  {
+    ++m_numberOfClusterCollection;      
+    const Tracker::FaserSCT_ClusterCollection* cl{*clusterCollections};
+    m_numberOfCluster += cl->size();
+    IdentifierHash hash = cl->identifyHash();
+    clusterMap.emplace(std::make_pair(hash,std::make_pair(std::vector<clusterInfo*>{ }, std::vector<clusterInfo*> { })));
+
+    FaserSCT_ClusterCollection::const_iterator clusters {cl->begin()};
+    FaserSCT_ClusterCollection::const_iterator clustersEnd {cl->end()};
+    for (; clusters != clustersEnd; ++clusters)
+    {
+        ATH_MSG_VERBOSE(**clusters);
+        const TrackerDD::SiDetectorElement* elem = (*clusters)->detectorElement();
+        if (elem != nullptr)
+        {
+            ATH_MSG_VERBOSE("( " << m_idHelper->wafer_hash(elem->identify()) << " = " << m_idHelper->layer(elem->identify()) <<  "/" << m_idHelper->eta_module(elem->identify()) << "/" << m_idHelper->phi_module(elem->identify()) << "|" << m_idHelper->side(elem->identify()) <<
+                         " ): isStereo? " << elem->isStereo() << " sinStereo: " << elem->sinStereo() << " Swap phi? " << elem->swapPhiReadoutDirection() << " Depth, Eta, Phi directions: " << 
+                         elem->hitDepthDirection() << " : " << elem->hitEtaDirection() << " : " << elem->hitPhiDirection() << " / zGlobal = " << (*clusters)->globalPosition().z());
+            stations.emplace(m_idHelper->station(elem->identify()));
+            clusterInfo* info = new clusterInfo { };
+            info->cluster  = *clusters;
+            info->sinAlpha = elem->sinStereo();
+            info->cosAlpha = sqrt(1.0 - info->sinAlpha * info->sinAlpha);
+            info->u        = (*clusters)->globalPosition().y() * info->cosAlpha + (*clusters)->globalPosition().x() * info->sinAlpha;
+            info->z        = (*clusters)->globalPosition().z();
+            info->sigmaSq  = (*clusters)->localCovariance()(0,0);
+            if (info->sinAlpha < 0)
+            {
+                clusterMap[hash/2].first.push_back(info);
+            }
+            else if (info->sinAlpha > 0)
+            {
+                clusterMap[hash/2].second.push_back(info);
+            }
+            else
+            {
+                ATH_MSG_ERROR("Invalid stereo angle");
+                delete info;
+            }
+        }
+        else
+        {
+            ATH_MSG_VERBOSE("detelem missing");
+        }
+    }
+    ATH_MSG_DEBUG("Cluster collection size=" << cl->size() << ", Hash=" << cl->identifyHash());
+  }
+  ATH_MSG_DEBUG("clusterContainer->numberOfCollections() " << clusterContainer->numberOfCollections());
+
+  // Loop over stations
+  if (!stations.empty())
+  {
+      for (int thisStation : stations)
+      {
+          bool layerGood[3] {false, false, false};
+          int nGoodLayers = 0;
+          std::vector<std::vector<layerCombo*>> layerCombos { std::vector<layerCombo*> {}, std::vector<layerCombo*> {}, std::vector<layerCombo*> {} };
+          ATH_MSG_VERBOSE(" Processing station: " << thisStation);
+          for (auto entry : clusterMap )
+          {
+              Identifier waferID = m_idHelper->wafer_id(2 * entry.first);
+              if (m_idHelper->station( waferID ) != thisStation) continue;
+              int layer = m_idHelper->layer( waferID );
+              std::vector<clusterInfo*>& stereoMinus = entry.second.first;
+              std::vector<clusterInfo*>& stereoPlus  = entry.second.second;
+              ATH_MSG_VERBOSE("Module entry in layer " << layer << " has " << stereoMinus.size() << " negative and " << stereoPlus.size() << " positive stereo clusters");
+              if (stereoMinus.size() > 0 && stereoPlus.size() > 0 && !layerGood[layer])
+              {
+                nGoodLayers++;
+                layerGood[layer] = true;
+                for (clusterInfo* minus : stereoMinus)
+                {
+                    for (clusterInfo* plus : stereoPlus)
+                    {
+                        layerCombo* combo = new layerCombo { };
+                        combo->initialize();
+                        combo->addCluster(plus, m_zCenter);
+                        combo->addCluster(minus, m_zCenter);
+                        layerCombos[layer].push_back( combo );
+                    }
+                }
+              }
+          }
+          ATH_MSG_VERBOSE( "Found " << nGoodLayers << " layers with stereo clusters in at least one module");
+          if (nGoodLayers == 3)
+          {
+              Eigen::Matrix< double, 4, 1 > bestFit;
+              Amg::MatrixX bestCov(4,4);
+              std::vector<const clusterInfo*> bestClusters;
+              double bestChi2 = -1;
+              for (layerCombo* combo_0 : layerCombos[0])
+              {
+                  for (layerCombo* combo_1 : layerCombos[1])
+                  {
+                      for (layerCombo* combo_2 : layerCombos[2])
+                      {
+                          std::tuple<Eigen::Matrix<double, 4, 1>, 
+                                     Eigen::Matrix<double, 4, 4>, 
+                                     double> 
+                                     fitResult = ClusterFit(combo_0, combo_1, combo_2);
+                          if (bestChi2 < 0 || std::get<2>(fitResult) < bestChi2)
+                          {
+                            bestChi2 = std::get<2>(fitResult);
+                            bestFit = std::get<0>(fitResult);
+                            bestCov = std::get<1>(fitResult);
+                            bestClusters.clear();
+                            if (combo_0->stereoPlus != nullptr)
+                              bestClusters.push_back(combo_0->stereoPlus);
+                            if (combo_0->stereoMinus != nullptr)
+                              bestClusters.push_back(combo_0->stereoMinus);
+                            if (combo_1->stereoPlus != nullptr)
+                              bestClusters.push_back(combo_1->stereoPlus);
+                            if (combo_1->stereoMinus != nullptr)
+                              bestClusters.push_back(combo_1->stereoMinus);
+                            if (combo_2->stereoPlus != nullptr)
+                              bestClusters.push_back(combo_2->stereoPlus);
+                            if (combo_2->stereoMinus != nullptr)
+                              bestClusters.push_back(combo_2->stereoMinus);
+                          }
+                       }
+                  }
+              }
+              ATH_MSG_VERBOSE("best fit: (" << bestFit(0) << "+/-" << sqrt(bestCov(0,0)) << "," << 
+                                               bestFit(1) << "+/-" << sqrt(bestCov(1,1)) << "," << 
+                                               bestFit(2) << "+/-" << sqrt(bestCov(2,2)) << "," << 
+                                               bestFit(3) << "+/-" << sqrt(bestCov(3,3)) << "); chi2 = " << bestChi2 );
+              Residuals(bestClusters);
+              ATH_CHECK(AddTrack(outputTracks, bestFit, bestCov, bestClusters, bestChi2, bestClusters.size()-4));
+              m_chi2->Fill(bestChi2);
+              setFilterPassed(true, ctx);
+              ++m_numberOfFits;
+          }
+          // clean-up
+          for (auto layerEntry : layerCombos)
+          {
+              for (auto combo : layerEntry)
+              {
+                  if (combo != nullptr) delete combo;
+              }
+              layerEntry.clear();
+          }
+          layerCombos.clear();
+      }
+  }
+  else
+  {
+      ATH_MSG_DEBUG("No stations with clusters found.");
+  }
+
+  ATH_CHECK(trackContainer.record(std::move(outputTracks)));
+
+  // Clean up
+  for (auto entry : clusterMap)
+  {
+      for (clusterInfo* info : entry.second.first)
+      {
+          if (info != nullptr) delete info;
+      }
+      entry.second.first.clear();
+      for (clusterInfo* info : entry.second.second)
+      {
+          if (info != nullptr) delete info;
+      }
+      entry.second.second.clear();
+  }
+  clusterMap.clear();
+
+  // Done
+  return StatusCode::SUCCESS;
+}
+
+// Finalize method:
+StatusCode ClusterFitAlg::finalize() 
+{
+  ATH_MSG_INFO("ClusterFitAlg::finalize()");
+  ATH_MSG_INFO( m_numberOfEvents << " events processed" );
+  ATH_MSG_INFO( m_numberOfTriggeredEvents << " triggered events processed" );
+  ATH_MSG_INFO( m_numberOfClusterCollection<< " cluster collections processed" );
+  ATH_MSG_INFO( m_numberOfCluster<< " cluster processed" );
+  ATH_MSG_INFO( m_numberOfFits << " fits performed" );
+
+
+  return StatusCode::SUCCESS;
+}
+
+// Method to create and store Trk::Track from fit results
+StatusCode 
+ClusterFitAlg::AddTrack(std::unique_ptr<TrackCollection>& tracks, 
+                        const Eigen::Matrix< double, 4, 1 >& fitResult, 
+                        const Eigen::Matrix< double, 4, 4 >& fitCovariance,  
+                        std::vector<const clusterInfo*>& fitClusters,
+                        double chi2, int ndof) const
+{
+    Trk::TrackInfo i { Trk::TrackInfo::TrackFitter::Unknown, Trk::ParticleHypothesis::muon };
+    Trk::FitQuality* q = new Trk::FitQuality {chi2, ndof};
+    DataVector<const Trk::TrackStateOnSurface>* s = new DataVector<const Trk::TrackStateOnSurface> {};
+
+    // translate parameters to nominal fit point
+    s->push_back( GetState(fitResult, fitCovariance, nullptr) );
+
+    for (const clusterInfo* cInfo : fitClusters)
+    {
+        s->push_back( GetState(fitResult, fitCovariance, cInfo->cluster) );
+    }
+
+    // Create and store track
+    tracks->push_back(new Trk::Track(i, s , q));
+    return StatusCode::SUCCESS;
+}
+
+Trk::TrackStateOnSurface*
+ClusterFitAlg::GetState( const Eigen::Matrix< double, 4, 1 >& fitResult, 
+                         const Eigen::Matrix< double, 4, 4 >& fitCovariance,  
+                         const FaserSCT_Cluster* fitCluster ) const
+{
+    // position of fit point:
+    double zFit = m_zCenter;
+    if (fitCluster != nullptr) zFit = fitCluster->globalPosition()[2];
+    Amg::Vector3D pos { fitResult[0] + fitResult[2] * (zFit - m_zCenter), fitResult[1] + fitResult[3] * (zFit - m_zCenter), zFit };
+    double phi = atan2( fitResult[3], fitResult[2] );
+    double theta = atan( sqrt(fitResult[2]*fitResult[2] + fitResult[3]*fitResult[3]) );
+    double qoverp = 1.0/100000.0;
+
+    Eigen::Matrix< double, 4, 4 > jacobian = Eigen::Matrix< double, 4, 4 >::Zero();
+    jacobian << 1, 0, zFit, 0, 
+                0, 1, 0, zFit,
+                0, 0, fitResult[3]/(fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3]), 
+                      fitResult[2]/(fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3]),
+                0, 0, fitResult[2]/(sqrt(fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3])*(1+fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3])),
+                      fitResult[3]/(sqrt(fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3])*(1+fitResult[2]*fitResult[2]+fitResult[3]*fitResult[3]));
+    Eigen::Matrix< double, 4, 4 > covPar {jacobian * fitCovariance * jacobian.transpose()};
+    std::unique_ptr<AmgSymMatrix(5)> covPar5 { new AmgSymMatrix(5){ AmgSymMatrix(5)::Zero() } };
+    covPar5->block<4,4>(0,0) = covPar;
+    covPar5->block<1,1>(4,4) = Eigen::Matrix< double, 1, 1 > { (50000.0)*qoverp*qoverp };
+
+    // Trk::RIO_OnTrack* rot = nullptr;
+    // if (fitCluster != nullptr)
+    // {
+    //     rot = new Trk::RIO_OnTrack{ Trk::LocalParameters { Trk::DefinedParameter { fitCluster->localPosition()[0], Trk::loc1 }, 
+    //                                                        Trk::DefinedParameter { fitCluster->localPosition()[1], Trk::loc2 } }, 
+    //                                                        fitCluster->localCovariance(), fitCluster->identify()};
+    // }
+    std::unique_ptr<Trk::TrackParameters> p { new Trk::CurvilinearParameters { pos, phi, theta, qoverp, covPar5.release() } };
+    return new Trk::TrackStateOnSurface { nullptr, p.release() };
+}
+
+std::tuple<Eigen::Matrix<double, 4, 1>, 
+           Eigen::Matrix<double, 4, 4>, 
+           double> 
+ClusterFitAlg::ClusterFit(layerCombo* c0, layerCombo* c1, layerCombo* c2) const
+{ 
+    double sums[15];
+    for (size_t i = 0; i < 15; i++)
+    {
+        sums[i] = c0->sums[i] + c1->sums[i] + c2->sums[i];
+    }
+    Amg::MatrixX s(5,5);
+    s << sums[1] , sums[2] , sums[4] , sums[5] , sums[10] ,
+        sums[2] , sums[3] , sums[5] , sums[6] , sums[11] ,
+        sums[4] , sums[5] , sums[7] , sums[8] , sums[12] ,
+        sums[5] , sums[6] , sums[8] , sums[9] , sums[13] ,
+        sums[10] , sums[11] , sums[12] , sums[13] , sums[14];
+    Amg::MatrixX s4(4,4);
+    s4 = s.block<4,4>(0,0);
+    Eigen::Matrix< double, 4, 1 > v;
+    v << sums[10] , sums[11] , sums[12] , sums[13];
+    Eigen::Matrix< double, 4, 1 > x = s4.colPivHouseholderQr().solve(v);                
+    Eigen::Matrix< double, 5, 1 > x5;
+    x5 << x(0), x(1), x(2), x(3), -1;
+    double chi2 = x5.transpose()*s*x5;  
+
+    return std::make_tuple(x, s4.inverse(), chi2);
+}
+
+void
+ClusterFitAlg::Residuals(std::vector<const clusterInfo*>& fitClusters) const
+{
+    for (const clusterInfo* cI : fitClusters)
+    {
+        double zFit = cI->z;
+        layerCombo* zero = new layerCombo{ };
+        layerCombo* one = new layerCombo{ };
+        layerCombo* two = new layerCombo{ };
+        zero->initialize();
+        one->initialize();
+        two->initialize();
+        if (fitClusters[0]->z != zFit) zero->addCluster(fitClusters[0], zFit);
+        if (fitClusters[1]->z != zFit) zero->addCluster(fitClusters[1], zFit);
+        if (fitClusters[2]->z != zFit) one->addCluster(fitClusters[2], zFit);
+        if (fitClusters[3]->z != zFit) one->addCluster(fitClusters[3], zFit);
+        if (fitClusters[4]->z != zFit) two->addCluster(fitClusters[4], zFit);
+        if (fitClusters[5]->z != zFit) two->addCluster(fitClusters[5], zFit);
+        std::tuple<Eigen::Matrix<double, 4, 1>, Eigen::Matrix<double, 4, 4>, double> newFit = ClusterFit( zero, one, two);
+        double deltaU = std::get<0>(newFit)[1] * cI->cosAlpha + std::get<0>(newFit)[0] * cI->sinAlpha - cI->u;
+        double pullU = deltaU/sqrt(cI->sigmaSq + std::get<1>(newFit)(0,0)*cI->sinAlpha*cI->sinAlpha + std::get<1>(newFit)(1,1)*cI->cosAlpha*cI->cosAlpha);
+
+        const TrackerDD::SiDetectorElement* elem = cI->cluster->detectorElement();
+        IdentifierHash hash = m_idHelper->wafer_hash(elem->identify());
+        ATH_MSG_VERBOSE("hash, residual, pull, n:" << hash << " : " << deltaU << " : " << pullU << " : " << zero->sums[0] + one->sums[0] + two->sums[0]);
+        m_hash = hash;
+        m_residual = deltaU;
+        m_pull = pullU;
+        m_refitChi2 = std::get<2>(newFit);
+        m_tree->Fill();
+
+        delete zero;
+        delete one;
+        delete two;
+    }
+}
+
+}
\ No newline at end of file
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.h b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6bc1bf981d443b466ac9450de3ca8118bdbc5f2
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/ClusterFitAlg.h
@@ -0,0 +1,220 @@
+/*
+   Copyright (C) 2021 CERN for the benefit of the FASER collaboration
+   */
+
+/**   @file ClusterFitAlg
+ *   Header file for the ClusterFitAlg class (an Algorithm).
+ *   @author Dave Casper
+ *   @date 28 February 2021
+ */
+
+#ifndef FASERCLUSTERFIT_CLUSTERFITALG_H
+#define FASERCLUSTERFIT_CLUSTERFITALG_H
+
+// Base class
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "AthenaBaseComps/AthHistogramming.h"
+
+////Next contains a typedef so cannot be fwd declared
+#include "TrackerPrepRawData/FaserSCT_ClusterContainer.h"
+#include "TrackerPrepRawData/FaserSCT_ClusterCollection.h"
+#include "TrackerPrepRawData/TrackerClusterContainer.h"
+#include "Identifier/IdentifierHash.h"
+#include "xAODFaserTrigger/FaserTriggerData.h"
+#include "TrkTrack/TrackCollection.h"
+
+//Gaudi
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+
+//STL
+#include <map>
+#include <string>
+
+class FaserSCT_ID;
+class ISvcLocator;
+class StatusCode;
+class TH1;
+class TTree;
+namespace Trk
+{
+    class TrackStateOnSurface;
+}
+
+namespace Tracker
+{
+
+/**
+ *    @class SCT_Clusterization
+ *    @brief Form clusters from SCT Raw Data Objects
+ *    The class loops over an RDO grouping strips and creating collections of clusters, subsequently recorded in StoreGate
+ *    Uses SCT_ConditionsTools to determine which strips to include.
+ */
+class ClusterFitAlg : public AthReentrantAlgorithm, AthHistogramming
+ {
+  public:
+    /// Constructor with parameters:
+    ClusterFitAlg(const std::string& name, ISvcLocator* pSvcLocator);
+
+    /**    @name Usual algorithm methods */
+    //@{
+    ///Retrieve the tools used and initialize variables
+    virtual StatusCode initialize() override;
+    ///Form clusters and record them in StoreGate (detector store)
+    virtual StatusCode execute(const EventContext& ctx) const override;
+    ///Clean up and release the collection containers
+    virtual StatusCode finalize() override;
+    //Make this algorithm clonable.
+    virtual bool isClonable() const override { return true; };
+    //@}
+    const ServiceHandle<ITHistSvc>& histSvc() const;
+
+
+  private:
+    /**    @name Disallow default instantiation, copy, assignment */
+    //@{
+    ClusterFitAlg() = delete;
+    ClusterFitAlg(const ClusterFitAlg&) = delete;
+    ClusterFitAlg &operator=(const ClusterFitAlg&) = delete;
+    //@}
+    struct clusterInfo
+    {
+        const FaserSCT_Cluster* cluster;
+        double sinAlpha;
+        double cosAlpha;
+        double u;
+        double z;
+        double sigmaSq;
+    };
+    
+    struct layerCombo
+    {
+        const clusterInfo* stereoPlus;  // no ownership
+        const clusterInfo* stereoMinus;
+        double sums[15];
+
+        void initialize()
+        {
+            stereoPlus = nullptr;
+            stereoMinus = nullptr;
+            for (auto i = 0; i < 15; i++) sums[i] = 0.0;
+        }
+
+        void addCluster(const clusterInfo* cluster, double zCenter)
+        {
+            double sinA = cluster->sinAlpha;
+            double cosA = cluster->cosAlpha;
+            double    u = cluster->u;
+            double    z = cluster->z - zCenter;
+            double  sSq = cluster->sigmaSq;
+            sums[0] += 1;
+            sums[1] += sinA * sinA / sSq;
+            sums[2] += sinA * cosA / sSq;
+            sums[3] += cosA * cosA / sSq;
+            sums[4] += z * sinA * sinA / sSq;
+            sums[5] += z * sinA * cosA / sSq;
+            sums[6] += z * cosA * cosA / sSq;
+            sums[7] += z * z * sinA * sinA / sSq;
+            sums[8] += z * z * sinA * cosA / sSq;
+            sums[9] += z * z * cosA * cosA / sSq;
+            sums[10] += u * sinA / sSq;
+            sums[11] += u * cosA / sSq;
+            sums[12] += u * z * sinA / sSq;
+            sums[13] += u * z * cosA / sSq;
+            sums[14] += u * u / sSq;
+            if (sinA > 0)
+            {
+                stereoPlus = cluster;
+            }
+            else if (sinA < 0)
+            {
+                stereoMinus = cluster;
+            }
+         }
+
+         void removeCluster(const clusterInfo* cluster, double zCenter)
+         {
+            double sinA = cluster->sinAlpha;
+            double cosA = cluster->cosAlpha;
+            double    u = cluster->u;
+            double    z = cluster->z - zCenter;
+            double  sSq = cluster->sigmaSq;
+            sums[0] -= 1;
+            sums[1] -= sinA * sinA / sSq;
+            sums[2] -= sinA * cosA / sSq;
+            sums[3] -= cosA * cosA / sSq;
+            sums[4] -= z * sinA * sinA / sSq;
+            sums[5] -= z * sinA * cosA / sSq;
+            sums[6] -= z * cosA * cosA / sSq;
+            sums[7] -= z * z * sinA * sinA / sSq;
+            sums[8] -= z * z * sinA * cosA / sSq;
+            sums[9] -= z * z * cosA * cosA / sSq;
+            sums[10] -= u * sinA / sSq;
+            sums[11] -= u * cosA / sSq;
+            sums[12] -= u * z * sinA / sSq;
+            sums[13] -= u * z * cosA / sSq;
+            sums[14] -= u * u / sSq;
+            if (sinA > 0)
+            {
+                stereoPlus = nullptr;
+            }
+            else if (sinA < 0)
+            {
+                stereoMinus = nullptr;
+            }
+         }         
+    };
+
+    StatusCode AddTrack(std::unique_ptr<TrackCollection>& tracks, 
+                        const Eigen::Matrix< double, 4, 1 >& fitResult, 
+                        const Eigen::Matrix< double, 4, 4>& fitCovariance,  
+                        std::vector<const clusterInfo*>& fitClusters, 
+                        double chi2, int ndof) const;
+
+    Trk::TrackStateOnSurface* GetState( const Eigen::Matrix< double, 4, 1 >& fitResult, 
+                                        const Eigen::Matrix< double, 4, 4 >& fitCovariance,  
+                                        const FaserSCT_Cluster* fitCluster ) const; 
+
+    std::tuple<Eigen::Matrix<double, 4, 1>, 
+               Eigen::Matrix<double, 4, 4>, 
+               double> 
+    ClusterFit(layerCombo* c0, layerCombo* c1, layerCombo* c2) const;
+
+    void
+    Residuals(std::vector<const clusterInfo*>& fitClusters) const;
+
+    const FaserSCT_ID* m_idHelper;
+
+    SG::ReadHandleKey<xAOD::FaserTriggerData> m_faserTriggerDataKey { this, "FaserTriggerDataKey", "FaserTriggerData", "ReadHandleKey for xAOD::FaserTriggerData" };
+    SG::ReadHandleKey<FaserSCT_ClusterContainer> m_clusterContainerKey { this, "ClustersName", "SCT_ClusterContainer", "FaserSCT cluster container" };
+    SG::WriteHandleKey<TrackCollection> m_trackCollection { this, "OutputCollection", "ClusterFit", "Output track collection name" };
+
+    DoubleProperty m_zCenter { this, "ZCenter", 2300.0, "Global z position at which to reconstruct track parameters"};
+    UnsignedIntegerProperty m_triggerMask { this, "TriggerMask", 0x0, "Trigger mask to analyze (0 = pass all)" };
+/// a handle on the Hist/TTree registration service
+    ServiceHandle<ITHistSvc> m_histSvc;
+
+
+
+    mutable TH1* m_chi2;
+    mutable TTree* m_tree;
+    mutable int   m_hash;
+    mutable float m_residual;
+    mutable float m_pull;
+    mutable float m_refitChi2;
+
+    mutable std::atomic<int> m_numberOfEvents{0};
+    mutable std::atomic<int> m_numberOfTriggeredEvents{0};
+    mutable std::atomic<int> m_numberOfClusterCollection{0};
+    mutable std::atomic<int> m_numberOfCluster{0};
+    mutable std::atomic<int> m_numberOfFits{0};
+};
+
+// For the THistSvc
+inline const ServiceHandle<ITHistSvc>& ClusterFitAlg::histSvc() const 
+{
+  return m_histSvc;
+}
+
+}
+#endif // FASERCLUSTERFIT_CLUSTERFITALG_H
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/src/components/TrackerClusterFit_entries.cxx b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/components/TrackerClusterFit_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fec53fa6d9705c2227bfe994381451bb434b18b2
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/src/components/TrackerClusterFit_entries.cxx
@@ -0,0 +1,3 @@
+#include "../ClusterFitAlg.h"
+
+DECLARE_COMPONENT( Tracker::ClusterFitAlg )
\ No newline at end of file
diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py
new file mode 100644
index 0000000000000000000000000000000000000000..77182425696ee70043778ba15026b8a167ebfad5
--- /dev/null
+++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py
@@ -0,0 +1,156 @@
+#!/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 = [
+    '/eos/project-f/faser-commissioning/TI12Data/Run-001261/Faser-Physics-001261-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 = "run001261.ESD.pool.root"
+ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX"          # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment
+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-01"           # FASER geometry
+ConfigFlags.Common.isOnline = False
+ConfigFlags.GeoModel.Align.Dynamic = False
+ConfigFlags.Beam.NumberOfCollisions = 0.
+
+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
+
+# explicitly save RDO information
+from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+itemList = [ "xAOD::EventInfo#*",
+             "xAOD::EventAuxInfo#*",
+             "FaserSCT_RDO_Container#*",
+             "xAOD::FaserTriggerData#*",
+             "xAOD::FaserTriggerDataAuxInfo#*",
+             "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=-1)
+
+# Success should be 0
+sys.exit(not sc.isSuccess())
\ No newline at end of file
diff --git a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/python/TrackerPrepRawDataFormationConfig.py b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/python/TrackerPrepRawDataFormationConfig.py
index a4051d50a5baadd3ccdbaa9cd5d0efcdb336ed30..295281a01081fa5490b5691ad5f1be5c35ac58c2 100644
--- a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/python/TrackerPrepRawDataFormationConfig.py
+++ b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/python/TrackerPrepRawDataFormationConfig.py
@@ -16,7 +16,6 @@ def FaserSCT_ClusterizationCommonCfg(flags, name="FaserSCT_ClusterizationToolCom
     """Return ComponentAccumulator with common FaserSCT Clusterization tool config"""
     acc = SctGeometryCfg(flags)
 
-    kwargs.setdefault("InputObjectName", "SCT_RDOs")
     Tracker__TrackerClusterMakerTool,Tracker__FaserSCT_ClusteringTool=CompFactory.getComps("Tracker::TrackerClusterMakerTool", "Tracker::FaserSCT_ClusteringTool")
     trackerClusterMakerTool = Tracker__TrackerClusterMakerTool(name = "TrackerClusterMakerTool")
     faserSCT_LorentzAngleTool=acc.popToolsAndMerge(FaserSCT_LorentzAngleCfg(flags))
diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py
index e3859d6d1c2ad9e764b59dd2e92344489090ad13..a1076d989a188d67de7f41979a8818a8c6729d5e 100644
--- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py
+++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py
@@ -66,7 +66,7 @@ def TrackerSpacePointFinderCfg(flags, **kwargs):
     """Return ComponentAccumulator for SCT SpacePoints and Output"""
     acc=TrackerDDSiElementPropertiesTableCondAlgCfg(flags)
     acc.merge(TrackerSpacePointFinderBasicCfg(flags, **kwargs))
-    acc.merge(TrackerSpacePointFinder_OutputCfg(flags))
+    # acc.merge(TrackerSpacePointFinder_OutputCfg(flags))
     return acc
 
 def StatisticsCfg(flags, **kwargs):
diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
index 8a73c7fc2ffb1a6cfcbe22d4c5f30ae4c3cf2528..5c9940aeaa3cef28e0631d9d6a6480c54f473b57 100755
--- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
+++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/src/TrackerSpacePointFinder.cxx
@@ -251,11 +251,11 @@ StatusCode TrackerSpacePointFinder::finalize()
 {
   ATH_MSG_INFO( "finalize()" );
   ATH_MSG_INFO( m_numberOfEvents << " events processed" );
-  ATH_MSG_INFO( m_numberOfSCT << " sct collections processed" );
+  ATH_MSG_INFO( m_numberOfSCT << " SCT collections processed" );
   ATH_MSG_INFO( m_numberOfClusterCollection << " cluster collections processed" );
-  ATH_MSG_INFO( m_numberOfCluster<< " cluster processed" );
-  ATH_MSG_INFO( m_numberOfSPCollection<< " spacepoint collection generatedprocessed" );
-  ATH_MSG_INFO( m_numberOfSP<< " spacepoint generatedprocessed" );
+  ATH_MSG_INFO( m_numberOfCluster<< " clusters processed" );
+  ATH_MSG_INFO( m_numberOfSPCollection<< " spacepoint collections generated" );
+  ATH_MSG_INFO( m_numberOfSP<< " spacepoints generated" );
   if(m_cachemode){
     //These are debug messages because they can be indeterminate in an MT environment and it could
     //lead to confusing log comparisons.
diff --git a/faser-common b/faser-common
index 7eb8e65e8342963e6f7e4d083c6b1128baa49fd1..42afb88e99deb8ea39e54889c98db93b85a9c16e 160000
--- a/faser-common
+++ b/faser-common
@@ -1 +1 @@
-Subproject commit 7eb8e65e8342963e6f7e4d083c6b1128baa49fd1
+Subproject commit 42afb88e99deb8ea39e54889c98db93b85a9c16e
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
index 66311b98c291f97be1d6f42ad024fa2baf32d89b..3b55a54922aeb41d8655cb97cba5ffdc508923e0 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
@@ -309,7 +309,8 @@ bool TrackCollHandleBase::cut(TrackHandleBase* handle)
   //   }
   // }
 
-  if (!m_cut_pt_allowall||!m_cut_eta_allowall||!m_cut_phi_allowall)
+  // if (!m_cut_pt_allowall||!m_cut_eta_allowall||!m_cut_phi_allowall)
+  if (false)
   {
 //    Trk::GlobalMomentum mom(handle->momentum());
 	  Amg::Vector3D mom(handle->momentum());
@@ -343,7 +344,7 @@ bool TrackCollHandleBase::cut(TrackHandleBase* handle)
     }
   }
   
-  if (cutOnlyVertexAssocTracks()){
+  if (false && cutOnlyVertexAssocTracks()){
     // std::cout<<"cutOnlyVertexAssocTracks: "<<handle<<",\t: "<<common()->system()->materialFromVertex(handle)<<std::endl;
     return common()->system()->materialFromVertex(handle)!=0; // return false if no vertex material associated to this track
   }