diff --git a/core/base/CbmMatchRecoToMC.cxx b/core/base/CbmMatchRecoToMC.cxx
index ab1604a2aefafc61e22141afb8e051c2abf90804..2b01da99d47779a9dc80ba0c0ebacbc233164ed3 100644
--- a/core/base/CbmMatchRecoToMC.cxx
+++ b/core/base/CbmMatchRecoToMC.cxx
@@ -849,51 +849,39 @@ void CbmMatchRecoToMC::MatchStsTracks(const TClonesArray* mvdHitMatches, const T
 
 
 void CbmMatchRecoToMC::MatchRichRings(const TClonesArray* richRings, const TClonesArray* richHits,
-                                      // const TClonesArray* richDigis,
-                                      // const TClonesArray* richDigiMatches,
                                       CbmMCDataArray* richMcPoints, CbmMCDataArray* mcTracks, TClonesArray* ringMatches)
 {
   // Loop over RichRings
   Int_t nRings = richRings->GetEntriesFast();
   for (Int_t iRing = 0; iRing < nRings; iRing++) {
     const CbmRichRing* ring = static_cast<const CbmRichRing*>(richRings->At(iRing));
-    if (nullptr == ring) continue;
-
+    if (!ring) continue;
     CbmTrackMatchNew* ringMatch = new ((*ringMatches)[iRing]) CbmTrackMatchNew();
-
-    Int_t nofHits = ring->GetNofHits();
-    for (Int_t iHit = 0; iHit < nofHits; iHit++) {
-      const CbmRichHit* hit = static_cast<const CbmRichHit*>(richHits->At(ring->GetHit(iHit)));
-      if (nullptr == hit) continue;
-
-      vector<pair<Int_t, Int_t>> motherIds =
-        GetMcTrackMotherIdsForRichHit(fDigiManager, hit, richMcPoints, mcTracks, fEventNumber);
-      for (UInt_t i = 0; i < motherIds.size(); i++) {
-        ringMatch->AddLink(1., motherIds[i].second, motherIds[i].first);
+    Int_t nHits                 = ring->GetNofHits();
+    for (Int_t iHit = 0; iHit < nHits; iHit++) {
+      const CbmRichHit* hit = static_cast<const CbmRichHit*>(richHits->At(static_cast<Int_t>(ring->GetHit(iHit))));
+      if (!hit) continue;
+      vector<CbmLink> motherIds = GetMcTrackMotherIdsForRichHit(fDigiManager, hit, richMcPoints, mcTracks);
+      for (const auto& motherId : motherIds) {
+        ringMatch->AddLink(motherId);
       }
     }
 
     if (ringMatch->GetNofLinks() != 0) {
-
-      Int_t bestTrackId      = ringMatch->GetMatchedLink().GetIndex();
-      Int_t bestTrackEventId = ringMatch->GetMatchedLink().GetEntry();
-
-      Int_t trueCounter  = 0;
-      Int_t wrongCounter = 0;
-      for (Int_t iHit = 0; iHit < nofHits; iHit++) {
-        const CbmRichHit* hit = static_cast<const CbmRichHit*>(richHits->At(ring->GetHit(iHit)));
-        if (nullptr == hit) continue;
-        vector<pair<Int_t, Int_t>> motherIds =
-          GetMcTrackMotherIdsForRichHit(fDigiManager, hit, richMcPoints, mcTracks, fEventNumber);
-        if (std::find(motherIds.begin(), motherIds.end(), std::make_pair(bestTrackEventId, bestTrackId))
-            != motherIds.end()) {
+      CbmLink bestTrackLink = ringMatch->GetMatchedLink();
+      Int_t trueCounter     = 0;
+      Int_t wrongCounter    = 0;
+      for (Int_t iHit = 0; iHit < nHits; iHit++) {
+        const CbmRichHit* hit = static_cast<const CbmRichHit*>(richHits->At(static_cast<Int_t>(ring->GetHit(iHit))));
+        if (!hit) continue;
+        vector<CbmLink> motherIds = GetMcTrackMotherIdsForRichHit(fDigiManager, hit, richMcPoints, mcTracks);
+        if (std::find(motherIds.begin(), motherIds.end(), bestTrackLink) != motherIds.end()) {
           trueCounter++;
         }
         else {
           wrongCounter++;
         }
       }
-
       ringMatch->SetNofTrueHits(trueCounter);
       ringMatch->SetNofWrongHits(wrongCounter);
     }
@@ -901,10 +889,42 @@ void CbmMatchRecoToMC::MatchRichRings(const TClonesArray* richRings, const TClon
       ringMatch->SetNofTrueHits(0);
       ringMatch->SetNofWrongHits(0);
     }
-
   }  // Ring loop
 }
 
+vector<CbmLink> CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan, const CbmRichHit* hit,
+                                                                CbmMCDataArray* richPoints, CbmMCDataArray* mcTracks)
+{
+  vector<CbmLink> result;
+  if (!hit) return result;
+  Int_t digiIndex = hit->GetRefId();
+  if (digiIndex < 0) return result;
+  const CbmRichDigi* digi = digiMan->Get<CbmRichDigi>(digiIndex);
+  if (!digi) return result;
+  const CbmMatch* digiMatch = digiMan->GetMatch(ECbmModuleId::kRich, digiIndex);
+  if (!digiMatch) return result;
+
+  vector<CbmLink> links = digiMatch->GetLinks();
+  for (const auto& link : links) {
+    Int_t pointId = link.GetIndex();
+    if (pointId < 0) continue;  // noise signal from digitizer
+    const CbmRichPoint* point = static_cast<const CbmRichPoint*>(richPoints->Get(link));
+    if (!point) continue;
+    Int_t mcTrackId = point->GetTrackID();
+    if (mcTrackId < 0) continue;
+    const CbmMCTrack* mcTrack =
+      static_cast<const CbmMCTrack*>(mcTracks->Get(link.GetFile(), link.GetEntry(), mcTrackId));
+    if (!mcTrack) continue;
+    if (mcTrack->GetPdgCode() != 50000050) continue;  // select only Cherenkov photons
+    Int_t motherId = mcTrack->GetMotherId();
+    // several photons can have same mother track
+    // count only unique motherIds
+    CbmLink val(1., motherId, link.GetEntry(), link.GetFile());
+    if (std::find(result.begin(), result.end(), val) == result.end()) result.push_back(val);
+  }
+
+  return result;
+}
 
 vector<pair<Int_t, Int_t>> CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan,
                                                                            const CbmRichHit* hit,
diff --git a/core/base/CbmMatchRecoToMC.h b/core/base/CbmMatchRecoToMC.h
index 9ab07054aa0f4d3a2c7719828f3758e07303e34a..6625cec6fa1f6ee302ee8ed4d4a3e0ef30c93919 100644
--- a/core/base/CbmMatchRecoToMC.h
+++ b/core/base/CbmMatchRecoToMC.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2021 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2013-2023 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev [committer], Volker Friese */
 
@@ -30,7 +30,7 @@ class CbmRichHit;
 class TClonesArray;
 
 class CbmMatchRecoToMC : public FairTask {
-public:
+ public:
   /**
     * \brief Constructor.
     */
@@ -56,7 +56,7 @@ public:
      */
   virtual void Finish();
 
-private:
+ private:
   /**
      * \brief Read and create data branches.
      */
@@ -117,17 +117,27 @@ private:
   void MatchRichRings(const TClonesArray* richRings, const TClonesArray* richHits, CbmMCDataArray* richMcPoints,
                       CbmMCDataArray* mcTracks, TClonesArray* ringMatches);
 
-public:
+ public:
   /**
-     * \brief Return McTrack Ids for RICH hit
-     * C++11 efficient way to return vector
-     */
-  static std::vector<std::pair<Int_t, Int_t>>
+    * \brief Get CbmLinks of Mother MC Tracks for RICH hit
+    */
+  static std::vector<CbmLink> GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan, const CbmRichHit* hit,
+                                                            CbmMCDataArray* richPoints, CbmMCDataArray* mcTracks);
+  /**
+    * \brief Get [EventId, MCTrackId] pair of Mother MC Tracks for RICH hit.
+    * This matching is only for TimeBased simulation
+    */
+  [[deprecated]] static std::vector<std::pair<Int_t, Int_t>>
   GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan, const CbmRichHit* hit, CbmMCDataArray* richPoints,
                                 CbmMCDataArray* mcTracks, Int_t eventNumber);
 
-  static std::vector<Int_t> GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan, const CbmRichHit* hit,
-                                                          const TClonesArray* richPoints, const TClonesArray* mcTracks);
+  /**
+    * \brief Get MCTrackId of Mother MC Tracks for RICH hit.
+    * This matching is only for EventBased simulation
+    */
+  [[deprecated]] static std::vector<Int_t> GetMcTrackMotherIdsForRichHit(CbmDigiManager* digiMan, const CbmRichHit* hit,
+                                                                         const TClonesArray* richPoints,
+                                                                         const TClonesArray* mcTracks);
 
   /**
    ** \brief  Suppresses cluster and hit matching procedures
@@ -139,11 +149,11 @@ public:
    **/
   void SuppressHitReMatching() { fbSuppressHitReMatching = true; }
 
-private:
+ private:
   static Int_t fEventNumber;
 
-  Bool_t fIsMvdActive       = kTRUE;  // is the Mvd module active
-  Bool_t fbDigiExpUsed      = kTRUE;  // Usage of CbmTofDigiExp instead of CbmTofDigi
+  Bool_t fIsMvdActive          = kTRUE;  // is the Mvd module active
+  Bool_t fbDigiExpUsed         = kTRUE;  // Usage of CbmTofDigiExp instead of CbmTofDigi
   bool fbSuppressHitReMatching = false;  // Suppression of MC->hit matching, if the matches are already there
 
   CbmMCDataArray* fMCTracks    = nullptr;  //! Monte-Carlo tracks
@@ -169,7 +179,7 @@ private:
   CbmMCDataArray* fRichMcPoints   = nullptr;  //! MC points [in]
   TClonesArray* fRichHits         = nullptr;  //! Hits [in]
   TClonesArray* fRichRings        = nullptr;  //! Rings [in]
-  TClonesArray* fRichTrackMatches = nullptr;  //! [out]
+  TClonesArray* fRichTrackMatches = nullptr;  //! Match Ring -> MC track [out]
 
   // MUCH
   CbmMCDataArray* fMuchPoints        = nullptr;  //! MC points [in]
diff --git a/core/detectors/rich/utils/CbmRichUtil.cxx b/core/detectors/rich/utils/CbmRichUtil.cxx
index a5357e1280283b356ce21a864a1243febe536e99..454dda8eea1a6e9b368502b04606893800a61a29 100644
--- a/core/detectors/rich/utils/CbmRichUtil.cxx
+++ b/core/detectors/rich/utils/CbmRichUtil.cxx
@@ -6,6 +6,7 @@
 
 #include "CbmDigiManager.h"
 #include "CbmGlobalTrack.h"
+#include "CbmLink.h"
 #include "CbmMCDataArray.h"
 #include "CbmMatchRecoToMC.h"
 #include "CbmRichDetectorData.h"
@@ -14,36 +15,12 @@
 #include "CbmRichGeoManager.h"
 #include "CbmRichHit.h"
 #include "CbmRichRing.h"
+#include "TClonesArray.h"
 
 #include <FairRootManager.h>
 
-#include "TClonesArray.h"
-
 using namespace std;
 
-map<pair<int, int>, int> CbmRichUtil::CreateNofHitsInRingMap(TClonesArray* richHits, CbmMCDataArray* richPoints,
-                                                             CbmMCDataArray* mcTracks, CbmDigiManager* digiMan)
-{
-  map<pair<int, int>, int> nofHitsInRingMap;
-  int nofRichHits = richHits->GetEntriesFast();
-  for (int iHit = 0; iHit < nofRichHits; iHit++) {
-    const CbmRichHit* hit = static_cast<CbmRichHit*>(richHits->At(iHit));
-    if (hit == nullptr || hit->GetRefId() < 0) continue;
-    const CbmRichDigi* digi = digiMan->Get<CbmRichDigi>(hit->GetRefId());
-    if (digi == nullptr) continue;
-    const CbmMatch* digiMatch = digiMan->GetMatch(ECbmModuleId::kRich, hit->GetRefId());
-    if (digiMatch == nullptr) continue;
-    int eventId = digiMatch->GetMatchedLink().GetEntry();
-
-    vector<pair<int, int>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(digiMan, hit, richPoints, mcTracks, eventId);
-    for (size_t i = 0; i < motherIds.size(); i++) {
-      nofHitsInRingMap[motherIds[i]]++;
-    }
-  }
-  return nofHitsInRingMap;
-}
-
 double CbmRichUtil::GetRingTrackDistance(Int_t globalTrackId) { return GetRingTrackDistanceImpl(globalTrackId)[0]; }
 
 double CbmRichUtil::GetRingTrackDistanceX(Int_t globalTrackId) { return GetRingTrackDistanceImpl(globalTrackId)[1]; }
diff --git a/core/detectors/rich/utils/CbmRichUtil.h b/core/detectors/rich/utils/CbmRichUtil.h
index 2ec2878a4ef1c0b6ab66460ac2ad1f317afb924b..7f9199c42bb89c0e465e1f978929a57aa323314b 100644
--- a/core/detectors/rich/utils/CbmRichUtil.h
+++ b/core/detectors/rich/utils/CbmRichUtil.h
@@ -14,6 +14,7 @@ class CbmDigiManager;
 class TClonesArray;
 class CbmMCDataArray;
 class TH2D;
+class CbmLink;
 
 class CbmRichUtil {
 
@@ -27,9 +28,6 @@ public:
   static std::vector<double> GetPmtHistYbins();
   static std::vector<double> GetPmtHistBins(bool isX);
 
-  static std::map<std::pair<int, int>, int> CreateNofHitsInRingMap(TClonesArray* richHits, CbmMCDataArray* richPoints,
-                                                                   CbmMCDataArray* mcTracks, CbmDigiManager* digiMan);
-
   static uint16_t GetDirichId(int Address) { return ((Address >> 16) & 0xFFFF); }
 
   static uint16_t GetDirichChannel(int Address) { return (Address & 0xFFFF); }
diff --git a/reco/detectors/rich/CMakeLists.txt b/reco/detectors/rich/CMakeLists.txt
index 7b3c900478f889094e6fd994bcbd63a22ea473a4..5c1eed784454e8a59ecd1036ec234b62a08fedad 100644
--- a/reco/detectors/rich/CMakeLists.txt
+++ b/reco/detectors/rich/CMakeLists.txt
@@ -35,7 +35,6 @@ set(SRCS
   qa/CbmRichUrqmdTest.cxx
   qa/CbmRichGeoTestOpt.cxx
   qa/CbmRichRecoQa.cxx
-  qa/CbmL1RichRingQa.cxx
   qa/CbmRichDigiQa.cxx
 
   unpack/CbmRichUnpackAlgo.cxx
diff --git a/reco/detectors/rich/CbmRichRecoLinkDef.h b/reco/detectors/rich/CbmRichRecoLinkDef.h
index 8423c69103f74b8e3b82ab0ce906741b836e0a95..a52374be46d23dcb686cbd7380e531f24cd67f5c 100644
--- a/reco/detectors/rich/CbmRichRecoLinkDef.h
+++ b/reco/detectors/rich/CbmRichRecoLinkDef.h
@@ -35,7 +35,6 @@
 #pragma link C++ class CbmRichRingFitterQa + ;
 #pragma link C++ class CbmRichRecoQa + ;
 #pragma link C++ class CbmRichRecoTbQa + ;
-#pragma link C++ class CbmL1RichRingQa + ;
 #pragma link C++ class CbmRichDigiQa + ;
 
 //unpack
diff --git a/reco/detectors/rich/finder/CbmRichRingFinderIdeal.cxx b/reco/detectors/rich/finder/CbmRichRingFinderIdeal.cxx
index 88f39ca10cfce95d27725b3faff76ae577580e3a..883f5f20955e2296026807dcf492365f8a2e34c8 100644
--- a/reco/detectors/rich/finder/CbmRichRingFinderIdeal.cxx
+++ b/reco/detectors/rich/finder/CbmRichRingFinderIdeal.cxx
@@ -44,6 +44,10 @@ CbmRichRingFinderIdeal::~CbmRichRingFinderIdeal() {}
 
 void CbmRichRingFinderIdeal::Init()
 {
+  LOG(fatal) << "CbmRichRingFinderIdeal::Init(): Ideal ringfinder is currently disabled. Will be reimplemented soon, "
+                "supporting time-based mode and mutiple MC input files. Also hits from the same mother particle in 2 "
+                "different cameras will be taken care of.";
+
   FairRootManager* manager = FairRootManager::Instance();
   if (nullptr == manager) LOG(fatal) << "CbmRichRingFinderIdeal::Init(): FairRootManager is nullptr.";
 
@@ -66,79 +70,82 @@ void CbmRichRingFinderIdeal::Init()
   if (fEventList == nullptr) LOG(fatal) << "CbmRichRingFinderIdeal::Init(): No MCEventList.";
 }
 
-Int_t CbmRichRingFinderIdeal::DoFind(CbmEvent* event, TClonesArray* hitArray, TClonesArray* /*projArray*/,
-                                     TClonesArray* ringArray)
+Int_t CbmRichRingFinderIdeal::DoFind(CbmEvent* /* event */, TClonesArray* /* hitArray */, TClonesArray* /*projArray*/,
+                                     TClonesArray* /* ringArray */)
 {
-
-  if (event != nullptr) {
-    LOG(fatal) << "CbmRichRingFinderIdeal::DoFind(): CbmEvent is not nullptr. "
-                  "This class does not support time-based mode. Please switch to event-by-event mode.";
-  }
-
-  if (hitArray == nullptr) {
-    LOG(error) << "CbmRichRingFinderIdeal::DoFind(), hitArray is nullptr.";
-    return -1;
-  }
-
-  if (ringArray == nullptr) {
-    LOG(error) << "CbmRichRingFinderIdeal::DoFind(): ringArray is nullptr.";
-    return -1;
-  }
-
-  // Create STL map from MCtrack index to number of valid RichHits
-  map<pair<Int_t, Int_t>, Int_t> hitMap;
-  Int_t nofRichHits = hitArray->GetEntriesFast();
-  for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
-    const CbmRichHit* richHit = static_cast<CbmRichHit*>(hitArray->At(iHit));
-    if (richHit == nullptr) continue;
-    Int_t eventId = GetEventIdForRichHit(richHit);
-    vector<pair<Int_t, Int_t>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, richHit, fRichPoints, fMcTracks, eventId);
-    for (UInt_t i = 0; i < motherIds.size(); i++) {
-      hitMap[motherIds[i]]++;
-    }
-  }
-
-  // Create STL map from MCTrack index to RichRing index
-  map<pair<Int_t, Int_t>, Int_t> ringMap;
-  Int_t nofRings  = 0;
-  Int_t nofEvents = fEventList->GetNofEvents();
-  for (Int_t iE = 0; iE < nofEvents; iE++) {
-    Int_t fileId  = fEventList->GetFileIdByIndex(iE);
-    Int_t eventId = fEventList->GetEventIdByIndex(iE);
-
-    // Create RichRings for McTracks
-    Int_t nofMcTracks = fMcTracks->Size(fileId, eventId);
-    for (Int_t iT = 0; iT < nofMcTracks; iT++) {
-      const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, eventId, iT));
-      if (mcTrack == nullptr) continue;
-      pair<Int_t, Int_t> val = std::make_pair(eventId, iT);
-      if (hitMap[val] <= 0) continue;
-      new ((*ringArray)[nofRings]) CbmRichRing();
-      ringMap[val] = nofRings++;
-    }
-  }
-
-  // Loop over RichHits. Get corresponding MCPoint and MCTrack index
-  for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
-    const CbmRichHit* richHit = static_cast<CbmRichHit*>(hitArray->At(iHit));
-    if (richHit == nullptr) continue;
-    Int_t eventId = GetEventIdForRichHit(richHit);
-
-    vector<pair<Int_t, Int_t>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, richHit, fRichPoints, fMcTracks, eventId);
-
-    for (UInt_t i = 0; i < motherIds.size(); i++) {
-      if (ringMap.find(motherIds[i]) == ringMap.end()) continue;
-      Int_t ringIndex   = ringMap[motherIds[i]];
-      CbmRichRing* ring = (CbmRichRing*) ringArray->At(ringIndex);
-      if (ring == nullptr) continue;
-
-      ring->AddHit(iHit);  // attach the hit to the ring
-    }
-  }
-
-  return nofRings;
+  return 0;  // FIXME: Ideal Rich Ring Finder needs to be reimplemented
+  // This will be done soon. Supporting time-based mode and mutiple MC input files.
+  // Also hits from the same mother particle in 2 different cameras will be taken care of.
+
+  // if (event != nullptr) {
+  //   LOG(fatal) << "CbmRichRingFinderIdeal::DoFind(): CbmEvent is not nullptr. "
+  //                 "This class does not support time-based mode. Please switch to event-by-event mode.";
+  // }
+
+  // if (hitArray == nullptr) {
+  //   LOG(error) << "CbmRichRingFinderIdeal::DoFind(), hitArray is nullptr.";
+  //   return -1;
+  // }
+
+  // if (ringArray == nullptr) {
+  //   LOG(error) << "CbmRichRingFinderIdeal::DoFind(): ringArray is nullptr.";
+  //   return -1;
+  // }
+
+  // // Create STL map from MCtrack index to number of valid RichHits
+  // map<pair<Int_t, Int_t>, Int_t> hitMap;
+  // Int_t nofRichHits = hitArray->GetEntriesFast();
+  // for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
+  //   const CbmRichHit* richHit = static_cast<CbmRichHit*>(hitArray->At(iHit));
+  //   if (richHit == nullptr) continue;
+  //   Int_t eventId = GetEventIdForRichHit(richHit);
+  //   vector<pair<Int_t, Int_t>> motherIds =
+  //     CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, richHit, fRichPoints, fMcTracks, eventId);
+  //   for (UInt_t i = 0; i < motherIds.size(); i++) {
+  //     hitMap[motherIds[i]]++;
+  //   }
+  // }
+
+  // // Create STL map from MCTrack index to RichRing index
+  // map<pair<Int_t, Int_t>, Int_t> ringMap;
+  // Int_t nofRings  = 0;
+  // Int_t nofEvents = fEventList->GetNofEvents();
+  // for (Int_t iE = 0; iE < nofEvents; iE++) {
+  //   Int_t fileId  = fEventList->GetFileIdByIndex(iE);
+  //   Int_t eventId = fEventList->GetEventIdByIndex(iE);
+
+  //   // Create RichRings for McTracks
+  //   Int_t nofMcTracks = fMcTracks->Size(fileId, eventId);
+  //   for (Int_t iT = 0; iT < nofMcTracks; iT++) {
+  //     const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, eventId, iT));
+  //     if (mcTrack == nullptr) continue;
+  //     pair<Int_t, Int_t> val = std::make_pair(eventId, iT);
+  //     if (hitMap[val] <= 0) continue;
+  //     new ((*ringArray)[nofRings]) CbmRichRing();
+  //     ringMap[val] = nofRings++;
+  //   }
+  // }
+
+  // // Loop over RichHits. Get corresponding MCPoint and MCTrack index
+  // for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
+  //   const CbmRichHit* richHit = static_cast<CbmRichHit*>(hitArray->At(iHit));
+  //   if (richHit == nullptr) continue;
+  //   Int_t eventId = GetEventIdForRichHit(richHit);
+
+  //   vector<pair<Int_t, Int_t>> motherIds =
+  //     CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, richHit, fRichPoints, fMcTracks, eventId);
+
+  //   for (UInt_t i = 0; i < motherIds.size(); i++) {
+  //     if (ringMap.find(motherIds[i]) == ringMap.end()) continue;
+  //     Int_t ringIndex   = ringMap[motherIds[i]];
+  //     CbmRichRing* ring = (CbmRichRing*) ringArray->At(ringIndex);
+  //     if (ring == nullptr) continue;
+
+  //     ring->AddHit(iHit);  // attach the hit to the ring
+  //   }
+  // }
+
+  // return nofRings;
 }
 
 
diff --git a/reco/detectors/rich/qa/CbmRichRecoQa.cxx b/reco/detectors/rich/qa/CbmRichRecoQa.cxx
index f6d4eabf2c275fcdcbfe4eb95b2a6ffc2744dc37..71a791b48a5643bdbf0ea9621ed2908cd4112b89 100644
--- a/reco/detectors/rich/qa/CbmRichRecoQa.cxx
+++ b/reco/detectors/rich/qa/CbmRichRecoQa.cxx
@@ -1,6 +1,6 @@
-/* Copyright (C) 2016-2021 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2016-2024 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Semen Lebedev, Andrey Lebedev [committer] */
+   Authors: Semen Lebedev, Andrey Lebedev [committer], Martin Beyer */
 
 #include "CbmRichRecoQa.h"
 
@@ -140,11 +140,10 @@ void CbmRichRecoQa::FillRichRingNofHits()
   for (int iHit = 0; iHit < nofRichHits; iHit++) {
     const CbmRichHit* hit = static_cast<CbmRichHit*>(fRichHits->At(iHit));
     if (nullptr == hit) continue;
-    vector<pair<int, int>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMcTracks, fEventNum);
+    vector<CbmLink> motherIds = CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMcTracks);
 
-    for (size_t i = 0; i < motherIds.size(); i++) {
-      fNofHitsInRingMap[motherIds[i]]++;
+    for (const auto& motherId : motherIds) {
+      fNofHitsInRingMap[motherId]++;
     }
   }
 }
@@ -160,9 +159,9 @@ void CbmRichRecoQa::RingTrackMismatchSource()
     int nMcTracks = fMcTracks->Size(fileId, eventId);
     for (int i = 0; i < nMcTracks; i++) {
       //At least one hit in RICH
-      pair<int, int> val = std::make_pair(eventId, i);
+      CbmLink val(1., i, eventId, fileId);
       if (fNofHitsInRingMap[val] < 1) continue;
-      const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, eventId, i));
+      const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(val));
       if (IsMcPrimaryElectron(mcTrack)) {
         fHM->H1("fhMismatchSrc")->Fill(0);  // MC
         fHM->H1("fhMismatchSrcMomMc")->Fill(mcTrack->GetP());
@@ -178,17 +177,15 @@ void CbmRichRecoQa::RingTrackMismatchSource()
     if (stsId < 0) continue;
     const CbmTrackMatchNew* stsTrackMatch = static_cast<const CbmTrackMatchNew*>(fStsTrackMatches->At(stsId));
     if (stsTrackMatch == nullptr) continue;
-    int stsMcTrackId          = stsTrackMatch->GetMatchedLink().GetIndex();
-    int stsMcEventId          = stsTrackMatch->GetMatchedLink().GetEntry();
-    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(0, stsMcEventId, stsMcTrackId));
+    auto stsMatchedLink       = stsTrackMatch->GetMatchedLink();
+    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(stsMatchedLink));
     if (!IsMcPrimaryElectron(mcTrack)) continue;
     double mom = mcTrack->GetP();
     //STS
     fHM->H1("fhMismatchSrc")->Fill(1);
     fHM->H1("fhMismatchSrcMomSts")->Fill(mom);
 
-    pair<int, int> val = std::make_pair(stsMcEventId, stsMcTrackId);
-    if (fNofHitsInRingMap[val] >= 7) {
+    if (fNofHitsInRingMap[stsMatchedLink] >= 7) {
       //Sts-AccRich
       fHM->H1("fhMismatchSrc")->Fill(2);
       fHM->H1("fhMismatchSrcMomStsAccRich")->Fill(mcTrack->GetP());
@@ -199,8 +196,8 @@ void CbmRichRecoQa::RingTrackMismatchSource()
     if (richId < 0) {
       fHM->H1("fhMismatchSrc")->Fill(5);  //STS-noRICH
       fHM->H1("fhMismatchSrcMomStsNoRich")->Fill(mom);
-      bool ringFound   = WasRingFound(stsMcTrackId);
-      bool ringMatched = WasRingMatched(stsMcTrackId);
+      bool ringFound   = WasRingFound(stsMatchedLink);
+      bool ringMatched = WasRingMatched(stsMatchedLink);
       bool hasProj     = HasRichProjection(stsId);
       if (ringFound) {
         fHM->H1("fhMismatchSrc")->Fill(6);  //STS-NoRich RF
@@ -228,23 +225,23 @@ void CbmRichRecoQa::RingTrackMismatchSource()
       fHM->H1("fhMismatchSrcMomStsRich")->Fill(mom);
       const CbmTrackMatchNew* richRingMatch = static_cast<const CbmTrackMatchNew*>(fRichRingMatches->At(richId));
       if (richRingMatch == nullptr) continue;
-      int richMcTrackId       = richRingMatch->GetMatchedLink().GetIndex();
+      auto richMcTrackLink    = richRingMatch->GetMatchedLink();
       const CbmRichRing* ring = static_cast<const CbmRichRing*>(fRichRings->At(richId));
       if (nullptr == ring) continue;
 
-      if (stsMcTrackId == richMcTrackId) {
+      if (stsMatchedLink == richMcTrackLink) {
         fHM->H1("fhMismatchSrc")->Fill(4);  //STS-RICH true
         fHM->H1("fhMismatchSrcMomStsRichTrue")->Fill(mom);
       }
       else {
         fHM->H1("fhMismatchSrc")->Fill(10);  //STS-RICH wrong
         fHM->H1("fhMismatchSrcMomStsRichWrong")->Fill(mom);
-        if (WasRingFound(stsMcTrackId)) {
+        if (WasRingFound(stsMatchedLink)) {
           fHM->H1("fhMismatchSrc")->Fill(11);  //STS-RICH wrong RF
           fHM->H1("fhMismatchSrcMomStsRichWrongRF")->Fill(mom);
         }
 
-        if (WasRingFound(stsMcTrackId)) {
+        if (WasRingFound(stsMatchedLink)) {
           fHM->H1("fhMismatchSrc")->Fill(12);  //STS-RICH wrong RM
           fHM->H1("fhMismatchSrcMomStsRichWrongRM")->Fill(mom);
         }
@@ -253,7 +250,7 @@ void CbmRichRecoQa::RingTrackMismatchSource()
   }
 }
 
-bool CbmRichRecoQa::WasRingFound(int mcTrackId)
+bool CbmRichRecoQa::WasRingFound(const CbmLink& mcTrackLink)
 {
   int nofRings = fRichRings->GetEntriesFast();
   for (int iR = 0; iR < nofRings; iR++) {
@@ -261,13 +258,13 @@ bool CbmRichRecoQa::WasRingFound(int mcTrackId)
     if (ring == nullptr) continue;
     const CbmTrackMatchNew* richRingMatch = static_cast<const CbmTrackMatchNew*>(fRichRingMatches->At(iR));
     if (richRingMatch == nullptr) continue;
-    int richMcTrackId = richRingMatch->GetMatchedLink().GetIndex();
-    if (richMcTrackId == mcTrackId) return true;
+    auto richMcTrackLink = richRingMatch->GetMatchedLink();
+    if (richMcTrackLink == mcTrackLink) return true;
   }
   return false;
 }
 
-bool CbmRichRecoQa::WasRingMatched(int mcTrackId)
+bool CbmRichRecoQa::WasRingMatched(const CbmLink& mcTrackLink)
 {
   int nofGlobalTracks = fGlobalTracks->GetEntriesFast();
   for (int iTrack = 0; iTrack < nofGlobalTracks; iTrack++) {
@@ -277,8 +274,10 @@ bool CbmRichRecoQa::WasRingMatched(int mcTrackId)
     if (richId < 0) continue;
     const CbmTrackMatchNew* richRingMatch = static_cast<const CbmTrackMatchNew*>(fRichRingMatches->At(richId));
     if (richRingMatch == nullptr) continue;
-    int richMcTrackId = richRingMatch->GetMatchedLink().GetIndex();
-    if (richMcTrackId == mcTrackId) { return true; }
+    auto richMcTrackLink = richRingMatch->GetMatchedLink();
+    if (richMcTrackLink == mcTrackLink) {
+      return true;
+    }
   }
 
   return false;
@@ -308,12 +307,11 @@ void CbmRichRecoQa::FillRingTrackDistance()
 
     const CbmTrackMatchNew* stsTrackMatch = static_cast<const CbmTrackMatchNew*>(fStsTrackMatches->At(stsId));
     if (stsTrackMatch == nullptr) continue;
-    int stsMcTrackId = stsTrackMatch->GetMatchedLink().GetIndex();
-    int stsMcEventId = stsTrackMatch->GetMatchedLink().GetEntry();
+    auto stsMcMatchedLink = stsTrackMatch->GetMatchedLink();
 
     const CbmTrackMatchNew* richRingMatch = static_cast<const CbmTrackMatchNew*>(fRichRingMatches->At(richId));
     if (richRingMatch == nullptr) continue;
-    int richMcTrackId       = richRingMatch->GetMatchedLink().GetIndex();
+    auto richMcTrackLink    = richRingMatch->GetMatchedLink();
     const CbmRichRing* ring = static_cast<const CbmRichRing*>(fRichRings->At(richId));
     if (nullptr == ring) continue;
 
@@ -322,7 +320,7 @@ void CbmRichRecoQa::FillRingTrackDistance()
     double yc         = ring->GetCenterY();
     int nofHits       = ring->GetNofHits();
 
-    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(0, stsMcEventId, stsMcTrackId));
+    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(stsMcMatchedLink));
     if (mcTrack == nullptr) continue;
     double mom = mcTrack->GetP();
     int charge = mcTrack->GetCharge();
@@ -341,7 +339,7 @@ void CbmRichRecoQa::FillRingTrackDistance()
       if (t == "PrimelPlus" && isEl && charge > 0) isGood = true;
       if (t == "PrimelMinus" && isEl && charge < 0) isGood = true;
       if (!isGood) continue;
-      if (stsMcTrackId == richMcTrackId) {
+      if (stsMcMatchedLink == richMcTrackLink) {
         fHM->H2("fhRTDistVsMomTruematch" + t)->Fill(mom, rtDistance);
         fHM->H3("fhRTDistVsXYTruematch" + t)->Fill(xc, yc, rtDistance);
         fHM->H2("fhRTDistVsXTruematch" + t)->Fill(xc, rtDistance);
@@ -550,15 +548,17 @@ bool CbmRichRecoQa::IsMcPion(const CbmMCTrack* mctrack)
 
 void CbmRichRecoQa::Finish()
 {
-  DrawHist();
-  fHM->SaveCanvasToImage(fOutputDir);
-
   TDirectory* oldir = gDirectory;
   TFile* outFile    = FairRootManager::Instance()->GetOutFile();
   if (outFile != nullptr) {
-    outFile->cd();
+    outFile->mkdir(GetName());
+    outFile->cd(GetName());
     fHM->WriteToFile();
   }
+
+  DrawHist();
+  fHM->SaveCanvasToImage(fOutputDir);
+
   gDirectory->cd(oldir->GetPath());
 }
 
diff --git a/reco/detectors/rich/qa/CbmRichRecoQa.h b/reco/detectors/rich/qa/CbmRichRecoQa.h
index 622973c2d16c8d92bcd36d91dbf37edb46282a87..4e5a731d1f413c40f97f1cab5906d107c5f7b4c1 100644
--- a/reco/detectors/rich/qa/CbmRichRecoQa.h
+++ b/reco/detectors/rich/qa/CbmRichRecoQa.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2016-2020 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2016-2024 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Andrey Lebedev [committer], Semen Lebedev */
+   Authors: Andrey Lebedev [committer], Semen Lebedev, Martin Beyer */
 
 #ifndef CBM_RICH_RECO_QA
 #define CBM_RICH_RECO_QA
@@ -18,6 +18,7 @@ class TH3;
 class CbmMCTrack;
 class CbmDigiManager;
 class CbmMCEventList;
+class CbmLink;
 
 #include <map>
 #include <vector>
@@ -104,12 +105,12 @@ private:
   /*
      * \brief Check that the ring with an input MCTrackId was found
      */
-  bool WasRingFound(int mcTrackId);
+  bool WasRingFound(const CbmLink& mcTrackLink);
 
   /*
      * \brief Check that the ring was matched with some global track
      */
-  bool WasRingMatched(int mcTrackId);
+  bool WasRingMatched(const CbmLink& mcTrackLink);
 
   /*
      * \brief Check that the Sts track projection was matched with RICH ring
@@ -152,7 +153,7 @@ private:
   CbmMCEventList* fEventList     = nullptr;
 
   // Number of hits in the MC RICH ring
-  std::map<std::pair<int, int>, int> fNofHitsInRingMap;
+  std::map<CbmLink, int> fNofHitsInRingMap;
 
   ClassDef(CbmRichRecoQa, 1)
 };
diff --git a/reco/detectors/rich/qa/CbmRichRecoTbQa.cxx b/reco/detectors/rich/qa/CbmRichRecoTbQa.cxx
index 050ca67841f794fd989f650ce1c0f503ca64eaf5..4bb4cd840bfac81e4aecf7bc1c1a09ae50088b2d 100644
--- a/reco/detectors/rich/qa/CbmRichRecoTbQa.cxx
+++ b/reco/detectors/rich/qa/CbmRichRecoTbQa.cxx
@@ -293,15 +293,14 @@ Int_t CbmRichRecoTbQa::GetNofPrimaryMcTracks(Int_t iEv)
 
 void CbmRichRecoTbQa::RingRecoEfficiency()
 {
-  map<pair<Int_t, Int_t>, Int_t> nofHitsInRing;
+  map<CbmLink, Int_t> nofHitsInRing;
   Int_t nofRichHits = fRichHits->GetEntriesFast();
   for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
     const CbmRichHit* hit = static_cast<const CbmRichHit*>(fRichHits->At(iHit));
     if (nullptr == hit) continue;
-    vector<pair<Int_t, Int_t>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMCTracks, -1);
-    for (UInt_t i = 0; i < motherIds.size(); i++) {
-      nofHitsInRing[motherIds[i]]++;
+    vector<CbmLink> motherIds = CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMCTracks);
+    for (const auto& motherId : motherIds) {
+      nofHitsInRing[motherId]++;
     }
   }
 
@@ -310,8 +309,8 @@ void CbmRichRecoTbQa::RingRecoEfficiency()
     Int_t nofMcTracks     = fMCTracks->Size(fileId, iEv);
     Int_t nofPrimMcTracks = GetNofPrimaryMcTracks(iEv);
     for (Int_t j = 0; j < nofMcTracks; j++) {
-      const CbmMCTrack* track = static_cast<CbmMCTrack*>(fMCTracks->Get(fileId, iEv, j));
-      pair<Int_t, Int_t> val  = std::make_pair(iEv, j);
+      CbmLink val(1., j, iEv, fileId);
+      const CbmMCTrack* track = static_cast<CbmMCTrack*>(fMCTracks->Get(val));
       Int_t nofRichHitsInRing = nofHitsInRing[val];
       Double_t mom            = track->GetP();
       if (nofRichHitsInRing >= 7 && IsMcPrimaryElectron(track)) {
@@ -334,8 +333,7 @@ void CbmRichRecoTbQa::RingRecoEfficiency()
     const CbmMCTrack* track = static_cast<CbmMCTrack*>(
       fMCTracks->Get(fileId, richRingMatch->GetMatchedLink().GetEntry(), richRingMatch->GetMatchedLink().GetIndex()));
     Int_t nofPrimMcTracks = GetNofPrimaryMcTracks(richRingMatch->GetMatchedLink().GetEntry());
-    pair<Int_t, Int_t> val =
-      std::make_pair(richRingMatch->GetMatchedLink().GetEntry(), richRingMatch->GetMatchedLink().GetIndex());
+    auto val                = richRingMatch->GetMatchedLink();
     Int_t nofRichHitsInRing = nofHitsInRing[val];
     Double_t mom            = track->GetP();
     Bool_t isClone          = (std::find(fRecRings.begin(), fRecRings.end(), val) != fRecRings.end());
@@ -598,15 +596,18 @@ void CbmRichRecoTbQa::DrawTimeLog(const string& hMainName, Int_t nofLogEvents, b
 void CbmRichRecoTbQa::Finish()
 {
   ProcessMc();
-  DrawHist();
-  fHM->SaveCanvasToImage(fOutputDir);
 
   TDirectory* oldir = gDirectory;
   TFile* outFile    = FairRootManager::Instance()->GetOutFile();
   if (outFile != NULL) {
-    outFile->cd();
+    outFile->mkdir(GetName());
+    outFile->cd(GetName());
     fHM->WriteToFile();
   }
+
+  DrawHist();
+  fHM->SaveCanvasToImage(fOutputDir);
+
   gDirectory->cd(oldir->GetPath());
 }
 
diff --git a/reco/detectors/rich/qa/CbmRichRecoTbQa.h b/reco/detectors/rich/qa/CbmRichRecoTbQa.h
index ae894f11a62eef08a147c02d56a05ca639839ded..56bb4ddf0c36dba9e1e46fb677542627cdef11dd 100644
--- a/reco/detectors/rich/qa/CbmRichRecoTbQa.h
+++ b/reco/detectors/rich/qa/CbmRichRecoTbQa.h
@@ -13,6 +13,7 @@ class CbmRichPoint;
 class CbmMCTrack;
 class CbmMCEventList;
 class CbmDigiManager;
+class CbmLink;
 
 #include <map>
 #include <vector>
@@ -116,7 +117,7 @@ private:
   TClonesArray* fRichRingMatches;
   CbmMCEventList* fEventList;
 
-  vector<pair<Int_t, Int_t>> fRecRings;
+  vector<CbmLink> fRecRings;
 
   ClassDef(CbmRichRecoTbQa, 1)
 };
diff --git a/reco/detectors/rich/qa/CbmRichUrqmdTest.cxx b/reco/detectors/rich/qa/CbmRichUrqmdTest.cxx
index 75ff25a53b269168ff0c1f91ae29e6b0ecad4109..8a9c401646e453e44227b3fc11ff0c9ef6fe0247 100644
--- a/reco/detectors/rich/qa/CbmRichUrqmdTest.cxx
+++ b/reco/detectors/rich/qa/CbmRichUrqmdTest.cxx
@@ -1,6 +1,6 @@
-/* Copyright (C) 2012-2020 UGiessen/JINR-LIT, Giessen/Dubna
+/* Copyright (C) 2012-2024 UGiessen/JINR-LIT, Giessen/Dubna
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Semen Lebedev [committer], Andrey Lebedev */
+   Authors: Semen Lebedev [committer], Andrey Lebedev, Martin Beyer */
 
 #include "CbmRichUrqmdTest.h"
 
@@ -11,6 +11,7 @@
 #include "CbmMCDataManager.h"
 #include "CbmMCEventList.h"
 #include "CbmMCTrack.h"
+#include "CbmMatchRecoToMC.h"
 #include "CbmRichDetectorData.h"
 #include "CbmRichDigi.h"
 #include "CbmRichDigiMapManager.h"
@@ -22,15 +23,14 @@
 #include "CbmRichUtil.h"
 #include "CbmTrackMatchNew.h"
 #include "CbmUtils.h"
-
 #include "FairMCPoint.h"
 #include "FairTrackParam.h"
-
 #include "TCanvas.h"
 #include "TClonesArray.h"
 #include "TH1.h"
 #include "TH1D.h"
 #include "TStyle.h"
+
 #include <TFile.h>
 
 #include <iostream>
@@ -73,7 +73,7 @@ void CbmRichUrqmdTest::Exec(Option_t* /*option*/)
 
   cout << "CbmRichUrqmdTest, event No. " << fEventNum << endl;
 
-  fNofHitsInRingMap = CbmRichUtil::CreateNofHitsInRingMap(fRichHits, fRichPoints, fMcTracks, fDigiMan);
+  FillRichRingNofHits();
   NofRings();
   NofHitsAndPoints();
   NofProjections();
@@ -81,6 +81,21 @@ void CbmRichUrqmdTest::Exec(Option_t* /*option*/)
   PmtXYSource();
 }
 
+void CbmRichUrqmdTest::FillRichRingNofHits()
+{
+  fNofHitsInRingMap.clear();
+  int nofRichHits = fRichHits->GetEntriesFast();
+  for (int iHit = 0; iHit < nofRichHits; iHit++) {
+    const CbmRichHit* hit = static_cast<CbmRichHit*>(fRichHits->At(iHit));
+    if (nullptr == hit) continue;
+    vector<CbmLink> motherIds = CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMcTracks);
+
+    for (const auto& motherId : motherIds) {
+      fNofHitsInRingMap[motherId]++;
+    }
+  }
+}
+
 void CbmRichUrqmdTest::InitHistograms()
 {
   fHM = new CbmHistManager();
@@ -147,7 +162,6 @@ void CbmRichUrqmdTest::InitHistograms()
 
 void CbmRichUrqmdTest::NofRings()
 {
-  int fileId     = 0;
   int nofRings   = fRichRings->GetEntriesFast();
   int nRings1hit = 0, nRings7hits = 0;
   int nRingsPrim1hit = 0, nRingsPrim7hits = 0;
@@ -158,9 +172,8 @@ void CbmRichUrqmdTest::NofRings()
     const CbmTrackMatchNew* ringMatch = static_cast<CbmTrackMatchNew*>(fRichRingMatches->At(iR));
     if (ringMatch == nullptr) continue;
 
-    int mcEventId             = ringMatch->GetMatchedLink().GetEntry();
-    int mcTrackId             = ringMatch->GetMatchedLink().GetIndex();
-    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, mcEventId, mcTrackId));
+    auto matchedLink          = ringMatch->GetMatchedLink();
+    const CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMcTracks->Get(matchedLink));
     if (mcTrack == nullptr) continue;
     int motherId = mcTrack->GetMotherId();
     int pdgAbs   = std::abs(mcTrack->GetPdgCode());
@@ -184,7 +197,7 @@ void CbmRichUrqmdTest::NofRings()
     if (nofHits >= 1) {
       if (motherId != -1) {
         int motherPdg            = -1;
-        const CbmMCTrack* mother = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, mcEventId, motherId));
+        const CbmMCTrack* mother = static_cast<CbmMCTrack*>(fMcTracks->Get(matchedLink));
         if (mother != nullptr) motherPdg = mother->GetPdgCode();
         if (motherId != -1 && pdgAbs == 11 && motherPdg != 22) fHM->H1("fh_secel_mom")->Fill(mom);
 
@@ -364,9 +377,9 @@ void CbmRichUrqmdTest::Vertex()
     int nMcTracks = fMcTracks->Size(fileId, eventId);
     for (int i = 0; i < nMcTracks; i++) {
       //At least one hit in RICH
-      pair<int, int> val = std::make_pair(eventId, i);
+      CbmLink val(1., i, eventId, fileId);
       if (fNofHitsInRingMap[val] < 1) continue;
-      const CbmMCTrack* mctrack = static_cast<CbmMCTrack*>(fMcTracks->Get(fileId, eventId, i));
+      const CbmMCTrack* mctrack = static_cast<CbmMCTrack*>(fMcTracks->Get(val));
       TVector3 v;
       mctrack->GetStartVertex(v);
       fHM->H1("fh_vertex_z")->Fill(v.Z());
@@ -583,14 +596,17 @@ void CbmRichUrqmdTest::DrawHist()
 
 void CbmRichUrqmdTest::Finish()
 {
-  DrawHist();
-  fHM->SaveCanvasToImage(fOutputDir);
   TDirectory* oldir = gDirectory;
   TFile* outFile    = FairRootManager::Instance()->GetOutFile();
   if (outFile != nullptr) {
-    outFile->cd();
+    outFile->mkdir(GetName());
+    outFile->cd(GetName());
     fHM->WriteToFile();
   }
+
+  DrawHist();
+  fHM->SaveCanvasToImage(fOutputDir);
+
   gDirectory->cd(oldir->GetPath());
 }
 
diff --git a/reco/detectors/rich/qa/CbmRichUrqmdTest.h b/reco/detectors/rich/qa/CbmRichUrqmdTest.h
index 61332bfa80479ab56e7eb1f0cd3f98d9d4e06b04..be0e8fa4799edd82ddad7aba28675d73b1298312 100644
--- a/reco/detectors/rich/qa/CbmRichUrqmdTest.h
+++ b/reco/detectors/rich/qa/CbmRichUrqmdTest.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2012-2021 UGiessen/JINR-LIT, Giessen/Dubna
+/* Copyright (C) 2012-2024 UGiessen/JINR-LIT, Giessen/Dubna
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Andrey Lebedev, Semen Lebedev [committer] */
+   Authors: Andrey Lebedev, Semen Lebedev [committer], Martin Beyer */
 
 #ifndef CBM_RICH_URQMD_TEST
 #define CBM_RICH_URQMD_TEST
@@ -13,6 +13,7 @@ class CbmHistManager;
 class CbmMCDataArray;
 class CbmMCEventList;
 class CbmDigiManager;
+class CbmLink;
 
 #include <map>
 #include <vector>
@@ -71,7 +72,7 @@ private:
   int fEventNum   = 0;
   int fMinNofHits = 7;  // Min number of hits in ring for detector acceptance calculation.
 
-  std::map<std::pair<int, int>, int> fNofHitsInRingMap;  // Number of hits in the MC RICH ring
+  std::map<CbmLink, int> fNofHitsInRingMap;  // Number of hits in the MC RICH ring
 
   std::vector<std::pair<int, int>> fVertexZStsSlices;  // Slices (Zmin - Zmax) inside STS
 
@@ -80,6 +81,8 @@ private:
      */
   void InitHistograms();
 
+  void FillRichRingNofHits();
+
   /**
      * \brief
      */
diff --git a/reco/detectors/rich/qa/CbmL1RichRingQa.cxx b/reco/detectors/rich/qa/legacy/CbmL1RichRingQa.cxx
similarity index 98%
rename from reco/detectors/rich/qa/CbmL1RichRingQa.cxx
rename to reco/detectors/rich/qa/legacy/CbmL1RichRingQa.cxx
index 5502e7ef7e5b0e42d54eb59fce8d82a6d8b591dd..bd4a7c028e9015d3cec96be70dc11b97a4db12c5 100644
--- a/reco/detectors/rich/qa/CbmL1RichRingQa.cxx
+++ b/reco/detectors/rich/qa/legacy/CbmL1RichRingQa.cxx
@@ -10,10 +10,8 @@
 #include "CbmRichRing.h"
 #include "CbmRichRingFitterEllipseTau.h"
 #include "CbmRichRingLight.h"
-
 #include "FairRootManager.h"
 #include "FairTask.h"
-
 #include "TArc.h"
 #include "TClonesArray.h"
 #include "TEllipse.h"
@@ -28,13 +26,13 @@
 #include "TStyle.h"
 #include "TText.h"
 
+#include <cmath>
 #include <iostream>
 #include <list>
 #include <map>
 #include <sstream>
 #include <vector>
 
-#include <cmath>
 #include <ctype.h>
 #include <stdio.h>
 
@@ -213,7 +211,9 @@ InitStatus CbmL1RichRingQa::Init()
 
   // Get hit Array
   fHitArray = dynamic_cast<TClonesArray*>(ioman->GetObject("RichHit"));
-  if (!fHitArray) { cout << "-W- CbmL1RichRingQa::Init: No RichHit array!" << endl; }
+  if (!fHitArray) {
+    cout << "-W- CbmL1RichRingQa::Init: No RichHit array!" << endl;
+  }
 
   // Get RichRing Array
   fRingArray = dynamic_cast<TClonesArray*>(ioman->GetObject("RichRing"));
@@ -547,7 +547,9 @@ void CbmL1RichRingQa::Exec(Option_t* /*option*/)
 //End of Use Fitter EllipseTau to fit MC Rings
 #endif  //DRAW
     if (ring.r > 3. && ring.r < 7. && ring.NHits >= 7 /* && ring.P > 0.2 */) {
-      if (ring.NHits >= 15 && ring.primary) { ring.kind = 2; }
+      if (ring.NHits >= 15 && ring.primary) {
+        ring.kind = 2;
+      }
       else
         ring.kind = 1;
     }
@@ -603,7 +605,8 @@ void CbmL1RichRingQa::Exec(Option_t* /*option*/)
 
     TArc* MCDown = new TArc(ring.x, -ring.y, ring.r, 0, 360);
     MCDown->SetLineWidth(2);
-    if (ring.PDG == 11 || ring.PDG == -11) MCDown->SetLineColor(2);  //electron MC Ring
+    if (ring.PDG == 11 || ring.PDG == -11)
+      MCDown->SetLineColor(2);  //electron MC Ring
     else if (ring.PDG == 211 || ring.PDG == -211)
       MCDown->SetLineColor(28);  //pion MC Ring
     else
@@ -777,7 +780,8 @@ void CbmL1RichRingQa::Exec(Option_t* /*option*/)
         dist        = sqrt((r1->GetCenterX() - r2->GetCenterX()) * (r1->GetCenterX() - r2->GetCenterX())
                     + (r1->GetCenterY() - r2->GetCenterY()) * (r1->GetCenterY() - r2->GetCenterY()));
         double dr;
-        if (r1->GetRadius() >= r2->GetRadius()) dr = r1->GetRadius() - r2->GetRadius();
+        if (r1->GetRadius() >= r2->GetRadius())
+          dr = r1->GetRadius() - r2->GetRadius();
         else
           dr = r2->GetRadius() - r1->GetRadius();
         RadiusVsDistanceClone->Fill(dist, dr);
@@ -854,7 +858,8 @@ void CbmL1RichRingQa::Exec(Option_t* /*option*/)
       //       fl = NClone;
       NAllReco++;
       NClone += i->second.Reconstructed - 1;
-      if (ring.kind == 2) NRefReco++;
+      if (ring.kind == 2)
+        NRefReco++;
       else
         NExtraReco++;
     }
diff --git a/reco/detectors/rich/qa/CbmL1RichRingQa.h b/reco/detectors/rich/qa/legacy/CbmL1RichRingQa.h
similarity index 97%
rename from reco/detectors/rich/qa/CbmL1RichRingQa.h
rename to reco/detectors/rich/qa/legacy/CbmL1RichRingQa.h
index 68e8b554c6d203ba3f4dbc4a2741896b45438680..6abcc20af9f5ff06c68a6b2ffa597b38ff50942b 100644
--- a/reco/detectors/rich/qa/CbmL1RichRingQa.h
+++ b/reco/detectors/rich/qa/legacy/CbmL1RichRingQa.h
@@ -6,7 +6,6 @@
 #define CBML1RICHRINGQA_H
 
 #include "FairTask.h"
-
 #include "TArc.h"
 #include "TCanvas.h"
 #include "TGraph.h"
@@ -29,7 +28,7 @@
 class TClonesArray;
 
 class CbmL1RichRingQa : public FairTask {
-private:
+ private:
   CbmL1RichRingQa(const CbmL1RichRingQa&);
   CbmL1RichRingQa operator=(const CbmL1RichRingQa&);
   struct MCRing {
@@ -48,7 +47,7 @@ private:
       , Hits()
       , BestReco(0)
       , NHitsBestReco(0)
-      , NHitsBestvsNHitsMC(0) {};
+      , NHitsBestvsNHitsMC(0){};
     Int_t MCTrackID;
     bool primary;
     Double_t P;
@@ -77,7 +76,7 @@ private:
   TClonesArray* fMCTrackArray;  // Array of CbmMCTracks
   TClonesArray* fHitArray;      // Array of CbmRichHits
 
-private:
+ private:
   TH1F* Chi2Ghost;
   TH1F* Chi2Ref;
   TH1F* Chi2All;
@@ -107,7 +106,7 @@ private:
   TH2F* RadiusVsDistanceClone;
   TH2F* NHitsRecoVsNHitsMC;
 
-public:
+ public:
   /** Default constructor **/
 
   CbmL1RichRingQa(const char* name = "CbmL1RichRingQa", const char* title = "CbmL1RichRingQa", Int_t verbose = 1);
diff --git a/reco/detectors/rich/qa/CbmRichParallelQa.cxx b/reco/detectors/rich/qa/legacy/CbmRichParallelQa.cxx
similarity index 95%
rename from reco/detectors/rich/qa/CbmRichParallelQa.cxx
rename to reco/detectors/rich/qa/legacy/CbmRichParallelQa.cxx
index 3fa1bf56596a22d515f477f88b4ef2637b80942b..41e32c73285c5f259cbcb9a7b971ea1f6a54d17f 100644
--- a/reco/detectors/rich/qa/CbmRichParallelQa.cxx
+++ b/reco/detectors/rich/qa/legacy/CbmRichParallelQa.cxx
@@ -11,9 +11,7 @@
 #include "CbmRichParallelQa.h"
 
 #include "CbmRichHit.h"
-
 #include "FairRootManager.h"
-
 #include "tbb/parallel_for.h"
 #include "tbb/parallel_invoke.h"
 #include "tbb/spin_mutex.h"
@@ -35,9 +33,9 @@ map<int, int> threadNumberToCpuMap;  // let get cpuId by threadNumber (see threa
 spin_mutex mutex;
 
 class TMyObserver : public task_scheduler_observer {
-public:
+ public:
   void FInit();  // set cpu - thread correspondence
-protected:
+ protected:
   void on_scheduler_entry(bool Is_worker);  // run at begin of each thread execution
   void on_scheduler_exit(bool Is_worker);   // run at end of each thread execution
 };
@@ -102,7 +100,7 @@ class FinderTaskQa : public task {
   //CbmRichRingFinderHough* fHT;
   std::vector<std::vector<CbmRichHoughHit>> fData;
   // std::vector<CbmRichHoughHit> fData;
-public:
+ public:
   FinderTaskQa(CbmL1RichENNRingFinder* HTImpl, const std::vector<std::vector<CbmRichHoughHit>>& data)
   {
     fHT   = HTImpl;
@@ -140,13 +138,19 @@ InitStatus CbmRichParallelQa::Init()
   cout << "InitStatus CbmRichParallelQa::Init()" << endl;
 
   FairRootManager* ioman = FairRootManager::Instance();
-  if (NULL == ioman) { Fatal("CbmRichParallelQa::Init", "RootManager not instantised!"); }
+  if (NULL == ioman) {
+    Fatal("CbmRichParallelQa::Init", "RootManager not instantised!");
+  }
 
   fRichHits = (TClonesArray*) ioman->GetObject("RichHit");
-  if (NULL == fRichHits) { Fatal("CbmRichParallelQa::Init", "No RichHit array!"); }
+  if (NULL == fRichHits) {
+    Fatal("CbmRichParallelQa::Init", "No RichHit array!");
+  }
 
   fRichRings = (TClonesArray*) ioman->GetObject("RichRing");
-  if (NULL == fRichRings) { Fatal("CbmRichParallelQa::Init", "No RichRing array!"); }
+  if (NULL == fRichRings) {
+    Fatal("CbmRichParallelQa::Init", "No RichRing array!");
+  }
 
   for (int i = 0; i < kMAX_NOF_THREADS; i++) {
     fHT[i]->Init();
diff --git a/reco/detectors/rich/qa/CbmRichParallelQa.h b/reco/detectors/rich/qa/legacy/CbmRichParallelQa.h
similarity index 99%
rename from reco/detectors/rich/qa/CbmRichParallelQa.h
rename to reco/detectors/rich/qa/legacy/CbmRichParallelQa.h
index f9431d527270a776fbdcb1d52c38742a370465bf..e81c15c5ca69600362b3b3ff09d1d3aee206a166 100644
--- a/reco/detectors/rich/qa/CbmRichParallelQa.h
+++ b/reco/detectors/rich/qa/legacy/CbmRichParallelQa.h
@@ -14,7 +14,6 @@
 #include "CbmL1RichENNRingFinder.h"
 #include "CbmRichRing.h"
 #include "CbmRichRingFinderHough.h"
-
 #include "FairTask.h"
 
 #include <vector>
@@ -33,7 +32,7 @@ class CbmRichParallelQa : public FairTask {
   CbmL1RichENNRingFinder* fHT[kMAX_NOF_THREADS];
   std::vector<std::vector<CbmRichHoughHit>> fData;
 
-public:
+ public:
   CbmRichParallelQa();
 
   virtual ~CbmRichParallelQa();
diff --git a/reco/littrack/cbm/qa/mc/CbmLitMCTrackCreator.cxx b/reco/littrack/cbm/qa/mc/CbmLitMCTrackCreator.cxx
index 212668dd82c00a651df481c26d13844714f0c175..fa4cef5c5064fe828b269ca6813711308411779f 100644
--- a/reco/littrack/cbm/qa/mc/CbmLitMCTrackCreator.cxx
+++ b/reco/littrack/cbm/qa/mc/CbmLitMCTrackCreator.cxx
@@ -175,7 +175,7 @@ void CbmLitMCTrackCreator::AddPoints(ECbmModuleId detId, CbmMCDataArray* array,
   }
 }
 
-void CbmLitMCTrackCreator::AddRichHits(Int_t iEvent)
+void CbmLitMCTrackCreator::AddRichHits(Int_t /* iEvent */)
 {
   if (NULL == fRichHits) return;
   map<pair<Int_t, Int_t>, Int_t> nofHitsInRing;
@@ -183,10 +183,10 @@ void CbmLitMCTrackCreator::AddRichHits(Int_t iEvent)
   for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
     const CbmRichHit* hit = static_cast<const CbmRichHit*>(fRichHits->At(iHit));
     if (NULL == hit) continue;
-    vector<pair<Int_t, Int_t>> motherIds =
-      CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMCTracks, iEvent);
+    vector<CbmLink> motherIds = CbmMatchRecoToMC::GetMcTrackMotherIdsForRichHit(fDigiMan, hit, fRichPoints, fMCTracks);
     for (UInt_t i = 0; i < motherIds.size(); i++) {
-      nofHitsInRing[motherIds[i]]++;
+      auto motherId = std::make_pair<Int_t, Int_t>(motherIds[i].GetEntry(), motherIds[i].GetIndex());
+      nofHitsInRing[motherId]++;
     }
   }