diff --git a/algo/ca/core/data/CaWindowData.h b/algo/ca/core/data/CaWindowData.h
index a0d76d345d5320d79bfa38f73837dea4f1d046a0..d0c091d7e83a8bf90c111eb876a8b4e616b5046e 100644
--- a/algo/ca/core/data/CaWindowData.h
+++ b/algo/ca/core/data/CaWindowData.h
@@ -66,55 +66,68 @@ namespace cbm::algo::ca
 
     /// \brief Index of the first hit on the station
     /// \param iStation  Index of the tracking station
-    [[gnu::always_inline]] ca::HitIndex_t& HitStartIndexOnStation(int iStation)
+    [[gnu::always_inline]] HitIndex_t& HitStartIndexOnStation(int iStation)
     {
       return fvHitStartIndexOnStation[iStation];
     }
 
     /// \brief Index of the first hit on the station
     /// \param iStation  Index of the tracking station
-    [[gnu::always_inline]] ca::HitIndex_t HitStartIndexOnStation(int iStation) const
+    [[gnu::always_inline]] HitIndex_t HitStartIndexOnStation(int iStation) const
     {
       return fvHitStartIndexOnStation[iStation];
     }
 
     /// \brief Number of hits on station
     /// \param iStation  Index of the tracking station
-    [[gnu::always_inline]] ca::HitIndex_t& NofHitsOnStation(int iStation) { return fvNofHitsOnStation[iStation]; }
+    [[gnu::always_inline]] HitIndex_t& NofHitsOnStation(int iStation) { return fvNofHitsOnStation[iStation]; }
 
     /// \brief Number of hits on station
     /// \param iStation  Index of the tracking station
-    [[gnu::always_inline]] ca::HitIndex_t NofHitsOnStation(int iStation) const { return fvNofHitsOnStation[iStation]; }
+    [[gnu::always_inline]] HitIndex_t NofHitsOnStation(int iStation) const { return fvNofHitsOnStation[iStation]; }
 
     /// \brief Accesses indices of hits, used by reconstructed tracks
-    [[gnu::always_inline]] Vector<ca::HitIndex_t>& RecoHitIndices() { return fvRecoHitIndices; }
+    [[gnu::always_inline]] Vector<HitIndex_t>& RecoHitIndices() { return fvRecoHitIndices; }
 
     /// \brief Accesses indices of hits
-    [[gnu::always_inline]] const Vector<ca::HitIndex_t>& RecoHitIndices() const { return fvRecoHitIndices; }
+    [[gnu::always_inline]] const Vector<HitIndex_t>& RecoHitIndices() const { return fvRecoHitIndices; }
 
     /// \brief Accesses index of hit in the input data
     /// \param iHit  Index of reconstructed hit, used in reconstructed tracks
     /// \return Index of reconstructed hit in the algorithm input data object
-    [[gnu::always_inline]] ca::HitIndex_t& RecoHitIndex(int iHit) { return fvRecoHitIndices[iHit]; }
+    [[gnu::always_inline]] HitIndex_t& RecoHitIndex(int iHit) { return fvRecoHitIndices[iHit]; }
 
     /// \brief Accesses index of hit in the input data
     /// \param iHit  Index of reconstructed hit, used in reconstructed tracks
     /// \return Index of reconstructed hit in the algorithm input data object
-    [[gnu::always_inline]] ca::HitIndex_t RecoHitIndex(int iHit) const { return fvRecoHitIndices[iHit]; }
+    [[gnu::always_inline]] HitIndex_t RecoHitIndex(int iHit) const { return fvRecoHitIndices[iHit]; }
 
     /// \brief Accesses reconstructed track by index
     /// \param iTrack  Track index
-    [[gnu::always_inline]] ca::Track& RecoTrack(int iTrack) { return fvRecoTracks[iTrack]; }
+    [[gnu::always_inline]] Track& RecoTrack(int iTrack) { return fvRecoTracks[iTrack]; }
 
     /// \brief Accesses reconstructed track by index
     /// \param iTrack  Track index
-    [[gnu::always_inline]] const ca::Track& RecoTrack(int iTrack) const { return fvRecoTracks[iTrack]; }
+    [[gnu::always_inline]] const Track& RecoTrack(int iTrack) const { return fvRecoTracks[iTrack]; }
 
     /// \brief Accesses reconstructed track container
-    [[gnu::always_inline]] Vector<ca::Track>& RecoTracks() { return fvRecoTracks; }
+    [[gnu::always_inline]] Vector<Track>& RecoTracks() { return fvRecoTracks; }
 
     /// \brief Accesses reconstructed track container
-    [[gnu::always_inline]] const Vector<ca::Track>& RecoTracks() const { return fvRecoTracks; }
+    [[gnu::always_inline]] const Vector<Track>& RecoTracks() const { return fvRecoTracks; }
+
+    /// \brief Maps hit index from sub-TS to full dataset
+    /// \param iSt   Index of tracking station
+    /// \param iHit  Index of hit in the sub-TS
+    [[gnu::always_inline]] HitIndex_t FullDsHitIndex(int iSt, int iHit) const { return fvFullDsHitIndices[iSt][iHit]; }
+
+    /// \brief Accesses container of hit index map from sub-TS to full dataset
+    /// \param iSt  Index of tracking station
+    [[gnu::always_inline]] Vector<HitIndex_t>& FullDsHitIndices(int iSt) { return fvFullDsHitIndices[iSt]; }
+
+    /// \brief Accesses container of hit index map from sub-TS to full dataset
+    /// \param iSt  Index of tracking station
+    [[gnu::always_inline]] const Vector<HitIndex_t>& FullDsHitIndices(int iSt) const { return fvFullDsHitIndices[iSt]; }
 
    private:
     static constexpr int kMaxNofStations = constants::size::MaxNstations;  ///< Alias to max number of stations
@@ -132,19 +145,22 @@ namespace cbm::algo::ca
     Vector<unsigned char> fvbHitSuppressed{"WindowData::fbHitSuppressed"};
 
     /// \brief First hit index of the station
-    std::array<ca::HitIndex_t, kMaxNofStations + 1> fvHitStartIndexOnStation = {0};
+    std::array<HitIndex_t, kMaxNofStations + 1> fvHitStartIndexOnStation = {0};
 
     /// \brief Number of hits on the station
-    std::array<ca::HitIndex_t, kMaxNofStations + 1> fvNofHitsOnStation = {0};
+    std::array<HitIndex_t, kMaxNofStations + 1> fvNofHitsOnStation = {0};
 
     /// \brief Sample of reconstructed tracks
-    Vector<ca::Track> fvRecoTracks{"WindowData::fvRecoTracks"};
+    Vector<Track> fvRecoTracks{"WindowData::fvRecoTracks"};
 
     /// \brief Sample of reconstructed hit indices
-    Vector<ca::HitIndex_t> fvRecoHitIndices{"WindowData::fvRecoHitIndices"};
+    Vector<HitIndex_t> fvRecoHitIndices{"WindowData::fvRecoHitIndices"};
 
     /// \brief Sample of track candidates
-    Vector<ca::Track> fvTrackCandidates{"WindowData::fvTrackCandidates"};
+    Vector<Track> fvTrackCandidates{"WindowData::fvTrackCandidates"};
+
+    /// \brief Map of hit indices from sub-TS to full dataset
+    std::array<Vector<HitIndex_t>, kMaxNofStations> fvFullDsHitIndices{"WindowData::fvFullDSHitIndex"};
 
   } _fvecalignment;
 }  // namespace cbm::algo::ca
diff --git a/algo/ca/core/tracking/CaFramework.cxx b/algo/ca/core/tracking/CaFramework.cxx
index f89059733a3f5f816fc828d273351a418bac728c..96907d4dec62c9d0395733af21ecfd8dbe2d02f4 100644
--- a/algo/ca/core/tracking/CaFramework.cxx
+++ b/algo/ca/core/tracking/CaFramework.cxx
@@ -16,9 +16,7 @@ namespace
 
 Framework::Framework()
 {
-  for (unsigned int i = 0; i < constants::size::MaxNstations; i++) {
-    fTriplets[i].SetName(std::stringstream() << "Framework::fTriplets[" << i << "]");
-  }
+
 }
 
 using cbm::algo::ca::ECounter;  // monitor counter key type
diff --git a/algo/ca/core/tracking/CaFramework.h b/algo/ca/core/tracking/CaFramework.h
index c7f1a3322dcb56c6fad8bc90da69ea8ea01df1e8..007484d946034ad6504b462f2d3cb8990944aee4 100644
--- a/algo/ca/core/tracking/CaFramework.h
+++ b/algo/ca/core/tracking/CaFramework.h
@@ -222,7 +222,6 @@ namespace cbm::algo::ca
    public:
     Vector<CaHitTimeInfo> fHitTimeInfo;
 
-    ca::WindowData fWData{};
 
     /// ----- Data used during track finding -----
     ///
@@ -235,16 +234,8 @@ namespace cbm::algo::ca
     Vector<Track> fRecoTracks{"Framework::fRecoTracks"};       ///< reconstructed tracks
     Vector<ca::HitIndex_t> fRecoHits{"Framework::fRecoHits"};  ///< packed hits of reconstructed tracks
 
-    /// Created triplets vs station index
-    Vector<ca::Triplet> fTriplets[constants::size::MaxNstations]{{"Framework::fTriplets"}};
-
-    /// Track candidates created out of adjacent triplets before the final track selection.
-    /// The candidates may share any amount of hits.
-    Vector<ca::Branch> fTrackCandidates{"Framework::fTrackCandidates"};
-
-    ///< indices of the sub-slice hits
-    Vector<ca::HitIndex_t> fSliceHitIds[constants::size::MaxNstations]{"Framework::fSliceHitIds"};
 
+    // WARN: Potential race conditions ->
     Vector<int> fHitKeyToTrack{"Framework::fHitKeyToTrack"};  // strip to track pointers
 
     TrackingMode fTrackingMode{kSts};
@@ -256,11 +247,9 @@ namespace cbm::algo::ca
     unsigned int fCurrentIterationIndex{0};         ///< index of the corrent iteration, needed for debug output
     const Iteration* fpCurrentIteration = nullptr;  ///< pointer to the current CA track finder iteration
 
-    Vector<int> fHitFirstTriplet{"Framework::fHitFirstTriplet"};  /// link hit -> first triplet { hit, *, *}
-    Vector<int> fHitNtriplets{"Framework::fHitNtriplets"};        /// link hit ->n triplets { hit, *, *}
-
 
    public:
+    ca::WindowData fWData{};
     ca::TrackExtender fTrackExtender{*this};          ///< Object of the track extender algorithm
     ca::CloneMerger fCloneMerger{*this};              ///< Object of  the clone merger algorithm
     ca::TrackFitter fTrackFitter{*this};              ///< Object of the track extender algorithm
diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx
index 98c47fe74ebfa361a3de8de77f31b636fe3b1350..c466fa1fd82bec47ec4af675afc83eeb9b7482b7 100644
--- a/algo/ca/core/tracking/CaTrackFinder.cxx
+++ b/algo/ca/core/tracking/CaTrackFinder.cxx
@@ -62,8 +62,8 @@ void TrackFinder::FindTracks()
   frAlgo.fRecoTracks.reserve(2 * frAlgo.fInputData.GetNhits() / frAlgo.GetParameters().GetNstationsActive());
 
   for (int iS = 0; iS < frAlgo.GetParameters().GetNstationsActive(); ++iS) {
-    frAlgo.fSliceHitIds[iS].clear();
-    frAlgo.fSliceHitIds[iS].reserve(frAlgo.fInputData.GetNhits());
+    frAlgo.fWData.FullDsHitIndices(iS).clear();
+    frAlgo.fWData.FullDsHitIndices(iS).reserve(frAlgo.fInputData.GetNhits());
   }
 
   frAlgo.fvHitKeyFlags.reset(frAlgo.fInputData.GetNhitKeys(), 0);
@@ -218,7 +218,7 @@ void TrackFinder::FindTracks()
     frAlgo.fMonitorData.IncrementCounter(ECounter::SubTS);
     // select the sub-slice hits
     for (int iS = 0; iS < frAlgo.GetParameters().GetNstationsActive(); ++iS) {
-      frAlgo.fSliceHitIds[iS].clear();
+      frAlgo.fWData.FullDsHitIndices(iS).clear();
     }
 
     areUntouchedDataLeft = false;
@@ -249,7 +249,7 @@ void TrackFinder::FindTracks()
         }
         else {
           if (tsStart <= info.fEventTimeMax) {  // the hit belongs to the sub-slice
-            frAlgo.fSliceHitIds[h.Station()].push_back(caHitId);
+            frAlgo.fWData.FullDsHitIndices(h.Station()).push_back(caHitId);
             statNwindowHits++;
             if (info.fMaxTimeBeforeHit < tsStart + tsLength - tsOverlap) {
               // this hit and all hits before are before the overlap
@@ -282,9 +282,9 @@ void TrackFinder::FindTracks()
     if (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) {
       // cut at 50 hits per station per 1 us.
       int maxStationHits = (int) (50 * tsLength / 1.e3);
-      for (int ista = 0; ista < frAlgo.GetParameters().GetNstationsActive(); ista++) {
-        if ((int) frAlgo.fSliceHitIds[ista].size() > maxStationHits) {
-          frAlgo.fSliceHitIds[ista].clear();
+      for (int ista = 0; ista < frAlgo.GetParameters().GetNstationsActive(); ++ista) {
+        if ((int) frAlgo.fWData.FullDsHitIndices(ista).size() > maxStationHits) {
+          frAlgo.fWData.FullDsHitIndices(ista).clear();
         }
       }
     }
diff --git a/algo/ca/core/tracking/CaTrackFinderWindow.cxx b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
index a6eba0e1db35d697e98aa64c393145a76098a050..5fc39952d04a696b6804d6826df688d2a154ebed 100644
--- a/algo/ca/core/tracking/CaTrackFinderWindow.cxx
+++ b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
@@ -46,7 +46,12 @@ using namespace cbm::algo::ca;
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-TrackFinderWindow::TrackFinderWindow(ca::Framework& algo) : frAlgo(algo) {}
+TrackFinderWindow::TrackFinderWindow(ca::Framework& algo) : frAlgo(algo)
+{
+  for (unsigned int i = 0; i < constants::size::MaxNstations; ++i) {
+    fvTriplets[i].SetName(std::stringstream() << "TrackFinderWindow::fTriplets[" << i << "]");
+  }
+}
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
@@ -121,7 +126,7 @@ void TrackFinderWindow::ReadWindowData()
   int nHits = 0;
   for (int iS = 0; iS < frAlgo.GetParameters().GetNstationsActive(); iS++) {
     frAlgo.fWData.HitStartIndexOnStation(iS) = nHits;
-    frAlgo.fWData.NofHitsOnStation(iS)       = frAlgo.fSliceHitIds[iS].size();
+    frAlgo.fWData.NofHitsOnStation(iS)       = frAlgo.fWData.FullDsHitIndices(iS).size();
     nHits += frAlgo.fWData.NofHitsOnStation(iS);
   }
   frAlgo.fWData.HitStartIndexOnStation(frAlgo.GetParameters().GetNstationsActive()) = nHits;
@@ -129,9 +134,9 @@ void TrackFinderWindow::ReadWindowData()
 
   for (int iS = 0; iS < frAlgo.GetParameters().GetNstationsActive(); iS++) {
     int iFstHit = frAlgo.fWData.HitStartIndexOnStation(iS);
-    for (ca::HitIndex_t ih = 0; ih < frAlgo.fSliceHitIds[iS].size(); ++ih) {
-      ca::Hit h = frAlgo.fInputData.GetHit(frAlgo.fSliceHitIds[iS][ih]);
-      h.SetId(frAlgo.fSliceHitIds[iS][ih]);
+    for (ca::HitIndex_t ih = 0; ih < frAlgo.fWData.FullDsHitIndices(iS).size(); ++ih) {
+      ca::Hit h = frAlgo.fInputData.GetHit(frAlgo.fWData.FullDsHitIndex(iS, ih));
+      h.SetId(frAlgo.fWData.FullDsHitIndex(iS, ih));
       frAlgo.fWData.Hit(iFstHit + ih) = h;
     }
   }
@@ -144,8 +149,8 @@ void TrackFinderWindow::ReadWindowData()
     LOG(info) << "===== ";
   }
 
-  frAlgo.fHitFirstTriplet.reset(nHits, 0);
-  frAlgo.fHitNtriplets.reset(nHits, 0);
+  fvHitFirstTriplet.reset(nHits, 0);
+  fvHitNofTriplets.reset(nHits, 0);
 
 
   frAlgo.fWData.RecoTracks().clear();
@@ -154,12 +159,12 @@ void TrackFinderWindow::ReadWindowData()
   frAlgo.fWData.RecoHitIndices().clear();
   frAlgo.fWData.RecoHitIndices().reserve(2 * nHits);
 
-  frAlgo.fTrackCandidates.clear();
-  frAlgo.fTrackCandidates.reserve(nHits / 10);
+  fvTrackCandidates.clear();
+  fvTrackCandidates.reserve(nHits / 10);
   for (unsigned int iS = 0; iS < constants::size::MaxNstations; iS++) {
-    int nHitsStation = frAlgo.fSliceHitIds[iS].size();
-    frAlgo.fTriplets[iS].clear();
-    frAlgo.fTriplets[iS].reserve(2 * nHitsStation);
+    int nHitsStation = frAlgo.fWData.FullDsHitIndices(iS).size();
+    fvTriplets[iS].clear();
+    fvTriplets[iS].reserve(2 * nHitsStation);
   }
 }
 
@@ -186,8 +191,8 @@ void TrackFinderWindow::CaTrackFinderSlice()
     fscal gridMinY = -0.1;
     fscal gridMaxY = 0.1;
 
-    for (ca::HitIndex_t ih = 0; ih < frAlgo.fSliceHitIds[iS].size(); ++ih) {
-      const ca::Hit& h = frAlgo.fInputData.GetHit(frAlgo.fSliceHitIds[iS][ih]);
+    for (ca::HitIndex_t ih = 0; ih < frAlgo.fWData.FullDsHitIndices(iS).size(); ++ih) {
+      const ca::Hit& h = frAlgo.fInputData.GetHit(frAlgo.fWData.FullDsHitIndex(iS, ih));
 
       if (h.X() < gridMinX) {
         gridMinX = h.X();
@@ -216,7 +221,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
     // TODO: changing the grid also changes the result. Investigate why it happens.
     // TODO: find the optimal grid size
 
-    int nSliceHits = frAlgo.fSliceHitIds[iS].size();
+    int nSliceHits = frAlgo.fWData.FullDsHitIndices(iS).size();
     fscal sizeY    = gridMaxY - gridMinY;
     fscal sizeX    = gridMaxX - gridMinX;
     int nBins2D    = 1 + nSliceHits;
@@ -265,11 +270,11 @@ void TrackFinderWindow::CaTrackFinderSlice()
     // --> frAlgo.fIsWindowHitSuppressed.reset(frAlgo.fWindowHits.size(), 0);
     frAlgo.fWData.ResetHitSuppressionFlags();  // TODO: ??? No effect?
     for (int j = 0; j < frAlgo.GetParameters().GetNstationsActive(); j++) {
-      frAlgo.fTriplets[j].clear();
+      fvTriplets[j].clear();
     }
 
-    frAlgo.fHitFirstTriplet.reset(nHits, 0);
-    frAlgo.fHitNtriplets.reset(nHits, 0);
+    fvHitFirstTriplet.reset(nHits, 0);
+    fvHitNofTriplets.reset(nHits, 0);
 
     {
       // #pragma omp  task
@@ -341,14 +346,14 @@ void TrackFinderWindow::CaTrackFinderSlice()
       Tindex nGridEntriesL = grid.GetEntries().size();
       for (Tindex iel = 0; iel < nGridEntriesL; ++iel) {
         ca::HitIndex_t ihitl = grid.GetEntries()[iel].GetObjectId();
-        auto oldSize         = frAlgo.fTriplets[istal].size();
+        auto oldSize         = fvTriplets[istal].size();
         for (auto& pattern : staPattern) {
           constructor.CreateTripletsForHit(istal, istal + pattern.first, istal + pattern.second, ihitl);
-          frAlgo.fTriplets[istal].insert(frAlgo.fTriplets[istal].end(), constructor.GetTriplets().begin(),
-                                         constructor.GetTriplets().end());
+          fvTriplets[istal].insert(fvTriplets[istal].end(), constructor.GetTriplets().begin(),
+                                   constructor.GetTriplets().end());
         }
-        frAlgo.fHitFirstTriplet[ihitl] = frAlgo.PackTripletId(istal, oldSize);
-        frAlgo.fHitNtriplets[ihitl]    = frAlgo.fTriplets[istal].size() - oldSize;
+        fvHitFirstTriplet[ihitl] = frAlgo.PackTripletId(istal, oldSize);
+        fvHitNofTriplets[ihitl]  = fvTriplets[istal].size() - oldSize;
       }
     }  // istal
 
@@ -360,16 +365,16 @@ void TrackFinderWindow::CaTrackFinderSlice()
     for (int istal = frAlgo.GetParameters().GetNstationsActive() - 2; istal >= frAlgo.fFirstCAstation;
          istal--) {  // start with downstream chambers
 
-      for (unsigned int it = 0; it < frAlgo.fTriplets[istal].size(); ++it) {
+      for (unsigned int it = 0; it < fvTriplets[istal].size(); ++it) {
 
-        ca::Triplet& tr = frAlgo.fTriplets[istal][it];
+        ca::Triplet& tr = fvTriplets[istal][it];
         tr.SetLevel(0);
         tr.SetFNeighbour(0);
         tr.SetNNeighbours(0);
 
-        unsigned int nNeighbours = frAlgo.fHitNtriplets[tr.GetMHit()];
+        unsigned int nNeighbours = fvHitNofTriplets[tr.GetMHit()];
 
-        unsigned int neighLocation = frAlgo.fHitFirstTriplet[tr.GetMHit()];
+        unsigned int neighLocation = fvHitFirstTriplet[tr.GetMHit()];
         unsigned int neighStation  = frAlgo.TripletId2Station(neighLocation);
         unsigned int neighTriplet  = frAlgo.TripletId2Triplet(neighLocation);
 
@@ -382,7 +387,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
         for (unsigned int iN = 0; iN < nNeighbours; ++iN, ++neighTriplet, ++neighLocation) {
 
-          ca::Triplet& neighbour = frAlgo.fTriplets[neighStation][neighTriplet];
+          ca::Triplet& neighbour = fvTriplets[neighStation][neighTriplet];
 
           fscal dchi2 = 0.;
           if (!checkTripletMatch(tr, neighbour, dchi2)) continue;
@@ -402,7 +407,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
         tr.SetLevel(level);
       }  // neighbour search
 
-      frAlgo.fMonitorData.IncrementCounter(ECounter::Triplet, frAlgo.fTriplets[istal].size());
+      frAlgo.fMonitorData.IncrementCounter(ECounter::Triplet, fvTriplets[istal].size());
 
     }  // istal
     frAlgo.fMonitorData.StopTimer(ETimer::NeighboringTripletSearch);
@@ -440,7 +445,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
         (firstTripletLevel > min_level) ? firstTripletLevel + 2 : min_level + 3;  // loose maximum
 
 
-      frAlgo.fTrackCandidates.clear();
+      fvTrackCandidates.clear();
 
       for (const auto& h : frAlgo.fWData.Hits()) {
         frAlgo.fHitKeyToTrack[h.FrontKey()] = -1;
@@ -454,9 +459,9 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
         if (--nlevel == 0) break;  //TODO: SG: this is not needed
 
-        for (Tindex itrip = 0; itrip < (Tindex) frAlgo.fTriplets[istaF].size(); ++itrip) {
+        for (Tindex itrip = 0; itrip < (Tindex) fvTriplets[istaF].size(); ++itrip) {
 
-          ca::Triplet& first_trip = (frAlgo.fTriplets[istaF][itrip]);
+          ca::Triplet& first_trip = (fvTriplets[istaF][itrip]);
           const auto& fstTripLHit = frAlgo.fWData.Hit(first_trip.GetLHit());
           if (frAlgo.fvHitKeyFlags[fstTripLHit.FrontKey()] || frAlgo.fvHitKeyFlags[fstTripLHit.BackKey()]) {
             continue;
@@ -519,14 +524,14 @@ void TrackFinderWindow::CaTrackFinderSlice()
               if (frAlgo.fpCurrentIteration->GetPrimaryFlag() && (best_tr.Chi2() > 5.0)) continue;
             }
           }
-          frAlgo.fTrackCandidates.push_back(best_tr);
-          ca::Branch& tr = frAlgo.fTrackCandidates.back();
+          fvTrackCandidates.push_back(best_tr);
+          ca::Branch& tr = fvTrackCandidates.back();
           tr.SetStation(istaF);
-          tr.SetId(frAlgo.fTrackCandidates.size() - 1);
+          tr.SetId(fvTrackCandidates.size() - 1);
           tr.SetAlive(true);
           if constexpr (fDebug) {
             std::stringstream s;
-            s << "iter " << frAlgo.fCurrentIterationIndex << ", track candidate " << frAlgo.fTrackCandidates.size() - 1
+            s << "iter " << frAlgo.fCurrentIterationIndex << ", track candidate " << fvTrackCandidates.size() - 1
               << " found, L = " << best_tr.NofHits() << " chi2= " << best_tr.Chi2() << " hits: ";
             for (auto hitId : tr.Hits()) {
               s << hitId << " (mc " << frAlgo.GetMcTrackIdForCaHit(hitId) << ") ";
@@ -536,7 +541,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
         }  // itrip
       }    // istaF
 
-      for (ca::Branch& tr : frAlgo.fTrackCandidates) {
+      for (ca::Branch& tr : fvTrackCandidates) {
         tr.SetAlive(false);
       }
 
@@ -548,7 +553,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
         repeatCompetition = false;
 
-        for (ca::Branch& tr : frAlgo.fTrackCandidates) {
+        for (ca::Branch& tr : fvTrackCandidates) {
 
           if (tr.IsAlive()) {
             continue;
@@ -559,7 +564,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
             {  // front  strip
               auto& stripF = (frAlgo.fHitKeyToTrack)[h.FrontKey()];
               if ((stripF >= 0) && (stripF != tr.Id())) {  // strip is used by other candidate
-                const auto& other = frAlgo.fTrackCandidates[stripF];
+                const auto& other = fvTrackCandidates[stripF];
                 if (!other.IsAlive() && tr.IsBetterThan(other)) {
                   stripF = tr.Id();
                 }
@@ -578,7 +583,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
             {  // back strip
               auto& stripB = (frAlgo.fHitKeyToTrack)[h.BackKey()];
               if ((stripB >= 0) && (stripB != tr.Id())) {  // strip is used by other candidate
-                const auto& other = frAlgo.fTrackCandidates[stripB];
+                const auto& other = fvTrackCandidates[stripB];
                 if (!other.IsAlive() && tr.IsBetterThan(other)) {
                   stripB = tr.Id();
                 }
@@ -598,7 +603,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
         // == Check if some suppressed candidates are still alive
 
-        for (ca::Branch& tr : frAlgo.fTrackCandidates) {
+        for (ca::Branch& tr : fvTrackCandidates) {
           if (tr.IsAlive()) {
             continue;
           }
@@ -632,8 +637,8 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
       // ==
 
-      for (Tindex iCandidate = 0; iCandidate < (Tindex) frAlgo.fTrackCandidates.size(); ++iCandidate) {
-        ca::Branch& tr = frAlgo.fTrackCandidates[iCandidate];
+      for (Tindex iCandidate = 0; iCandidate < (Tindex) fvTrackCandidates.size(); ++iCandidate) {
+        ca::Branch& tr = fvTrackCandidates[iCandidate];
 
         if constexpr (fDebug) {
           LOG(info) << "iter " << frAlgo.fCurrentIterationIndex << ", track candidate " << iCandidate
@@ -757,7 +762,7 @@ void TrackFinderWindow::CAFindTrack(int ista, ca::Branch& best_tr, const ca::Tri
       unsigned int Station = frAlgo.TripletId2Station(ID);
       unsigned int Triplet = frAlgo.TripletId2Triplet(ID);
 
-      const ca::Triplet& new_trip = frAlgo.fTriplets[Station][Triplet];
+      const ca::Triplet& new_trip = fvTriplets[Station][Triplet];
 
       fscal dchi2 = 0.;
       if (!checkTripletMatch(*curr_trip, new_trip, dchi2)) continue;
diff --git a/algo/ca/core/tracking/CaTrackFinderWindow.h b/algo/ca/core/tracking/CaTrackFinderWindow.h
index ee5d3d717db29de89350639ebf100b669c976875..830e3c4685349018d4ae16a23de7d7c41bbbd5df 100644
--- a/algo/ca/core/tracking/CaTrackFinderWindow.h
+++ b/algo/ca/core/tracking/CaTrackFinderWindow.h
@@ -67,7 +67,17 @@ namespace cbm::algo::ca
     ///-------------------------------
     /// Data members
 
-    ca::Framework& frAlgo;  ///< Reference to the main track finder algorithm class
+    /// \brief Created triplets vs station index
+    std::array<Vector<ca::Triplet>, constants::size::MaxNstations> fvTriplets;
+
+    /// \brief Track candidates created out of adjacent triplets before the final track selection.
+    /// \note  The candidates may share any amount of hits.
+    Vector<ca::Branch> fvTrackCandidates{"TrackFinderWindow::fTrackCandidates"};
+
+    Vector<int> fvHitFirstTriplet{"Framework::fHitFirstTriplet"};  /// link hit -> first triplet { hit, *, *}
+    Vector<int> fvHitNofTriplets{"Framework::fHitNofTriplets"};    /// link hit ->n triplets { hit, *, *}
+
+    ca::Framework& frAlgo;                 ///< Reference to the main track finder algorithm class
     static constexpr bool fDebug = false;  // print debug info
   };