diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index c18903ab4dfe8f42ae0b54fedad23b8cf62583ee..78fa9029f84220d3dc175192700aa32839f8c8f1 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -102,11 +102,11 @@ install(DIRECTORY detectors/trd2d TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
 install(
   FILES
     base/ChainContext.h
+    base/Definitions.h
     base/Options.h
     base/Prelude.h
     base/RecoParams.h
     base/SubChain.h
-    base/Types.h
     ca/simd/CaSimd.h
     ca/simd/CaSimdVc.h
     ca/simd/CaSimdPseudo.h
diff --git a/algo/base/Definitions.h b/algo/base/Definitions.h
new file mode 100644
index 0000000000000000000000000000000000000000..d07a3add58dd57d5c7601a08dd741177752a9768
--- /dev/null
+++ b/algo/base/Definitions.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+#ifndef CBM_BASE_TYPES_H
+#define CBM_BASE_TYPES_H
+
+#include "MicrosliceDescriptor.hpp"  // For fles::SubsystemIdentifier
+
+#include "util/EnumDict.h"
+
+namespace cbm::algo
+{
+
+  enum class Step
+  {
+    Unpack,
+    DigiTrigger,
+    LocalReco,
+  };
+
+  enum class RecoData
+  {
+    Digi,
+    Cluster,
+    Hit,
+  };
+
+}  // namespace cbm::algo
+
+CBM_ENUM_DICT(fles::SubsystemIdentifier,
+  // CBM detectors
+  {"STS", fles::SubsystemIdentifier::STS},
+  {"MVD", fles::SubsystemIdentifier::MVD},
+  {"RICH", fles::SubsystemIdentifier::RICH},
+  {"TRD", fles::SubsystemIdentifier::TRD},
+  {"TRD2D", fles::SubsystemIdentifier::TRD2D},
+  {"MUCH", fles::SubsystemIdentifier::MUCH},
+  {"RPC", fles::SubsystemIdentifier::RPC},
+  {"ECAL", fles::SubsystemIdentifier::ECAL},
+  {"PSD", fles::SubsystemIdentifier::PSD},
+
+  // Other detectors (experimental)
+  {"T0", fles::SubsystemIdentifier::T0},
+  {"TRB3", fles::SubsystemIdentifier::TRB3},
+  {"HODOSCOPE", fles::SubsystemIdentifier::Hodoscope},
+  {"CHERENKOV", fles::SubsystemIdentifier::Cherenkov},
+
+  // FLES (pattern generators)
+  {"FLES", fles::SubsystemIdentifier::FLES},
+);
+
+CBM_ENUM_DICT(cbm::algo::Step,
+  {"Unpack", Step::Unpack},
+  {"DigiTrigger", Step::DigiTrigger},
+  {"LocalReco", Step::LocalReco}
+);
+
+CBM_ENUM_DICT(cbm::algo::RecoData,
+  {"Digi", RecoData::Digi},
+  {"Cluster", RecoData::Cluster},
+  {"Hit", RecoData::Hit}
+);
+
+#endif
diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx
index f49b7db2e9d27b0dfc4a72b4ed0bd925b59ac67d..779b4ebbcfca986d2c1f738e4ebec35fe3703f7b 100644
--- a/algo/base/Options.cxx
+++ b/algo/base/Options.cxx
@@ -71,7 +71,7 @@ Options::Options(int argc, char** argv)
       "comma seperated list of reconstruction output types (hit, digi, ...)")
     ("steps", po::value(&fRecoSteps)->multitoken()->default_value({Step::LocalReco})->value_name("<steps>"),
       "comma seperated list of reconstruction steps (upack, digitrigger, localreco, ...)")
-    ("systems,s", po::value(&fDetectors)->multitoken()->default_value({Detector::STS})->value_name("<detectors>"),
+    ("systems,s", po::value(&fDetectors)->multitoken()->default_value({fles::SubsystemIdentifier::STS})->value_name("<detectors>"),
       "comma seperated list of detectors to process (sts, mvd, ...)")
     ("num-ts,n", po::value(&fNumTimeslices)->default_value(-1)->value_name("<num>"),
       "Stop after <num> timeslices (-1 = all)")
diff --git a/algo/base/Options.h b/algo/base/Options.h
index bc67dae908892eb33c8c5a7da7dace92a22c78d3..a164ed7378443a877c1db861f419b75cd2e45ec1 100644
--- a/algo/base/Options.h
+++ b/algo/base/Options.h
@@ -4,12 +4,11 @@
 #ifndef CBM_ALGO_BASE_OPTIONS_H
 #define CBM_ALGO_BASE_OPTIONS_H
 
-#include "Types.h"
-
 #include <set>
 #include <string>
 #include <vector>
 
+#include "Definitions.h"
 #include "compat/Filesystem.h"
 #include "log.hpp"
 
@@ -40,8 +39,8 @@ namespace cbm::algo
       return std::find(fOutputTypes.begin(), fOutputTypes.end(), recoData) != fOutputTypes.end();
     }
 
-    const std::vector<Detector>& Detectors() const { return fDetectors; }
-    bool HasDetector(Detector detector) const
+    const std::vector<fles::SubsystemIdentifier>& Detectors() const { return fDetectors; }
+    bool HasDetector(fles::SubsystemIdentifier detector) const
     {
       return std::find(fDetectors.begin(), fDetectors.end(), detector) != fDetectors.end();
     }
@@ -59,7 +58,7 @@ namespace cbm::algo
     int fSkipTimeslices      = 0;
     std::vector<Step> fRecoSteps;
     std::vector<RecoData> fOutputTypes;
-    std::vector<Detector> fDetectors;
+    std::vector<fles::SubsystemIdentifier> fDetectors;
   };
 
 }  // namespace cbm::algo
diff --git a/algo/base/Types.h b/algo/base/Types.h
deleted file mode 100644
index 12c5682b5305a2ae8a16e670df29b20af3e3d7d3..0000000000000000000000000000000000000000
--- a/algo/base/Types.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_BASE_TYPES_H
-#define CBM_BASE_TYPES_H
-
-#include "util/EnumDict.h"
-
-namespace cbm::algo
-{
-
-  enum class Detector
-  {
-    STS,
-    TOF,
-  };
-
-  enum class Step
-  {
-    Unpack,
-    DigiTrigger,
-    LocalReco,
-  };
-
-  enum class RecoData
-  {
-    Digi,
-    Cluster,
-    Hit,
-  };
-
-}  // namespace cbm::algo
-
-CBM_ENUM_DICT(cbm::algo::Detector,
-  {"STS", Detector::STS},
-  {"TOF", Detector::TOF}
-);
-
-CBM_ENUM_DICT(cbm::algo::Step,
-  {"Unpack", Step::Unpack},
-  {"DigiTrigger", Step::DigiTrigger},
-  {"LocalReco", Step::LocalReco}
-);
-
-CBM_ENUM_DICT(cbm::algo::RecoData,
-  {"Digi", RecoData::Digi},
-  {"Cluster", RecoData::Cluster},
-  {"Hit", RecoData::Hit}
-);
-
-#endif
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 0d3c0ffc506e0d30d9429a54bebeeac62caedc73..fba6629a2e6a694939b499328b954933c0bdd70f 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -24,7 +24,12 @@ void Reco::Validate(const Options& opts)
     throw std::runtime_error("ParamsDir does not exist: " + opts.ParamsDir().string());
   }
 
-  if (opts.HasDetector(Detector::TOF)) { throw std::runtime_error("TOF not implemented yet"); }
+  for (auto detector : opts.Detectors()) {
+    switch (detector) {
+      case fles::SubsystemIdentifier::STS: break;
+      default: throw std::runtime_error(fmt::format("Unsupported system: {}", ToString(detector)));
+    }
+  }
 }
 
 void Reco::Init(const Options& opts)