From b1c45531f98866436bc3d962df0192f41736bddf Mon Sep 17 00:00:00 2001
From: Elliot Lipeles <lipeles@sas.upenn.edu>
Date: Mon, 17 Mar 2025 16:17:10 -0500
Subject: [PATCH 1/7] bugs fixed + tested with GenScanTool

---
 .../FPGATrackSimBinning/FPGATrackSimBinStep.h | 11 ++---
 .../FPGATrackSimBinning/FPGATrackSimBinTool.h | 18 +++----
 .../FPGATrackSimBinning/FPGATrackSimBinUtil.h |  1 +
 .../FPGATrackSimBinnedHits.h                  |  8 +--
 .../src/FPGATrackSimBinStep.cxx               | 49 ++++++++++---------
 .../src/FPGATrackSimBinTool.cxx               | 18 ++++++-
 .../src/FPGATrackSimBinUtil.cxx               |  4 +-
 .../src/FPGATrackSimBinnedHits.cxx            | 40 ++++++++++-----
 .../src/FPGATrackSimKeyLayerBinDesc.cxx       | 24 +++++++--
 .../src/FPGATrackSimKeyLayerBinDesc.h         |  7 ++-
 10 files changed, 117 insertions(+), 63 deletions(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinStep.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinStep.h
index b92b0a833962..996bfa1723b2 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinStep.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinStep.h
@@ -52,14 +52,14 @@ public:
                       const IInterface * ifc) : AthAlgTool(algname, name, ifc) {}
 
   virtual StatusCode initialize() override;
-  StatusCode setRanges(const FPGATrackSimBinStep* prev,const ParSet& parMin, const ParSet& parMax);
+  StatusCode setRanges(FPGATrackSimBinStep* prev,const ParSet& parMin, const ParSet& parMax);
 
   // property of step
   const std::vector<unsigned> stepIdx(IdxSet idx) const; // index for only the pars used in this step
   const std::vector<unsigned> stepBins() const;   // bin sizes for only the pars used in this step
   const std::vector<unsigned>& stepPars() const {return m_pars;}  // parameters used for this step
   const std::vector<unsigned> nBins() const {return m_parBins;}   // bin sizes for only the pars used in this step
-  const std::string& stepName() const {return m_name;}
+  const std::string stepName() const {return this->name().substr(this->name().find_last_of(".")+1);}
   unsigned stepNum() const {return m_stepNum;}
 
   // Calculation of bin boundaries
@@ -78,8 +78,8 @@ public:
   IdxSet binIdx(const ParSet &pars) const;
 
   // Convert to previous steps idx
-  IdxSet convertToPrev(const IdxSet& cur) const;  
-
+  IdxSet convertToPrev(const IdxSet& cur) const;
+  
   //--------------------------------------------------------------------------------------------------
   //
   //  Set which bins are valid
@@ -95,7 +95,6 @@ public:
   const FPGATrackSimBinArray<int>& validBinsLocal() const { return m_validBinLocal;}
 
 private:
-  Gaudi::Property<std::string> m_name{this, "name", {}, "String name assigned to Binning Step"};
   Gaudi::Property<std::vector<unsigned>> m_parBinsConfig{this,"parBins",{},"Vector of number of bins for each parameter (expect 5)"};
 
   // pars used in this step
@@ -108,7 +107,7 @@ private:
   FPGATrackSimBinArray<int> m_validBinLocal; // this is for the pars used at this step
 
   // pointer to FPGATrackSimBinStep of previous step
-  const FPGATrackSimBinStep *m_prev{0};
+  FPGATrackSimBinStep *m_prev{0};
   unsigned m_stepNum{}; // number of step
   
   // the bins for this step
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
index b344b03d76ca..801e0e0390c5 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
@@ -45,9 +45,7 @@ class FPGATrackSimBinTool : virtual public AthAlgTool {
 public:
   friend FPGATrackSimBinStep;
 
-  FPGATrackSimBinTool(const std::string &algname, const std::string &name,
-                      const IInterface *ifc)
-      : AthAlgTool(algname, name, ifc) {}
+  FPGATrackSimBinTool(const std::string &algname, const std::string &name, const IInterface *ifc);
   
   virtual StatusCode initialize() override;
 
@@ -101,19 +99,19 @@ private:
   Gaudi::Property<double> m_etaFractionalPadding{this, "etaFractionalPadding", {}, "Fractional padding used when calculating the valid range of bins"};
   Gaudi::Property<double> m_phiFractionalPadding{this, "phiFractionalPadding", {}, "Fractional padding used when calculating the valid range of bins"};
   Gaudi::Property<double> m_qOverPtFractionalPadding{this, "qOverPtFractionalPadding", {}, "Fractional padding used when calculating the valid range of bins"};
-  Gaudi::Property<std::vector<float>> m_parMinConfig{this, "parMin", {}, "Vector of minimum bounds of parameters (expect 5"};
-  Gaudi::Property<std::vector<float>> m_parMaxConfig{this, "parMax", {}, "Vector of maximum bounds of parameters (expect 5"};
-
-  ToolHandleArray<FPGATrackSimBinStep> m_steps;
-  ToolHandle<IFPGATrackSimBinDesc> m_binDesc;
+  Gaudi::Property<std::vector<double>> m_parMinConfig{this, "parMin", {}, "Vector of minimum bounds of parameters (expect 5"};
+  Gaudi::Property<std::vector<double>> m_parMaxConfig{this, "parMax", {}, "Vector of maximum bounds of parameters (expect 5"};
 
+  ToolHandleArray<FPGATrackSimBinStep> m_steps{this, "Steps", {}, "Array of FPGATrackSimBinStep: describes which parameters are binned at each step"};
+  ToolHandle<IFPGATrackSimBinDesc> m_binDesc{this, "BinDesc", "FPGATrackSimBinDescBase", "FPGATrackSimBinDescBase: describes binning track parameters"};
+  
   //
   // Internal data
   //
 
   // These indicate the range of the full binning
-  ParSet m_parMin;
-  ParSet m_parMax;
+  ParSet m_parMin{};
+  ParSet m_parMax{};
 
   // A list of the step names for convienience
   std::vector<std::string> m_stepNames;
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinUtil.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinUtil.h
index 266f182e3987..6d19e048d3e2 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinUtil.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinUtil.h
@@ -94,6 +94,7 @@ struct StoredHit {
   double etaShift;  // shift in r-z plane as  quantified by BinDesc
   unsigned layer;
   double rzrad() const;
+  static const unsigned invalidLayer = std::numeric_limits<unsigned>::max();
 };
 std::ostream &operator<<(std::ostream &os, const StoredHit &hit);
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
index 2a12b906d447..218dc640565d 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
@@ -54,7 +54,7 @@ public:
                          const IInterface *ifc)
       : AthAlgTool(algname, name, ifc) {}
 
-  StatusCode initialize() override;
+  virtual StatusCode initialize() override;
   void initBinnedDataArrays();
 
   StatusCode fill(const std::vector<std::shared_ptr<const FPGATrackSimHit>> &hits);
@@ -105,8 +105,10 @@ private:
   std::vector<FPGATrackSimBinArray<BinEntry>> m_binnedHitsStep;
 
   // The tool where the steps are defined
-  ToolHandle<FPGATrackSimBinTool> m_bintool;
-
+  ToolHandle<FPGATrackSimBinTool> m_bintool {
+    this, "BinTool", "FPGATrackSimBinTool",
+        "FPGATrackSimBinTool: contains tools describe which parameters are used and each step of binning"};
+  
   // The number of layers, either set externally from pmap or set by the layerMap
   unsigned m_nLayers{0}; 
 };
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinStep.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinStep.cxx
index 5e7cc40a109d..ae8564b3cb29 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinStep.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinStep.cxx
@@ -9,7 +9,7 @@
  */
 
 #include "AthenaBaseComps/AthMsgStreamMacros.h"
-#include "FPGATrackSimBinning/FPGATrackSimBinTool.h"
+#include "FPGATrackSimBinning/IFPGATrackSimBinDesc.h"
 #include <GaudiKernel/StatusCode.h>
 #include "FPGATrackSimBinning/FPGATrackSimBinStep.h"
 
@@ -26,16 +26,15 @@ StatusCode FPGATrackSimBinStep::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode FPGATrackSimBinStep::setRanges(const FPGATrackSimBinStep *prev,
+StatusCode FPGATrackSimBinStep::setRanges(FPGATrackSimBinStep *prev,
                                           const ParSet &parMin,
                                           const ParSet &parMax) {
+
   m_prev = prev;
   if (prev) {
     m_stepNum = prev->m_stepNum+1;
   } else {
-    m_stepNum = 0;
-    //prev is dereferenced in several places after this; better to exit than crash
-    return StatusCode::FAILURE;
+    m_stepNum = 0;    
   }
   m_parMin = parMin;
   m_parMax = parMax;
@@ -46,22 +45,28 @@ StatusCode FPGATrackSimBinStep::setRanges(const FPGATrackSimBinStep *prev,
       return StatusCode::FAILURE;
     }
     m_parStep[par] = (m_parMax[par] - m_parMin[par]) / m_parBins[par];
-
     if (m_parBins[par] <= 0)
     {
       ATH_MSG_FATAL("Every dimension must be at least one bin (set #bins=1 for not binning in that parameter)");
     }
-    if (m_parBins[par] < prev->m_parBins[par]) {
-      ATH_MSG_FATAL("Number of bins can only increase with each step");
-      return StatusCode::FAILURE;
-    }
-    if (m_parBins[par] % prev->m_parBins[par] !=0) {
-      ATH_MSG_FATAL("Number of bins must be integer multiple of bins in previous step");
-      return StatusCode::FAILURE;
-    }
-    if (m_parBins[par] != prev->m_parBins[par]) {
-      // This step involves this parameter
-      m_pars.push_back(par);      
+    if (prev) {
+      if (m_parBins[par] < prev->m_parBins[par]) {
+        ATH_MSG_FATAL("Number of bins can only increase with each step");
+        return StatusCode::FAILURE;
+      }
+      if (m_parBins[par] % prev->m_parBins[par] !=0) {
+        ATH_MSG_FATAL("Number of bins must be integer multiple of bins in previous step");
+        return StatusCode::FAILURE;
+      }
+      if (m_parBins[par] != prev->m_parBins[par]) {
+        // This step involves this parameter
+        m_pars.push_back(par);
+      }
+    } else {
+      if (m_parBins[par] != 1) {
+        // This step involves this parameter
+        m_pars.push_back(par);
+      }
     }
   }
 
@@ -105,7 +110,7 @@ IdxSet FPGATrackSimBinStep::convertToPrev(const IdxSet &cur) const {
   IdxSet retv{};
   if (m_prev) {
     for (unsigned par =0; par < FPGATrackSimTrackPars::NPARS; par++) {
-      retv[par] = (cur[par]*m_prev->m_parBins[par]/m_parBins[par]);
+      retv[par] = int(cur[par]*((const FPGATrackSimBinStep*)m_prev)->m_parBins[par]/m_parBins[par]);
     }
   } else {
     ATH_MSG_FATAL("convertToPrev called, but no previous");
@@ -123,12 +128,12 @@ const std::vector<unsigned> FPGATrackSimBinStep::stepBins() const {
 void FPGATrackSimBinStep::setValidBin(const std::vector<unsigned>& idx) {
   m_validBinFull[idx] = true;
   m_validBinLocal[stepIdx(idx)] = true;
-  if (m_prev) setValidBin(convertToPrev(idx));
+  if (m_prev) m_prev->setValidBin(convertToPrev(idx));
 }
 
 void FPGATrackSimBinStep::initValidBins() {
   m_validBinFull.setsize(m_parBins, false);
-  m_validBinLocal[stepBins()] = true;
+  m_validBinLocal.setsize(stepBins(), false);
 }
 
 void FPGATrackSimBinStep::printValidBin() const {
@@ -139,7 +144,7 @@ void FPGATrackSimBinStep::printValidBin() const {
     if (bin.data())
       validBinsFull++;
   }
-  ATH_MSG_INFO("Step" << m_name<< "Valid Bins Full: " << validBinsFull);
+  ATH_MSG_INFO("Step" << name() << "Valid Bins Full: " << validBinsFull);
 
   // count valid bins
   int validBinsLocal = 0;
@@ -147,7 +152,7 @@ void FPGATrackSimBinStep::printValidBin() const {
   if (bin.data())
     validBinsLocal++;
   }
-  ATH_MSG_INFO("Step" << m_name<<  "Valid Bins Local: " << validBinsLocal);
+  ATH_MSG_INFO("Step" << name() <<  "Valid Bins Local: " << validBinsLocal);
   
 }
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinTool.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinTool.cxx
index 21af3113dbb6..49340db1bdd9 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinTool.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinTool.cxx
@@ -9,12 +9,25 @@
 
 #include "FPGATrackSimBinning/FPGATrackSimBinTool.h"
 
+FPGATrackSimBinTool::FPGATrackSimBinTool(const std::string &algname, const std::string &name,
+  const IInterface *ifc)
+: AthAlgTool(algname, name, ifc) {
+}
+
 
 // ----------------------------------------------------------------------------------------
 //  AthTool Methods
 // ----------------------------------------------------------------------------------------
 
 StatusCode FPGATrackSimBinTool::initialize() {
+  // Dump the configuration to make sure it propagated through right
+  const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
+  for( Gaudi::Details::PropertyBase* prop : props ) {
+    if (prop->ownerTypeName()==this->type()) {      
+      ATH_MSG_DEBUG("Property:\t" << prop->name() << "\t : \t" << prop->toString());
+    }
+  }
+
   // Retrieve
   ATH_MSG_INFO("Using " << m_steps.size() << " steps");
   ATH_CHECK(m_steps.retrieve());
@@ -24,11 +37,14 @@ StatusCode FPGATrackSimBinTool::initialize() {
     return StatusCode::FAILURE;
   }
 
+  m_parMin = std::vector<double>(m_parMinConfig);
+  m_parMax = std::vector<double>(m_parMaxConfig);
+
   FPGATrackSimBinStep* prev = 0;
   for (auto &step : m_steps) {
     ATH_MSG_INFO("Got Binning Step " << step->stepName());
     m_stepNames.push_back(step->stepName());
-    if (step->setRanges(prev, m_parMin, m_parMax)) {
+    if (!step->setRanges(prev, m_parMin, m_parMax)) {
       ATH_MSG_FATAL("Failed to setRange on step");
       return StatusCode::FAILURE;
     }
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinUtil.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinUtil.cxx
index eaa97e4ff628..a42f440dffe6 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinUtil.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinUtil.cxx
@@ -164,10 +164,8 @@ double GeomHelpers::zFromPars(double r, const FPGATrackSimTrackPars &pars)
     return zhit;
 }
 
-double GeomHelpers::phiFromPars(double r, const FPGATrackSimTrackPars &pars)
-{
+double GeomHelpers::phiFromPars(double r, const FPGATrackSimTrackPars &pars) {
     double phi_hit = xAOD::P4Helpers::deltaPhi(pars.phi,asin(r * CurvatureConstant * pars.qOverPt - pars.d0 / r));
-
     return phi_hit;
 }
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
index 59a7c0d67d35..be6a9bfe8d60 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
@@ -9,6 +9,8 @@
 
 #include "FPGATrackSimBinning/FPGATrackSimBinnedHits.h"
 #include "FPGATrackSimBinning/IFPGATrackSimBinDesc.h"
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
+#include "FPGATrackSimBinning/IFPGATrackSimBinDesc.h"
 #include "FPGATrackSimBinning/FPGATrackSimBinStep.h"
 #include "FPGATrackSimBinning/FPGATrackSimBinUtil.h"
 #include <GaudiKernel/StatusCode.h>
@@ -16,9 +18,19 @@
 
 
 StatusCode FPGATrackSimBinnedHits::initialize() {
+  // Dump the configuration to make sure it propagated through right
+  const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
+  for( Gaudi::Details::PropertyBase* prop : props ) {
+    if (prop->ownerTypeName()==this->type()) {      
+      ATH_MSG_DEBUG("Property:\t" << prop->name() << "\t : \t" << prop->toString());
+    }
+  }
+
+
+  ATH_MSG_DEBUG("Retrieving BinTool");
   ATH_CHECK(m_bintool.retrieve());
+  ATH_MSG_DEBUG("Retrieving EvtSel");
   ATH_CHECK(m_EvtSel.retrieve());
-
   // Compute which bins correspond to track parameters that are in the region
   // i.e. the pT, eta, phi, z0 and d0 bounds
   // list of valid bins is extracted from the layer map if its loaded
@@ -30,9 +42,8 @@ StatusCode FPGATrackSimBinnedHits::initialize() {
     readLayerMap(m_lyrmapFile);
   }
   m_bintool->printValidBin(); // also dumps firmware constants
-
   initBinnedDataArrays();
-  
+
   return StatusCode::SUCCESS;
 }
 
@@ -60,54 +71,57 @@ void FPGATrackSimBinnedHits::resetBins() {
 // by m_binning object)
 StatusCode FPGATrackSimBinnedHits::fill(
     const std::vector<std::shared_ptr<const FPGATrackSimHit>> &hits) {
-  ATH_MSG_DEBUG("In fillImage");
+  ATH_MSG_DEBUG("In fill");
 
   for (const auto &step : m_bintool->steps()) {
     int stepnum = 0;
 
+    ATH_MSG_DEBUG("fill binning: step num " << stepnum << " " << step->stepName());
     for (auto &bin : step->validBinsFull()) {
 
       // skip bin if it is invalid
       if (!bin.data())
         continue;
 
+      //ATH_MSG_DEBUG("valid bin");
       if (stepnum == 0) {
 
         // first step, hits from input stream
         for (const std::shared_ptr<const FPGATrackSimHit> &hit : hits) {
           StoredHit storedhit(hit);
           if (m_bintool->binDesc()->hitInBin(*step.get(), bin.idx(),
-                                            storedhit)) {
+                                             storedhit)) {
             m_binnedHitsStep[stepnum][bin.idx()].addHit(storedhit);
           }
         }
 
-      } else {
-
+      } else {        
         // subsequent steps, use hits from previous step
         for (const auto &hit :
              m_binnedHitsStep[stepnum - 1][step->convertToPrev(bin.idx())].hits) {
           StoredHit storedhit(hit);
           if (m_bintool->binDesc()->hitInBin(*step.get(), bin.idx(),
-                                            storedhit)) {
+                                             storedhit)) {
+            
             // One last step, set layer based on layerMap or use default from pmap
             if (step.get() == m_bintool->lastStep()) {
               if (m_mod_to_lyr_map.size() != 0) {
                 if (m_mod_to_lyr_map[bin.idx()].contains(hit.hitptr->getIdentifierHash())) {
                   storedhit.layer = m_mod_to_lyr_map[bin.idx()][hit.hitptr->getIdentifierHash()];
-                }
+                  m_binnedHitsStep[stepnum][bin.idx()].addHit(storedhit);
+                } 
               } else {
                 storedhit.layer = hit.hitptr->getLayer();
+                m_binnedHitsStep[stepnum][bin.idx()].addHit(storedhit);
               }
-            }
-
-            m_binnedHitsStep[stepnum][bin.idx()].addHit(storedhit);
-
+            }            
           }
         }
       }
 
     } //  end loop over bins
+      
+    stepnum++;
   } // end loop over stepsd
 
   return StatusCode::SUCCESS;
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.cxx
index 6c89f8d7e2b8..3d6eb749888f 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.cxx
@@ -9,9 +9,24 @@
  */
 
 #include "FPGATrackSimKeyLayerBinDesc.h"
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
 #include "FPGATrackSimBinning/FPGATrackSimBinStep.h"
 
+StatusCode FPGATrackSimKeyLayerBinDesc::initialize()
+{
+  // Dump the configuration to make sure it propagated through right
+  const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
+  for( Gaudi::Details::PropertyBase* prop : props ) {
+    if (prop->ownerTypeName()==this->type()) {      
+      ATH_MSG_DEBUG("Property:\t" << prop->name() << "\t : \t" << prop->toString());
+    }
+  }
 
+  m_keylyrtool.setR1(m_rin);
+  m_keylyrtool.setR2(m_rout);
+
+  return StatusCode::SUCCESS;
+}
 
 bool FPGATrackSimKeyLayerBinDesc::hitInBin(const FPGATrackSimBinStep &step,
                                            const IdxSet &idx,
@@ -26,8 +41,9 @@ bool FPGATrackSimKeyLayerBinDesc::hitInBin(const FPGATrackSimBinStep &step,
 
     if (stepIsRPhi(step)) {
         // distance of hit from bin center
-        storedhit.phiShift = phiResidual(step.binCenter(idx),storedhit.hitptr.get());
-
+        storedhit.phiShift =
+            phiResidual(step.binCenter(idx), storedhit.hitptr.get());
+        
         // Get expected curvature shift from bin center    
         auto half_xm_bin_pars = parSetToKeyPars(step.binCenter(idx));
         half_xm_bin_pars.xm = step.binWidth(4)/2.0; // 4 = xm par
@@ -43,8 +59,8 @@ bool FPGATrackSimKeyLayerBinDesc::hitInBin(const FPGATrackSimBinStep &step,
         // distance of hit from bin center
         storedhit.etaShift = etaResidual(step.binCenter(idx),storedhit.hitptr.get());
     
-        double width_z_in  = step.binWidth(0);
-        double width_z_out = step.binWidth(1);
+        double width_z_in  = step.binWidth(0)/2.0;
+        double width_z_out = step.binWidth(1)/2.0;
         double zrange = width_z_in + (width_z_out-width_z_in) * (hitr-r1)/(r2-r1);
         
         passesEta = std::abs(storedhit.etaShift) < zrange;
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.h
index 9293feb85b4b..cea3fcddf6bb 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimKeyLayerBinDesc.h
@@ -23,6 +23,8 @@
  */
 #include "AthenaBaseComps/AthAlgTool.h"
 
+#include "FPGATrackSimBinning/IFPGATrackSimBinDesc.h"
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
 #include "FPGATrackSimBinning/IFPGATrackSimBinDesc.h"
 #include "FPGATrackSimObjects/FPGATrackSimTrackPars.h"
 #include "FPGATrackSimObjects/FPGATrackSimHit.h"
@@ -48,10 +50,13 @@ public:
       declareInterface<IFPGATrackSimBinDesc>(this);
     }
 
+    virtual StatusCode initialize() override;
+
     virtual const std::string &parNames(unsigned i) const override { return m_parNames[i]; }
 
     // convert back and forth from pT, eta, phi, d0, z0 and internal paramater set
-    virtual const ParSet trackParsToParSet(const FPGATrackSimTrackPars &pars) const override {
+    virtual const ParSet
+    trackParsToParSet(const FPGATrackSimTrackPars &pars) const override {
       return keyparsToParSet(m_keylyrtool.trackParsToKeyPars(pars));
     }
     virtual const FPGATrackSimTrackPars parSetToTrackPars(const ParSet &parset) const override {
-- 
GitLab


From 31c548d4b33873c3c529af757c48c734fca5f933 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Mon, 17 Mar 2025 06:27:20 -0500
Subject: [PATCH 2/7] FPGATrackSim: first pass at binning implementation for
 matrix gen

Except it doesn't work and I don't understand why it doesn't compile
---
 .../FPGATrackSimAlgorithms/CMakeLists.txt     |   2 +-
 .../src/FPGATrackSimMatrixGenAlgo.cxx         | 250 ++++++++++--------
 .../src/FPGATrackSimMatrixGenAlgo.h           |  10 +-
 .../FPGATrackSimBinnedHits.h                  |   4 +-
 .../src/FPGATrackSimBinnedHits.cxx            |   2 +
 5 files changed, 146 insertions(+), 122 deletions(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimAlgorithms/CMakeLists.txt b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimAlgorithms/CMakeLists.txt
index 05ce01c6e6ee..ee50a47f09c7 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimAlgorithms/CMakeLists.txt
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimAlgorithms/CMakeLists.txt
@@ -15,7 +15,7 @@ atlas_add_library( FPGATrackSimAlgorithmsLib
    src/*.cxx
    PUBLIC_HEADERS FPGATrackSimAlgorithms
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}  ${ONNXRUNTIME_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringKernelLib GaudiKernel FPGATrackSimBanksLib FPGATrackSimConfToolsLib FPGATrackSimHoughLib FPGATrackSimInputLib FPGATrackSimLRTLib FPGATrackSimMapsLib FPGATrackSimObjectsLib FPGATrackSimSGInputLib  ${ONNXRUNTIME_LIBRARIES}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringKernelLib GaudiKernel FPGATrackSimBanksLib FPGATrackSimBinningLib FPGATrackSimConfToolsLib FPGATrackSimHoughLib FPGATrackSimInputLib FPGATrackSimLRTLib FPGATrackSimMapsLib FPGATrackSimObjectsLib FPGATrackSimSGInputLib  ${ONNXRUNTIME_LIBRARIES}
    PRIVATE_LINK_LIBRARIES FPGATrackSimBanksLib FPGATrackSimConfToolsLib )
  
 # Component(s) in the package:
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
index 57eda2dfc949..88bbdc2ef4c7 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
@@ -80,6 +80,8 @@ StatusCode FPGATrackSimMatrixGenAlgo::initialize()
   ATH_CHECK(m_trackFitterTool_1st.retrieve(EnableTool{m_doHoughConstants && m_doSecondStage}));
   ATH_CHECK(m_overlapRemovalTool.retrieve(EnableTool{m_doHoughConstants && m_doSecondStage}));
 
+  // In some cases we may not want this, but I need to think about what those are.
+  ATH_CHECK(m_hitBinningTool.retrieve());
 
   
   if (m_doHoughConstants) {
@@ -239,121 +241,141 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         t_pmap->map(iHit);
       }
       
-      
-      std::vector<FPGATrackSimHit> sector_hits;
-      bool success = filterSectorHits(track_hits, sector_hits, track, true, iSlice);
-      if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
-      m_h_trackQoP_okHits->Fill(track.getQOverPt());
-      
-      // Get the region of this sector
-      int region = getRegion(sector_hits, true);
-      if (region < 0 || region >= m_nRegions) continue;
-      m_h_trackQoP_okRegion->Fill(track.getQOverPt());
-      //For the Hough constants, find the Hough roads
-      std::vector<std::shared_ptr<const FPGATrackSimRoad>> houghRoads;
-      if (m_doHoughConstants){
-	
-	std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
-	
-	for (const FPGATrackSimHit& hit : sector_hits) if (hit.isMapped() && hit.isReal()) phits.emplace_back(std::make_shared<const FPGATrackSimHit>(hit));
-	StatusCode sc = m_roadFinderTool->getRoads(phits, houghRoads);
-	if (sc.isFailure()) ATH_MSG_WARNING("Hough Transform -> getRoads() failed");
-	if (m_doSecondStage) { // if doing 2nd stage, we want to get tracks from the road and then do tracking and overlap removal
-
-	  /// map hits as 2nd stage
-	  const FPGATrackSimPlaneMap *pmap_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(iSlice);
-	  for (auto & iHit : track_hits) {
-	    pmap_2nd->map(iHit);
-	  }
-
-	  std::vector<FPGATrackSimTrack> tracks_1st;
-	  ATH_CHECK(m_trackFitterTool_1st->getTracks(houghRoads, tracks_1st));
-	  ATH_CHECK(m_overlapRemovalTool->runOverlapRemoval(tracks_1st));
-	  // Prepare the accumulator struct
-	  std::vector<module_t> modules(m_nLayers_2nd);
-	  FPGATrackSimMatrixAccumulator acc(m_nLayers_2nd, m_nDim_2nd);	
-	  std::vector<FPGATrackSimHit> hits_2nd;
-	  std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_2nd;
-	  success = filterSectorHits(track_hits, hits_2nd, track, false, iSlice); // only look at 2nd stage hits!
-	  
-	  
-	  if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
-	  // awkward fixme
-	  for (const auto& hit : hits_2nd) {
-	    phits_2nd.push_back(std::make_shared<const FPGATrackSimHit>(hit));
-	  }
-	  
-	  // Use the track extension tool to actually produce a new set of roads.
-	  std::vector<std::shared_ptr<const FPGATrackSimRoad>> roads_2nd;
-	  std::vector<std::shared_ptr<const FPGATrackSimTrack>> ptracks_1st;
-	  ptracks_1st.reserve(tracks_1st.size());
-	  for (const auto& track : tracks_1st) {
-	    ptracks_1st.push_back(std::make_shared<const FPGATrackSimTrack>(track));
-	  }
-	  ATH_CHECK(m_trackExtensionTool->extendTracks(phits_2nd, ptracks_1st, roads_2nd));
-	  for (auto road_2nd : roads_2nd) {
-	    std::vector<module_t> modules(m_nLayers_2nd);
-	    FPGATrackSimMatrixAccumulator acc(m_nLayers_2nd, m_nDim_2nd);
-	    acc.pars.qOverPt = road_2nd->getY();
-	    acc.pars.phi = road_2nd->getX();
-	    
-	    std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
-	    std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
-	    ATH_CHECK(makeAccumulator(hits_2nd, track, modules_acc));
-	    
-	    // Add the track to the accumulate map
-	    accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
-	    
-	    if (m_dropHitsAndFill)
-	      ATH_CHECK(fillAccumulatorByDropping(hits_2nd, false, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
-	    
-	    m_nTracksUsed++;
-	  }
-	}
-	else {	
-	  //For each Hough road, make the accumulator
-	  if (!houghRoads.empty()){
-	    double y = 0.0;
-	    double x = 0.0;
-	    
-	    //For each Hough road, make the accumulator
-	    for (auto const &hr : houghRoads){
-	      y = hr->getY();
-	      x = hr->getX();
-	      // Prepare the accumulator struct
-	      std::vector<module_t> modules(m_nLayers_1st);
-	      FPGATrackSimMatrixAccumulator acc(m_nLayers_1st, m_nDim_1st);
-	      acc.pars.qOverPt = y;
-	      acc.pars.phi = x;
-	      std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
-	      ATH_CHECK(makeAccumulator(sector_hits, track, modules_acc));
-	      
-	      // Add the track to the accumulate map
-	      accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
-	      
-	      if (m_dropHitsAndFill)
-		ATH_CHECK(fillAccumulatorByDropping(sector_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));	      
-	      
-	      m_nTracksUsed++;
-	    }
-	  }
-	}
-      }
-      else{
-	// Prepare the accumulator struct
-	std::vector<module_t> modules(m_nLayers_1st);
-	FPGATrackSimMatrixAccumulator acc(m_nLayers_1st, m_nDim_1st);
-	std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
-	ATH_CHECK(makeAccumulator(sector_hits, track, modules_acc));
-	
-	// Add the track to the accumulate map
-	accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);      
-	
-	if (m_dropHitsAndFill)
-	  ATH_CHECK(fillAccumulatorByDropping(sector_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
-	
-	m_nTracksUsed++;
+      // Again need a conditional here, but we want to bin the hits, and then separately filterSectorHits for each.
+      ATH_CHECK(m_hitBinningTool->fill(track_hits));
+      FPGATrackSimBinArray<BinEntry> & binnedHits = m_hitBinningTool->lastStepBinnedHits();
+      for (BinEntry& binEntry : binnedHits) {
+        // Skip any bins that have zero hits.
+        if (binEntry.hitCnt == 0) continue;
+
+        std::vector<FPGATrackSimHit> binned_hits;
+        // All the code below assumes "real" hit objects. Since we don't need these hits to survive
+        // outside each iteration of the loop, the path of least resistance is to actually change the hit's layer
+        // TODO: it might make sense to make track_hits and binned_hits a vector of hit pointers? The memory management
+        // makes be a bit nervous, I don't think we need to be making copies.
+        for (StoredHit& storedHit : binEntry.hits) {
+          binned_hits.push_back(*(storedHit.hitptr));
+          binned_hits.at(binned_hits.size() - 1).setLayer(storedHit.layer);
+        }
+
+        // Now, proceed, but filter the sector hits using "binned_hits".
+
+        std::vector<FPGATrackSimHit> sector_hits;
+        bool success = filterSectorHits(binned_hits, sector_hits, track, true, iSlice);
+        if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
+        m_h_trackQoP_okHits->Fill(track.getQOverPt());
+
+        // Get the region of this sector
+        int region = getRegion(sector_hits, true);
+        if (region < 0 || region >= m_nRegions) continue;
+        m_h_trackQoP_okRegion->Fill(track.getQOverPt());
+        //For the Hough constants, find the Hough roads
+        std::vector<std::shared_ptr<const FPGATrackSimRoad>> houghRoads;
+        if (m_doHoughConstants){
+
+          std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
+
+          for (const FPGATrackSimHit& hit : sector_hits) if (hit.isMapped() && hit.isReal()) phits.emplace_back(std::make_shared<const FPGATrackSimHit>(hit));
+          StatusCode sc = m_roadFinderTool->getRoads(phits, houghRoads);
+          if (sc.isFailure()) ATH_MSG_WARNING("Hough Transform -> getRoads() failed");
+          if (m_doSecondStage) { // if doing 2nd stage, we want to get tracks from the road and then do tracking and overlap removal
+
+            /// map hits as 2nd stage
+            const FPGATrackSimPlaneMap *pmap_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(iSlice);
+            for (auto & iHit : track_hits) {
+              pmap_2nd->map(iHit);
+            }
+
+            std::vector<FPGATrackSimTrack> tracks_1st;
+            ATH_CHECK(m_trackFitterTool_1st->getTracks(houghRoads, tracks_1st));
+            ATH_CHECK(m_overlapRemovalTool->runOverlapRemoval(tracks_1st));
+            // Prepare the accumulator struct
+            std::vector<module_t> modules(m_nLayers_2nd);
+            FPGATrackSimMatrixAccumulator acc(m_nLayers_2nd, m_nDim_2nd);
+            std::vector<FPGATrackSimHit> hits_2nd;
+            std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_2nd;
+            success = filterSectorHits(track_hits, hits_2nd, track, false, iSlice); // only look at 2nd stage hits!
+
+
+            if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
+            // awkward fixme
+            for (const auto& hit : hits_2nd) {
+              phits_2nd.push_back(std::make_shared<const FPGATrackSimHit>(hit));
+            }
+
+            // Use the track extension tool to actually produce a new set of roads.
+            std::vector<std::shared_ptr<const FPGATrackSimRoad>> roads_2nd;
+            std::vector<std::shared_ptr<const FPGATrackSimTrack>> ptracks_1st;
+            ptracks_1st.reserve(tracks_1st.size());
+            for (const auto& track : tracks_1st) {
+              ptracks_1st.push_back(std::make_shared<const FPGATrackSimTrack>(track));
+            }
+            ATH_CHECK(m_trackExtensionTool->extendTracks(phits_2nd, ptracks_1st, roads_2nd));
+            for (auto road_2nd : roads_2nd) {
+              std::vector<module_t> modules(m_nLayers_2nd);
+              FPGATrackSimMatrixAccumulator acc(m_nLayers_2nd, m_nDim_2nd);
+              acc.pars.qOverPt = road_2nd->getY();
+              acc.pars.phi = road_2nd->getX();
+
+              std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
+              std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
+              ATH_CHECK(makeAccumulator(hits_2nd, track, modules_acc));
+
+              // Add the track to the accumulate map
+              accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
+
+              if (m_dropHitsAndFill)
+                ATH_CHECK(fillAccumulatorByDropping(hits_2nd, false, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
+
+              m_nTracksUsed++;
+            }
+          }
+          else {
+            //For each Hough road, make the accumulator
+            if (!houghRoads.empty()){
+              double y = 0.0;
+              double x = 0.0;
+
+              //For each Hough road, make the accumulator
+              for (auto const &hr : houghRoads){
+                y = hr->getY();
+                x = hr->getX();
+                // Prepare the accumulator struct
+                std::vector<module_t> modules(m_nLayers_1st);
+                FPGATrackSimMatrixAccumulator acc(m_nLayers_1st, m_nDim_1st);
+                acc.pars.qOverPt = y;
+                acc.pars.phi = x;
+                std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
+                ATH_CHECK(makeAccumulator(sector_hits, track, modules_acc));
+
+                // Add the track to the accumulate map
+                accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
+
+                if (m_dropHitsAndFill)
+                  ATH_CHECK(fillAccumulatorByDropping(sector_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
+
+                m_nTracksUsed++;
+              }
+            }
+          }
+        }
+        else{
+          // Prepare the accumulator struct
+          std::vector<module_t> modules(m_nLayers_1st);
+          FPGATrackSimMatrixAccumulator acc(m_nLayers_1st, m_nDim_1st);
+          std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
+          ATH_CHECK(makeAccumulator(sector_hits, track, modules_acc));
+
+          // Add the track to the accumulate map
+          accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
+
+          if (m_dropHitsAndFill)
+            ATH_CHECK(fillAccumulatorByDropping(sector_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
+
+          m_nTracksUsed++;
+        }
       }
+
     }
   }
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
index fd28258437b6..83015677119b 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
@@ -36,6 +36,7 @@
 #include "FPGATrackSimObjects/FPGATrackSimEventInputHeader.h"
 #include "FPGATrackSimObjects/FPGATrackSimTruthTrack.h"
 #include "FPGATrackSimHough/FPGATrackSimRoadUnionTool.h"
+#include "FPGATrackSimBinning/FPGATrackSimBinnedHits.h"
 #include "FPGATrackSimMatrixIO.h"
 
 #include "TTree.h"
@@ -77,14 +78,15 @@ class FPGATrackSimMatrixGenAlgo : public AthAlgorithm
         ServiceHandle<ITHistSvc>             m_tHistSvc{this,"THistSvc","THistSvc"};
 
         ToolHandle<IFPGATrackSimInputTool>       m_hitInputTool {this, "FPGATrackSimSGToRawHitsTool", "FPGATrackSimSGToRawHitsTool/FPGATrackSimSGToRawHits", "input handler"};
-	ToolHandle<FPGATrackSimRawToLogicalHitsTool> m_hitMapTool {this, "FPGATrackSimRawToLogicalHitsTool", "FPGATrackSimRawToLogicalHitsTool/FPGATrackSim_RawToLogicalHitsTool", "FPGATrackSim_RawToLogicalHitsTool"};
+        ToolHandle<FPGATrackSimRawToLogicalHitsTool> m_hitMapTool {this, "FPGATrackSimRawToLogicalHitsTool", "FPGATrackSimRawToLogicalHitsTool/FPGATrackSim_RawToLogicalHitsTool", "FPGATrackSim_RawToLogicalHitsTool"};
         ToolHandle<FPGATrackSimClusteringToolI>       m_clusteringTool { this, "FPGATrackSimClusteringFTKTool", "FPGATrackSimClusteringFTKTool/FPGATrackSimClusteringFTKTool", "FPGATrackSimClusteringFTKTool" };
         ToolHandle<FPGATrackSimSpacePointsToolI>       m_spacePointsTool { this, "SpacePointTool", "FPGATrackSimSpacePointsTool/FPGATrackSimSpacePointsTool", "FPGATrackSimSpacePointsTool" };
-	const FPGATrackSimPlaneMap* m_pmap = nullptr; // alias to m_FPGATrackSimMapping->PlaneMap();
-	ToolHandle<FPGATrackSimRoadUnionTool>       m_roadFinderTool {this, "RoadFinder", "RoadFinder"};
+        const FPGATrackSimPlaneMap* m_pmap = nullptr; // alias to m_FPGATrackSimMapping->PlaneMap();
+        ToolHandle<FPGATrackSimRoadUnionTool>       m_roadFinderTool {this, "RoadFinder", "RoadFinder"};
         ToolHandle<FPGATrackSimTrackFitterTool>          m_trackFitterTool_1st {this, "TrackFitter_1st", "FPGATrackSimTrackFitterTool/FPGATrackSimTrackFitterTool_1st", "1st stage track fit tool"};
+        ToolHandle<FPGATrackSimBinnedHits>      m_hitBinningTool {this, "BinningTool", "FPGATrackSimBinning/FPGATrackSimBinnedHits", "Hit binning tool, needed to apply new layer map"}:
 
-        ToolHandle<IFPGATrackSimTrackExtensionTool>      m_trackExtensionTool {this, "TrackExtensionTool", "FPGATrackSimTrackExtensionTool", "Track extensoin tool"};
+        ToolHandle<IFPGATrackSimTrackExtensionTool>      m_trackExtensionTool {this, "TrackExtensionTool", "FPGATrackSimTrackExtensionTool", "Track extension tool"};
         ToolHandle<FPGATrackSimOverlapRemovalTool>       m_overlapRemovalTool {this, "OverlapRemoval_1st", "FPGATrackSimOverlapRemovalTool/FPGATrackSimOverlapRemovalTool_1st", "1st stage overlap removal tool"};
 
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
index 218dc640565d..297ea619061b 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
@@ -50,9 +50,7 @@ using FPGATrackSimBinUtil::StoredHit;
 //-------------------------------------------------------------------------------------------------------
 class FPGATrackSimBinnedHits : public AthAlgTool {
 public:
-  FPGATrackSimBinnedHits(const std::string &algname, const std::string &name,
-                         const IInterface *ifc)
-      : AthAlgTool(algname, name, ifc) {}
+  FPGATrackSimBinnedHits(const std::string &algname, const std::string &name, const IInterface *ifc);
 
   virtual StatusCode initialize() override;
   void initBinnedDataArrays();
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
index be6a9bfe8d60..9ced0be2b5fc 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
@@ -16,6 +16,8 @@
 #include <GaudiKernel/StatusCode.h>
 #include <nlohmann/json.hpp>
 
+FPGATrackSimBinnedHits::FPGATrackSimBinnedHits(const std::string &algname, const std::string &name, const IInterface *ifc)
+      : AthAlgTool(algname, name, ifc) {}
 
 StatusCode FPGATrackSimBinnedHits::initialize() {
   // Dump the configuration to make sure it propagated through right
-- 
GitLab


From 6ffe0e70c576945f4c846773415a386dee65db11 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Mon, 17 Mar 2025 16:52:11 +0100
Subject: [PATCH 3/7] FPGATrackSim: fix implementation of binning in matrix
 gen, add Python config

Not sure this will work
---
 .../python/FPGATrackSimBankGenConfig.py       | 58 ++++++++++++++++++-
 .../src/FPGATrackSimMatrixGenAlgo.cxx         | 16 +++--
 .../src/FPGATrackSimMatrixGenAlgo.h           |  2 +-
 .../FPGATrackSimBinning/FPGATrackSimBinTool.h |  2 +
 .../FPGATrackSimBinnedHits.h                  |  5 +-
 .../src/FPGATrackSimBinnedHits.cxx            |  3 -
 6 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
index cea3732b7de6..9c1b6f35c6c5 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
@@ -11,7 +11,7 @@
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from FPGATrackSimConfTools.FPGATrackSimAnalysisConfig import FPGATrackSimRoadUnionToolCfg,FPGATrackSimRoadUnionTool1DCfg,FPGATrackSimRoadUnionToolGenScanCfg
-from FPGATrackSimConfTools.FPGATrackSimDataPrepConfig import FPGATrackSimRawLogicCfg, FPGATrackSimMappingCfg
+from FPGATrackSimConfTools.FPGATrackSimDataPrepConfig import FPGATrackSimRawLogicCfg, FPGATrackSimMappingCfg, FPGATrackSimEventSelectionCfg
 from AthenaCommon.SystemOfUnits import GeV
 
 
@@ -25,6 +25,61 @@ def FPGATrackSimSpacePointsToolCfg(flags):
     result.setPrivateTools(SpacePointTool)
     return result
 
+def FPGATrackSimBinnedHitsToolCfg(flags):
+    # This can probably be imported in the future from the analysis config, but for now it's here.
+    result = ComponentAccumulator()
+
+    # read the cuts from a seperate python file specified by FPGATrackSim.GenScan.genScanCuts
+    cutset = importlib.import_module(flags.Trigger.FPGATrackSim.GenScan.genScanCuts).cuts[flags.Trigger.FPGATrackSim.region]
+
+    # make the binned hits class
+    BinnnedHits = CompFactory.FPGATrackSimBinnedHits("BinnedHits_MatrixGen")
+    BinnnedHits.OutputLevel=flags.Trigger.FPGATrackSim.loglevel
+    BinnnedHits.FPGATrackSimEventSelectionSvc = result.getPrimaryAndMerge(FPGATrackSimEventSelectionCfg(flags))
+    BinnnedHits.layerMapFile = flags.Trigger.FPGATrackSim.GenScan.layerMapFile
+
+    # make the bintool class
+    BinTool = CompFactory.FPGATrackSimBinTool("BinTool_MatrixGen")
+    BinTool.OutputLevel=flags.Trigger.FPGATrackSim.loglevel
+
+    # Inputs for the BinTool
+    binsteps=[]
+    BinDesc=None
+    if (cutset["parSet"]=="PhiSlicedKeyLyrPars"):
+        BinDesc = CompFactory.FPGATrackSimKeyLayerBinDesc("KeyLayerBinDescMatrixGen")
+        BinDesc.OutputLevel=flags.Trigger.FPGATrackSim.loglevel
+        BinDesc.rin=cutset["rin"]
+        BinDesc.rout=cutset["rout"]
+
+        # parameters for key layer bindesc are :"zR1", "zR2", "phiR1", "phiR2", "xm"
+        step1 = CompFactory.FPGATrackSimBinStep("PhiBinning")
+        step1.OutputLevel=flags.Trigger.FPGATrackSim.loglevel
+        step1.parBins = [1,1,cutset["parBins"][2],cutset["parBins"][3],cutset["parBins"][4]]
+        step2 = CompFactory.FPGATrackSimBinStep("FullBinning")
+        step2.OutputLevel=flags.Trigger.FPGATrackSim.loglevel
+        step2.parBins = cutset["parBins"]
+        binsteps = [step1,step2]
+    else:
+        log.error("Unknown Binning Setup: ",cutset["parSet"])
+
+    BinTool.BinDesc = BinDesc
+    BinTool.steps = binsteps
+
+
+    # configure the padding around the nominal region
+    BinTool.d0FractionalPadding =0.05
+    BinTool.z0FractionalPadding =0.05
+    BinTool.etaFractionalPadding =0.05
+    BinTool.phiFractionalPadding =0.05
+    BinTool.qOverPtFractionalPadding =0.05
+    BinTool.parMin = cutset["parMin"]
+    BinTool.parMax = cutset["parMax"]
+    BinnnedHits.BinTool = BinTool
+
+    result.setPrivateTools(BinnedHits)
+
+    return result
+
 def prepareFlagsForFPGATrackSimBankGen(flags):
     newFlags = flags.cloneAndReplace("Trigger.FPGATrackSim.ActiveConfig", "Trigger.FPGATrackSim." + flags.Trigger.FPGATrackSim.algoTag)
     return newFlags
@@ -68,6 +123,7 @@ def FPGATrackSimBankGenCfg(flags, **kwargs):
     theFPGATrackSimMatrixGenAlg.SpacePoints = True
     theFPGATrackSimMatrixGenAlg.SpacePointTool = acc.getPrimaryAndMerge(FPGATrackSimSpacePointsToolCfg(flags))
     theFPGATrackSimMatrixGenAlg.minSpacePlusPixel = flags.Trigger.FPGATrackSim.minSpacePlusPixel
+    theFPGATracKSimMatrixGenAlg.BinningTool = acc.getPrimaryAndMerge(FPGATrackSimBinnedHitsToolCfg(flags))
 
     theFPGATrackSimMatrixGenAlg.FPGATrackSimMappingSvc = acc.getPrimaryAndMerge(FPGATrackSimMappingCfg(flags))
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
index 88bbdc2ef4c7..c4244fb617c2 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
@@ -15,6 +15,8 @@
 #include "FPGATrackSimConfTools/FPGATrackSimRegionSlices.h"
 #include "FPGATrackSimObjects/FPGATrackSimConstants.h"
 #include "FPGATrackSimObjects/FPGATrackSimFunctions.h"
+#include "FPGATrackSimBinning/FPGATrackSimBinnedHits.h"
+#include "FPGATrackSimBinning/FPGATrackSimBinUtil.h"
 #include "TruthUtils/MagicNumbers.h"
 
 #include "TH1.h"
@@ -229,6 +231,8 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
 
     // Get list of hits associated to the current truth track
     std::vector<FPGATrackSimHit> & track_hits = barcode_hits[track.getBarcode()];
+    std::vector<std::shared_ptr<const FPGATrackSimHit>> ref_track_hits;
+    for (const auto& hit : track_hits) ref_track_hits.push_back(std::make_shared<FPGATrackSimHit>(hit));
 
     const FPGATrackSimPlaneMap *t_pmap = nullptr;
 
@@ -242,9 +246,10 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
       }
       
       // Again need a conditional here, but we want to bin the hits, and then separately filterSectorHits for each.
-      ATH_CHECK(m_hitBinningTool->fill(track_hits));
-      FPGATrackSimBinArray<BinEntry> & binnedHits = m_hitBinningTool->lastStepBinnedHits();
-      for (BinEntry& binEntry : binnedHits) {
+      // NOTE: fill apparently *does* require a vector of smart pointers, which we don't have, so we have to make it above.
+      ATH_CHECK(m_hitBinningTool->fill(ref_track_hits));
+      const FPGATrackSimBinArray<FPGATrackSimBinnedHits::BinEntry> & binnedHits = m_hitBinningTool->lastStepBinnedHits();
+      for (auto& binEntry : binnedHits.flatdata()) {
         // Skip any bins that have zero hits.
         if (binEntry.hitCnt == 0) continue;
 
@@ -253,7 +258,7 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         // outside each iteration of the loop, the path of least resistance is to actually change the hit's layer
         // TODO: it might make sense to make track_hits and binned_hits a vector of hit pointers? The memory management
         // makes be a bit nervous, I don't think we need to be making copies.
-        for (StoredHit& storedHit : binEntry.hits) {
+        for (const FPGATrackSimBinUtil::StoredHit& storedHit : binEntry.hits) {
           binned_hits.push_back(*(storedHit.hitptr));
           binned_hits.at(binned_hits.size() - 1).setLayer(storedHit.layer);
         }
@@ -263,6 +268,9 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         std::vector<FPGATrackSimHit> sector_hits;
         bool success = filterSectorHits(binned_hits, sector_hits, track, true, iSlice);
         if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
+
+        ATH_MSG_INFO("Successfully selected track using new hit binning");
+
         m_h_trackQoP_okHits->Fill(track.getQOverPt());
 
         // Get the region of this sector
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
index 83015677119b..5e87be1af707 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.h
@@ -84,7 +84,7 @@ class FPGATrackSimMatrixGenAlgo : public AthAlgorithm
         const FPGATrackSimPlaneMap* m_pmap = nullptr; // alias to m_FPGATrackSimMapping->PlaneMap();
         ToolHandle<FPGATrackSimRoadUnionTool>       m_roadFinderTool {this, "RoadFinder", "RoadFinder"};
         ToolHandle<FPGATrackSimTrackFitterTool>          m_trackFitterTool_1st {this, "TrackFitter_1st", "FPGATrackSimTrackFitterTool/FPGATrackSimTrackFitterTool_1st", "1st stage track fit tool"};
-        ToolHandle<FPGATrackSimBinnedHits>      m_hitBinningTool {this, "BinningTool", "FPGATrackSimBinning/FPGATrackSimBinnedHits", "Hit binning tool, needed to apply new layer map"}:
+        ToolHandle<FPGATrackSimBinnedHits>      m_hitBinningTool {this, "BinningTool", "FPGATrackSimBinning/FPGATrackSimBinnedHits"};
 
         ToolHandle<IFPGATrackSimTrackExtensionTool>      m_trackExtensionTool {this, "TrackExtensionTool", "FPGATrackSimTrackExtensionTool", "Track extension tool"};
         ToolHandle<FPGATrackSimOverlapRemovalTool>       m_overlapRemovalTool {this, "OverlapRemoval_1st", "FPGATrackSimOverlapRemovalTool/FPGATrackSimOverlapRemovalTool_1st", "1st stage overlap removal tool"};
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
index 801e0e0390c5..f28d9d51eec5 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
@@ -88,6 +88,8 @@ public:
   void setValidBin(const std::vector<unsigned>& idx); // also sets SubBins
   void printValidBin() const; // dump an output to log for x-checks
 
+  ToolHandleArray<FPGATrackSimBinStep> const & steps() const { return m_steps; }
+
 private:
   //--------------------------------------------------------------------------------------------------
   //
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
index 297ea619061b..c48bd8b63550 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinnedHits.h
@@ -50,7 +50,8 @@ using FPGATrackSimBinUtil::StoredHit;
 //-------------------------------------------------------------------------------------------------------
 class FPGATrackSimBinnedHits : public AthAlgTool {
 public:
-  FPGATrackSimBinnedHits(const std::string &algname, const std::string &name, const IInterface *ifc);
+  FPGATrackSimBinnedHits(const std::string &algname, const std::string &name, const IInterface *ifc)
+        : AthAlgTool(algname, name, ifc) {}
 
   virtual StatusCode initialize() override;
   void initBinnedDataArrays();
@@ -106,7 +107,7 @@ private:
   ToolHandle<FPGATrackSimBinTool> m_bintool {
     this, "BinTool", "FPGATrackSimBinTool",
         "FPGATrackSimBinTool: contains tools describe which parameters are used and each step of binning"};
-  
+
   // The number of layers, either set externally from pmap or set by the layerMap
   unsigned m_nLayers{0}; 
 };
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
index 9ced0be2b5fc..c7fac60fc362 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
@@ -16,9 +16,6 @@
 #include <GaudiKernel/StatusCode.h>
 #include <nlohmann/json.hpp>
 
-FPGATrackSimBinnedHits::FPGATrackSimBinnedHits(const std::string &algname, const std::string &name, const IInterface *ifc)
-      : AthAlgTool(algname, name, ifc) {}
-
 StatusCode FPGATrackSimBinnedHits::initialize() {
   // Dump the configuration to make sure it propagated through right
   const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
-- 
GitLab


From aff054358faebd40fdbb85a74f508b9205784f38 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Tue, 18 Mar 2025 02:47:04 -0500
Subject: [PATCH 4/7] Fixes to get things to initialize

Matrix gen now crashes with a FPE, but at least it configures properly.
---
 .../python/FPGATrackSimBankGenConfig.py             | 13 ++++++++-----
 .../FPGATrackSim/FPGATrackSimBinning/CMakeLists.txt |  6 +++---
 .../FPGATrackSimBinning/FPGATrackSimBinTool.h       |  3 +--
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
index 9c1b6f35c6c5..62fe8e30a7a4 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/python/FPGATrackSimBankGenConfig.py
@@ -13,7 +13,7 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 from FPGATrackSimConfTools.FPGATrackSimAnalysisConfig import FPGATrackSimRoadUnionToolCfg,FPGATrackSimRoadUnionTool1DCfg,FPGATrackSimRoadUnionToolGenScanCfg
 from FPGATrackSimConfTools.FPGATrackSimDataPrepConfig import FPGATrackSimRawLogicCfg, FPGATrackSimMappingCfg, FPGATrackSimEventSelectionCfg
 from AthenaCommon.SystemOfUnits import GeV
-
+import importlib
 
 def FPGATrackSimSpacePointsToolCfg(flags):
     result=ComponentAccumulator()
@@ -30,7 +30,10 @@ def FPGATrackSimBinnedHitsToolCfg(flags):
     result = ComponentAccumulator()
 
     # read the cuts from a seperate python file specified by FPGATrackSim.GenScan.genScanCuts
-    cutset = importlib.import_module(flags.Trigger.FPGATrackSim.GenScan.genScanCuts).cuts[flags.Trigger.FPGATrackSim.region]
+    toload=flags.Trigger.FPGATrackSim.GenScan.genScanCuts
+    if toload == 'FPGATrackSimGenScanCuts': # its on the newRegion default so it hasn't been set
+        toload = 'FPGATrackSimHough.FPGATrackSimGenScanCuts_incr'
+    cutset = importlib.import_module(toload).cuts[flags.Trigger.FPGATrackSim.region]
 
     # make the binned hits class
     BinnnedHits = CompFactory.FPGATrackSimBinnedHits("BinnedHits_MatrixGen")
@@ -63,7 +66,7 @@ def FPGATrackSimBinnedHitsToolCfg(flags):
         log.error("Unknown Binning Setup: ",cutset["parSet"])
 
     BinTool.BinDesc = BinDesc
-    BinTool.steps = binsteps
+    BinTool.Steps = binsteps
 
 
     # configure the padding around the nominal region
@@ -76,7 +79,7 @@ def FPGATrackSimBinnedHitsToolCfg(flags):
     BinTool.parMax = cutset["parMax"]
     BinnnedHits.BinTool = BinTool
 
-    result.setPrivateTools(BinnedHits)
+    result.setPrivateTools(BinnnedHits)
 
     return result
 
@@ -123,7 +126,7 @@ def FPGATrackSimBankGenCfg(flags, **kwargs):
     theFPGATrackSimMatrixGenAlg.SpacePoints = True
     theFPGATrackSimMatrixGenAlg.SpacePointTool = acc.getPrimaryAndMerge(FPGATrackSimSpacePointsToolCfg(flags))
     theFPGATrackSimMatrixGenAlg.minSpacePlusPixel = flags.Trigger.FPGATrackSim.minSpacePlusPixel
-    theFPGATracKSimMatrixGenAlg.BinningTool = acc.getPrimaryAndMerge(FPGATrackSimBinnedHitsToolCfg(flags))
+    theFPGATrackSimMatrixGenAlg.BinningTool = acc.getPrimaryAndMerge(FPGATrackSimBinnedHitsToolCfg(flags))
 
     theFPGATrackSimMatrixGenAlg.FPGATrackSimMappingSvc = acc.getPrimaryAndMerge(FPGATrackSimMappingCfg(flags))
 
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/CMakeLists.txt b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/CMakeLists.txt
index 69e470255d1d..a4a73236c43d 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/CMakeLists.txt
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/CMakeLists.txt
@@ -16,9 +16,9 @@ atlas_add_library( FPGATrackSimBinningLib
    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
    PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} FPGATrackSimBanksLib FPGATrackSimConfToolsLib )
 
-#atlas_add_component( FPGATrackSimBinning
-#   src/components/*.cxx
-#   LINK_LIBRARIES FPGATrackSimBanksLib FPGATrackSimBinningLib )
+atlas_add_component( FPGATrackSimBinning
+   src/components/*.cxx
+   LINK_LIBRARIES FPGATrackSimBanksLib FPGATrackSimBinningLib )
 
 # Install files from the package:
 #atlas_install_python_modules( python/*.py )
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
index f28d9d51eec5..b9dc856fb34f 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/FPGATrackSimBinning/FPGATrackSimBinTool.h
@@ -88,8 +88,6 @@ public:
   void setValidBin(const std::vector<unsigned>& idx); // also sets SubBins
   void printValidBin() const; // dump an output to log for x-checks
 
-  ToolHandleArray<FPGATrackSimBinStep> const & steps() const { return m_steps; }
-
 private:
   //--------------------------------------------------------------------------------------------------
   //
@@ -104,6 +102,7 @@ private:
   Gaudi::Property<std::vector<double>> m_parMinConfig{this, "parMin", {}, "Vector of minimum bounds of parameters (expect 5"};
   Gaudi::Property<std::vector<double>> m_parMaxConfig{this, "parMax", {}, "Vector of maximum bounds of parameters (expect 5"};
 
+
   ToolHandleArray<FPGATrackSimBinStep> m_steps{this, "Steps", {}, "Array of FPGATrackSimBinStep: describes which parameters are binned at each step"};
   ToolHandle<IFPGATrackSimBinDesc> m_binDesc{this, "BinDesc", "FPGATrackSimBinDescBase", "FPGATrackSimBinDescBase: describes binning track parameters"};
   
-- 
GitLab


From 17d4644f8f9bd2450739feff7a2a749a3d80a313 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Tue, 18 Mar 2025 03:37:09 -0500
Subject: [PATCH 5/7] Got binning to actually run in matrix gen

It's really slow though. I don't know if that's because of the hit copying
or because of something else...
---
 .../FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx    | 5 +++++
 .../FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx       | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
index c4244fb617c2..d45587c75995 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
@@ -85,6 +85,11 @@ StatusCode FPGATrackSimMatrixGenAlgo::initialize()
   // In some cases we may not want this, but I need to think about what those are.
   ATH_CHECK(m_hitBinningTool.retrieve());
 
+  // Setup layer configuration if not already set from layerMap
+  // TODO needs to support both stages.
+  if (m_hitBinningTool->getNLayers()==0)
+    m_hitBinningTool->setNLayers(m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers());
+
   
   if (m_doHoughConstants) {
     if (m_ideal_geom == 0) {
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
index c7fac60fc362..a70ee66b4e74 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBinning/src/FPGATrackSimBinnedHits.cxx
@@ -72,8 +72,8 @@ StatusCode FPGATrackSimBinnedHits::fill(
     const std::vector<std::shared_ptr<const FPGATrackSimHit>> &hits) {
   ATH_MSG_DEBUG("In fill");
 
+  int stepnum = 0;
   for (const auto &step : m_bintool->steps()) {
-    int stepnum = 0;
 
     ATH_MSG_DEBUG("fill binning: step num " << stepnum << " " << step->stepName());
     for (auto &bin : step->validBinsFull()) {
-- 
GitLab


From 5775c40649f3e6c205150fa47741823d16f7b446 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Tue, 18 Mar 2025 04:10:01 -0500
Subject: [PATCH 6/7] Reset binning at the end of matrix gen execute()

---
 .../src/FPGATrackSimMatrixGenAlgo.cxx                    | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
index d45587c75995..612a47495864 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
@@ -258,6 +258,12 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         // Skip any bins that have zero hits.
         if (binEntry.hitCnt == 0) continue;
 
+        // More intelligently, skip any bin that has fewer than layers - m_MaxWC hits
+        // since that would be guaranteed to be below threshold
+        if (binEntry.hitCnt < (m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers() - m_MaxWC)) continue;
+
+        ATH_MSG_INFO("Processing bin with hitCnt = " << binEntry.hitCnt);
+
         std::vector<FPGATrackSimHit> binned_hits;
         // All the code below assumes "real" hit objects. Since we don't need these hits to survive
         // outside each iteration of the loop, the path of least resistance is to actually change the hit's layer
@@ -392,6 +398,9 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
     }
   }
 
+  // Reset the bins
+  m_hitBinningTool->resetBins();
+
   return StatusCode::SUCCESS;
 }
 
-- 
GitLab


From 08f7c1ca587801382962614f215735c427d7e1c6 Mon Sep 17 00:00:00 2001
From: Ben Rosser <bjr@sas.upenn.edu>
Date: Tue, 18 Mar 2025 05:42:01 -0500
Subject: [PATCH 7/7] Always use the physlayer when testing if a hit is in
 region

Also pass the selected truth tracks to pattern rec when running matrix
generation.
---
 .../src/FPGATrackSimMatrixGenAlgo.cxx         | 15 ++++++--------
 .../src/FPGATrackSimRegionMap.cxx             | 20 ++++++++-----------
 2 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
index 612a47495864..2fc8a1ff00c8 100755
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimBankGen/src/FPGATrackSimMatrixGenAlgo.cxx
@@ -222,7 +222,7 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
   std::vector<FPGATrackSimTruthTrack> truth_tracks = m_eventHeader->optional().getTruthTracks();
   std::vector<FPGATrackSimTruthTrack> tracks = filterTrainingTracks(truth_tracks);
   m_nTracks += truth_tracks.size();
-  if (tracks.empty()) {  
+  if (tracks.empty()) {
     ATH_MSG_DEBUG("Empty training tracks");
     return StatusCode::SUCCESS;
   }
@@ -231,7 +231,7 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
   // For each training track, find the sector it belongs to and accumulate the
   // hit coordinates and track parameters.
   for (FPGATrackSimTruthTrack const & track : tracks) {
-    
+
     int nSlices = m_FPGATrackSimMapping->SubRegionMap()->getNRegions();
 
     // Get list of hits associated to the current truth track
@@ -245,7 +245,7 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
 
     for (int iSlice = 0; iSlice<nSlices; iSlice++){
       t_pmap = m_FPGATrackSimMapping->PlaneMap_1st(iSlice);
-      
+
       for (auto & iHit : track_hits) {
         t_pmap->map(iHit);
       }
@@ -262,8 +262,6 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         // since that would be guaranteed to be below threshold
         if (binEntry.hitCnt < (m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers() - m_MaxWC)) continue;
 
-        ATH_MSG_INFO("Processing bin with hitCnt = " << binEntry.hitCnt);
-
         std::vector<FPGATrackSimHit> binned_hits;
         // All the code below assumes "real" hit objects. Since we don't need these hits to survive
         // outside each iteration of the loop, the path of least resistance is to actually change the hit's layer
@@ -280,8 +278,6 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
         bool success = filterSectorHits(binned_hits, sector_hits, track, true, iSlice);
         if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
 
-        ATH_MSG_INFO("Successfully selected track using new hit binning");
-
         m_h_trackQoP_okHits->Fill(track.getQOverPt());
 
         // Get the region of this sector
@@ -295,7 +291,7 @@ StatusCode FPGATrackSimMatrixGenAlgo::execute()
           std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
 
           for (const FPGATrackSimHit& hit : sector_hits) if (hit.isMapped() && hit.isReal()) phits.emplace_back(std::make_shared<const FPGATrackSimHit>(hit));
-          StatusCode sc = m_roadFinderTool->getRoads(phits, houghRoads);
+          StatusCode sc = m_roadFinderTool->getRoads(phits, houghRoads, tracks);
           if (sc.isFailure()) ATH_MSG_WARNING("Hough Transform -> getRoads() failed");
           if (m_doSecondStage) { // if doing 2nd stage, we want to get tracks from the road and then do tracking and overlap removal
 
@@ -625,6 +621,7 @@ bool FPGATrackSimMatrixGenAlgo::filterSectorHits(std::vector<FPGATrackSimHit> co
     if (rmap->getRegions(hit).size() == 0) {
       continue;
     }
+
     int layer = hit.getLayer();
     if (layer_count[layer] == 0){
       layer_count[layer]++;
@@ -634,7 +631,7 @@ bool FPGATrackSimMatrixGenAlgo::filterSectorHits(std::vector<FPGATrackSimHit> co
       layer_count[layer]++;
       // Already found a hit in this layer, so pick which hit to use
       selectHit_returnCode selected_hit = selectHit(sector_hits[layer], hit, is1ststage, subregion);
-      
+
       if (selected_hit == selectHit_returnCode::SH_FAILURE) {
          fillTrackPars(m_h_SHfailure, t);
          return false;
diff --git a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimMaps/src/FPGATrackSimRegionMap.cxx b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimMaps/src/FPGATrackSimRegionMap.cxx
index a1de7756d6c7..c5b64de9ae47 100644
--- a/Trigger/EFTracking/FPGATrackSim/FPGATrackSimMaps/src/FPGATrackSimRegionMap.cxx
+++ b/Trigger/EFTracking/FPGATrackSim/FPGATrackSimMaps/src/FPGATrackSimRegionMap.cxx
@@ -224,24 +224,20 @@ void FPGATrackSimRegionMap::loadRadiiFile(std::string const & filepath)
 
 bool FPGATrackSimRegionMap::isInRegion(uint32_t region, const FPGATrackSimHit &hit) const
 {
-    // If the hit is unmapped, then instead of calling hit.getLayer(), use the (relevant) pmap
+    // Always assume that the hit's "layer" might not correspond to what's in the pmap
     // Also, to avoid confusion and double-counting, by convention, always use the coordinates of the inner hit
     // when testing if a spacepoint is in a (sub)region.
     uint32_t layer;
     uint32_t section;
-    if (hit.isMapped()) {
-        layer = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedLayer() : hit.getLayer();
-        section = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedSection() : hit.getSection();
+
+    LayerSection ls;
+    if (hit.getHitType() == HitType::spacepoint) {
+        ls = m_pmaps.at(region)->getLayerSection(hit.getPairedDetType(), hit.getPairedDetZone(), hit.getPairedPhysLayer());
     } else {
-        LayerSection ls;
-        if (hit.getHitType() == HitType::spacepoint) {
-            ls = m_pmaps.at(region)->getLayerSection(hit.getPairedDetType(), hit.getPairedDetZone(), hit.getPairedPhysLayer());
-        } else {
-            ls = m_pmaps.at(region)->getLayerSection(hit.getDetType(), hit.getDetectorZone(), hit.getPhysLayer());
-        }
-        layer = ls.layer;
-        section = ls.section;
+        ls = m_pmaps.at(region)->getLayerSection(hit.getDetType(), hit.getDetectorZone(), hit.getPhysLayer());
     }
+    layer = ls.layer;
+    section = ls.section;
 
     int etamod = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedEtaModule() : hit.getEtaModule();
     unsigned phimod = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedPhiModule() : hit.getPhiModule();
-- 
GitLab