diff --git a/reco/L1/CbmCaMCModule.cxx b/reco/L1/CbmCaMCModule.cxx
index db1e8fc942f59fd4df8f048f8c97f1e3020f2b02..549d5d8b07f277cea95df8665398ee6d4d378e61 100644
--- a/reco/L1/CbmCaMCModule.cxx
+++ b/reco/L1/CbmCaMCModule.cxx
@@ -67,9 +67,6 @@ try {
   fvpBrPoints.fill(nullptr);
   fvpBrHitMatches.fill(nullptr);
 
-  fpStsClusterMatches = nullptr;
-  fpStsHits           = nullptr;
-
   fFileEventIDs.clear();
 
   auto InitPointBranch = [&](const char* brName, L1DetectorID detID) {
@@ -92,11 +89,6 @@ try {
   InitMatchesBranch("TrdHitMatch", L1DetectorID::kTrd);
   InitMatchesBranch("TofHitMatch", L1DetectorID::kTof);
 
-  if (fvbUseDet[L1DetectorID::kSts]) {
-    fpStsClusterMatches = dynamic_cast<TClonesArray*>(fairManager->GetObject("StsClusterMatch"));
-    fpStsHits           = dynamic_cast<TClonesArray*>(fairManager->GetObject("StsHit"));
-  }
-
   // Check initialization
   this->CheckInit();
 
@@ -231,53 +223,20 @@ template<>
 int MCModule::MatchHitWithMc<L1DetectorID::kSts>(int iHitExt) const
 {
   int iPoint     = -1;
-  const auto* sh = dynamic_cast<CbmStsHit*>(fpStsHits->At(iHitExt));
-
-  // Match MC point
-  if (fpStsClusterMatches) {
-    const auto* clusterMatchF = static_cast<const CbmMatch*>(fpStsClusterMatches->At(sh->GetFrontClusterId()));
-    const auto* clusterMatchB = static_cast<const CbmMatch*>(fpStsClusterMatches->At(sh->GetBackClusterId()));
-    CbmMatch hitMatch;
-    for (int iLinkF = 0; iLinkF < clusterMatchF->GetNofLinks(); ++iLinkF) {
-      const auto& linkF = clusterMatchF->GetLink(iLinkF);
-      for (int iLinkB = 0; iLinkB < clusterMatchB->GetNofLinks(); ++iLinkB) {
-        const auto& linkB = clusterMatchB->GetLink(iLinkB);
-        if (linkF == linkB) {
-          hitMatch.AddLink(linkF);
-          hitMatch.AddLink(linkB);
-        }
-      }
-    }
-    float bestWeight = 0.f;
-    for (int iLink = 0; iLink < hitMatch.GetNofLinks(); ++iLink) {
-      const CbmLink& link = hitMatch.GetLink(iLink);
-
-      int iIndex = link.GetIndex();
-      if (iIndex < 0) {
-        iPoint = -1;
-        break;
-      }
-      int iFile  = link.GetFile();
-      int iEvent = link.GetEntry();
-
-      if (fbLegacyEventMode) {
-        iFile  = fFileEventIDs.begin()->first;
-        iEvent = fFileEventIDs.begin()->second;
-
-        // NOTE: Assertions below are temporary for testing consistency between link.GetFile() and
-        //       fvFileEvent.begin()->first. It seems like this if-block is not needed, because
-        //       assertions do not work out for a single file case (SZh)
-        assert(iFile == link.GetFile());
-        assert(iEvent == link.GetEntry());
-      }
-
-      if (link.GetWeight() > bestWeight) {
-        bestWeight = link.GetWeight();
-        iPoint     = fpMCData->FindInternalPointIndex(L1DetectorID::kSts, iIndex, iEvent, iFile);
+  const auto* pHitMatch = dynamic_cast<CbmMatch*>(fvpBrHitMatches[L1DetectorID::kSts]->At(iHitExt));
+  assert(pHitMatch);
+  if (pHitMatch->GetNofLinks() > 0) {
+    const auto& link = pHitMatch->GetMatchedLink();
+    if (link.GetIndex() > 0) {
+      int index = link.GetIndex();
+      int event = link.GetEntry();
+      int file  = link.GetFile();
+      if (index > -1) {
+        iPoint = fpMCData->FindInternalPointIndex(L1DetectorID::kSts, index, event, file);
         assert(iPoint != -1);
       }
     }
-  }  // Match MC point
+  }
   return iPoint;
 }
 
@@ -369,7 +328,6 @@ void MCModule::MatchRecoAndMCTracks()
     //mNofHitsVsMCTrkID.clear();
     for (int iH : trkRe.Hits) {
       int iP = (*fpvQaHits)[iH].GetMCPointIndex();
-      L1_SHOW(iP);
       if (iP > -1) {
         int iTmc = fpMCData->GetPoint(iP).GetTrackId();
         if (mNofHitsVsMCTrkID.find(iTmc) == mNofHitsVsMCTrkID.end()) { mNofHitsVsMCTrkID[iTmc] = 1; }
@@ -448,11 +406,6 @@ void MCModule::CheckInit() const
       if (!fvpBrHitMatches[iD]) { throw std::logic_error(Form("Hit matches are unavailable for %s", kDetName[iD])); }
     }
   }
-
-  if (fvbUseDet[L1DetectorID::kSts]) {
-    if (!fpStsClusterMatches) { throw std::logic_error("Cluster matches unavailable for STS"); }
-    if (!fpStsHits) { throw std::logic_error("Hits unavailable for STS"); }
-  }
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/L1/CbmCaMCModule.h b/reco/L1/CbmCaMCModule.h
index e1f2b90296fc06f8cb9c8f782f2717e008eb2536..767e7385c6cb32cc2a4ff9cd7f7e7e40738dfb28 100644
--- a/reco/L1/CbmCaMCModule.h
+++ b/reco/L1/CbmCaMCModule.h
@@ -218,9 +218,6 @@ namespace cbm::ca
     CbmCaDetIdArr_t<CbmMCDataArray*> fvpBrPoints   = {{nullptr}};  ///< Array of points vs. detector
     CbmCaDetIdArr_t<TClonesArray*> fvpBrHitMatches = {{nullptr}};  ///< Array of hit match branches vs. detector
 
-    TClonesArray* fpStsHits           = nullptr;  ///< Array of STS hits (currently needed for matching)
-    TClonesArray* fpStsClusterMatches = nullptr;  ///< Array of STS cluster matches
-
     // Matching information
     std::set<std::pair<int, int>> fFileEventIDs;  ///< Set of file and event indexes: first - iFile, second - iEvent
 
diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx
index 400efdeb0e6403826da9967973597253c1c82b25..7920c9cf9f189cc89138b05c4c32a1c23675ddb2 100644
--- a/reco/L1/CbmL1ReadEvent.cxx
+++ b/reco/L1/CbmL1ReadEvent.cxx
@@ -165,6 +165,42 @@ int CbmL1::MatchHitWithMc<L1DetectorID::kMvd>(int iHit) const
 template<>
 int CbmL1::MatchHitWithMc<L1DetectorID::kSts>(int iHit) const
 {
+  //int iPointCHECK     = -1;
+  //const auto* pHitMatch = dynamic_cast<CbmMatch*>(fpStsHitMatches->At(iHit));
+  //assert(pHitMatch);  // Note: it's guaranteed, that a match object (empty or full) exists for every hit in the tree
+  //if (pHitMatch->GetNofLinks() > 0) {
+  //  const auto& link = pHitMatch->GetMatchedLink();
+  //  if (link.GetIndex() > -1) {
+  //    int index = link.GetIndex();
+  //    int file  = link.GetFile();
+  //    int event = link.GetEntry();
+  //    auto itPoint = fmMCPointsLinksMap.find(CbmL1LinkKey(index + fNpointsMvdAll, event, file));
+  //    assert(itPoint != fmMCPointsLinksMap.cend());
+  //    iPointCHECK = itPoint->second;
+  //  }
+  //}
+
+  //float bestWeight = 0.f;
+  //for (int iLink = 0; iLink < pHitMatch->GetNofLinks(); ++iLink) {
+  //  const CbmLink& link = pHitMatch->GetLink(iLink);
+
+  //  int index = link.GetIndex();
+  //  if (index < 0) {
+  //    iPoint = -1;
+  //    break;
+  //  }
+  //  int file  = link.GetFile();
+  //  int event = link.GetEntry();
+
+  //  auto itPoint = fmMCPointsLinksMap.find(CbmL1LinkKey(index + fNpointsMvdAll, event, file));
+  //  assert(itPoint != fmMCPointsLinksMap.cend());
+
+  //  if (link.GetWeight() > bestWeight) {
+  //    bestWeight = link.GetWeight();
+  //    iPoint     = itPoint->second;
+  //  }
+  //}
+
   int iPoint     = -1;
   const auto* sh = dynamic_cast<CbmStsHit*>(fpStsHits->At(iHit));
 
@@ -173,6 +209,7 @@ int CbmL1::MatchHitWithMc<L1DetectorID::kSts>(int iHit) const
     const auto* clusterMatchF = static_cast<const CbmMatch*>(fpStsClusterMatches->At(sh->GetFrontClusterId()));
     const auto* clusterMatchB = static_cast<const CbmMatch*>(fpStsClusterMatches->At(sh->GetBackClusterId()));
     CbmMatch hitMatch;
+
     for (int iLinkF = 0; iLinkF < clusterMatchF->GetNofLinks(); ++iLinkF) {
       const auto& linkF = clusterMatchF->GetLink(iLinkF);
       for (int iLinkB = 0; iLinkB < clusterMatchB->GetNofLinks(); ++iLinkB) {
@@ -183,6 +220,8 @@ int CbmL1::MatchHitWithMc<L1DetectorID::kSts>(int iHit) const
         }
       }
     }
+
+
     float bestWeight = 0.f;
     for (int iLink = 0; iLink < hitMatch.GetNofLinks(); ++iLink) {
       const CbmLink& link = hitMatch.GetLink(iLink);
diff --git a/reco/L1/qa/CbmCaInputQaSts.cxx b/reco/L1/qa/CbmCaInputQaSts.cxx
index 40ad8b5e7c0f7df104185d01cc91e1c9c90b208f..711e69cf033556a2c718a549a9c524ba3544b2cd 100644
--- a/reco/L1/qa/CbmCaInputQaSts.cxx
+++ b/reco/L1/qa/CbmCaInputQaSts.cxx
@@ -368,12 +368,13 @@ void CbmCaInputQaSts::FillHistograms()
     // ** MC information QA
 
     if (IsMCUsed()) {
-      CbmMatch hitMatch = GetHitMatch(iH);
+      const auto* pHitMatch = dynamic_cast<CbmMatch*>(fpHitMatches->At(iH));
+      assert(pHitMatch);
 
       // Evaluate number of hits per one MC point
       int nMCpoints = 0;  // Number of MC points for this hit
-      for (int iLink = 0; iLink < hitMatch.GetNofLinks(); ++iLink) {
-        const auto& link = hitMatch.GetLink(iLink);
+      for (int iLink = 0; iLink < pHitMatch->GetNofLinks(); ++iLink) {
+        const auto& link = pHitMatch->GetLink(iLink);
 
         int iP = link.GetIndex();  // Index of MC point
 
@@ -399,7 +400,8 @@ void CbmCaInputQaSts::FillHistograms()
       if (nMCpoints != 1) { continue; }  // ??
 
       // The best link to in the match (probably, the cut on nMCpoints is meaningless)
-      const auto& bestPointLink = hitMatch.GetMatchedLink();
+      assert(pHitMatch->GetNofLinks() > 0);  // Should be always true due to the cut above
+      const auto& bestPointLink = pHitMatch->GetMatchedLink();
 
       // Skip noisy links
       if (bestPointLink.GetIndex() < 0) { continue; }
@@ -608,9 +610,9 @@ InitStatus CbmCaInputQaSts::InitDataBranches()
     fpMCPoints = fpMCDataManager->InitBranch("StsPoint");
     LOG_IF(fatal, !fpMCTracks) << "\033[1;31m" << fName << ": MC point branch is not found for STS\033[0m";
 
-    // Cluster matches
-    fpClusterMatches = dynamic_cast<TClonesArray*>(pFairRootManager->GetObject("StsClusterMatch"));
-    LOG_IF(fatal, !fpClusterMatches) << "\033[1;31m]" << fName << ": cluster match branch is not found for STS\033[0m";
+    // Hit matches
+    fpHitMatches = dynamic_cast<TClonesArray*>(pFairRootManager->GetObject("StsHitMatch"));
+    LOG_IF(fatal, !fpHitMatches) << "\033[1;31m]" << fName << ": hit match branch is not found for STS\033[0m";
   }
 
   return kSUCCESS;
@@ -1143,57 +1145,3 @@ InitStatus CbmCaInputQaSts::InitHistograms()
   return kSUCCESS;
 }
 
-// ---------------------------------------------------------------------------------------------------------------------
-//
-CbmMatch CbmCaInputQaSts::GetHitMatch(int iHit) const
-{
-  CbmMatch aMatch;
-
-  const auto* pHit = static_cast<const CbmStsHit*>(fpHits->At(iHit));  // NOTE: dynamic cast check is done in main loop
-
-  // Get front and back clusters
-  int iCf = pHit->GetFrontClusterId();
-  int iCb = pHit->GetBackClusterId();
-
-  // TODO: errors instead of fatals?
-  LOG_IF(fatal, iCf < 0) << fName << ": hit with id = " << iHit << " has wrong front cluster (iCf = " << iCf << ')';
-  LOG_IF(fatal, iCb < 0) << fName << ": hit with id = " << iHit << " has wrong back cluster (iCb = " << iCb << ')';
-
-  const auto* pClusterF = dynamic_cast<const CbmStsCluster*>(fpClusters->At(iCf));
-  const auto* pClusterB = dynamic_cast<const CbmStsCluster*>(fpClusters->At(iCb));
-
-  LOG_IF(fatal, !pClusterF) << fName << ": front cluster does not exist for hit with id = " << iHit
-                            << " and cluster id = " << iCf;
-  LOG_IF(fatal, !pClusterB) << fName << ": back cluster does not exist for hit with id = " << iHit
-                            << " and cluster id = " << iCb;
-
-  const auto* pClusterMatchF = dynamic_cast<const CbmMatch*>(fpClusterMatches->At(iCf));
-  const auto* pClusterMatchB = dynamic_cast<const CbmMatch*>(fpClusterMatches->At(iCb));
-
-  LOG_IF(fatal, !pClusterMatchF) << fName << ": front cluster match was not found for cluster with id = " << iCf;
-  LOG_IF(fatal, !pClusterMatchB) << fName << ": back cluster match was not found for cluster with id = " << iCf;
-
-  // Check addresses of hit and cluster
-  int addrHit      = pHit->GetAddress();
-  int addrClusterF = pClusterF->GetAddress();
-  int addrClusterB = pClusterB->GetAddress();
-  bool ifAddrCons  = addrHit == addrClusterF && addrClusterF == addrClusterB;
-  LOG_IF(fatal, !ifAddrCons) << fName << ": hit, front and (or) back cluster has inconsistent addresses: hit - "
-                             << addrHit << ", front - " << addrClusterF << ", back - " << addrClusterB << '\n';
-
-  // CUSTOM MATCHING IN STS: The link is selected if it is presented BOTH in front and back cluster, thus only true
-  //                         hits are matched. The standard matching in STS assumes only one (front or back) cluster
-  //                         to be matched, so it matches both true and fake hits.
-
-  for (int iLinkF = 0; iLinkF < pClusterMatchF->GetNofLinks(); ++iLinkF) {
-    const auto& linkF = pClusterMatchF->GetLink(iLinkF);
-    for (int iLinkB = 0; iLinkB < pClusterMatchB->GetNofLinks(); ++iLinkB) {
-      const auto& linkB = pClusterMatchB->GetLink(iLinkB);
-      if (linkF == linkB) {
-        aMatch.AddLink(linkF);
-        aMatch.AddLink(linkB);
-      }
-    }
-  }
-  return aMatch;
-}
diff --git a/reco/L1/qa/CbmCaInputQaSts.h b/reco/L1/qa/CbmCaInputQaSts.h
index 343307a805ed4d5f963e8d88d9cb75ba126c9c04..2a11a0c10a4620a597d2f9c8ee8f6e4e57aaaffd 100644
--- a/reco/L1/qa/CbmCaInputQaSts.h
+++ b/reco/L1/qa/CbmCaInputQaSts.h
@@ -67,20 +67,6 @@ protected:
   void DeInit();
 
 private:
-  // *********************
-  // ** Private methods **
-  // *********************
-
-  /// Gets match object for the hit
-  /// \param   iHit  Index of hit
-  /// \return        Match object
-  CbmMatch GetHitMatch(int iHit) const;
-
-
-  // *********************
-  // ** Class variables **
-  // *********************
-
   // ----- Data branches
   CbmStsTrackingInterface* fpDetInterface = nullptr;  ///< Instance of detector interface
 
@@ -94,7 +80,7 @@ private:
   CbmMCDataArray* fpMCTracks        = nullptr;  ///< Array of MC tracks
   CbmMCDataArray* fpMCPoints        = nullptr;  ///< Array of MC points
 
-  TClonesArray* fpClusterMatches = nullptr;  ///< Array of hit matches
+  TClonesArray* fpHitMatches = nullptr;  ///< Array of hit matches
 
 
   // ----- Histograms