diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt
index 3f7df7475f706967e01d0240c87854d8421714f6..6396001755583cf065c56b1a8bdcc25266a43ad6 100644
--- a/reco/L1/CMakeLists.txt
+++ b/reco/L1/CMakeLists.txt
@@ -41,7 +41,8 @@ set(SRCS
 
   L1Algo/L1Algo.cxx
   L1Algo/L1TrackPar.cxx
-  L1Algo/L1CATrackFinder.cxx
+  L1Algo/L1CaTrackFinder.cxx
+  L1Algo/L1CaTrackFinderSlice.cxx
   L1Algo/L1BranchExtender.cxx
   L1Algo/L1TrackFitter.cxx
   L1Algo/L1Grid.cxx
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index 73ab89b5131c90532941fade2f6e258729819e49..ec5af950fd4821a0cf0cb98b6a6b3983fc1b131b 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -1002,25 +1002,18 @@ void CbmL1::Reconstruct(CbmEvent* event)
     //     }
 
     if (fVerbose > 1) { cout << "L1 Track finder..." << endl; }
-    fpAlgo->CATrackFinder();
+    fpAlgo->CaTrackFinder();
     //       IdealTrackFinder();
-    fTrackingTime += fpAlgo->fCATime;
+    fTrackingTime += fpAlgo->fCaRecoTime;
 
     if (fVerbose > 1) { cout << "L1 Track finder ok" << endl; }
-    //  fpAlgo->L1KFTrackFitter( fExtrapolateToTheEndOfSTS );
-
-    // track fit
-    fpAlgo->L1KFTrackFitter();
-
-
-    if (fVerbose > 1) { cout << "L1 Track fitter  ok" << endl; }
 
     // save reconstructed tracks
     int trackFirstHit = 0;
 
     float TsStart_new = TsStart + TsLength - TsOverlap;
 
-    for (L1Vector<L1Track>::iterator it = fpAlgo->fTracks.begin(); it != fpAlgo->fTracks.end(); it++) {
+    for (L1Vector<L1Track>::iterator it = fpAlgo->fRecoTracks.begin(); it != fpAlgo->fRecoTracks.end(); it++) {
 
       CbmL1Track t;
 
@@ -1047,8 +1040,8 @@ void CbmL1::Reconstruct(CbmEvent* event)
 
       for (int i = 0; i < it->NHits; i++) {
         int caHitId  = fpAlgo->fRecoHits[trackFirstHit + i];
-        int cbmHitID = fpAlgo->GetInputData()->GetHit(caHitId).ID;
-        double time  = fpAlgo->GetInputData()->GetHit(caHitId).t;
+        int cbmHitID = fpAlgo->GetInputData().GetHit(caHitId).ID;
+        double time  = fpAlgo->GetInputData().GetHit(caHitId).t;
         t.Hits.push_back(cbmHitID);
         if (time >= (TsStart + TsLength - TsOverlap)) {
           isTrackInOverlap = 1;
@@ -1076,7 +1069,7 @@ void CbmL1::Reconstruct(CbmEvent* event)
 
     TsStart = TsStart_new;  ///Set new TS strat to earliest discarted track
 
-    LOG(debug) << "CA Track Finder: " << fpAlgo->fCATime << " s/sub-ts" << endl;
+    LOG(debug) << "CA Track Finder: " << fpAlgo->fCaRecoTime << " s/sub-ts" << endl;
   }
 
 
@@ -1225,7 +1218,7 @@ void CbmL1::writedir2current(TObject* obj)
 
 void CbmL1::IdealTrackFinder()
 {
-  fpAlgo->fTracks.clear();
+  fpAlgo->fRecoTracks.clear();
   fpAlgo->fRecoHits.clear();
 
   for (L1Vector<CbmL1MCTrack>::iterator i = fvMCTracks.begin(); i != fvMCTracks.end(); ++i) {
@@ -1275,7 +1268,7 @@ void CbmL1::IdealTrackFinder()
     algoTr.TFirst[4] = MC.q / MC.p;
     algoTr.TFirst[5] = MC.z;
 
-    fpAlgo->fTracks.push_back(algoTr);
+    fpAlgo->fRecoTracks.push_back(algoTr);
   }
 }  // void CbmL1::IdealTrackFinder()
 
diff --git a/reco/L1/CbmL1MCTrack.cxx b/reco/L1/CbmL1MCTrack.cxx
index 2b75033cb1cd84077c59559bf00003fbdc72b2b7..befff96e6c7863b30bad194d998364c4f259db2e 100644
--- a/reco/L1/CbmL1MCTrack.cxx
+++ b/reco/L1/CbmL1MCTrack.cxx
@@ -126,7 +126,7 @@ void CbmL1MCTrack::CalculateHitCont()
   {
     for (int ih = 0; ih < nhits; ih++) {
       int jh         = Hits[ih];
-      const L1Hit& h = algo->GetInputData()->GetHit(jh);
+      const L1Hit& h = algo->GetInputData().GetHit(jh);
       int ista       = h.iSt;
 
       if (ista - istaold == 1) ncont++;
diff --git a/reco/L1/CbmL1Performance.cxx b/reco/L1/CbmL1Performance.cxx
index 86378a9eb78a32cfe427a399c8f3a831d478194a..717216a3808549bfb69d0f5996d6846e7e126c6f 100644
--- a/reco/L1/CbmL1Performance.cxx
+++ b/reco/L1/CbmL1Performance.cxx
@@ -1047,17 +1047,17 @@ void CbmL1::HistoPerformance()  // TODO: check if works correctly. Change vHitFa
   }  // for mcTracks
 
   int NFakes = 0;
-  for (unsigned int ih = 0; ih < fpAlgo->GetInputData()->GetNhits(); ih++) {
+  for (unsigned int ih = 0; ih < fpAlgo->GetInputData().GetNhits(); ih++) {
     int iMC = fvHitPointIndexes[ih];  // TODO2: adapt to linking
     if (iMC < 0) NFakes++;
   }
 
   h_reco_time->Fill(fTrackingTime);
   h_reco_timeNtr->Fill(mc_total, fTrackingTime);
-  h_reco_timeNhit->Fill(fpAlgo->GetInputData()->GetNhits(), fTrackingTime);
+  h_reco_timeNhit->Fill(fpAlgo->GetInputData().GetNhits(), fTrackingTime);
 
   h_reco_fakeNtr->Fill(mc_total, NFakes);
-  h_reco_fakeNhit->Fill(fpAlgo->GetInputData()->GetNhits() - NFakes, NFakes);
+  h_reco_fakeNhit->Fill(fpAlgo->GetInputData().GetNhits() - NFakes, NFakes);
 
 
   h_reg_MCmom->Scale(1.f / NEvents);
diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx
index b5039b558c6c13f050f2f3f7da48565bac8f45cc..20e47bdfbf30c5a763d2f1ba1bdfb10a9c3e534d 100644
--- a/reco/L1/L1Algo/L1Algo.cxx
+++ b/reco/L1/L1Algo/L1Algo.cxx
@@ -28,9 +28,9 @@ void L1Algo::SetNThreads(unsigned int n)
 
   for (int i = 0; i < fNThreads; i++) {
 
-    fTracks_local[i].SetName(std::stringstream() << "L1Algo::fTracks_local[" << i << "]");
+    fSliceRecoTracks_thread[i].SetName(std::stringstream() << "L1Algo::fSliceRecoTracks_thread[" << i << "]");
 
-    fRecoHits_local[i].SetName(std::stringstream() << "L1Algo::fRecoHits_local[" << i << "]");
+    fSliceRecoHits_thread[i].SetName(std::stringstream() << "L1Algo::fSliceRecoHits_thread[" << i << "]");
 
     fTrackCandidates[i].SetName(std::stringstream() << "L1Algo::fTrackCandidates[" << i << "]");
 
@@ -85,18 +85,27 @@ void L1Algo::ReceiveInputData(L1InputData&& inputData)
 {
   // ----- Get input data ----------------------------------------------------------------------------------------------
   fInputData = std::move(inputData);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void L1Algo::ResetSliceData()
+{
+  int nHits = fSliceHitIds.size();
 
-  // ----- Reset data arrays -------------------------------------------------------------------------------------------
-  fvHitKeyFlags.reset(fInputData.GetNhitKeys(), 0);
-  int nHits    = fInputData.GetNhits();
-  NHitsIsecAll = nHits;
   fGridHits.reset(nHits);
   fGridHitsBuf.reset(nHits);
-  fGridHits.reset(nHits);
-  fGridPoints.reset(nHits);
-  fGridPointsBuf.reset(nHits);
   fGridHitIds.reset(nHits);
   fGridHitIdsBuf.reset(nHits);
+  fGridPoints.reset(nHits);
+  fGridPointsBuf.reset(nHits);
+
+  fHitFirstTriplet.reset(nHits);
+  fHitNtriplets.reset(nHits);
+
+  // TODO: SG: reduce the array size to the number of keys in subslice
+
+  fStripToTrack.reset(fInputData.GetNhitKeys(), -1);
 
 #ifdef _OPENMP
   fStripToTrackLock.reset(fInputData.GetNhitKeys());
@@ -105,31 +114,34 @@ void L1Algo::ReceiveInputData(L1InputData&& inputData)
   }
 #endif
 
-  fStripToTrack.clear();
-  fStripToTrack.reserve(fInputData.GetNhitKeys());
+  fSliceRecoTracks.clear();
+  fSliceRecoTracks.reserve(2 * nHits / fParameters.GetNstationsActive());
 
-  fHitFirstTriplet.reset(nHits);
-  fHitNtriplets.reset(nHits);
+  fSliceRecoHits.clear();
+  fSliceRecoHits.reserve(2 * nHits);
 
   for (int i = 0; i < L1Constants::size::kMaxNstations; i++) {
+    int nHitsStation = fSliceHitIdsStopIndex[i] - fSliceHitIdsStartIndex[i] + 1;
     fSingletPortionSize[i].clear();
-    fSingletPortionSize[i].reserve(2 * fInputData.GetNhits(i));
+    fSingletPortionSize[i].reserve(2 * nHitsStation);
   }
 
   for (int i = 0; i < fNThreads; i++) {
-    fTracks_local[i].clear();
-    fTracks_local[i].reserve(nHits / 10);
-    fRecoHits_local[i].clear();
-    fRecoHits_local[i].reserve(nHits);
+    fSliceRecoTracks_thread[i].clear();
+    fSliceRecoTracks_thread[i].reserve(nHits / 10);
+    fSliceRecoHits_thread[i].clear();
+    fSliceRecoHits_thread[i].reserve(nHits);
     fTrackCandidates[i].clear();
     fTrackCandidates[i].reserve(nHits / 10);
     for (unsigned int j = 0; j < L1Constants::size::kMaxNstations; j++) {
+      int nHitsStation = fSliceHitIdsStopIndex[i] - fSliceHitIdsStartIndex[i] + 1;
       fTriplets[j][i].clear();
-      fTriplets[j][i].reserve(2 * nHits);
+      fTriplets[j][i].reserve(2 * nHitsStation);
     }
   }
 }
 
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void L1Algo::ReceiveParameters(L1Parameters&& parameters)
@@ -185,7 +197,7 @@ void L1Algo::CreateHitPoint(const L1Hit& hit, L1HitPoint& point)
   point.Set(hit.z, hit.u, hit.v, hit.t, hit.du2, hit.dv2, hit.dt2);
 }
 
-int L1Algo::GetMcTrackIdForHit(int iHit) const
+int L1Algo::GetMcTrackIdForCaHit(int iHit) const
 {
   int hitId    = iHit;
   int iMcPoint = CbmL1::Instance()->GetHitMCRefs()[hitId];
diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index 702b8d403913635465105f8d5b6735019ff17e92..db73196b6c72e90c8494cbe497a0e6673eba1765 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -166,7 +166,7 @@ public:
   void ReceiveParameters(L1Parameters&& parameters);
 
   /// Gets pointer to input data object for external access
-  const L1InputData* GetInputData() const { return &fInputData; }
+  const L1InputData& GetInputData() const { return fInputData; }
 
   /// ----- Hit-point-strips conversion routines ------
 
@@ -201,7 +201,9 @@ public:
    *                             ------  FUNCTIONAL PART ------
    ************************************************************************************************/
 
-  /// ----- Subroutines used by L1Algo::CATrackFinder() ------
+  /// ----- Subroutines used by L1Algo::CaTrackFinder() ------
+
+  void ResetSliceData();
 
   void CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best_L, fscal& best_chi2, const L1Triplet* curr_trip,
                    L1Branch& curr_tr, unsigned char& curr_L, fscal& curr_chi2, unsigned char min_best_l,
@@ -357,8 +359,11 @@ public:
 
   void PrintHits();
 
-  /// The main procedure - find tracks.
-  void CATrackFinder();
+  /// The main procedure - find tracks
+  void CaTrackFinder();
+
+  /// find tracks in a sub-timeslice
+  void CaTrackFinderSlice();
 
   /// Track fitting procedures
 
@@ -377,7 +382,7 @@ public:
   int GetNfieldStations() const { return fNfieldStations; }
 
   /// Get mc track ID for a hit (debug tool)
-  int GetMcTrackIdForHit(int iHit) const;
+  int GetMcTrackIdForCaHit(int iHit) const;
 
   /// Get mc track ID for a hit (debug tool)
   int GetMcTrackIdForGridHit(int iGridHit) const;
@@ -405,7 +410,7 @@ private:
     "L1Algo::fvHitKeyFlags"};  ///< List of key flags: has been this hit or cluster already used
 
 public:
-  L1Vector<L1HitTimeInfo> fHitTimeInfo[L1Constants::size::kMaxNstations];
+  L1Vector<L1HitTimeInfo> fHitTimeInfo;
 
   L1Grid vGrid[L1Constants::size::kMaxNstations];      ///<
   L1Grid vGridTime[L1Constants::size::kMaxNstations];  ///<
@@ -414,11 +419,14 @@ public:
   fscal fMaxDy[L1Constants::size::kMaxNstations];
   fscal fMaxDt[L1Constants::size::kMaxNstations];
 
-  double fCATime {0.};  // time of track finding
+  double fCaRecoTime {0.};  // time of the track finder + fitter
 
-  L1Vector<L1Track> fTracks {"L1Algo::fTracks"};           ///< reconstructed tracks
+  L1Vector<L1Track> fRecoTracks {"L1Algo::fRecoTracks"};   ///< reconstructed tracks
   L1Vector<L1HitIndex_t> fRecoHits {"L1Algo::fRecoHits"};  ///< packed hits of reconstructed tracks
 
+  L1Vector<L1Track> fSliceRecoTracks {"L1Algo::fSliceRecoTracks"};   ///< reconstructed tracks in sub-timeslice
+  L1Vector<L1HitIndex_t> fSliceRecoHits {"L1Algo::fSliceRecoHits"};  ///< packed hits of reconstructed tracks
+
   /// Created triplets vs station and thread index
   L1Vector<L1Triplet> fTriplets[L1Constants::size::kMaxNstations][L1Constants::size::kMaxNthreads] {
     {"L1Algo::fTriplets"}};
@@ -431,9 +439,6 @@ public:
     "L1Algo::fSingletPortionSize"};  ///< Number of doublets in a portion
 
 
-  //  L1Branch* pointer;
-  unsigned int NHitsIsecAll {0};
-
   L1Vector<L1HitIndex_t> fSliceHitIds {"L1Algo::fSliceHitIds"};                   ///< indices of the sub-slice hits
   L1HitIndex_t fSliceHitIdsStartIndex[L1Constants::size::kMaxNstations + 1] {0};  ///< start of station hit inices
   L1HitIndex_t fSliceHitIdsStopIndex[L1Constants::size::kMaxNstations + 1] {0};   ///< stop of station hit inices
@@ -450,8 +455,8 @@ public:
   L1HitIndex_t fGridHitStartIndex[L1Constants::size::kMaxNstations + 1] {0};
   L1HitIndex_t fGridHitStopIndex[L1Constants::size::kMaxNstations + 1] {0};
 
-  L1Vector<L1Track> fTracks_local[L1Constants::size::kMaxNthreads] {"L1Algo::fTracks_local"};
-  L1Vector<L1HitIndex_t> fRecoHits_local[L1Constants::size::kMaxNthreads] {"L1Algo::fRecoHits_local"};
+  L1Vector<L1Track> fSliceRecoTracks_thread[L1Constants::size::kMaxNthreads] {"L1Algo::fSliceRecoTracks_thread"};
+  L1Vector<L1HitIndex_t> fSliceRecoHits_thread[L1Constants::size::kMaxNthreads] {"L1Algo::fSliceRecoHits_thread"};
 
 
 #ifdef _OPENMP
@@ -459,7 +464,7 @@ public:
 #endif
 
   L1Vector<int> fStripToTrack {"L1Algo::fStripToTrack"};    // front strip to track pointers
-  L1Vector<int> fStripToTrackB {"L1Algo::fStripToTrackB"};  // back strip to track pointers
+  // L1Vector<int> fStripToTrack1B {"L1Algo::fStripToTrackB"};  // back strip to track pointers
 
   int fNThreads {0};
   bool fMissingHits {0};  ///< TODO ???
diff --git a/reco/L1/L1Algo/L1CaTrackFinder.cxx b/reco/L1/L1Algo/L1CaTrackFinder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6f65227f3027e27ac88cafc7ffcbf3c07c6d9699
--- /dev/null
+++ b/reco/L1/L1Algo/L1CaTrackFinder.cxx
@@ -0,0 +1,190 @@
+/* Copyright (C) 2009-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Valentina Akishina, Ivan Kisel, Sergey Gorbunov [committer], Igor Kulakov, Maksym Zyzak */
+
+/*
+ *=====================================================
+ *
+ *  CBM Level 1 4D Reconstruction
+ *
+ *  Authors: V.Akishina, I.Kisel,  S.Gorbunov, I.Kulakov, M.Zyzak
+ *  Documentation: V.Akishina
+ *
+ *  e-mail : v.akishina@gsi.de
+ *
+ *=====================================================
+ *
+ *  Finds tracks using the Cellular Automaton algorithm
+ *
+ */
+
+#include <chrono>
+
+#include "L1Algo.h"
+#include "L1Track.h"
+
+void L1Algo::CaTrackFinder()
+{
+  //
+  // The main CaTrackFinder routine
+  // It splits the input data into sub-timeslices
+  // and runs the track finder over the sub-slices
+  //
+
+  auto timerStart = std::chrono::high_resolution_clock::now();
+
+  // ----- Reset data arrays -------------------------------------------------------------------------------------------
+  fvHitKeyFlags.reset(fInputData.GetNhitKeys(), 0);
+
+  fRecoTracks.clear();
+  fRecoHits.clear();
+  fRecoHits.reserve(2 * fInputData.GetNhits());
+  fRecoTracks.reserve(2 * fInputData.GetNhits() / fParameters.GetNstationsActive());
+
+  fSliceHitIds.clear();
+  fSliceHitIds.reserve(fInputData.GetNhits());
+
+  fvHitKeyFlags.reset(fInputData.GetNhitKeys(), 0);
+  fHitTimeInfo.reset(fInputData.GetNhits());
+
+  // TODO: move these values to CbmL1Parameters namespace (S.Zharko)
+  const fscal tsLength    = 10000;  // length of sub-TS
+  const fscal tsOverlap   = 15;     // min length of overlap region
+  fscal minProtonMomentum = 0.1;
+
+  fscal targX = fParameters.GetTargetPositionX()[0];
+  fscal targY = fParameters.GetTargetPositionY()[0];
+  fscal targZ = fParameters.GetTargetPositionZ()[0];
+
+  fscal tsStart = std::numeric_limits<fscal>::max();  // starting time of sub-TS
+
+  // calculate possible event time for the hits (fHitTimeInfo array)
+
+  for (int iS = 0; iS < fParameters.GetNstationsActive(); ++iS) {
+
+    const L1Station& st       = fParameters.GetStation(iS);
+    L1HitIndex_t nStationHits = fInputData.GetNhits(iS);
+    for (L1HitIndex_t ih = 0; ih < nStationHits; ++ih) {
+      int caHitId         = fInputData.GetStartHitIndex(iS) + ih;
+      const L1Hit& h      = fInputData.GetHit(caHitId);
+      L1HitTimeInfo& info = fHitTimeInfo[caHitId];
+      if (0 && !st.timeInfo) {
+        info.fEventTimeMin = -std::numeric_limits<fscal>::max() / 2.;
+        info.fEventTimeMax = std::numeric_limits<fscal>::max() / 2.;
+      }
+      else {
+        auto [x, y] = st.ConvUVtoXY(h.u, h.v);
+        fscal dx    = x - targX;
+        fscal dy    = y - targY;
+        fscal dz    = h.z - targZ;
+        fscal l     = sqrt(dx * dx + dy * dy + dz * dz);
+
+        fscal timeOfFlightMin = l * L1TrackPar::kClightNsInv;
+        fscal timeOfFlightMax =
+          1.5 * l * sqrt(1. + L1TrackPar::kProtonMass * L1TrackPar::kProtonMass / minProtonMomentum / minProtonMomentum)
+          * L1TrackPar::kClightNsInv;
+        fscal dt           = 3.5 * sqrt(h.dt2);
+        info.fEventTimeMin = h.t - dt - timeOfFlightMax;
+        info.fEventTimeMax = h.t + dt - timeOfFlightMin;
+      }
+      if (tsStart > info.fEventTimeMax - 5) {
+        tsStart = info.fEventTimeMax - 5;  // 5 ns margin
+      }
+    }
+  }
+
+  // cut data into sub-timeslices and process them one by one
+
+  bool areDataLeft = true;  // is the whole TS processed
+
+  while (areDataLeft) {
+
+    // select the sub-slice hits
+    fSliceHitIds.clear();
+
+    areDataLeft = false;
+
+    // TODO: skip empty regions and start the subslice with the earliest hit
+
+    for (int iS = 0; iS < fParameters.GetNstationsActive(); ++iS) {
+      fSliceHitIdsStartIndex[iS] = fSliceHitIds.size();
+      for (L1HitIndex_t caHitId = fInputData.GetStartHitIndex(iS); caHitId < fInputData.GetStopHitIndex(iS);
+           ++caHitId) {
+        L1HitTimeInfo& info = fHitTimeInfo[caHitId];
+        const L1Hit& h      = fInputData.GetHit(caHitId);
+        if (fvHitKeyFlags[h.f] || fvHitKeyFlags[h.b]) {  // the hit is already reconstructed
+          continue;
+        }
+        if (info.fEventTimeMin > tsStart + tsLength) {  // the hit is too late for the sub slice
+          areDataLeft = true;
+        }
+        else {
+          if (tsStart <= info.fEventTimeMax) {  // the hit belongs to the sub-slice
+            fSliceHitIds.push_back(caHitId);
+          }
+        }  // else the hit has been alread processed in previous sub-slices
+      }
+      fSliceHitIdsStopIndex[iS] = fSliceHitIds.size();
+    }
+
+    CaTrackFinderSlice();
+    L1KFTrackFitter();
+
+    // save reconstructed tracks with no hits in the overlap region
+
+    tsStart += tsLength - tsOverlap;
+
+    // we should add hits from reconstructed but not stored tracks to the new sub-timeslice
+    // we do it in a simple way by extending the tsStartNew
+    // TODO: only add those hits from the region before tsStartNew that belong to the not stored tracks
+
+    int trackFirstHit = 0;
+    for (L1Vector<L1Track>::iterator it = fSliceRecoTracks.begin(); it != fSliceRecoTracks.end();
+         trackFirstHit += it->NHits, it++) {
+
+      bool isTrackCompletelyInOverlap = true;
+      for (int ih = 0; ih < it->NHits; ih++) {
+        int caHitId         = fSliceRecoHits[trackFirstHit + ih];
+        L1HitTimeInfo& info = fHitTimeInfo[caHitId];
+        if (info.fEventTimeMax < tsStart) {  // this hit is before the overlap
+          isTrackCompletelyInOverlap = false;
+          break;
+        }
+      }
+
+      if (!areDataLeft) {  // don't reject tracks in the overlap when no more data are left
+        isTrackCompletelyInOverlap = 0;
+      }
+
+      if (isTrackCompletelyInOverlap) {
+        //
+        // Don't save tracks from the overlap region, since they might have additional hits in the next subslice
+        //
+
+        // release the track hits
+        for (int i = 0; i < it->NHits; i++) {
+          int caHitId        = fSliceRecoHits[trackFirstHit + i];
+          const auto& h      = fInputData.GetHit(caHitId);
+          fvHitKeyFlags[h.f] = 0;
+          fvHitKeyFlags[h.b] = 0;
+        }
+      }
+      else {  // save the track
+        fRecoTracks.push_back(*it);
+        // mark the track hits as used
+        for (int i = 0; i < it->NHits; i++) {
+          int caHitId        = fSliceRecoHits[trackFirstHit + i];
+          const auto& h      = fInputData.GetHit(caHitId);
+          fvHitKeyFlags[h.f] = 1;
+          fvHitKeyFlags[h.b] = 1;
+          fRecoHits.push_back(caHitId);
+        }
+      }
+    }  // sub-timeslice tracks
+
+    tsStart -= 5;  // do 5 ns margin
+  }
+
+  auto timerEnd = std::chrono::high_resolution_clock::now();
+  fCaRecoTime   = (double) (std::chrono::duration<double>(timerEnd - timerStart).count());
+}
\ No newline at end of file
diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx
similarity index 95%
rename from reco/L1/L1Algo/L1CATrackFinder.cxx
rename to reco/L1/L1Algo/L1CaTrackFinderSlice.cxx
index 10e249b9ebf34f933480d243aad6edffa66c0483..1bbd894c6852ad4ca799445a92b85efdfcc815be 100644
--- a/reco/L1/L1Algo/L1CATrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx
@@ -870,9 +870,9 @@ inline void L1Algo::findTripletsStep2(Tindex n3, int istal, int istam, int istar
                                 fGridHitIds[hitsr_3[i3] + fGridHitStartIndex[ista[2]]]};
 
     if (fParameters.DevIsMatchTripletsViaMc()) {
-      int mc1 = GetMcTrackIdForGridHit(ihit[0]);
-      int mc2 = GetMcTrackIdForGridHit(ihit[1]);
-      int mc3 = GetMcTrackIdForGridHit(ihit[2]);
+      int mc1 = GetMcTrackIdForCaHit(ihit[0]);
+      int mc2 = GetMcTrackIdForCaHit(ihit[1]);
+      int mc3 = GetMcTrackIdForCaHit(ihit[2]);
       if ((mc1 != mc2) || (mc1 != mc3)) { continue; }
     }
 
@@ -993,9 +993,9 @@ inline void L1Algo::findTripletsStep2(Tindex n3, int istal, int istam, int istar
     T3.SetOneEntry(i3_4, T, i3_4);
 
     {
-      int mc1 = GetMcTrackIdForGridHit(ihit[0]);
-      int mc2 = GetMcTrackIdForGridHit(ihit[1]);
-      int mc3 = GetMcTrackIdForGridHit(ihit[2]);
+      int mc1 = GetMcTrackIdForCaHit(ihit[0]);
+      int mc2 = GetMcTrackIdForCaHit(ihit[1]);
+      int mc3 = GetMcTrackIdForCaHit(ihit[2]);
       if ((mc1 >= 0) && (mc1 == mc2) && (mc1 == mc3)) {
         const CbmL1MCTrack& mctr = CbmL1::Instance()->GetMcTracks()[mc1];
         float ev                 = 0;
@@ -1469,7 +1469,7 @@ inline void L1Algo::CreatePortionOfTriplets(
 // *                                                                                                *
 // **************************************************************************************************
 
-void L1Algo::CATrackFinder()
+void L1Algo::CaTrackFinderSlice()
 {
   fNFindIterations = fParameters.GetNcaIterations();
 
@@ -1506,7 +1506,7 @@ void L1Algo::CATrackFinder()
   draw->InitL1Draw(this);
 #endif
 
-  TStopwatch c_time;  // for performance time
+
 #if defined(XXX) || defined(COUNTERS)
   static unsigned int stat_N = 0;  // number of events
   stat_N++;
@@ -1551,49 +1551,40 @@ void L1Algo::CATrackFinder()
   static Tindex stat_nLevels[L1Constants::size::kMaxNstations - 2][fNFindIterations] = {{0}};
   static Tindex stat_nCalls[fNFindIterations]                                        = {0};  // n calls of CAFindTrack
   static Tindex stat_nTrCandidates[fNFindIterations]                                 = {0};
+
+  stat_nStartHits += fSliceHitIds.size();
 #endif
 
   /********************************/ /**
    * CATrackFinder routine setting
    ***********************************/
 
-  NHitsIsecAll = 0;
-  fTracks.clear();
-  fRecoHits.clear();
-
-  fRecoHits.reserve(2 * fInputData.GetNhits());
-  fTracks.reserve(2 * fInputData.GetNhits() / fParameters.GetNstationsActive());
+  ResetSliceData();
 
-  int nNotUsedHits = 0;
-
-  // #pragma omp parallel for  reduction(+:nNotUsedHits)
-  for (int ista = 0; ista < fParameters.GetNstationsActive(); ++ista) {
-    nNotUsedHits += (fInputData.GetStopHitIndex(ista) - fInputData.GetStartHitIndex(ista));
-    fGridHitStartIndex[ista] = fInputData.GetStartHitIndex(ista);
-    fGridHitStopIndex[ista]  = fInputData.GetStopHitIndex(ista);
-  }
+  int nSliceHits = fSliceHitIds.size();
 
 #ifdef XXX
-  c_time.Start();
   c_timerG.Start();
 #endif  // XXX
 
-  fscal yStep = 1.5 / sqrt(nNotUsedHits);  // empirics. 0.01*sqrt(2374) ~= 0.5
+  fscal yStep = 1.5 / sqrt(nSliceHits);  // empirics. 0.01*sqrt(2374) ~= 0.5
 
 
-  //  fscal yStep = 0.5 / sqrt(nNotUsedHits);  // empirics. 0.01*sqrt(2374) ~= 0.5
+  //  fscal yStep = 0.5 / sqrt(nSliceHits);  // empirics. 0.01*sqrt(2374) ~= 0.5
   if (yStep > 0.3) yStep = 0.3;
   fscal xStep = yStep * 3;
   // fscal xStep = yStep * 3;
 
   //  yStep = 0.0078;
-  //  const fscal hitDensity = sqrt( nNotUsedHits );
+  //  const fscal hitDensity = sqrt( nSliceHits );
 
   //     fscal yStep = 0.7*4/hitDensity; // empirics. 0.01*sqrt(2374) ~= 0.5
   //     if (yStep > 0.3)
   //      yStep = 1.25;
   //      xStep = 2.05;
 
+  L1HitIndex_t nGridHitsFilled = 0;
+
   for (int iS = 0; iS < fParameters.GetNstationsActive(); ++iS) {
     const L1Station& st    = fParameters.GetStation(iS);
     fMaxDx[iS]             = 0.;
@@ -1602,8 +1593,9 @@ void L1Algo::CATrackFinder()
     bool timeUninitialised = 1;
     fscal lasttime         = 0;
     fscal starttime        = 0;
-    for (L1HitIndex_t ih = fInputData.GetStartHitIndex(iS); ih < fInputData.GetStopHitIndex(iS); ++ih) {
-      const L1Hit& h       = fInputData.GetHit(ih);
+
+    for (L1HitIndex_t ih = fSliceHitIdsStartIndex[iS]; ih < fSliceHitIdsStopIndex[iS]; ++ih) {
+      const L1Hit& h       = fInputData.GetHit(fSliceHitIds[ih]);
       auto [dxx, dxy, dyy] = st.FormXYCovarianceMatrix(h.du2, h.dv2);
       fscal dx             = sqrt(dxx);
       fscal dy             = sqrt(dyy);
@@ -1621,48 +1613,31 @@ void L1Algo::CATrackFinder()
     }
 
     vGridTime[iS].BuildBins(-1, 1, -0.6, 0.6, starttime, lasttime, xStep, yStep, (lasttime - starttime + 1));
-    int start = fGridHitStartIndex[iS];
-    int nhits = fGridHitStopIndex[iS] - start;
-
-    if (nhits > 0) {
-      vGridTime[iS].StoreHits(*this, iS, start, nhits, &(fInputData.GetHit(start)), &(fGridHits[start]),
-                              &(fGridHitIds[start]));
-    }
-    else {  // to avoid out-of-range crash in array[start]
-      vGridTime[iS].StoreHits(*this, iS, start, nhits, nullptr, nullptr, nullptr);
-    }
+    vGridTime[iS].StoreHits(*this, iS, nGridHitsFilled);
   }
 
+  fGridHits.reduce(nGridHitsFilled);
+  fGridHitsBuf.reduce(nGridHitsFilled);
+  fGridHitIds.reduce(nGridHitsFilled);
+  fGridHitIdsBuf.reduce(nGridHitsFilled);
+  fGridPoints.reduce(nGridHitsFilled);
+  fGridPointsBuf.reduce(nGridHitsFilled);
 
-  for (int ist = 0; ist < fParameters.GetNstationsActive(); ++ist)
-    for (L1HitIndex_t ih = fInputData.GetStartHitIndex(ist); ih < fInputData.GetStopHitIndex(ist); ++ih) {
-      const L1Hit& h = fInputData.GetHit(ih);
-      fvHitKeyFlags[h.f] = 0;
-      fvHitKeyFlags[h.b] = 0;
-    }
 
-  for (int ista = 0; ista < fParameters.GetNstationsActive(); ++ista) {
 #ifdef _OPENMP
 #pragma omp parallel for schedule(dynamic, 5)
 #endif
-    for (L1HitIndex_t ih = fInputData.GetStartHitIndex(ista); ih < fInputData.GetStopHitIndex(ista); ++ih) {
-      CreateHitPoint(fGridHits[ih], fGridPoints[ih]);
-    }
+  for (unsigned int ih = 0; ih < fGridHits.size(); ++ih) {
+    const L1Hit& h = fGridHits[ih];
+    CreateHitPoint(h, fGridPoints[ih]);
   }
 
-#ifdef COUNTERS
-  stat_nStartHits += nNotUsedHits;
-#endif
-
 #ifdef XXX
   c_timerG.Stop();
   gti["init  "] = c_timerG;
   c_timerG.Start();
 #endif
 
-  TStopwatch c_time1;
-  c_time1.Start();
-
   /********************************/ /**
    *  Loop over tracking iterations
    ***********************************/
@@ -2027,7 +2002,7 @@ void L1Algo::CATrackFinder()
                    << " chi2= " << best_chi2 << endl;
               cout << " hits: ";
               for (unsigned int i = 0; i < tr.fHits.size(); i++) {
-                cout << GetMcTrackIdForHit(tr.fHits[i]) << " ";
+                cout << GetMcTrackIdForCaHit(tr.fHits[i]) << " ";
               }
               cout << endl;
             }
@@ -2136,8 +2111,8 @@ void L1Algo::CATrackFinder()
       // ==
 
       for (int i = 0; i < fNThreads; ++i) {
-        fTracks_local[i].clear();
-        fRecoHits_local[i].clear();
+        fSliceRecoTracks_thread[i].clear();
+        fSliceRecoHits_thread[i].clear();
       }
 
       for (int i = 0; i < fNThreads; ++i) {
@@ -2173,7 +2148,7 @@ void L1Algo::CATrackFinder()
             const L1Hit& hit     = fInputData.GetHit(*phIt);
             fvHitKeyFlags[hit.f] = 1;
             fvHitKeyFlags[hit.b] = 1;
-            fRecoHits_local[num_thread].push_back(*phIt);
+            fSliceRecoHits_thread[num_thread].push_back(*phIt);
             L1HitPoint tempPoint = CreateHitPoint(hit);  //TODO take number of station from hit
 
             const L1Station& stah = fParameters.GetStation(hit.iSt);
@@ -2186,12 +2161,12 @@ void L1Algo::CATrackFinder()
           }
 
           t.NHits = tr.NHits;
-          fTracks_local[num_thread].push_back(t);
+          fSliceRecoTracks_thread[num_thread].push_back(t);
           if (0) {  // SG debug
             cout << "store track " << iCandidate << " chi2= " << tr.chi2 << endl;
             cout << " hits: ";
             for (unsigned int ih = 0; ih < tr.fHits.size(); ih++) {
-              cout << GetMcTrackIdForHit(tr.fHits[ih]) << " ";
+              cout << GetMcTrackIdForCaHit(tr.fHits[ih]) << " ";
             }
             cout << '\n';
           }
@@ -2206,46 +2181,44 @@ void L1Algo::CATrackFinder()
       Time.Start();
 
 #endif
-      int nTracks = fTracks.size();
-      L1Vector<int> offset_tracks("L1CATrackFinder::offset_tracks", fNThreads, nTracks);
-      L1Vector<int> offset_hits("L1CATrackFinder::offset_hits", fNThreads, NHitsIsecAll);
+      int nRecoTracks = fSliceRecoTracks.size();
+      int nRecoHits   = fSliceRecoHits.size();
+
+      L1Vector<int> offset_tracks("L1CATrackFinder::offset_tracks", fNThreads, nRecoTracks);
+      L1Vector<int> offset_hits("L1CATrackFinder::offset_hits", fNThreads, nRecoHits);
 
-      assert(NHitsIsecAll == fRecoHits.size());  //SG!!
 
-      nTracks += fTracks_local[0].size();
-      NHitsIsecAll += fRecoHits_local[0].size();
+      nRecoTracks += fSliceRecoTracks_thread[0].size();
+      nRecoHits += fSliceRecoHits_thread[0].size();
 
       for (int i = 1; i < fNThreads; ++i) {
-        offset_tracks[i] = offset_tracks[i - 1] + fTracks_local[i - 1].size();
-        offset_hits[i]   = offset_hits[i - 1] + fRecoHits_local[i - 1].size();
-        nTracks += fTracks_local[i].size();
-        NHitsIsecAll += fRecoHits_local[i].size();
+        offset_tracks[i] = offset_tracks[i - 1] + fSliceRecoTracks_thread[i - 1].size();
+        offset_hits[i]   = offset_hits[i - 1] + fSliceRecoHits_thread[i - 1].size();
+        nRecoTracks += fSliceRecoTracks_thread[i].size();
+        nRecoHits += fSliceRecoHits_thread[i].size();
       }
-      fTracks.enlarge(nTracks);
-      fRecoHits.enlarge(NHitsIsecAll);
+      fSliceRecoTracks.enlarge(nRecoTracks);
+      fSliceRecoHits.enlarge(nRecoHits);
 #ifdef _OPENMP
 #pragma omp parallel for
 #endif
       for (int i = 0; i < fNThreads; ++i) {
-        for (Tindex iC = 0; iC < (Tindex) fTracks_local[i].size(); ++iC) {
-          fTracks[offset_tracks[i] + iC] = fTracks_local[i][iC];
+        for (Tindex iC = 0; iC < (Tindex) fSliceRecoTracks_thread[i].size(); ++iC) {
+          fSliceRecoTracks[offset_tracks[i] + iC] = fSliceRecoTracks_thread[i][iC];
         }
-        for (Tindex iH = 0; iH < (Tindex) fRecoHits_local[i].size(); ++iH) {
-          fRecoHits[offset_hits[i] + iH] = fRecoHits_local[i][iH];
+        for (Tindex iH = 0; iH < (Tindex) fSliceRecoHits_thread[i].size(); ++iH) {
+          fSliceRecoHits[offset_hits[i] + iH] = fSliceRecoHits_thread[i][iH];
         }
       }
     }  // firstTripletLevel
 
     // suppress strips of suppressed hits
-    for (int ista = 0; ista < fParameters.GetNstationsActive(); ++ista) {
-      for (L1HitIndex_t ih = fGridHitStartIndex[ista]; ih < fGridHitStopIndex[ista]; ih++) {
-        const L1HitPoint& hp = fGridPoints[ih];
-        if (hp.IsSuppressed()) {
-          int hitId            = fGridHitIds[ih];
-          const L1Hit& hit     = fInputData.GetHit(hitId);
-          fvHitKeyFlags[hit.f] = 1;
-          fvHitKeyFlags[hit.b] = 1;
-        }
+    for (L1HitIndex_t ip = 0; ip < fGridPoints.size(); ip++) {
+      const L1HitPoint& hp = fGridPoints[ip];
+      if (hp.IsSuppressed()) {
+        const L1Hit& hit     = fGridHits[ip];
+        fvHitKeyFlags[hit.f] = 1;
+        fvHitKeyFlags[hit.b] = 1;
       }
     }
 
@@ -2329,7 +2302,7 @@ void L1Algo::CATrackFinder()
     this->L1KFTrackFitter();
 
     // Merge clones
-    fCloneMerger.Exec(fTracks, fRecoHits);
+    fCloneMerger.Exec(fSliceRecoTracks, fSliceRecoHits);
   }
 
 #ifdef XXX
@@ -2339,12 +2312,6 @@ void L1Algo::CATrackFinder()
 
   //==================================
 
-  c_time.Stop();
-
-  //   cout << "End TrackFinder" << endl;
-  //  CATime = (double(c_time.CpuTime()));
-  fCATime = (double(c_time.RealTime()));
-
 #ifdef XXX
 
 
@@ -2382,8 +2349,8 @@ void L1Algo::CATrackFinder()
 
         NBranches += stat_max_n_branches;
         BranchSize += stat_max_BranchSize;
-        NTracks += fTracks.size();
-        TrackSize += sizeof(L1Track)*fTracks.size() + sizeof(L1HitIndex_t)*fRecoHits.size();
+        NTracks += fSliceRecoTracks.size();
+        TrackSize += sizeof(L1Track)*fSliceRecoTracks.size() + sizeof(L1HitIndex_t)*fSliceRecoHits.size();
         int k = 1024*NTimes;
 
         cout<<"L1 Event size: \n"
diff --git a/reco/L1/L1Algo/L1CloneMerger.cxx b/reco/L1/L1Algo/L1CloneMerger.cxx
index cc5fd275e9745dd0465ffccb2809cc0d76230688..82ed524da52d1f067538b06ee178a85dbc7a62ca 100644
--- a/reco/L1/L1Algo/L1CloneMerger.cxx
+++ b/reco/L1/L1Algo/L1CloneMerger.cxx
@@ -64,10 +64,10 @@ void L1CloneMerger::Exec(L1Vector<L1Track>& extTracks, L1Vector<L1HitIndex_t>& e
 #endif
   for (int iTr = 0; iTr < nTracks; iTr++) {
     firstHit[iTr]     = start_hit;
-    firstStation[iTr] = frAlgo.GetInputData()->GetHit(extRecoHits[start_hit]).iSt;
+    firstStation[iTr] = frAlgo.GetInputData().GetHit(extRecoHits[start_hit]).iSt;
     start_hit += extTracks[iTr].NHits - 1;
     lastHit[iTr]     = start_hit;
-    lastStation[iTr] = frAlgo.GetInputData()->GetHit(extRecoHits[start_hit]).iSt;
+    lastStation[iTr] = frAlgo.GetInputData().GetHit(extRecoHits[start_hit]).iSt;
     start_hit++;
 
     isStored[iTr]              = false;
diff --git a/reco/L1/L1Algo/L1Grid.cxx b/reco/L1/L1Algo/L1Grid.cxx
index 6f0d182412a1bf09af34031b674a11fcc9d5d95d..5b80e0e8066b40e030e3eb10fb1952af83186c76 100644
--- a/reco/L1/L1Algo/L1Grid.cxx
+++ b/reco/L1/L1Algo/L1Grid.cxx
@@ -166,10 +166,14 @@ void L1Grid::BuildBins(float yMin, float yMax, float zMin, float zMax, float tMi
 }
 
 
-void L1Grid::StoreHits(L1Algo& Algo, char iS, L1HitIndex_t firstHitIndex, L1HitIndex_t nHits, const L1Hit hits[],
-                       L1Hit gridHits[], L1HitIndex_t gridHitIds[])
+void L1Grid::StoreHits(L1Algo& algo, int iS, L1HitIndex_t& nGridHitsFilled)
 {
 
+  L1HitIndex_t firstHitIndex = algo.fSliceHitIdsStartIndex[iS];
+  L1HitIndex_t nHits         = algo.fSliceHitIdsStopIndex[iS] - firstHitIndex;
+
+  algo.fGridHitStartIndex[iS] = nGridHitsFilled;
+
   fscal x = 0;
   fscal y = 0;
 
@@ -179,8 +183,10 @@ void L1Grid::StoreHits(L1Algo& Algo, char iS, L1HitIndex_t firstHitIndex, L1HitI
 #pragma omp parallel for firstprivate(x, y)
 #endif
   for (L1HitIndex_t ih = 0; ih < nHits; ih++) {
-    Algo.GetHitCoor((hits)[ih], x, y, iS);
-    auto bin       = GetBinBounded(x, y, (hits)[ih].t);
+    L1HitIndex_t caHitId = algo.fSliceHitIds[firstHitIndex + ih];
+    const L1Hit& h       = algo.GetInputData().GetHit(caHitId);
+    algo.GetHitCoor(h, x, y, iS);
+    auto bin       = GetBinBounded(x, y, h.t);
     fHitsInBin[ih] = fFirstHitInBin[bin + 1];
 #ifdef _OPENMP
 #pragma omp atomic
@@ -215,12 +221,17 @@ void L1Grid::StoreHits(L1Algo& Algo, char iS, L1HitIndex_t firstHitIndex, L1HitI
 
 #pragma omp parallel for firstprivate(x, y)
   for (L1HitIndex_t ih = 0; ih < nHits; ih++) {
-    Algo.GetHitCoor((hits)[ih], x, y, iS);
-    auto bin = GetBinBounded(x, y, (hits)[ih].t);
+    L1HitIndex_t caHitId = algo.fSliceHitIds[firstHitIndex + ih];
+    const L1Hit& h       = algo.GetInputData().GetHit(caHitId);
+    algo.GetHitCoor(h, x, y, iS);
+    auto bin = GetBinBounded(x, y, h.t);
     {
-      const L1HitIndex_t& index1 = fFirstHitInBin[bin] + fHitsInBin[ih];
-      gridHits[index1]           = hits[ih];
-      gridHitIds[index1]         = firstHitIndex + ih;
+      const L1HitIndex_t& index1                 = fFirstHitInBin[bin] + fHitsInBin[ih];
+      algo.fGridHits[nGridHitsFilled + index1]   = h;
+      algo.fGridHitIds[nGridHitsFilled + index1] = caHitId;
     }
   }
+
+  nGridHitsFilled += nHits;
+  algo.fGridHitStopIndex[iS] = nGridHitsFilled;
 }
diff --git a/reco/L1/L1Algo/L1Grid.h b/reco/L1/L1Algo/L1Grid.h
index 03d2d487dab999845bc6c5912af289b826382f59..58fa660eb4e489dd16c0e0210a806cb01a9e9616 100644
--- a/reco/L1/L1Algo/L1Grid.h
+++ b/reco/L1/L1Algo/L1Grid.h
@@ -43,16 +43,11 @@ public:
 
   ~L1Grid() = default;
 
-  void StoreHits(L1Algo& Algo, char iS, L1HitIndex_t firstHitIndex, L1HitIndex_t nHits, const L1Hit hits[],
-                 L1Hit gridHits[], L1HitIndex_t gridHitIds[]);
+  void StoreHits(L1Algo& Algo, int iS, L1HitIndex_t& nGridHitsFilled);
 
   void CreatePar0(float yMin, float yMax, float zMin, float zMax, float sy, float sz);
   void BuildBins(float yMin, float yMax, float zMin, float zMax, float tMin, float tMax, float sy, float sz, float st);
 
-  void HitsSort(L1HitPoint* pointsBuf, L1Hit* hitsBuf, const L1Hit* hits, L1HitIndex_t* indices,
-                L1HitIndex_t* indicesBuf, L1HitPoint* points, L1HitIndex_t n, L1HitIndex_t nhits, char iS,
-                L1Algo& Algo);
-
   void Initial1(int NThreads);
   void AllocateMemory(int NThreads);
   void Create(float yMin, float yMax, float zMin, float zMax, float sy, float sz);
diff --git a/reco/L1/L1Algo/L1TrackFitter.cxx b/reco/L1/L1Algo/L1TrackFitter.cxx
index 6f8330d0ea5b79901056e0a373bfd8d6dee703a2..1e51f2762e6aab01e7dc34861c29e03cfeef57f9 100644
--- a/reco/L1/L1Algo/L1TrackFitter.cxx
+++ b/reco/L1/L1Algo/L1TrackFitter.cxx
@@ -24,7 +24,7 @@ using namespace NS_L1TrackFitter;
 void L1Algo::L1KFTrackFitter()
 {
   //  cout << " Start L1 Track Fitter " << endl;
-  int start_hit = 0;  // for interation in fRecoHits[]
+  int start_hit = 0;  // for interation in fSliceRecoHits[]
 
   //  static L1FieldValue fldB0, fldB1, fldB2 _fvecalignment;
   //  static L1FieldRegion fld _fvecalignment;
@@ -106,19 +106,19 @@ void L1Algo::L1KFTrackFitter()
     ZSta[ista] = sta[ista].fZ;
   }
 
-  unsigned short N_vTracks = fTracks.size();  // number of tracks processed per one SSE register
+  unsigned short N_vTracks = fSliceRecoTracks.size();  // number of tracks processed per one SSE register
 
   for (unsigned short itrack = 0; itrack < N_vTracks; itrack += fvec::size()) {
 
     if (N_vTracks - itrack < static_cast<unsigned short>(fvec::size())) nTracks_SIMD = N_vTracks - itrack;
 
     for (int i = 0; i < nTracks_SIMD; i++) {
-      t[i] = &fTracks[itrack + i];
+      t[i] = &fSliceRecoTracks[itrack + i];
     }
 
     // fill the rest of the SIMD vectors with something reasonable
     for (uint i = nTracks_SIMD; i < fvec::size(); i++) {
-      t[i] = &fTracks[itrack];
+      t[i] = &fSliceRecoTracks[itrack];
     }
 
     // get hits of current track
@@ -137,7 +137,7 @@ void L1Algo::L1KFTrackFitter()
 
       for (int ih = 0; ih < nHitsTrack; ih++) {
 
-        const L1Hit& hit = fInputData.GetHit(fRecoHits[start_hit++]);
+        const L1Hit& hit = fInputData.GetHit(fSliceRecoHits[start_hit++]);
         const int ista   = hit.iSt;
 
         //if (sta[ista].fieldStatus) { isFieldPresent[iVec] = true; }
diff --git a/reco/L1/L1Algo/utils/L1AlgoDraw.cxx b/reco/L1/L1Algo/utils/L1AlgoDraw.cxx
index e03940db1bdfe0d6a5ed3e00ca531aa4d60bc052..c11bfb6a5e6928a91c3a65e1f3fae6846f368286 100644
--- a/reco/L1/L1Algo/utils/L1AlgoDraw.cxx
+++ b/reco/L1/L1Algo/utils/L1AlgoDraw.cxx
@@ -74,15 +74,15 @@ void L1AlgoDraw::InitL1Draw(L1Algo* algo_)
   //   algo = CbmL1::Instance()->algo;
   algo = algo_;
 
-  vHits.reserve(algo->GetInputData()->GetNhits());
-  for (unsigned int i = 0; i < algo->GetInputData()->GetNhits(); i++) {
-    vHits.push_back(algo->GetInputData()->GetHit(i));
+  vHits.reserve(algo->GetInputData().GetNhits());
+  for (unsigned int i = 0; i < algo->GetInputData().GetNhits(); i++) {
+    vHits.push_back(algo->GetInputData().GetHit(i));
   }
   NStations = algo->GetParameters()->GetNstationsActive();
   for (int i = 0; i < NStations; i++) {
-    HitsStartIndex[i]    = algo->GetInputData()->GetStartHitIndex(i);
-    HitsStopIndex[i]     = algo->GetInputData()->GetStopHitIndex(i);
-    vStations[i]         = algo->GetParameters()->GetStation(i);
+    HitsStartIndex[i] = algo->GetInputData().GetStartHitIndex(i);
+    HitsStopIndex[i]  = algo->GetInputData().GetStopHitIndex(i);
+    vStations[i]      = algo->GetParameters()->GetStation(i);
   }
 }
 
@@ -234,9 +234,9 @@ void L1AlgoDraw::DrawRecoTracks()
   int NRecTracks = 0;
   //   CbmL1 &L1 = *CbmL1::Instance();
 
-  int curRecoHit            = 0;
-  L1Vector<L1HitIndex_t>& recoHits = algo->fRecoHits;
-  for (vector<L1Track>::iterator it = algo->fTracks.begin(); it != algo->fTracks.end(); ++it) {
+  int curRecoHit                   = 0;
+  L1Vector<L1HitIndex_t>& recoHits = algo->fSliceRecoHits;
+  for (vector<L1Track>::iterator it = algo->fSliceRecoTracks.begin(); it != algo->fSliceRecoTracks.end(); ++it) {
     L1Track& T = *it;
     int nHits  = T.NHits;
     //     if (nHits > 5) continue; // draw clones
@@ -368,8 +368,8 @@ void L1AlgoDraw::DrawDoublets(vector<L1HitIndex_t>* Doublets_hits, map<L1HitInde
                               const int /*MaxArrSize*/, L1HitIndex_t* StsRestHitsStartIndex, unsigned int* realIHit)
 {
   for (int iSta = 0; iSta < NStations - 1; iSta++) {
-    const int firstHitOnSta            = StsRestHitsStartIndex[iSta];
-    const int firstHitOnNextSta        = StsRestHitsStartIndex[iSta + 1];
+    const int firstHitOnSta                           = StsRestHitsStartIndex[iSta];
+    const int firstHitOnNextSta                       = StsRestHitsStartIndex[iSta + 1];
     L1HitIndex_t* staDoubletsHits                     = &(Doublets_hits[iSta][0]);
     map<L1HitIndex_t, L1HitIndex_t>& staDoubletsStart = Doublets_start[iSta];
 
@@ -400,8 +400,8 @@ void L1AlgoDraw::DrawDoublets(vector<L1HitIndex_t>* Doublets_hits, map<L1HitInde
 void L1AlgoDraw::DrawDoubletsOnSta(int iSta, L1HitIndex_t* Doublets_hits, L1HitIndex_t* Doublets_start,
                                    const int MaxArrSize, L1HitIndex_t* StsRestHitsStartIndex, unsigned int* realIHit)
 {
-  const int firstHitOnSta     = StsRestHitsStartIndex[iSta];
-  const int firstHitOnNextSta = StsRestHitsStartIndex[iSta + 1];
+  const int firstHitOnSta        = StsRestHitsStartIndex[iSta];
+  const int firstHitOnNextSta    = StsRestHitsStartIndex[iSta + 1];
   L1HitIndex_t* staDoubletsHits  = Doublets_hits + MaxArrSize * iSta;
   L1HitIndex_t* staDoubletsStart = Doublets_start + MaxArrSize * iSta;
 
@@ -466,9 +466,9 @@ void L1AlgoDraw::DrawDoublet(int il, int ir)
 
 void L1AlgoDraw::DrawInfo()
 {
-  cout << " vHits.size = " << algo->GetInputData()->GetNhits() << endl;
-  cout << " vRecoHits.size = " << algo->fRecoHits.size() << endl;
-  cout << " vTracks.size = " << algo->fTracks.size() << endl;
+  cout << " vHits.size = " << algo->GetInputData().GetNhits() << endl;
+  cout << " vRecoHits.size = " << algo->fSliceRecoHits.size() << endl;
+  cout << " vTracks.size = " << algo->fSliceRecoTracks.size() << endl;
 }
 
 void L1AlgoDraw::DrawTarget()