diff --git a/algo/ca/core/pars/CaInitManager.cxx b/algo/ca/core/pars/CaInitManager.cxx
index feb8f35208f66cf062a03fb8905d14f09e4ccc91..4203b8142578fb26bee629b53bee055af7fa9682 100644
--- a/algo/ca/core/pars/CaInitManager.cxx
+++ b/algo/ca/core/pars/CaInitManager.cxx
@@ -264,8 +264,11 @@ void InitManager::InitStationLayout()
       fParameters.fvActiveToGeoMap[iStActive] = iStGeo;
     }
   }
-
   fInitController.SetFlag(EInitKey::kStationLayoutInitialized, true);
+
+  for (auto& aStation : fvStationInfo) {
+    aStation.SetGeoLayerID(fParameters.GetStationIndexGeometry(aStation.GetStationID(), aStation.GetDetectorID()));
+  }
 }
 
 // ----------------------------------------------------------------------------------------------------------------------
diff --git a/algo/ca/core/pars/CaInitManager.h b/algo/ca/core/pars/CaInitManager.h
index 7dc949619f892feb309d1d4eaa843b6f829ecfc9..a4cc95bcbf8616f4829c82900f3d46bc78e5688d 100644
--- a/algo/ca/core/pars/CaInitManager.h
+++ b/algo/ca/core/pars/CaInitManager.h
@@ -266,7 +266,9 @@ namespace cbm::algo::ca
       }
       fParameters.fGeometrySetup = kf::Setup<fvec>(setup);
       fParameters.fActiveSetup   = fParameters.fGeometrySetup;
-      for (int iStGeo = 0; iStGeo < setup.GetNofLayers(); ++iStGeo) {
+      // A sequence of the last inactive materials will be anyway thrown away, so it is more effective to
+      // loop over stations downstream
+      for (int iStGeo = setup.GetNofLayers() - 1; iStGeo >= 0; --iStGeo) {
         auto [detID, locID] = fParameters.GetStationIndexLocal(iStGeo);
         int iStActive       = fParameters.GetStationIndexActive(locID, detID);
         if (iStActive < 0) {
diff --git a/algo/ca/core/pars/CaStation.cxx b/algo/ca/core/pars/CaStation.cxx
index ce69e8ea14a5215d28d31070382303764d928d36..ce84b8ce17f16886e0d81234bc5cab3b084e53e2 100644
--- a/algo/ca/core/pars/CaStation.cxx
+++ b/algo/ca/core/pars/CaStation.cxx
@@ -83,6 +83,7 @@ std::string Station<DataT>::ToString(int verbosityLevel, int indentLevel, bool i
       msg << std::setw(columnSize) << std::setfill(' ') << "type" << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << "time status" << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << "field status" << ' ';
+      msg << std::setw(columnSize) << std::setfill(' ') << "geo layer ID" << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << "z [cm]" << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << "Xmax [cm]" << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << "Ymax [cm]";
@@ -92,6 +93,7 @@ std::string Station<DataT>::ToString(int verbosityLevel, int indentLevel, bool i
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetType() << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetTimeStatus() << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetFieldStatus() << ' ';
+      msg << std::setw(columnSize) << std::setfill(' ') << this->GetGeoLayerID() << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetZ<float>() << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetXmax<float>() << ' ';
       msg << std::setw(columnSize) << std::setfill(' ') << this->GetYmax<float>();
diff --git a/algo/ca/core/pars/CaStation.h b/algo/ca/core/pars/CaStation.h
index 0ecc40f15d6d60f136e49ac7273aefc5babb63b0..ba6988242dc75df5f666853a3aac4e52429f5502 100644
--- a/algo/ca/core/pars/CaStation.h
+++ b/algo/ca/core/pars/CaStation.h
@@ -25,6 +25,7 @@ namespace cbm::algo::ca
     int timeInfo = constants::Undef<int>;  ///< flag: if time information can be used
     int fieldStatus =
       constants::Undef<int>;               ///< flag: 1 - station is INSIDE the field, 0 - station is OUTSIDE the field
+    int geoLayerID = constants::Undef<int>;    ///< Index of layer in geometrical setup
     DataT fZ   = constants::Undef<DataT>;  ///< z position of station     [cm]
     DataT Xmax = constants::Undef<DataT>;  ///< min radius of the station [cm]
     DataT Ymax = constants::Undef<DataT>;  ///< max radius of the station [cm]
@@ -39,6 +40,7 @@ namespace cbm::algo::ca
       : type(other.GetType())
       , timeInfo(other.GetTimeStatus())
       , fieldStatus(other.GetFieldStatus())
+      , geoLayerID(other.GetGeoLayerID())
       , fZ(other.template GetZ<DataT>())
       , Xmax(other.template GetXmax<DataT>())
       , Ymax(other.template GetYmax<DataT>())
@@ -54,6 +56,7 @@ namespace cbm::algo::ca
       ar& type;
       ar& timeInfo;
       ar& fieldStatus;
+      ar& geoLayerID;
 
       ar& fZ;
       ar& Xmax;
@@ -76,6 +79,9 @@ namespace cbm::algo::ca
     /// \brief Gets field status flag
     int GetFieldStatus() const { return fieldStatus; }
 
+    /// \brief Gets index of the layer in the geometry setup (which can include inactive stations as well)
+    int GetGeoLayerID() const { return geoLayerID; }
+
     /// \brief Gets z-position of the station
     template<typename DataOut = DataT>
     DataOut GetZ() const
diff --git a/algo/ca/core/pars/CaStationInitializer.cxx b/algo/ca/core/pars/CaStationInitializer.cxx
index 3bfcea6e3fa36e6ce3188de24fa1a33b509f1340..3e179cb3eae209597ab2a5849d52d5764c435e19 100644
--- a/algo/ca/core/pars/CaStationInitializer.cxx
+++ b/algo/ca/core/pars/CaStationInitializer.cxx
@@ -131,6 +131,14 @@ void StationInitializer::SetFieldStatus(int fieldStatus)
   fInitController.SetFlag(EInitKey::kFieldStatus);
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void StationInitializer::SetGeoLayerID(int geoLayerID)
+{
+  fStation.geoLayerID = geoLayerID;
+  fInitController.SetFlag(EInitKey::kGeoLayerID);
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void StationInitializer::SetMaterialMap(const MaterialMap& thicknessMap)
diff --git a/algo/ca/core/pars/CaStationInitializer.h b/algo/ca/core/pars/CaStationInitializer.h
index 6f328f2f7eae2192f488c1230cb7c194c2558824..ceefb2abd41a908c6156c312e2cb6e9887e93f33 100644
--- a/algo/ca/core/pars/CaStationInitializer.h
+++ b/algo/ca/core/pars/CaStationInitializer.h
@@ -52,6 +52,7 @@ namespace cbm::algo::ca
       kZmax,          ///< max z of the station
       kThicknessMap,  ///< thickness map of the station (optional?)
       kFieldSlice,    ///< ca::Station.ca::FieldSlice object initialization
+      kGeoLayerID,    ///< index of geo layer in geometrical setup (including possibly inactive stations)
       // The last item is equal to the number of bits in fInitFlags
       kEnd
     };
@@ -128,6 +129,9 @@ namespace cbm::algo::ca
     ///                 of magnetic field components in position
     void SetFieldFunction(const std::function<void(const double (&xyz)[3], double (&B)[3])>& getFieldValue);
 
+    /// \brief Sets geometry ID (index of the layer in the geometrical setup)
+    void SetGeoLayerID(int geoLayerID);
+
     /// \brief Sets station thickness in units of radiation length mapped vs. position in XY plane (copy semantics)
     /// \param thicknessMap  Map of station thickness in units of radiation length
     void SetMaterialMap(const MaterialMap& thicknessMap);
diff --git a/algo/kf/core/geo/KfModuleIndexMap.h b/algo/kf/core/geo/KfModuleIndexMap.h
index 791d2b549d606192ad60ef0eec26f09dd9f22981..9410ecd395c84eea1e0f52074dd7437d7f874541 100644
--- a/algo/kf/core/geo/KfModuleIndexMap.h
+++ b/algo/kf/core/geo/KfModuleIndexMap.h
@@ -140,33 +140,23 @@ namespace cbm::algo::kf
   template<class EDetID>
   void ModuleIndexMap::Disable(EDetID detIdDisable, int locIdDisable)
   {
-    std::cout << "---- Disabling layer: " << static_cast<int>(detIdDisable) << ", " << locIdDisable << '\n';
     // Check, if the detector id is there
     auto iDetIntDsbl{fvDetExtToInt[static_cast<int>(detIdDisable)]};
-    std::cout << "iDetIntDsbl = " << iDetIntDsbl << '\n';
     if (iDetIntDsbl >= static_cast<int>(fvDetIntToExt.size())) {
       return;  // Nothing to disable, detector is already not in the map
     }
 
-
     auto& iGlbDsbl = fvLocToGlb[fvDetLocOffset[iDetIntDsbl] + locIdDisable];
-    std::cout << "iGlbDsbl = " << iGlbDsbl << '\n';
     if (iGlbDsbl == -1) {
       return;  // Nothing to disable, component is already inactive
     }
 
-    for (auto [a, b] : fvGlbToLoc) {
-      std::cout << "--> " << a << ", " << b << '\n';
-    }
     fvGlbToLoc.erase(fvGlbToLoc.begin() + iGlbDsbl);  // Removing component from glob->(det, loc) map
     for (auto& val : fvLocToGlb) {
       if (val > iGlbDsbl) {
         --val;
       }
     }
-    for (auto [a, b] : fvGlbToLoc) {
-      std::cout << "--> " << a << ", " << b << '\n';
-    }
     iGlbDsbl = -1;
   }
 
diff --git a/algo/kf/core/geo/KfSetup.h b/algo/kf/core/geo/KfSetup.h
index aaae02050019e5cd03493ee3ea34e240faf49b49..eeff57dfa4a1932eacdd08ceef43054a5cb5f0e1 100644
--- a/algo/kf/core/geo/KfSetup.h
+++ b/algo/kf/core/geo/KfSetup.h
@@ -131,14 +131,15 @@ namespace cbm::algo::kf
   template<class EDetID>
   void Setup<T>::DisableLayer(EDetID iDet, int iLoc)
   {
-    std::cout << "Disabling layer: " << static_cast<int>(iDet) << ", " << iLoc << '\n';
     int iLayer{fModuleIndexMap.LocalToGlobal(iDet, iLoc)};
+    //std::cout << "Disabling layer: iDet = " << static_cast<int>(iDet) << ", iLoc = " << iLoc << ", iLayer = " << iLayer << '\n';
     if (iLayer == -1) {
       return;
     }
 
     // Remove material layer and add it to the next one
     if (iLayer < static_cast<int>(fvMaterialLayers.size() - 1)) {
+      //std::cout << " -- adding layer " << iLayer << " to layer " << iLayer + 1 << " with z = " << fvMaterialLayers[iLayer + 1].GetZref() << '\n';
       fvMaterialLayers[iLayer + 1].Add(fvMaterialLayers[iLayer], utils::simd::Cast<T, float>(fTarget.GetZ()));
     }
     fvMaterialLayers.erase(fvMaterialLayers.begin() + iLayer);
@@ -148,6 +149,7 @@ namespace cbm::algo::kf
 
     // Disable layer in the index map
     fModuleIndexMap.Disable(iDet, iLoc);
+    //std::cout << "LAYERS: \n" << fModuleIndexMap.ToString() << '\n';
   }
 
 
diff --git a/core/base/CbmTrackingDetectorInterfaceBase.cxx b/core/base/CbmTrackingDetectorInterfaceBase.cxx
index 03610868e32c2221056394607ccb68b8c50860e5..4e6176ff9b05819770bec7de6b7248f6b33c91ac 100644
--- a/core/base/CbmTrackingDetectorInterfaceBase.cxx
+++ b/core/base/CbmTrackingDetectorInterfaceBase.cxx
@@ -111,8 +111,8 @@ std::string CbmTrackingDetectorInterfaceBase::ToString() const
                   "|{0:->9}|{0:->9}|{0:->9}|{0:->9}|{0:->9}|\n",
                   "");
   for (int iSt = 0; iSt < GetNtrackingStations(); ++iSt) {
-    table << format("|{:>5d}|{:>9f}|{:>17f}|{:>17f}|{:>17f}|{:>17f}|{:>17f}|{:>17f}|{:>9f}|{:>9f}|{:>9f}|{:>9f}|{:>9f}|"
-                    "{:>9f}|{:>9}|\n",
+    table << format("|{:>5}|{:>9}|{:>17}|{:>17}|{:>17}|{:>17}|{:>17}|{:>17}|{:>9}|{:>9}|{:>9}|{:>9}|{:>9}|"
+                    "{:>9}|{:>9}|\n",
                     iSt, GetZref(iSt), GetActiveXmin(iSt), GetActiveXmax(iSt), GetActiveYmin(iSt), GetActiveYmax(iSt),
                     GetActiveZmin(iSt), GetActiveZmax(iSt), GetXmin(iSt), GetXmax(iSt), GetYmin(iSt), GetYmax(iSt),
                     GetZmin(iSt), GetZmax(iSt), IsTimeInfoProvided(iSt));
diff --git a/macro/L1/configs/ca_params_global.yaml b/macro/L1/configs/ca_params_global.yaml
index da809e59a76b58361bfba29a7269d358f43029e3..de164d1703fb1feebf49b423e34eb26cc0be73b4 100644
--- a/macro/L1/configs/ca_params_global.yaml
+++ b/macro/L1/configs/ca_params_global.yaml
@@ -43,12 +43,12 @@ ca:
       max_doublets_per_singlet: 150
 
       # Max number of triplets per doublet
-      max_triplets_per_doublet: 15
+      max_triplets_per_doublet: 1000
     
     # Developement flags
     dev:
       ignore_hit_search_areas:      true
-      use_of_original_field:        false
+      use_of_original_field:        true
       match_doublets_via_mc:        false
       match_triplets_via_mc:        false
       extend_tracks_via_mc:         false
diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C
index 770afe903b37c41047061af23aefe92841212cd9..8f41a3c63589d5888b47f99bcb03444d7cd42c65 100644
--- a/macro/mcbm/mcbm_qa.C
+++ b/macro/mcbm/mcbm_qa.C
@@ -335,10 +335,6 @@ void mcbm_qa(Int_t nEvents = 0,
   caParFile.ReplaceAll(".root", ".ca.par");
 
   auto* pCaInputQaSetup = new cbm::ca::InputQaSetup(verbose, bUseMC);
-  pCaInputQaSetup->SetDetectorFlag(cbm::algo::ca::EDetectorID::kSts, bUseSts);
-  pCaInputQaSetup->SetDetectorFlag(cbm::algo::ca::EDetectorID::kMuch, bUseMuch);
-  pCaInputQaSetup->SetDetectorFlag(cbm::algo::ca::EDetectorID::kTrd, bUseTrd);
-  pCaInputQaSetup->SetDetectorFlag(cbm::algo::ca::EDetectorID::kTof, bUseTof);
   pCaInputQaSetup->ReadParameters(caParFile.Data());
   pCaInputQaSetup->SetSetupName(setupName.Data());
   qaManager->AddTask(pCaInputQaSetup);
diff --git a/reco/L1/CbmCaTrackingSetupBuilder.cxx b/reco/L1/CbmCaTrackingSetupBuilder.cxx
index c0c29668b7475f9a5a41a7fb87e409ffea4051c0..243f81a5e72ccbb8a56b67ac7e4d3714a84fd195 100644
--- a/reco/L1/CbmCaTrackingSetupBuilder.cxx
+++ b/reco/L1/CbmCaTrackingSetupBuilder.cxx
@@ -11,14 +11,15 @@
 
 #include "CbmKfOriginalField.h"
 #include "CbmKfTarget.h"
-#include "CbmL1DetectorID.h"
 #include "CbmMuchTrackingInterface.h"
 #include "CbmMvdTrackingInterface.h"
 #include "CbmSetup.h"
+#include "CbmStsFindTracks.h"
 #include "CbmStsTrackingInterface.h"
 #include "CbmTofTrackingInterface.h"
 #include "CbmTrdTrackingInterface.h"
 #include "FairField.h"
+#include "FairRootManager.h"
 #include "FairRunAna.h"
 #include "KfDefs.h"
 #include "KfMaterialMapFactory.h"
@@ -31,21 +32,40 @@ using kf::tools::MaterialMapFactory;
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-// TODO: Provide separate initialization steps for geo layers and field
-bool TrackingSetupBuilder::Init()
+void TrackingSetupBuilder::CheckDetectorPresence()
+{
+  LOG(info) << "TrackingSetupBuilder: detector subsystems in geometry: ";
+  auto Check = [&](ca::EDetectorID detID) {
+    fvbDetUsed[detID] = CbmSetup::Instance()->IsActive(kCbmModuleId[detID])
+                        && FairRootManager::Instance()->GetObject(kDetHitBrName[detID]);
+    LOG(info) << fmt::format("\t{:6}: {}", kDetName[detID], fvbDetUsed[detID]);
+  };
+
+  Check(ca::EDetectorID::kMvd);
+  Check(ca::EDetectorID::kSts);
+  Check(ca::EDetectorID::kMuch);
+  Check(ca::EDetectorID::kTrd);
+  Check(ca::EDetectorID::kTof);
+
+  // Explicitly disable MVD, if it is not required from the STSFindTracks task
+  if (fvbDetUsed[ca::EDetectorID::kMvd]) {
+    auto* pTrackFinderTask = dynamic_cast<CbmStsFindTracks*>(FairRunAna::Instance()->GetTask("STSFindTracks"));
+    if (pTrackFinderTask) {
+      fvbDetUsed[ca::EDetectorID::kMvd] = pTrackFinderTask->MvdUsage();
+    }
+  }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void TrackingSetupBuilder::Init()
 try {
   using cbm::algo::kf::EFieldType;
   using cbm::algo::kf::GeoLayer;
   using cbm::algo::kf::defs::MinField;
-  fBuilder.Reset();
-
-  // Check, if a subsystem exists in the setup
-  fbUseMvd &= CbmSetup::Instance()->IsActive(ECbmModuleId::kMvd);
-  fbUseSts &= CbmSetup::Instance()->IsActive(ECbmModuleId::kSts);
-  fbUseMuch &= CbmSetup::Instance()->IsActive(ECbmModuleId::kMuch);
-  fbUseTrd &= CbmSetup::Instance()->IsActive(ECbmModuleId::kTrd);
-  fbUseTof &= CbmSetup::Instance()->IsActive(ECbmModuleId::kTof);
+  CheckDetectorPresence();
 
+  fBuilder.Reset();
   // Magnetic field initialization
   if (auto* pField = FairRunAna::Instance()->GetField()) {
     LOG(info) << fabs(pField->GetBx(0., 0., 0.)) << ", " << fabs(pField->GetBy(0., 0., 0.)) << ", "
@@ -69,7 +89,7 @@ try {
 
   // Tracking station property initialization
   auto CollectStations = [&](const auto* pIfs, ca::EDetectorID detID) -> void {
-    if (!pIfs) {
+    if (!fvbDetUsed[detID]) {
       return;
     }
     for (int iSt = 0; iSt < pIfs->GetNtrackingStations(); ++iSt) {
@@ -81,11 +101,11 @@ try {
                                   std::max(std::fabs(pIfs->GetYmin(iSt)), std::fabs(pIfs->GetYmax(iSt)))});
     }
   };
-  CollectStations(fbUseMvd ? CbmMvdTrackingInterface::Instance() : nullptr, ca::EDetectorID::kMvd);
-  CollectStations(fbUseSts ? CbmStsTrackingInterface::Instance() : nullptr, ca::EDetectorID::kSts);
-  CollectStations(fbUseMuch ? CbmMuchTrackingInterface::Instance() : nullptr, ca::EDetectorID::kMuch);
-  CollectStations(fbUseTrd ? CbmTrdTrackingInterface::Instance() : nullptr, ca::EDetectorID::kTrd);
-  CollectStations(fbUseTof ? CbmTofTrackingInterface::Instance() : nullptr, ca::EDetectorID::kTof);
+  CollectStations(CbmMvdTrackingInterface::Instance(), ca::EDetectorID::kMvd);
+  CollectStations(CbmStsTrackingInterface::Instance(), ca::EDetectorID::kSts);
+  CollectStations(CbmMuchTrackingInterface::Instance(), ca::EDetectorID::kMuch);
+  CollectStations(CbmTrdTrackingInterface::Instance(), ca::EDetectorID::kTrd);
+  CollectStations(CbmTofTrackingInterface::Instance(), ca::EDetectorID::kTof);
 
   // Retrieve target properties
   const auto* pTarget = cbm::kf::Target::Instance();
@@ -100,13 +120,11 @@ try {
 
   // Set the initialization flags back
   fbInitialized = true;
-
   LOG(info) << "ca::TrackingSetupBuilder: Tracking setup was initialized successfully";
-  return true;
 }
 catch (const std::exception& err) {
+  fbInitialized = false;
   LOG(error) << "ca::TrackingSetupBuilder: Tracking setup was not initialized. Reason: " << err.what();
-  return false;
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -116,18 +134,7 @@ TrackingSetupBuilder* TrackingSetupBuilder::Instance()
   if (fpInstance == nullptr) {
     std::lock_guard<std::mutex> lock(fMutex);
     fpInstance = new TrackingSetupBuilder{};
+    fpInstance->Init();  // Init for the first time?
   }
   return fpInstance;
 }
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-void TrackingSetupBuilder::Use(bool mvd, bool sts, bool much, bool trd, bool tof)
-{
-  fbUseMvd      = mvd;
-  fbUseSts      = sts;
-  fbUseMuch     = much;
-  fbUseTrd      = trd;
-  fbUseTof      = tof;
-  fbInitialized = false;
-}
diff --git a/reco/L1/CbmCaTrackingSetupBuilder.h b/reco/L1/CbmCaTrackingSetupBuilder.h
index 4cfd16113ce20e0451395cb42740a496601927e2..409775a73d565c98307da9222034c18f3fe7416c 100644
--- a/reco/L1/CbmCaTrackingSetupBuilder.h
+++ b/reco/L1/CbmCaTrackingSetupBuilder.h
@@ -9,6 +9,7 @@
 
 #pragma once
 
+#include "CbmL1DetectorID.h"
 #include "KfSetupBuilder.h"
 
 #include <mutex>
@@ -34,13 +35,8 @@ namespace cbm::ca
       return fBuilder.MakeSetup<T>(fldMode);
     }
 
-    /// \brief  Enables/disables detector subsystems in the setup
-    /// \param  mvd   Is MVD used
-    /// \param  sts   Is STS used
-    /// \param  much  Is MuCh used
-    /// \param  trd   Is TRD used
-    /// \param  tof   Is TOF used
-    void Use(bool mvd, bool sts, bool much, bool trd, bool tof);
+    /// \brief  Checks, if a tracking detector is used (is in geometry and has hits)
+    bool Has(ca::EDetectorID detID) const { return fvbDetUsed[detID]; }
 
     // Disable copy and move
     TrackingSetupBuilder(const TrackingSetupBuilder&) = delete;
@@ -55,14 +51,11 @@ namespace cbm::ca
     /// \brief Destructor
     ~TrackingSetupBuilder() = default;
 
-    inline static TrackingSetupBuilder* fpInstance{nullptr};
-    inline static std::mutex fMutex{};
+    /// \brief  Check detector presence
+    void CheckDetectorPresence();
 
     /// \brief  Initializes the instance
-    /// \param  fldMode  Field mode
-    bool Init();
-
-    cbm::algo::kf::SetupBuilder fBuilder{};
+    void Init();
 
     // Material map creator properties (TODO: Provide setters, if needed)
     static constexpr double kMatCreatorPitch{0.1};    ///< Material budget map minimal bin size [cm]
@@ -72,13 +65,11 @@ namespace cbm::ca
     static constexpr double kTargFieldInitStep{2.5};  ///< Step between nodes in the target field initialization [cm]
     static constexpr double kTargMaterialOffset{1};   ///< Offset between target upper limit and its material zMax [cm]
 
-    cbm::algo::kf::EFieldMode fFieldMode{cbm::algo::kf::EFieldMode::Intrpl};
+    inline static TrackingSetupBuilder* fpInstance{nullptr};
+    inline static std::mutex fMutex{};
 
-    bool fbUseMvd{false};   ///< Are MVD stations included in the tracking setup
-    bool fbUseSts{false};   ///< Are STS stations included in the tracking setup
-    bool fbUseMuch{false};  ///< Are MuCh stations included in the tracking setup
-    bool fbUseTrd{false};   ///< Are TRD stations included in the tracking setup
-    bool fbUseTof{false};   ///< Are TOF stations included in the tracking setup
+    cbm::algo::kf::SetupBuilder fBuilder{};  ///< KF-setup builder
+    DetIdArr_t<bool> fvbDetUsed{{false}};    ///< Detector subsystem usage flag
 
     /// \brief Checks, if the setup was already initialized
     /// \note  Each call of the setup initializer resets the setup builder, so the initialization is called
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index 4bc93774b0893c6642b76f07b934a7bf6d1f0bb1..15fb967f551f3192d581dbbec6cf33ed0f45e6c3 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -193,54 +193,12 @@ try {
 
   // turn on reconstruction in sub-detectors
 
-  fUseMVD  = false;
-  fUseSTS  = false;
-  fUseMUCH = false;
-  fUseTRD  = false;
-  fUseTOF  = false;
-
-  if (ca::TrackingMode::kSts == fTrackingMode) {
-    fUseMVD  = true;
-    fUseSTS  = true;
-    fUseMUCH = false;
-    fUseTRD  = false;
-    fUseTOF  = false;
-    // check if MVD is switched off in the Sts task
-    CbmStsFindTracks* findTask = dynamic_cast<CbmStsFindTracks*>(FairRunAna::Instance()->GetTask("STSFindTracks"));
-    if (findTask) fUseMVD = findTask->MvdUsage();
-  }
-
-  if (ca::TrackingMode::kMcbm == fTrackingMode) {
-    fUseMVD  = false;
-    fUseSTS  = true;
-    fUseMUCH = true;
-    fUseTRD  = true;
-    fUseTOF  = true;
-    // fInitManager.DevSetIgnoreHitSearchAreas(true);  // uncomment for debug
-  }
-
-  if (ca::TrackingMode::kGlobal == fTrackingMode) {
-    //at the moment trd2d tracking only
-    fUseMVD  = false;
-    fUseSTS  = false;
-    fUseMUCH = false;
-    fUseTRD  = true;
-    fUseTOF  = false;
-
-    fInitManager.DevSetUseOfOriginalField();
-    fInitManager.DevSetIgnoreHitSearchAreas(true);
-    fInitManager.SetMaxTripletPerDoublets(1000);
-  }
-
-  // uncomment for debug
-  //fInitManager.DevSetIgnoreHitSearchAreas(true);
-  //fInitManager.DevSetIsMatchDoubletsViaMc(true);
-  //fInitManager.DevSetIsMatchTripletsViaMc(true);
-  //fInitManager.DevSetIsExtendTracksViaMc(true);
-  //fInitManager.DevSetIsSuppressOverlapHitsViaMc(true);
-
-  CheckDetectorPresence();
-
+  auto* pSetupBuilder{cbm::ca::TrackingSetupBuilder::Instance()};
+  fUseMVD  = pSetupBuilder->Has(ca::EDetectorID::kMvd);
+  fUseSTS  = pSetupBuilder->Has(ca::EDetectorID::kSts);
+  fUseMUCH = pSetupBuilder->Has(ca::EDetectorID::kMuch);
+  fUseTRD  = pSetupBuilder->Has(ca::EDetectorID::kTrd);
+  fUseTOF  = pSetupBuilder->Has(ca::EDetectorID::kTof);
 
   // *****************************
   // **                         **
@@ -496,8 +454,6 @@ try {
     // ** Initialize KF-setup **
     // *************************
     {
-      auto* pSetupBuilder = cbm::ca::TrackingSetupBuilder::Instance();
-      pSetupBuilder->Use(fUseMVD, fUseSTS, fUseMUCH, fUseTRD, fUseTOF);
       auto trackerSetup  = pSetupBuilder->MakeSetup<float>(cbm::algo::kf::EFieldMode::Intrpl);
       TString outputFile = fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString(kSTAPSetupSuffix.data());
       cbm::algo::kf::SetupBuilder::Store(trackerSetup, outputFile.Data());
@@ -521,6 +477,12 @@ try {
       return kFATAL;
     }
 
+    fUseMVD &= fInitManager.IsActive(ca::EDetectorID::kMvd);
+    fUseSTS &= fInitManager.IsActive(ca::EDetectorID::kSts);
+    fUseMUCH &= fInitManager.IsActive(ca::EDetectorID::kMuch);
+    fUseTRD &= fInitManager.IsActive(ca::EDetectorID::kTrd);
+    fUseTOF &= fInitManager.IsActive(ca::EDetectorID::kTof);
+
     // Write parameters object to file if needed
     if (1 == fSTAPDataMode || 4 == fSTAPDataMode) {
       this->WriteSTAPParamObject();
@@ -550,6 +512,8 @@ try {
   }
   fpAlgo->Init(fTrackingMode);
 
+
+
   // Initialize time-slice reader
   fpTSReader = std::make_unique<TimeSliceReader>();
   fpTSReader->SetDetector(ca::EDetectorID::kMvd, fUseMVD);
diff --git a/reco/L1/CbmL1DetectorID.h b/reco/L1/CbmL1DetectorID.h
index 72258838acfc715039ca3b5992a23334c4931d4a..a56c8af09b15a8490a605be42543a6428323cdc0 100644
--- a/reco/L1/CbmL1DetectorID.h
+++ b/reco/L1/CbmL1DetectorID.h
@@ -98,6 +98,10 @@ namespace cbm::ca
   }};
   /* clang-format on */
 
+  /// @brief Conversion map from ca::EDetectorID to ECbmModuleId
+  constexpr DetIdArr_t<ECbmModuleId> kCbmModuleId = {
+    {ECbmModuleId::kMvd, ECbmModuleId::kSts, ECbmModuleId::kMuch, ECbmModuleId::kTrd, ECbmModuleId::kTof}};
+
   /// @brief Name
 
   /// @brief Types of MC point objects for each detector
diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx
index ed1d3d2d69a543bc11830fc72388a5f4e94f7ee3..1d49ab0bc11c41104ef1164503a45a5074ec2891 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.cxx
+++ b/reco/L1/qa/CbmCaInputQaSetup.cxx
@@ -253,18 +253,20 @@ void InputQaSetup::ExecQa()
 InitStatus InputQaSetup::InitQa()
 try {
   LOG(info) << fName << ": initializing... ";
+  auto* pSetupBuilder = cbm::ca::TrackingSetupBuilder::Instance();
+  auto CheckPresence  = [&](ca::EDetectorID detID) { fvbUseDet[detID] = pSetupBuilder->Has(detID); };
+  CheckPresence(ca::EDetectorID::kMvd);
+  CheckPresence(ca::EDetectorID::kSts);
+  CheckPresence(ca::EDetectorID::kMuch);
+  CheckPresence(ca::EDetectorID::kTrd);
+  CheckPresence(ca::EDetectorID::kTof);
+
   // Tracking parameters
   {
+    using cbm::algo::kf::EFieldMode;
     ca::InitManager manager;
     manager.ReadParametersObject(fsParametersFilename.c_str());
-    bool bMvd{manager.IsPresent(ca::EDetectorID::kMvd)};
-    bool bSts{manager.IsPresent(ca::EDetectorID::kSts)};
-    bool bMuch{manager.IsPresent(ca::EDetectorID::kMuch)};
-    bool bTrd{manager.IsPresent(ca::EDetectorID::kTrd)};
-    bool bTof{manager.IsPresent(ca::EDetectorID::kTof)};
-    auto* pSetupBuilder = cbm::ca::TrackingSetupBuilder::Instance();
-    pSetupBuilder->Use(bMvd, bSts, bMuch, bTrd, bTof);
-    manager.SetGeometrySetup(pSetupBuilder->MakeSetup<ca::fvec>(cbm::algo::kf::EFieldMode::Intrpl));
+    manager.SetGeometrySetup(pSetupBuilder->MakeSetup<ca::fvec>(EFieldMode::Intrpl));
     fpParameters = std::make_unique<ca::Parameters<ca::fvec>>(manager.TakeParameters());
   }
 
diff --git a/reco/L1/qa/CbmCaInputQaSetup.h b/reco/L1/qa/CbmCaInputQaSetup.h
index 7c0f226a325d9361ea44edcb239169be28b8d56c..fd4d08f7ef5afe4c7a56234bda3ba577f9181b76 100644
--- a/reco/L1/qa/CbmCaInputQaSetup.h
+++ b/reco/L1/qa/CbmCaInputQaSetup.h
@@ -50,9 +50,6 @@ namespace cbm::ca
     /// \note  TEMPORARY FUNCTION, A SEPARATE PARAMETERS INITIALIZATION CLASS IS TO BE USED
     void ReadParameters(const char* filename) { fsParametersFilename = filename; }
 
-    /// \brief Sets detector flag
-    void SetDetectorFlag(ca::EDetectorID detID, bool flag = true) { fvbUseDet[detID] = flag; }
-
     /// \brief Checks results of the QA and returns a success flag
     void Check() override;
 
diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx
index 59ed3c4d64ef12494ca9031d57518ce96b3a930e..2f6bfb721443d9c0dd82aab7b28c6ee3d5b8af3a 100644
--- a/reco/L1/qa/CbmCaOutputQa.cxx
+++ b/reco/L1/qa/CbmCaOutputQa.cxx
@@ -797,16 +797,11 @@ try {
   }
 
   {
+    using cbm::algo::kf::EFieldMode;
+    using cbm::ca::TrackingSetupBuilder;
     ca::InitManager manager;
     manager.ReadParametersObject(fsParametersFilename.c_str());
-    bool bMvd{manager.IsPresent(ca::EDetectorID::kMvd)};
-    bool bSts{manager.IsPresent(ca::EDetectorID::kSts)};
-    bool bMuch{manager.IsPresent(ca::EDetectorID::kMuch)};
-    bool bTrd{manager.IsPresent(ca::EDetectorID::kTrd)};
-    bool bTof{manager.IsPresent(ca::EDetectorID::kTof)};
-    auto* pSetupBuilder = cbm::ca::TrackingSetupBuilder::Instance();
-    pSetupBuilder->Use(bMvd, bSts, bMuch, bTrd, bTof);
-    manager.SetGeometrySetup(pSetupBuilder->MakeSetup<ca::fvec>(cbm::algo::kf::EFieldMode::Intrpl));
+    manager.SetGeometrySetup(TrackingSetupBuilder::Instance()->MakeSetup<ca::fvec>(EFieldMode::Intrpl));
     fpParameters = std::make_shared<ca::Parameters<ca::fvec>>(manager.TakeParameters());
   }