From 9bb00372740c04ab7b78ef4bcc24231e0c58f2fc Mon Sep 17 00:00:00 2001
From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
Date: Thu, 22 Feb 2024 11:23:29 +0000
Subject: [PATCH] online: Reduce compile times.

---
 algo/CMakeLists.txt                      |  5 ++
 algo/base/RecoParams.cxx                 |  6 ++
 algo/base/RecoParams.h                   |  3 +
 algo/base/config/Yaml.h                  | 59 +++++++++++++++---
 algo/ca/core/tracking/CaCloneMerger.h    |  1 +
 algo/data/sts/HitfinderPars.cxx          |  8 +++
 algo/data/sts/HitfinderPars.h            |  8 ++-
 algo/detectors/sts/ChannelMaskSet.cxx    |  8 +++
 algo/detectors/sts/ChannelMaskSet.h      |  3 +
 algo/detectors/sts/ReadoutConfig.cxx     |  2 +
 algo/detectors/sts/ReadoutConfig.h       |  3 +
 algo/detectors/sts/WalkMap.cxx           |  2 +
 algo/detectors/sts/WalkMap.h             |  3 +
 algo/detectors/trd/ReadoutConfig.cxx     |  2 +
 algo/detectors/trd/ReadoutConfig.h       |  8 +--
 algo/detectors/trd/UnpackMS.cxx          |  5 +-
 algo/detectors/trd2d/ReadoutConfig.cxx   |  2 +
 algo/detectors/trd2d/ReadoutConfig.h     |  8 +--
 algo/detectors/trd2d/UnpackMS.h          |  2 -
 algo/global/Reco.cxx                     | 24 +++++---
 algo/global/Reco.h                       | 77 +++++++++++++++++++-----
 algo/global/RecoResults.h                |  1 +
 algo/global/RecoResultsInputArchive.cxx  | 11 ++++
 algo/global/RecoResultsInputArchive.h    | 10 ++-
 algo/global/RecoResultsOutputArchive.cxx | 11 ++++
 algo/global/RecoResultsOutputArchive.h   | 10 ++-
 core/data/trd/CbmTrdDigi.h               |  1 -
 core/data/trd/CbmTrdRawMessageSpadic.h   |  1 -
 28 files changed, 229 insertions(+), 55 deletions(-)
 create mode 100644 algo/base/RecoParams.cxx
 create mode 100644 algo/data/sts/HitfinderPars.cxx
 create mode 100644 algo/detectors/sts/ChannelMaskSet.cxx
 create mode 100644 algo/global/RecoResultsInputArchive.cxx
 create mode 100644 algo/global/RecoResultsOutputArchive.cxx

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 3790983c8a..c96bac5cfd 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -72,7 +72,9 @@ set(SRCS
   base/DigiData.cxx
   base/Options.cxx
   base/MainConfig.cxx
+  base/RecoParams.cxx
   base/util/TimingsFormat.cxx
+  data/sts/HitfinderPars.cxx
   data/sts/LandauTable.cxx
   evbuild/Config.cxx
   evbuild/EventBuilder.cxx
@@ -83,6 +85,7 @@ set(SRCS
   evselector/DigiEventSelector.cxx
   evselector/DigiEventSelectorConfig.cxx
   unpack/CommonUnpacker.cxx
+  detectors/sts/ChannelMaskSet.cxx
   detectors/sts/ChannelMaskSet_mCBM2022.cxx
   detectors/sts/ReadoutConfig.cxx
   detectors/sts/ReadoutConfig_mCBM2022.cxx
@@ -116,6 +119,8 @@ set(SRCS
   detectors/rich/Unpack.cxx
   detectors/rich/UnpackMS.cxx
   global/Reco.cxx
+  global/RecoResultsInputArchive.cxx
+  global/RecoResultsOutputArchive.cxx
   qa/DigiEventQa.cxx
   qa/Histo1D.cxx
   qa/CanvasConfig.cxx
diff --git a/algo/base/RecoParams.cxx b/algo/base/RecoParams.cxx
new file mode 100644
index 0000000000..851df115fa
--- /dev/null
+++ b/algo/base/RecoParams.cxx
@@ -0,0 +1,6 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+#include "RecoParams.h"
+
+CBM_YAML_INSTANTIATE(cbm::algo::RecoParams);
diff --git a/algo/base/RecoParams.h b/algo/base/RecoParams.h
index d51fdbef8f..22a01f3769 100644
--- a/algo/base/RecoParams.h
+++ b/algo/base/RecoParams.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 #include "util/EnumDict.h"
 
 #include <xpu/defines.h>
@@ -95,6 +96,8 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
+CBM_YAML_EXTERN_DECL(cbm::algo::RecoParams);
+
 CBM_ENUM_DICT(cbm::algo::RecoParams::SortMode,
   {"BlockSort", RecoParams::SortMode::BlockSort},
   {"CUBSegmentedSort", RecoParams::SortMode::CUBSegmentedSort}
diff --git a/algo/base/config/Yaml.h b/algo/base/config/Yaml.h
index c73124ef14..d7b5d5c0c3 100644
--- a/algo/base/config/Yaml.h
+++ b/algo/base/config/Yaml.h
@@ -55,9 +55,19 @@ namespace cbm::algo::config
     return Read<T>(node);
   }
 
+
   template<typename T>
   T Read(const YAML::Node& node)
   {
+// Disable uninitialized warning for the whole function.
+// GCC 11.4 sometimes incorrectly warns about uninitialized variables in constexpr if branches.
+// I'm fairly certain this is a compiler bug, because it only happens when
+// explicitly instantiating the function template. And the error message
+// references a variable 't' that doesn't exist in the function!
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
     using Type = std::remove_cv_t<std::remove_reference_t<T>>;
 
     static_assert(!IsEnum<T> || detail::EnumHasDict_v<T>, "Enum must have a dictionary to be deserializable");
@@ -102,7 +112,7 @@ namespace cbm::algo::config
 
       static_assert(IsScalar<Key_t>, "Map key must be a fundamental or enum type");
 
-      Type map;
+      Type map{};
       for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) {
         const auto& key       = it->first;
         const auto& value     = it->second;
@@ -111,7 +121,7 @@ namespace cbm::algo::config
       return map;
     }
     else {
-      Type object;
+      Type object{};
 
       constexpr auto nProperties = std::tuple_size<decltype(Type::Properties)>::value;
 
@@ -132,6 +142,10 @@ namespace cbm::algo::config
 
       return object;
     }
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
   }
 
   template<typename T>
@@ -202,15 +216,28 @@ namespace cbm::algo::config
           ss << object;
       }
       else if constexpr (IsEnum<T>) {
-        ss << ToString<T>(object);
+        ss << std::string{ToString<T>(object)};
       }
       else if constexpr (IsVector<T> || IsArray<T> || IsSet<T>) {
         ss << YAML::BeginSeq;
-        for (const auto& element : object) {
-          if (formatEntries.has_value()) {
-            ss << formatEntries.value();
+        // Special case for vector<bool> because it is not a real vector
+        // Clang does not the compile the generic version of the loop
+        // in this case.
+        if constexpr (std::is_same_v<T, std::vector<bool>>) {
+          for (bool element : object) {
+            if (formatEntries.has_value()) {
+              ss << formatEntries.value();
+            }
+            ss << element;
+          }
+        }
+        else {
+          for (const auto& element : object) {
+            if (formatEntries.has_value()) {
+              ss << formatEntries.value();
+            }
+            DoDump(element, ss);
           }
-          DoDump(element, ss);
         }
         ss << YAML::EndSeq;
       }
@@ -262,4 +289,22 @@ namespace cbm::algo::config
 
 }  // namespace cbm::algo::config
 
+/**
+ * @brief Declare the external instantiation of the Read and Dump functions for a type.
+ * @param type The type to declare the external instantiation for.
+ * @note This macro should be used in a header file to declare the external instantiation of the Read and Dump.
+ * Must be paired with CBM_YAML_INSTANTIATE in a source file.
+ **/
+#define CBM_YAML_EXTERN_DECL(type)                                                                                     \
+  extern template type cbm::algo::config::Read<type>(const YAML::Node& node);                                          \
+  extern template std::string cbm::algo::config::Dump::operator()<type>(const type& value, int floatPrecision)
+
+/**
+ * @brief Explicitly instantiate the Read and Dump functions for a type.
+ * @see CBM_YAML_EXTERN_DECL
+ */
+#define CBM_YAML_INSTANTIATE(type)                                                                                     \
+  template type cbm::algo::config::Read<type>(const YAML::Node& node);                                                 \
+  template std::string cbm::algo::config::Dump::operator()<type>(const type& value, int floatPrecision);
+
 #endif
diff --git a/algo/ca/core/tracking/CaCloneMerger.h b/algo/ca/core/tracking/CaCloneMerger.h
index c16d53fe4f..0cef1c285d 100644
--- a/algo/ca/core/tracking/CaCloneMerger.h
+++ b/algo/ca/core/tracking/CaCloneMerger.h
@@ -11,6 +11,7 @@
 
 #include "CaHit.h"   // For ca::HitIndex_t
 #include "CaSimd.h"  // TEMPORARY FOR fvec, fscal
+#include "CaTrack.h"
 #include "CaVector.h"
 
 
diff --git a/algo/data/sts/HitfinderPars.cxx b/algo/data/sts/HitfinderPars.cxx
new file mode 100644
index 0000000000..ac6fe3baca
--- /dev/null
+++ b/algo/data/sts/HitfinderPars.cxx
@@ -0,0 +1,8 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "HitfinderPars.h"
+
+using namespace cbm::algo;
+CBM_YAML_INSTANTIATE(sts::HitfinderPars);
diff --git a/algo/data/sts/HitfinderPars.h b/algo/data/sts/HitfinderPars.h
index 84e99607ed..b0923900ec 100644
--- a/algo/data/sts/HitfinderPars.h
+++ b/algo/data/sts/HitfinderPars.h
@@ -1,12 +1,14 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_DATA_STS_HITFINDERPARS_H
-#define CBM_ALGO_DATA_STS_HITFINDERPARS_H
+#pragma once
 
 #include "Definitions.h"
 #include "LandauTable.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
+
+#include <xpu/defines.h>
 
 namespace cbm::algo::sts
 {
@@ -78,4 +80,4 @@ namespace cbm::algo::sts
   };
 }  // namespace cbm::algo::sts
 
-#endif
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::HitfinderPars);
diff --git a/algo/detectors/sts/ChannelMaskSet.cxx b/algo/detectors/sts/ChannelMaskSet.cxx
new file mode 100644
index 0000000000..10dce9224e
--- /dev/null
+++ b/algo/detectors/sts/ChannelMaskSet.cxx
@@ -0,0 +1,8 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer], Dominik Smith */
+
+#include "ChannelMaskSet.h"
+
+using namespace cbm::algo;
+CBM_YAML_INSTANTIATE(sts::ChannelMaskSet);
diff --git a/algo/detectors/sts/ChannelMaskSet.h b/algo/detectors/sts/ChannelMaskSet.h
index 0523eaec5e..aab508cee3 100644
--- a/algo/detectors/sts/ChannelMaskSet.h
+++ b/algo/detectors/sts/ChannelMaskSet.h
@@ -7,6 +7,7 @@
 #include "Definitions.h"
 #include "compat/Filesystem.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <set>
@@ -49,3 +50,5 @@ namespace cbm::algo::sts
   };
 
 }  // namespace cbm::algo::sts
+
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::ChannelMaskSet);
diff --git a/algo/detectors/sts/ReadoutConfig.cxx b/algo/detectors/sts/ReadoutConfig.cxx
index c50ef025b1..1d08012559 100644
--- a/algo/detectors/sts/ReadoutConfig.cxx
+++ b/algo/detectors/sts/ReadoutConfig.cxx
@@ -14,6 +14,8 @@ using std::setw;
 
 using namespace cbm::algo;
 
+CBM_YAML_INSTANTIATE(sts::ReadoutSetup);
+
 sts::ReadoutConfig::ReadoutConfig(const ReadoutSetup& config, const ChannelMaskSet& chanMaskSet)
 {
   Init(config, chanMaskSet);
diff --git a/algo/detectors/sts/ReadoutConfig.h b/algo/detectors/sts/ReadoutConfig.h
index 23366c8dc8..324b3efca0 100644
--- a/algo/detectors/sts/ReadoutConfig.h
+++ b/algo/detectors/sts/ReadoutConfig.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <string>
@@ -161,4 +162,6 @@ namespace cbm::algo::sts
 
 }  // namespace cbm::algo::sts
 
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::ReadoutSetup);
+
 #endif  // CBM_ALGO_DETECTOR_STS_READOUT_CONFIG_H
diff --git a/algo/detectors/sts/WalkMap.cxx b/algo/detectors/sts/WalkMap.cxx
index e1ab3a314d..e97620a5d6 100644
--- a/algo/detectors/sts/WalkMap.cxx
+++ b/algo/detectors/sts/WalkMap.cxx
@@ -6,6 +6,8 @@
 
 using namespace cbm::algo::sts;
 
+CBM_YAML_INSTANTIATE(WalkMap);
+
 std::vector<double> WalkMap::Get(int32_t modAddress, uint16_t asic)
 {
   std::vector<double> result;
diff --git a/algo/detectors/sts/WalkMap.h b/algo/detectors/sts/WalkMap.h
index 139a8d985e..04fcc7df31 100644
--- a/algo/detectors/sts/WalkMap.h
+++ b/algo/detectors/sts/WalkMap.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <vector>
@@ -57,3 +58,5 @@ namespace cbm::algo::sts
   };
 
 }  // namespace cbm::algo::sts
+
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::WalkMap);
diff --git a/algo/detectors/trd/ReadoutConfig.cxx b/algo/detectors/trd/ReadoutConfig.cxx
index 1a462bbfa4..828665b6ff 100644
--- a/algo/detectors/trd/ReadoutConfig.cxx
+++ b/algo/detectors/trd/ReadoutConfig.cxx
@@ -14,6 +14,8 @@
 using std::pair;
 using std::setw;
 
+CBM_YAML_INSTANTIATE(cbm::algo::trd::ReadoutConfig);
+
 namespace cbm::algo::trd
 {
 
diff --git a/algo/detectors/trd/ReadoutConfig.h b/algo/detectors/trd/ReadoutConfig.h
index 98528a7fbd..b8730f47b6 100644
--- a/algo/detectors/trd/ReadoutConfig.h
+++ b/algo/detectors/trd/ReadoutConfig.h
@@ -2,10 +2,10 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese [committer] */
 
-#ifndef ALGO_DETECTORS_TRD_READOUTCONFIG_H
-#define ALGO_DETECTORS_TRD_READOUTCONFIG_H
+#pragma once
 
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <sstream>
@@ -36,7 +36,7 @@ namespace cbm::algo::trd
 
 
     /** @brief Destructor **/
-    virtual ~ReadoutConfig();
+    ~ReadoutConfig();
 
 
     /** @brief Equipment in the configuration
@@ -92,4 +92,4 @@ namespace cbm::algo::trd
 
 }  // namespace cbm::algo::trd
 
-#endif /* ALGO_DETECTORS_TRD_READOUTCONFIG_H_ */
+CBM_YAML_EXTERN_DECL(cbm::algo::trd::ReadoutConfig);
diff --git a/algo/detectors/trd/UnpackMS.cxx b/algo/detectors/trd/UnpackMS.cxx
index 72b6f7ab59..1ae1f29bf2 100644
--- a/algo/detectors/trd/UnpackMS.cxx
+++ b/algo/detectors/trd/UnpackMS.cxx
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <log.hpp>
 #include <vector>
 
 using std::unique_ptr;
@@ -335,8 +336,8 @@ namespace cbm::algo::trd
       return Spadic::MsInfoType::kMIS;
     }
     else {
-      std::cout << "UnpackMS::GetInfoType] unknown type!" << std::endl;
-      exit(1);
+      // TODO: track this error
+      L_(error) << "UnpackMS::GetInfoType] unknown type!";
       return Spadic::MsInfoType::kMSB;
     }
   }
diff --git a/algo/detectors/trd2d/ReadoutConfig.cxx b/algo/detectors/trd2d/ReadoutConfig.cxx
index 067f7b1fe0..3aaa79b1c2 100644
--- a/algo/detectors/trd2d/ReadoutConfig.cxx
+++ b/algo/detectors/trd2d/ReadoutConfig.cxx
@@ -14,6 +14,8 @@
 using std::pair;
 using std::setw;
 
+CBM_YAML_INSTANTIATE(cbm::algo::trd2d::ReadoutConfig);
+
 namespace cbm::algo::trd2d
 {
 
diff --git a/algo/detectors/trd2d/ReadoutConfig.h b/algo/detectors/trd2d/ReadoutConfig.h
index a672169c60..6942caa9bc 100644
--- a/algo/detectors/trd2d/ReadoutConfig.h
+++ b/algo/detectors/trd2d/ReadoutConfig.h
@@ -2,11 +2,11 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese, Dominik Smith [committer] */
 
-#ifndef ALGO_DETECTORS_TRD2D_READOUTCONFIG_H
-#define ALGO_DETECTORS_TRD2D_READOUTCONFIG_H
+#pragma once
 
 #include "UnpackMS.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <sstream>
@@ -57,7 +57,7 @@ namespace cbm::algo::trd2d
 
 
     /** @brief Destructor **/
-    virtual ~ReadoutConfig();
+    ~ReadoutConfig();
 
 
     /** @brief Equipment in the configuration
@@ -126,4 +126,4 @@ namespace cbm::algo::trd2d
 
 }  // namespace cbm::algo::trd2d
 
-#endif /* ALGO_DETECTORS_TRD2D_READOUTCONFIG_H_ */
+CBM_YAML_EXTERN_DECL(cbm::algo::trd2d::ReadoutConfig);
diff --git a/algo/detectors/trd2d/UnpackMS.h b/algo/detectors/trd2d/UnpackMS.h
index 7f1f4f5356..264b30ae44 100644
--- a/algo/detectors/trd2d/UnpackMS.h
+++ b/algo/detectors/trd2d/UnpackMS.h
@@ -6,10 +6,8 @@
 #include "CbmTrdDigi.h"
 #include "CbmTrdRawMessageSpadic.h"
 #include "MicrosliceDescriptor.hpp"
-#include "Timeslice.hpp"
 
 #include <array>
-#include <cmath>
 #include <memory>
 #include <sstream>
 
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 785f6b936f..57964a6958 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -5,12 +5,22 @@
 
 #include "BuildInfo.h"
 #include "CbmDigiEvent.h"
+#include "EventbuildChain.h"
 #include "Exceptions.h"
+#include "HistogramSender.h"
+#include "bmon/Unpack.h"
+#include "ca/TrackingChain.h"
 #include "compat/OpenMP.h"
 #include "config/Yaml.h"
 #include "evbuild/Config.h"
 #include "log.hpp"
+#include "much/Unpack.h"
+#include "rich/Unpack.h"
 #include "sts/ChannelMaskSet.h"
+#include "sts/Unpack.h"
+#include "tof/Unpack.h"
+#include "trd/Unpack.h"
+#include "trd2d/Unpack.h"
 #include "util/TimingsFormat.h"
 #include "util/TsUtils.h"
 
@@ -80,9 +90,7 @@ void Reco::Init(const Options& opts)
   }
 
   // Reco Params
-  fs::path recoParamsPath = opts.ParamsDir() / "RecoParams.yaml";
-  YAML::Node yaml         = YAML::LoadFile(recoParamsPath.string());
-  fContext.recoParams     = config::Read<RecoParams>(yaml);
+  fContext.recoParams = config::ReadFromFile<RecoParams>(opts.ParamsDir() / "RecoParams.yaml");
 
   // Unpackers
   if (Opts().Has(Subsystem::BMON) && Opts().Has(Step::Unpack)) {
@@ -115,14 +123,12 @@ void Reco::Init(const Options& opts)
   }
 
   if (Opts().Has(Subsystem::TRD) && Opts().Has(Step::Unpack)) {
-    yaml       = YAML::LoadFile((Opts().ParamsDir() / "TrdReadoutSetup.yaml").string());
-    auto cfg   = config::Read<trd::ReadoutConfig>(yaml);
+    auto cfg   = config::ReadFromFile<trd::ReadoutConfig>(Opts().ParamsDir() / "TrdReadoutSetup.yaml");
     fTrdUnpack = std::make_unique<trd::Unpack>(cfg);
   }
 
   if (Opts().Has(Subsystem::TRD2D) && Opts().Has(Step::Unpack)) {
-    yaml         = YAML::LoadFile((Opts().ParamsDir() / "Trd2dReadoutSetup.yaml").string());
-    auto cfg     = config::Read<trd2d::ReadoutConfig>(yaml);
+    auto cfg     = config::ReadFromFile<trd2d::ReadoutConfig>(Opts().ParamsDir() / "Trd2dReadoutSetup.yaml");
     fTrd2dUnpack = std::make_unique<trd2d::Unpack>(cfg);
   }
 
@@ -132,9 +138,7 @@ void Reco::Init(const Options& opts)
   fEventBuild = std::make_unique<evbuild::EventbuildChain>(config, fSender);
 
   // STS Hitfinder
-  fs::path stsHitfinderParamsPath   = opts.ParamsDir() / "StsHitfinder.yaml";
-  yaml                              = YAML::LoadFile(stsHitfinderParamsPath.string());
-  sts::HitfinderPars hitFinderSetup = config::Read<sts::HitfinderPars>(yaml);
+  sts::HitfinderPars hitFinderSetup = config::ReadFromFile<sts::HitfinderPars>(opts.ParamsDir() / "StsHitfinder.yaml");
   hitFinderSetup.landauTable        = sts::LandauTable::FromFile(opts.ParamsDir() / "LandauWidthTable.txt");
   sts::HitfinderChainPars hitFinderPars;
   hitFinderPars.setup  = std::move(hitFinderSetup);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 569c7bbe8e..6846544a88 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -1,37 +1,86 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECO_H
-#define CBM_ALGO_GLOBAL_RECO_H
+#pragma once
 
 #include "AlgoTraits.h"
-#include "EventbuildChain.h"
-#include "HistogramSender.h"
 #include "SubChain.h"
-#include "bmon/Unpack.h"
-#include "ca/TrackingChain.h"
 #include "global/RecoResults.h"
-#include "much/Unpack.h"
-#include "rich/Unpack.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"
 
 #include <xpu/host.h>
 
+// fwd declarations
 namespace fles
 {
   class Timeslice;
-}  // namespace fles
+}
 
 namespace cbm::algo
 {
+  class HistogramSender;
   class Options;
+  class TrackingChain;
+
+  template<class M>
+  struct UnpackMonitor;
+
+  namespace bmon
+  {
+    class Unpack;
+  }
+
+  namespace much
+  {
+    class Unpack;
+  }
+
+  namespace rich
+  {
+    class Unpack;
+  }
+
+  namespace sts
+  {
+    class Unpack;
+  }
+
+  namespace tof
+  {
+    class Unpack;
+  }
+
+  namespace trd
+  {
+    class Unpack;
+  }
+
+  namespace trd2d
+  {
+    class Unpack;
+  }
+
+  namespace evbuild
+  {
+    class EventbuildChain;
+    struct EventbuildChainMonitorData;
+  }  // namespace evbuild
+
+  namespace ca
+  {
+    template<class C, class T>
+    class MonitorData;
+    enum class ECounter;
+    enum class ETimer;
+    using TrackingMonitorData = MonitorData<ECounter, ETimer>;
+  }  // namespace ca
 
+}  // namespace cbm::algo
+
+namespace cbm::algo
+{
   struct ProcessingMonitor {
     xpu::timings time;           //< total processing time
     xpu::timings timeUnpack;     //< time spent in unpacking
@@ -106,5 +155,3 @@ namespace cbm::algo
     void QueueProcessingMetrics(const ProcessingMonitor&);
   };
 }  // namespace cbm::algo
-
-#endif
diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h
index 1fd92e64ca..4fa01c8f16 100644
--- a/algo/global/RecoResults.h
+++ b/algo/global/RecoResults.h
@@ -12,6 +12,7 @@
 #include "DigiData.h"
 #include "PartitionedSpan.h"
 #include "PartitionedVector.h"
+#include "ca/core/data/CaTrack.h"
 #include "ca/core/utils/CaVector.h"
 #include "sts/Cluster.h"
 #include "sts/Hit.h"
diff --git a/algo/global/RecoResultsInputArchive.cxx b/algo/global/RecoResultsInputArchive.cxx
new file mode 100644
index 0000000000..650f014e8a
--- /dev/null
+++ b/algo/global/RecoResultsInputArchive.cxx
@@ -0,0 +1,11 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "RecoResultsInputArchive.h"
+
+namespace fles
+{
+  template class InputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                              ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsInputArchive.h b/algo/global/RecoResultsInputArchive.h
index 4291d47f57..f73e338265 100644
--- a/algo/global/RecoResultsInputArchive.h
+++ b/algo/global/RecoResultsInputArchive.h
@@ -1,8 +1,7 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
-#define CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
+#pragma once
 
 #include "StorableRecoResults.h"
 
@@ -16,4 +15,9 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
-#endif  // CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
+// explicit instantiation of the template class because of long compile times
+namespace fles
+{
+  extern template class InputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                                     ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsOutputArchive.cxx b/algo/global/RecoResultsOutputArchive.cxx
new file mode 100644
index 0000000000..e1094f362b
--- /dev/null
+++ b/algo/global/RecoResultsOutputArchive.cxx
@@ -0,0 +1,11 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "RecoResultsOutputArchive.h"
+
+namespace fles
+{
+  template class OutputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                               ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsOutputArchive.h b/algo/global/RecoResultsOutputArchive.h
index 2b574b51a8..8c673eb16d 100644
--- a/algo/global/RecoResultsOutputArchive.h
+++ b/algo/global/RecoResultsOutputArchive.h
@@ -1,8 +1,7 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
-#define CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
+#pragma once
 
 #include "StorableRecoResults.h"
 
@@ -16,4 +15,9 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
-#endif  // CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
+// explicit instantiation of the template class because of long compile times
+namespace fles
+{
+  extern template class OutputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                                      ArchiveType::RecoResultsArchive>;
+}
diff --git a/core/data/trd/CbmTrdDigi.h b/core/data/trd/CbmTrdDigi.h
index 3124b5cf9b..c8a5fcd280 100644
--- a/core/data/trd/CbmTrdDigi.h
+++ b/core/data/trd/CbmTrdDigi.h
@@ -12,7 +12,6 @@
 #endif
 
 #include <boost/serialization/access.hpp>
-#include <boost/serialization/base_object.hpp>
 
 #include <cstdint>
 #include <string>  // for string
diff --git a/core/data/trd/CbmTrdRawMessageSpadic.h b/core/data/trd/CbmTrdRawMessageSpadic.h
index abf4698f25..dff22a0ea0 100644
--- a/core/data/trd/CbmTrdRawMessageSpadic.h
+++ b/core/data/trd/CbmTrdRawMessageSpadic.h
@@ -12,7 +12,6 @@
 #define CbmTrdRawMessageSpadic_H
 
 #include <boost/serialization/access.hpp>
-#include <boost/serialization/base_object.hpp>
 #include <boost/serialization/vector.hpp>
 
 #include <cstdint>
-- 
GitLab