diff --git a/algo/detectors/tof/Clusterizer.cxx b/algo/detectors/tof/Clusterizer.cxx
index 68b462701d1eea61129cbbaf53f147fc689e19aa..9b23eb627ed0c9857b30873af38c458d0790b926 100644
--- a/algo/detectors/tof/Clusterizer.cxx
+++ b/algo/detectors/tof/Clusterizer.cxx
@@ -20,7 +20,8 @@ namespace cbm::algo::tof
   {
     //std::vector<inputType> input = calibrateDigis(digisIn);
     std::vector<inputType> input = chanSortDigis(digisIn);
-    return buildClusters(input);
+    //return buildClusters(input);
+    return buildClustersIter(input);  //Iterator based implementation
   }
 
   std::vector<Clusterizer::inputType> Clusterizer::chanSortDigis(inputType& digisIn)
@@ -330,119 +331,116 @@ namespace cbm::algo::tof
   }
 
 
-  /*
-  Clusterizer::resultType Clusterizer::buildClusters(inputType& input)
+  Clusterizer::resultType Clusterizer::buildClustersIter(std::vector<inputType>& input)
   {
-    // Intermediate storage variables
-    std::vector<std::vector<CbmTofDigi*>>& digisExp = input.first;   //[nbCh][nDigis]
-    std::vector<std::vector<int32_t>>& digisInd     = input.second;  //[nbCh][nDigis]
-
     // Hit variables
     TofCluster cluster;
     std::vector<TofCluster> clustersOut;
 
     // Reference cell of a cluster
-    TofCell* trafoCell = nullptr;
-    int32_t iTrafoCell = -1;
+    TofCell* cell = nullptr;
 
     // Last Channel Temp variables
     int32_t lastChan = -1;
     double lastPosY  = 0.0;
     double lastTime  = 0.0;
 
-    //reset counter
-    numSameSide = 0;
+    const size_t numChan = fParams.fChanPar.size();
 
-    for (int32_t chan = 0; chan < fParams.fChanPar.size(); chan++) {
+    for (int32_t chan = 0; chan < numChan; chan++) {
+      if (fParams.fDeadStrips & (1 << chan)) { continue; }  // skip over dead channels
 
-      std::vector<CbmTofDigi*>& storDigiExp = digisExp[chan];
-      std::vector<int32_t>& storDigiInd     = digisInd[chan];
-      ClusterizerChanPar& chanPar          = fParams.fChanPar[chan];
+      inputType& storDigi = input[chan];
+      auto digiIt         = storDigi.begin();
 
-      auto digiExpIt = storDigiExp.begin();
-      auto digiIndIt = storDigiInd.begin();
+      while (1 < std::distance(digiIt, storDigi.end())) {
 
-      while (1 < std::distance(digiExpIt, storDigiExp.end())) {
-        while ((*digiExpIt)->GetSide() == (*std::next(digiExpIt, 1))->GetSide()) {
-          // Not one Digi of each end!
-          numSameSide++;
-          digiExpIt++;
-          digiIndIt++;
-          if (2 > std::distance(digiExpIt, storDigiExp.end())) break;
+        while (digiIt->first->GetSide() == std::next(digiIt, 1)->first->GetSide()) {  // Not one Digi of each end!
+          digiIt++;
+          if (2 > std::distance(digiIt, storDigi.end())) { break; }
         }
-        if (2 > std::distance(digiExpIt, storDigiExp.end())) break;  // 2 Digis = both sides present
+        if (2 > std::distance(digiIt, storDigi.end())) { break; }
 
-        TofCell* channelInfo = &chanPar.cell;
-        CbmTofDigi* xDigiA   = *digiExpIt;
-        CbmTofDigi* xDigiB   = *std::next(digiExpIt, 1);
+        // 2 Digis = both sides present
+        cell               = &fParams.fChanPar[chan].cell;
+        CbmTofDigi* xDigiA = digiIt->first;
+        CbmTofDigi* xDigiB = std::next(digiIt, 1)->first;
 
-        // The "Strip" time is the mean time between each end
-        const double time = 0.5 * (xDigiA->GetTime() + xDigiB->GetTime());
+        // use local coordinates, (0,0,0) is in the center of counter  ?
+        ROOT::Math::XYZVector pos(((-(double) numChan / 2. + (double) chan) + 0.5) * cell->sizeX, 0., 0.);
 
-        // Weight is the total charge => sum of both ends ToT
-        const double totSum = xDigiA->GetTot() + xDigiB->GetTot();
+        double timeDif = xDigiA->GetTime() - xDigiB->GetTime();
 
-        if (nullptr == trafoCell) {
-          trafoCell  = channelInfo;
-          iTrafoCell = chan;
-        }
+        pos.SetY(fParams.fSigVel * timeDif * 0.5);            // A is the top side, B is the bottom side
+        if (xDigiA->GetSide() != 1.) { pos.SetY(-pos.Y()); }  // B is the bottom side, A is the top side
 
-        // switch to local coordinates, (0,0,0) is in the center of counter  ?
-        // It is assumed that the cell size is the same for all channels within one rpc!
-        ROOT::Math::XYZVector pos(((double) (-iTrafoCell + chan)) * trafoCell->sizeX, 0., 0.);
+        while (std::distance(digiIt, storDigi.end()) > 2 && std::abs(pos.Y()) > cell->sizeY * fParams.fPosYMaxScal) {
 
-        if (1 == xDigiA->GetSide()) {
-          // 0 is the top side, 1 is the bottom side
-          pos.SetY(fParams.CPSigPropSpeed * (xDigiA->GetTime() - xDigiB->GetTime()) / 2.0);
-        }
-        else {
-          // 0 is the bottom side, 1 is the top side
-          pos.SetY(fParams.CPSigPropSpeed * (xDigiB->GetTime() - xDigiA->GetTime()) / 2.0);
+          CbmTofDigi* xDigiC = std::next(digiIt, 2)->first;
+
+          double timeDifN = 0;
+          if (xDigiC->GetSide() == xDigiA->GetSide()) { timeDifN = xDigiC->GetTime() - xDigiB->GetTime(); }
+          else {
+            timeDifN = xDigiC->GetTime() - xDigiA->GetTime();
+          }
+
+          double posYN = fParams.fSigVel * timeDifN * 0.5;
+          if (xDigiC->GetSide() != 1.) { posYN *= -1.; }
+
+          if (std::abs(posYN) >= std::abs(pos.Y())) { break; }
+          pos.SetY(posYN);
+
+          if (xDigiC->GetSide() == xDigiA->GetSide()) { xDigiA = xDigiC; }
+          else {
+            xDigiB = xDigiC;
+          }
+          digiIt++;
         }
 
-        if (channelInfo->sizeY / 2.0 < pos.Y() || -1 * channelInfo->sizeY / 2.0 > pos.Y()) {
-          // if outside of strip limits, the pair is bad => try to remove one end and check the next pair
-          // (if another possibility exist)
-          digiExpIt++;
-          digiIndIt++;
+        if (std::abs(pos.Y()) > cell->sizeY * fParams.fPosYMaxScal) {  // remove both digis
+          digiIt++;
           continue;
-        }  // Pair leads to hit oustide of strip limits
+        }
+        // The "Strip" time is the mean time between each end
+        double time = 0.5 * (xDigiA->GetTime() + xDigiB->GetTime());
+
+        // Weight is the total charge => sum of both ends ToT
+        double totSum = xDigiA->GetTot() + xDigiB->GetTot();
 
         // Now check if a hit/cluster is already started
         if (0 < cluster.numChan()) {
           // a cluster is already started => check distance in space/time
           // For simplicity, just check along strip direction for now
           // and break cluster when a not fired strip is found
-          if (!(std::abs(time - lastTime) < fParams.maxTimeDist && lastChan == chan - 1
-                && std::abs(pos.Y() - lastPosY) < fParams.maxSpaceDist)) {
-            // simple error scaling with TOT
-            // weightedTimeErr = TMath::Sqrt( weightedTimeErr ) * SysTimeRes / weightsSum;
-            // OR harcoded value: weightedTimeErr = SysTimeRes;
-            cluster.normalize(fParams.SysTimeRes);
-
-            // Save Hit and start a new one
-            cluster.finalize(*trafoCell, iTrafoCell, fParams);
+          if (!(std::abs(time - lastTime) < fParams.fdMaxTimeDist && lastChan == chan - 1
+                && std::abs(pos.Y() - lastPosY) < fParams.fdMaxSpaceDist)) {
+
+            cluster.normalize(fParams.fTimeRes);
+            cluster.finalize(*cell, fParams);
             clustersOut.push_back(cluster);
             cluster.reset();
           }
         }
-        cluster.add(pos, time, totSum, totSum, *digiIndIt, *std::next(digiIndIt, 1));
-        digiExpIt += 2;
-        digiIndIt += 2;
+        cluster.add(pos, time, totSum, totSum, storDigi[0].second, storDigi[1].second);
+        digiIt += 2;
 
         lastChan = chan;
         lastPosY = pos.Y();
         lastTime = time;
-      }  // while (1 < storDigiExp.size())
-    }    // for( int32_t chan = 0; chan < iNbCh; chan++ )
+        if (AddNextChan(input, lastChan, cluster, clustersOut)) { cluster.reset(); }
+      }                  // while( 1 < storDigi.size() )
+      storDigi.clear();  //D.Smith 11.8.23: In rare cases, a single digi remains and is deleted here.
+    }                    // for( int32_t chan = 0; chan < iNbCh; chan++ )
 
-    // Save last cluster if it exists
+    // Now check if another hit/cluster is started
+    // and save it if it's the case.
     if (0 < cluster.numChan()) {
-      cluster.normalize(fParams.SysTimeRes);
-      cluster.finalize(*trafoCell, iTrafoCell, fParams);
+      cluster.normalize(fParams.fTimeRes);
+      cluster.finalize(*cell, fParams);
       clustersOut.push_back(cluster);
     }
+    //std::cout << "hits " << fiNbHits << std::endl;
     return clustersOut;
   }
-*/
+
 }  // namespace cbm::algo::tof
diff --git a/algo/detectors/tof/Clusterizer.h b/algo/detectors/tof/Clusterizer.h
index ac2776002e2d37e804d626d3a7965dd9694e278c..9fe5bdc807ed1c6292cf1d11612e412b87be7863 100644
--- a/algo/detectors/tof/Clusterizer.h
+++ b/algo/detectors/tof/Clusterizer.h
@@ -177,6 +177,8 @@ namespace cbm::algo::tof
     std::vector<inputType> chanSortDigis(inputType& digisIn);
 
     resultType buildClusters(std::vector<inputType>& input);
+    resultType buildClustersIter(std::vector<inputType>& input);
+
 
     bool AddNextChan(std::vector<inputType>& input, int32_t iLastChan, TofCluster& cluster,
                      std::vector<TofCluster>& clustersOut);