diff --git a/algo/ca/core/pars/CaInitManager.h b/algo/ca/core/pars/CaInitManager.h
index 826f0a353220b8a49ad3203ace27426778c4ce28..1b836d09fa0e48cf7edf8e6e9e8259cc64ab4f57 100644
--- a/algo/ca/core/pars/CaInitManager.h
+++ b/algo/ca/core/pars/CaInitManager.h
@@ -295,6 +295,7 @@ namespace cbm::algo::ca
     FieldFunction_t fFieldFunction {[](const double (&)[3], double (&)[3]) {}};
     // NOTE: Stations of the detectors which are not assigned as active, are not included in the tracking!
 
+    // TODO: remove
     int fCAIterationsNumberCrosscheck {-1};  ///< Number of iterations to be passed (must be used for cross-checks)
 
     Parameters fParameters {};  ///< CA parameters object
diff --git a/reco/L1/L1Algo/L1Grid.cxx b/reco/L1/L1Algo/L1Grid.cxx
index 85ff8dbe4b8489e26765ff5f0350ed7b7fd4aaf3..a07ed395ef40055d1d87741b9591b9a7f1077c5d 100644
--- a/reco/L1/L1Algo/L1Grid.cxx
+++ b/reco/L1/L1Algo/L1Grid.cxx
@@ -30,9 +30,9 @@ template<typename T>
 
 inline void memset(T* dest, T i, size_t num)
 {
-  const size_t tsize   = sizeof(T);
-  unsigned int lastBin = 0;
-  dest[0]              = i;
+  const size_t tsize = sizeof(T);
+  size_t lastBin     = 0;
+  dest[0]            = i;
   while (lastBin + 1 < num) {
     unsigned int l = lastBin + 1;
     l              = lastBin + l + 1 > num ? num - lastBin - 1 : l;
@@ -41,82 +41,36 @@ inline void memset(T* dest, T i, size_t num)
   }
 }
 
-void L1Grid::UpdateIterGrid(unsigned int Nelements, ca::Hit* hits, Vector<ca::HitIndex_t>& indicesBuf,
-                            ca::HitIndex_t* indices, Vector<ca::Hit>& hitsBuf, Vector<ca::GridEntry>& pointsBuf,
-                            ca::GridEntry* points, int& NHitsOnStation, const Vector<unsigned char>& vSFlag)
-{
-  //L1_SHOW(vSFlag.size());
-  fFirstHitInBin.reset(fN + 2, 0);
-
-  for (ca::HitIndex_t x = 0; x < Nelements; x++) {
-
-    const ca::Hit& hit = hits[x];
-
-    if (!(vSFlag[hit.f] || vSFlag[hit.b])) {
-      const ca::HitIndex_t& bin = GetBinBounded(hit.x, hit.y);
-      fHitsInBin[x]             = fFirstHitInBin[bin + 1];
-      fFirstHitInBin[bin + 1]++;
-    }
-  }
-
-  int kk = 2;
-  /* Up-Sweep Phase */
-  for (unsigned int k = 1; k < fN + 2; k = kk) {
-    kk = k << 1;
-    for (unsigned int i = kk - 1; i < fN + 2; i += kk) {
-      fFirstHitInBin[i] = fFirstHitInBin[i - k] + fFirstHitInBin[i];
-    }
-  }
-
-  /* Down-Sweep Phase */
-  for (int k = kk >> 1; k > 1; k = kk) {
-    kk = k >> 1;
-    for (unsigned int i = k - 1; i < fN + 2 - kk; i += k) {
-      fFirstHitInBin[i + kk] = fFirstHitInBin[i] + fFirstHitInBin[i + kk];
-    }
-  }
-
-  for (ca::HitIndex_t x = 0; x < Nelements; x++) {
-
-    const ca::Hit& hit = hits[x];
-    if (!(vSFlag[hit.f] || vSFlag[hit.b])) {
-      const ca::HitIndex_t& bin           = GetBinBounded(hit.x, hit.y);
-      const ca::HitIndex_t& index1        = fHitsInBin[x] + fFirstHitInBin[bin];
-      hitsBuf[index1 + NHitsOnStation]    = hits[x];
-      indicesBuf[index1 + NHitsOnStation] = indices[x];
-      pointsBuf[index1 + NHitsOnStation]  = points[x];
-    }
-  }
-
-  NHitsOnStation += fFirstHitInBin[fN + 1];
-}
-
 
 void L1Grid::AllocateMemory()
 {
   int binsGrid = 600000;
 
-  fFirstHitInBin.reset(binsGrid, 0);
+  fBinFirstEntryIndex.reset(binsGrid, 0);
   fHitsInBin.reset(binsGrid, 0);
 }
 
 
-void L1Grid::BuildBins(float xMin, float xMax, float yMin, float yMax, float sx, float sy)
+void L1Grid::BuildBins(fscal xMin, fscal xMax, fscal yMin, fscal yMax, fscal sx, fscal sy)
 {
-  fStepXInv = 1.f / sx;
-  fStepYInv = 1.f / sy;
+  fMinX = std::min(xMin, xMax);
+  fMinY = std::min(yMin, yMax);
 
-  fXMinOverStep = xMin * fStepXInv;
-  fYMinOverStep = yMin * fStepYInv;
+  xMax = std::max(xMin, xMax);
+  yMax = std::max(yMin, yMax);
 
-  fNx = (xMax * fStepXInv - fXMinOverStep + 1.f);
-  fNy = (yMax * fStepYInv - fYMinOverStep + 1.f);
+  fBinWidthX = sx;
+  fBinWidthY = sy;
 
-  // unsigned int Nold = fN;
+  fBinWidthXinv = 1. / fBinWidthX;
+  fBinWidthYinv = 1. / fBinWidthY;
 
-  fN = fNx * fNy;
+  fNx = static_cast<int>(std::ceil((xMax - fMinX) / fBinWidthX));
+  fNy = static_cast<int>(std::ceil((yMax - fMinY) / fBinWidthY));
+  if (fNx < 1) fNx = 1;
+  if (fNy < 1) fNy = 1;
 
-  fBinInGrid = fN + 1;
+  fN = fNx * fNy;
 }
 
 
@@ -126,30 +80,30 @@ void L1Grid::StoreHits(L1Algo& algo, int iS, ca::HitIndex_t& nGridHitsFilled)
 
   algo.fGridHitStartIndex[iS] = nGridHitsFilled;
 
-  fFirstHitInBin.reset(fN + 2, 0);
-
+  fBinFirstEntryIndex.reset(fN + 2, 0);
+  fHitsInBin.reset(nHits, 0);
   for (ca::HitIndex_t ih = 0; ih < nHits; ih++) {
     ca::HitIndex_t caHitId = algo.fSliceHitIds[iS][ih];
     const ca::Hit& hit     = algo.GetInputData().GetHit(caHitId);
     auto bin               = GetBinBounded(hit.x, hit.y);
-    fHitsInBin[ih]         = fFirstHitInBin[bin + 1];
-    fFirstHitInBin[bin + 1]++;
+    fHitsInBin[ih]         = fBinFirstEntryIndex[bin + 1];
+    fBinFirstEntryIndex[bin + 1]++;
   }
 
   int kk = 2;
-  /* Up-Sweep Phase */
-  for (unsigned int k = 1; k < fN + 2; k = kk) {
+  // Up-Sweep Phase
+  for (int k = 1; k < fN + 2; k = kk) {
     kk = k << 1;
-    for (unsigned int i = kk - 1; i < fN + 2; i += kk) {
-      fFirstHitInBin[i] = fFirstHitInBin[i - k] + fFirstHitInBin[i];
+    for (int i = kk - 1; i < fN + 2; i += kk) {
+      fBinFirstEntryIndex[i] = fBinFirstEntryIndex[i - k] + fBinFirstEntryIndex[i];
     }
   }
 
-  /* Down-Sweep Phase */
-  for (unsigned int k = kk >> 1; k > 1; k = kk) {
+  // Down-Sweep Phase
+  for (int k = kk >> 1; k > 1; k = kk) {
     kk = k >> 1;
-    for (unsigned int i = k - 1; i < fN + 2 - kk; i += k) {
-      fFirstHitInBin[i + kk] = fFirstHitInBin[i] + fFirstHitInBin[i + kk];
+    for (int i = k - 1; i < fN + 2 - kk; i += k) {
+      fBinFirstEntryIndex[i + kk] = fBinFirstEntryIndex[i] + fBinFirstEntryIndex[i + kk];
     }
   }
 
@@ -158,7 +112,7 @@ void L1Grid::StoreHits(L1Algo& algo, int iS, ca::HitIndex_t& nGridHitsFilled)
     const ca::Hit& hit     = algo.GetInputData().GetHit(caHitId);
     auto bin               = GetBinBounded(hit.x, hit.y);
 
-    const ca::HitIndex_t& index1               = fFirstHitInBin[bin] + fHitsInBin[ih];
+    const ca::HitIndex_t& index1               = fBinFirstEntryIndex[bin] + fHitsInBin[ih];
     algo.fGridHits[nGridHitsFilled + index1]   = hit;
     algo.fGridHitIds[nGridHitsFilled + index1] = caHitId;
   }
@@ -166,3 +120,54 @@ void L1Grid::StoreHits(L1Algo& algo, int iS, ca::HitIndex_t& nGridHitsFilled)
   nGridHitsFilled += nHits;
   algo.fGridHitStopIndex[iS] = nGridHitsFilled;
 }
+
+
+void L1Grid::UpdateIterGrid(ca::HitIndex_t Nelements, ca::Hit* hits, Vector<ca::HitIndex_t>& indicesBuf,
+                            ca::HitIndex_t* indices, Vector<ca::Hit>& hitsBuf, Vector<ca::GridEntry>& pointsBuf,
+                            ca::GridEntry* points, int& NHitsOnStation, const Vector<unsigned char>& vSFlag)
+{
+  //L1_SHOW(vSFlag.size());
+  fBinFirstEntryIndex.reset(fN + 2, 0);
+  fHitsInBin.reset(Nelements, 0);
+  for (ca::HitIndex_t x = 0; x < Nelements; x++) {
+
+    const ca::Hit& hit = hits[x];
+
+    if (!(vSFlag[hit.f] || vSFlag[hit.b])) {
+      const ca::HitIndex_t& bin = GetBinBounded(hit.x, hit.y);
+      fHitsInBin[x]             = fBinFirstEntryIndex[bin + 1];
+      fBinFirstEntryIndex[bin + 1]++;
+    }
+  }
+
+  int kk = 2;
+  /* Up-Sweep Phase */
+  for (int k = 1; k < fN + 2; k = kk) {
+    kk = k << 1;
+    for (int i = kk - 1; i < fN + 2; i += kk) {
+      fBinFirstEntryIndex[i] = fBinFirstEntryIndex[i - k] + fBinFirstEntryIndex[i];
+    }
+  }
+
+  /* Down-Sweep Phase */
+  for (int k = kk >> 1; k > 1; k = kk) {
+    kk = k >> 1;
+    for (int i = k - 1; i < fN + 2 - kk; i += k) {
+      fBinFirstEntryIndex[i + kk] = fBinFirstEntryIndex[i] + fBinFirstEntryIndex[i + kk];
+    }
+  }
+
+  for (ca::HitIndex_t x = 0; x < Nelements; x++) {
+
+    const ca::Hit& hit = hits[x];
+    if (!(vSFlag[hit.f] || vSFlag[hit.b])) {
+      const ca::HitIndex_t& bin           = GetBinBounded(hit.x, hit.y);
+      const ca::HitIndex_t& index1        = fHitsInBin[x] + fBinFirstEntryIndex[bin];
+      hitsBuf[index1 + NHitsOnStation]    = hits[x];
+      indicesBuf[index1 + NHitsOnStation] = indices[x];
+      pointsBuf[index1 + NHitsOnStation]  = points[x];
+    }
+  }
+
+  NHitsOnStation += fBinFirstEntryIndex[fN + 1];
+}
diff --git a/reco/L1/L1Algo/L1Grid.h b/reco/L1/L1Algo/L1Grid.h
index de031048555d388c4f742aff68a61317d797a962..f117a93b6c3a326711f6efc16ec374573d11cd9f 100644
--- a/reco/L1/L1Algo/L1Grid.h
+++ b/reco/L1/L1Algo/L1Grid.h
@@ -13,6 +13,7 @@
 
 #include "CaGridEntry.h"
 #include "CaHit.h"
+#include "CaSimd.h"
 #include "CaVector.h"
 
 class L1Algo;
@@ -28,112 +29,116 @@ namespace
 /// \class L1Grid
 ///
 /// \brief 2-dimensional grid of pointers.
+///
 /// pointers to (x,y)-like objects are assigned to the corresponding grid bin
 /// used by L1Tracker to speed-up the hit operations
 /// grid axis are named X,Y
 ///
 class L1Grid {
 public:
+  /// Constructor
   L1Grid() = default;
 
+  /// Constructor
   L1Grid(const L1Grid& grid) : fN(grid.N()), fNx(grid.Nx()), fNy(grid.Ny()) {}
 
+  /// Destructor
   ~L1Grid() = default;
 
+  void AllocateMemory();
+
+  void BuildBins(fscal xMin, fscal xMax, fscal yMin, fscal yMax, fscal sx, fscal sy);
+
   void StoreHits(L1Algo& Algo, int iS, ca::HitIndex_t& nGridHitsFilled);
 
-  void BuildBins(float xMin, float xMax, float yMin, float yMax, float sx, float sy);
+  void UpdateIterGrid(ca::HitIndex_t Nelements, ca::Hit* hits, Vector<ca::HitIndex_t>& indicesBuf,
+                      ca::HitIndex_t* indices, Vector<ca::Hit>& hitsBuf, Vector<ca::GridEntry>& entriesBuf,
+                      ca::GridEntry* entries, int& NHitsOnStation, const Vector<unsigned char>& vSFlag);
 
-  void AllocateMemory();
-  void Create(float xMin, float xMax, float yMin, float yMax, float sx, float sy);
+  /// get bin index
+  int GetBin(fscal X, fscal Y) const;
 
-  void Fill(const ca::GridEntry* entries, ca::HitIndex_t n);  // call after sort
-  void FillPar(const ca::GridEntry* entries, ca::HitIndex_t n);
+  /// get bin index with boundary check
+  int GetBinBounded(fscal X, fscal Y) const;
 
+  /// get bin X,Y indices with boundary check
+  void GetBinBounded(fscal X, fscal Y, int& bX, int& bY) const;
 
-  int GetBin(float X, float Y) const;
+  /// get bin bounds
+  void GetBinBounds(int iBin, fscal& Xmin, fscal& Xmax, fscal& Ymin, fscal& Ymax) const;
 
-  unsigned int GetBinBounded(const float& X, const float& Y) const;
-  void GetBinBounded(const float& X, const float& Y, unsigned short& bX, unsigned short& bY) const;
+  /// get number of bins
+  int N() const { return fN; }
 
-  void GetBinBounds(unsigned int iBin, float& Xmin, float& Xmax, float& Ymin, float& Ymax) const;
+  /// get number of bins in X
+  int Nx() const { return fNx; }
 
-  unsigned int N() const { return fN; }
-  unsigned short Nx() const { return fNx; }
-  unsigned short Ny() const { return fNy; }
+  /// get number of bins in Y
+  int Ny() const { return fNy; }
 
-  ca::HitIndex_t FirstHitInBin(unsigned int i) const
+  /// get index of the first bin entry in fHitsInBin array
+  ca::HitIndex_t FirstHitInBin(int i) const
   {
-    if (i < (fN + 1)) return fFirstHitInBin[i];
+    if (i < (fN + 1)) return fBinFirstEntryIndex[i];
     else
-      return fFirstHitInBin[fN + 1];
+      return fBinFirstEntryIndex[fN + 1];
   }
 
-
-  void UpdateIterGrid(unsigned int Nelements, ca::Hit* hits, Vector<ca::HitIndex_t>& indicesBuf,
-                      ca::HitIndex_t* indices, Vector<ca::Hit>& hitsBuf, Vector<ca::GridEntry>& entriesBuf,
-                      ca::GridEntry* entries, int& NHitsOnStation, const Vector<unsigned char>& vSFlag);
-
-
 private:
-  unsigned int fN {0};        //* total N bins
-  unsigned short fNx {0};     //* N bins in X
-  unsigned short fNy {0};     //* N bins in Y
-  float fXMinOverStep {0.f};  //* minimal X value * fStepXInv
-  float fYMinOverStep {0.f};  //* minimal Y value * fStepYInv
-  float fStepXInv {0.f};      //* inverse bin size in X
-  float fStepYInv {0.f};      //* inverse bin size in Y
-  int fBinInGrid {0};
-
-  Vector<ca::HitIndex_t> fFirstHitInBin {"L1Grid::fFirstHitInBin"};
+  int fN {0};                ///< total N bins
+  int fNx {0};               ///< N bins in X
+  int fNy {0};               ///< N bins in Y
+  fscal fMinX {0.};          ///< minimal X value
+  fscal fMinY {0.};          ///< minimal Y value
+  fscal fBinWidthX {0.};     ///< bin width in X
+  fscal fBinWidthY {0.};     ///< bin width in Y
+  fscal fBinWidthXinv {0.};  ///< inverse bin width in X
+  fscal fBinWidthYinv {0.};  ///< inverse bin width in Y
+
+  Vector<ca::HitIndex_t> fBinFirstEntryIndex {"L1Grid::fBinFirstEntryIndex"};
   Vector<ca::HitIndex_t> fHitsInBin {"L1Grid::fHitsInBin"};
-
-  // vector <omp_lock_t> lock;
 };
 
 
-inline int L1Grid::GetBin(float X, float Y) const
+inline int L1Grid::GetBin(fscal X, fscal Y) const
 {
-  //* get the bin pointer
-  const int& xBin = static_cast<int>(X * fStepXInv - fXMinOverStep);
-  const int& yBin = static_cast<int>(Y * fStepYInv - fYMinOverStep);
+  /// get bin index
+  int xBin = static_cast<int>((X - fMinX) * fBinWidthXinv);
+  int yBin = static_cast<int>((Y - fMinY) * fBinWidthYinv);
   assert(xBin >= 0);
   assert(yBin >= 0);
-  assert(xBin < static_cast<int>(fNx));
-  assert(yBin < static_cast<int>(fNy));
-  const int& bin = yBin * fNx + xBin;
-  return bin;
+  assert(xBin < fNx);
+  assert(yBin < fNy);
+  return yBin * fNx + xBin;
 }
 
 
-inline void L1Grid::GetBinBounds(unsigned int iBin, float& Xmin, float& Xmax, float& Ymin, float& Ymax) const
+inline void L1Grid::GetBinBounds(int iBin, fscal& Xmin, fscal& Xmax, fscal& Ymin, fscal& Ymax) const
 {
   int yBin = iBin / fNx;
   int xBin = iBin % fNx;
-  Xmin     = (fXMinOverStep + xBin) / fStepXInv;
-  Ymin     = (fYMinOverStep + yBin) / fStepYInv;
-  Xmax     = Xmin + 1. / fStepXInv;
-  Ymax     = Ymin + 1. / fStepYInv;
+  Xmin     = fMinX + xBin * fBinWidthX;
+  Ymin     = fMinY + yBin * fBinWidthY;
+  Xmax     = Xmin + fBinWidthX;
+  Ymax     = Ymin + fBinWidthY;
 }
 
 
-inline unsigned int L1Grid::GetBinBounded(const float& X, const float& Y) const
+inline int L1Grid::GetBinBounded(fscal X, fscal Y) const
 {
-  //* get the bin pointer at
-
-  unsigned short xBin, yBin;
+  /// get bin index
+  int xBin, yBin;
   GetBinBounded(X, Y, xBin, yBin);
-  return (unsigned int) yBin * (unsigned int) fNx + (unsigned int) xBin;
+  return yBin * fNx + xBin;
 }
 
 
-inline void L1Grid::GetBinBounded(const float& X, const float& Y, unsigned short& bX, unsigned short& bY) const
+inline void L1Grid::GetBinBounded(fscal X, fscal Y, int& bX, int& bY) const
 {
-  const short& xBin = (X * fStepXInv - fXMinOverStep);
-  const short& yBin = (Y * fStepYInv - fYMinOverStep);
-
-  bX = std::max(short(0), std::min(short(fNx - 1), xBin));
-  bY = std::max(short(0), std::min(short(fNy - 1), yBin));
+  int xBin = (X - fMinX) * fBinWidthXinv;
+  int yBin = (Y - fMinY) * fBinWidthYinv;
+  bX       = std::max(0, std::min(fNx - 1, xBin));
+  bY       = std::max(0, std::min(fNy - 1, yBin));
 }
 
 
diff --git a/reco/L1/L1Algo/L1HitArea.h b/reco/L1/L1Algo/L1HitArea.h
index bddd6868128c509e9055b4ca7c97e1fd70c0077c..206fe60ae1536fe3a156933120cf2e452892d910 100644
--- a/reco/L1/L1Algo/L1HitArea.h
+++ b/reco/L1/L1Algo/L1HitArea.h
@@ -28,10 +28,10 @@ public:
 protected:
   const L1Grid& fGrid;
 
-  unsigned short fBYmax;  // maximal Y bin index
-  unsigned short fBDX;    // X distance of bin indexes
-  unsigned int fIndXmin;  // minimum index for
-  unsigned short fIy;     // current Y bin index (incremented while iterating)
+  int fBYmax;               // maximal Y bin index
+  int fBDX;                 // X distance of bin indexes
+  int fIndXmin;             // minimum index for
+  int fIy;                  // current Y bin index (incremented while iterating)
   ca::HitIndex_t fHitXlst;  // last possible hit index in current y-line
   ca::HitIndex_t fIh;       // hit index iterating inside the bins
   int fNx;                // Number of bins in X direction
@@ -51,7 +51,7 @@ inline L1HitArea::L1HitArea(const L1Grid& grid, float x, float y, float dx, floa
   const float maxX = x + dx;
   const float minY = y - dy;
   const float maxY = y + dy;
-  unsigned short bXmin, bYmin, bXmax;  // boundary bin indexes
+  int bXmin, bYmin, bXmax;  // boundary bin indexes
   fGrid.GetBinBounded(minX, minY, bXmin, bYmin);
   fGrid.GetBinBounded(maxX, maxY, bXmax, fBYmax);