diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 22f753ef4624c5e595241f4d71a9dcf6edb38600..5da292f47dc3c8eab99ce34df6b7a455b566a6b6 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -17,7 +17,10 @@
 #include "much/Unpack.h"
 #include "rich/Unpack.h"
 #include "sts/ChannelMaskSet.h"
+#include "sts/HitfinderChain.h"
 #include "sts/Unpack.h"
+#include "tof/CalibratorChain.h"
+#include "tof/HitfinderChain.h"
 #include "tof/Unpack.h"
 #include "trd/Unpack.h"
 #include "trd2d/Unpack.h"
@@ -72,9 +75,6 @@ void Reco::Init(const Options& opts)
 
   fContext.opts = opts;
   SetContext(&fContext);
-  fStsHitFinder.SetContext(&fContext);
-  fTofCalibrator.SetContext(&fContext);
-  fTofHitFinder.SetContext(&fContext);
 
   if (Opts().HistogramUri() != "") {
     fSender = std::make_shared<HistogramSender>(Opts().HistogramUri());
@@ -139,26 +139,42 @@ void Reco::Init(const Options& opts)
   }
 
   // --- Event building
-  fs::path configFile = opts.ParamsDir() / "EventbuildConfig.yaml";
-  evbuild::Config config(YAML::LoadFile(configFile.string()));
-  fEventBuild = std::make_unique<evbuild::EventbuildChain>(config, fSender);
+  if (Opts().Has(Step::DigiTrigger)) {
+    fs::path configFile = opts.ParamsDir() / "EventbuildConfig.yaml";
+    evbuild::Config config(YAML::LoadFile(configFile.string()));
+    fEventBuild = std::make_unique<evbuild::EventbuildChain>(config, fSender);
+  }
 
   // STS Hitfinder
-  sts::HitfinderPars hitFinderSetup = yaml::ReadFromFile<sts::HitfinderPars>(opts.ParamsDir() / "StsHitfinder.yaml");
-  hitFinderSetup.landauTable        = sts::LandauTable::FromFile(opts.ParamsDir() / "LandauWidthTable.txt");
-  sts::HitfinderChainPars hitFinderPars;
-  hitFinderPars.setup  = std::move(hitFinderSetup);
-  hitFinderPars.memory = Params().sts.memory;
-  fStsHitFinder.SetParameters(hitFinderPars);
+  if (Opts().Has(fles::Subsystem::STS) && Opts().Has(Step::LocalReco)) {
+    sts::HitfinderPars hitFinderSetup = yaml::ReadFromFile<sts::HitfinderPars>(opts.ParamsDir() / "StsHitfinder.yaml");
+    hitFinderSetup.landauTable        = sts::LandauTable::FromFile(opts.ParamsDir() / "LandauWidthTable.txt");
+    sts::HitfinderChainPars hitFinderPars;
+    hitFinderPars.setup  = std::move(hitFinderSetup);
+    hitFinderPars.memory = Params().sts.memory;
+    fStsHitFinder        = std::make_unique<sts::HitfinderChain>();
+    fStsHitFinder->SetContext(&fContext);
+    fStsHitFinder->SetParameters(hitFinderPars);
+  }
+
 
   // TOF Hitfinder
-  fTofHitFinder.Init();
-  fTofCalibrator.Init();
+  if (Opts().Has(fles::Subsystem::TOF) && Opts().Has(Step::LocalReco)) {
+    fTofCalibrator = std::make_unique<tof::CalibratorChain>();
+    fTofCalibrator->SetContext(&fContext);
+    fTofCalibrator->Init();
+
+    fTofHitFinder = std::make_unique<tof::HitfinderChain>();
+    fTofHitFinder->SetContext(&fContext);
+    fTofHitFinder->Init();
+  }
 
   // Tracking
-  fTracking = std::make_unique<TrackingChain>(fSender);
-  fTracking->SetContext(&fContext);
-  fTracking->Init();
+  if (Opts().Has(Step::Tracking)) {
+    fTracking = std::make_unique<TrackingChain>(fSender);
+    fTracking->SetContext(&fContext);
+    fTracking->Init();
+  }
 
   fInitialized = true;
 
@@ -229,9 +245,9 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
     sts::HitfinderMonitor stsHitfinderMonitor;
     PartitionedSpan<sts::Hit> stsHits;
     PartitionedVector<sts::Cluster> stsClusters;
-    if (Opts().Has(Step::LocalReco) && Opts().Has(fles::Subsystem::STS)) {
+    if (fStsHitFinder) {
       bool storeClusters  = Opts().HasOutput(RecoData::Cluster);
-      auto stsResults     = fStsHitFinder(digis.fSts, storeClusters);
+      auto stsResults     = (*fStsHitFinder)(digis.fSts, storeClusters);
       stsHits             = stsResults.hits;
       stsClusters         = std::move(stsResults.clusters);
       stsHitfinderMonitor = stsResults.monitor;
@@ -240,8 +256,8 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
 
     PartitionedVector<tof::Hit> tofHits;
     if (Opts().Has(Step::LocalReco) && Opts().Has(fles::Subsystem::TOF)) {
-      auto [caldigis, calmonitor]          = fTofCalibrator.Run(digis.fTof);
-      auto [hits, hitmonitor, digiindices] = fTofHitFinder.Run(caldigis);
+      auto [caldigis, calmonitor]          = fTofCalibrator->Run(digis.fTof);
+      auto [hits, hitmonitor, digiindices] = fTofHitFinder->Run(caldigis);
       tofHits                              = std::move(hits);
       QueueTofCalibMetrics(calmonitor);
       QueueTofRecoMetrics(hitmonitor);
@@ -282,8 +298,12 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
 
 void Reco::Finalize()
 {
-  fStsHitFinder.Finalize();
-  fTracking->Finalize();
+  if (fStsHitFinder) {
+    fStsHitFinder->Finalize();
+  }
+  if (fTracking) {
+    fTracking->Finalize();
+  }
 
   // Pop timer that was started in Init()
   xpu::timings t = xpu::pop_timer();
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 9a193027e82724331cce58bcbd22bf066c2f912d..7db340ca937ad5fb30bd18668ab45549ea87c251 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -6,9 +6,6 @@
 #include "AlgoTraits.h"
 #include "SubChain.h"
 #include "global/RecoResults.h"
-#include "sts/HitfinderChain.h"
-#include "tof/CalibratorChain.h"
-#include "tof/HitfinderChain.h"
 
 #include <xpu/host.h>
 
@@ -46,11 +43,17 @@ namespace cbm::algo
   {
     class Unpack;
     class DigiQa;
+    class HitfinderChain;
+    class HitfinderMonitor;
   }
 
   namespace tof
   {
     class Unpack;
+    class CalibratorChain;
+    struct CalibrateMonitorData;
+    class HitfinderChain;
+    struct HitfindMonitorData;
   }
 
   namespace trd
@@ -123,12 +126,12 @@ namespace cbm::algo
     // STS
     std::unique_ptr<sts::Unpack> fStsUnpack;
     std::unique_ptr<sts::DigiQa> fStsDigiQa;  ///< Raw STS-digis QA
-    sts::HitfinderChain fStsHitFinder;
+    std::unique_ptr<sts::HitfinderChain> fStsHitFinder;
 
     // TOF
     std::unique_ptr<tof::Unpack> fTofUnpack;
-    tof::HitfinderChain fTofHitFinder;
-    tof::CalibratorChain fTofCalibrator;
+    std::unique_ptr<tof::HitfinderChain> fTofHitFinder;
+    std::unique_ptr<tof::CalibratorChain> fTofCalibrator;
 
     // TRD
     std::unique_ptr<trd::Unpack> fTrdUnpack;
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index b175d7d798fce41f074a1ec28bb1993d4f5b858c..475ceef3fe79a877f1c4086c8190b7a5ebf015bb 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -9,6 +9,7 @@
 #include "RecoResultsInputArchive.h"
 #include "RecoResultsOutputArchive.h"
 #include "compat/OpenMP.h"
+#include "gpu/DeviceImage.h"
 
 #include <TimesliceAutoSource.hpp>