diff --git a/algo/detectors/tof/UnpackTof.cxx b/algo/detectors/tof/UnpackTof.cxx
index 03d182708fdda3e1d09e058e557cf741a5ec3b87..5ce7650562f7097473d75a4df2262b8ddfa7f57d 100644
--- a/algo/detectors/tof/UnpackTof.cxx
+++ b/algo/detectors/tof/UnpackTof.cxx
@@ -18,15 +18,16 @@ namespace cbm::algo
 
   // ----   Algorithm execution   ---------------------------------------------
   UnpackTof::resultType UnpackTof::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
-                                              const uint64_t tTimeslice)
+                                              const uint64_t tTimeslice) const
   {
 
     // --- Output data
     resultType result = {};
+    TimeSpec time     = {};
 
     // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs
     // --- and the epoch is a multiple of ns.
-    fCurrentTsTime = static_cast<uint64_t>(tTimeslice / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
+    time.currentTsTime = static_cast<uint64_t>(tTimeslice / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
 
     // --- Number of messages in microslice
     auto msSize = msDescr.size;
@@ -72,11 +73,11 @@ namespace cbm::algo
       switch (message[messageNr].getMessageType()) {
 
         case critof001::MSG_HIT: {
-          ProcessHitMessage(message[messageNr], result.first, result.second);
+          ProcessHitMessage(message[messageNr], result.first, result.second, time);
           break;
         }
         case critof001::MSG_EPOCH: {
-          ProcessEpochMessage(message[messageNr]);
+          ProcessEpochMessage(message[messageNr], time);
           break;
         }
         case critof001::MSG_SLOWC: {
@@ -101,7 +102,7 @@ namespace cbm::algo
 
   // -----   Process hit message   --------------------------------------------
   inline void UnpackTof::ProcessHitMessage(const critof001::Message& message, vector<CbmTofDigi>& digiVec,
-                                           UnpackTofMonitorData& monitor) const
+                                           UnpackTofMonitorData& monitor, TimeSpec& time) const
   {
     // --- Check eLink and get parameters
     const uint32_t elink = message.getGet4Idx();
@@ -114,7 +115,7 @@ namespace cbm::algo
     const uint32_t channel    = message.getGdpbHitChanId();
     const uint32_t channelUId = (elinkPar.fChannelUId)[channel];
 
-    double messageTime  = message.getMsgFullTimeD(fCurrentEpochInTs) - elinkPar.fTimeOffset;
+    double messageTime  = message.getMsgFullTimeD(time.currentEpochInTs) - elinkPar.fTimeOffset;
     const double charge = (double) message.getGdpbHit32Tot();  //cast from uint32_t
 
     // --- Create output digi
@@ -124,14 +125,14 @@ namespace cbm::algo
 
 
   // -----   Process an epoch message   ---------------------------------------
-  inline void UnpackTof::ProcessEpochMessage(const critof001::Message& message)
+  inline void UnpackTof::ProcessEpochMessage(const critof001::Message& message, TimeSpec& time) const
   {
     const uint64_t epoch = message.getGdpbEpEpochNb();
 
     // --- Calculate epoch relative to timeslice start time; correct for epoch cycles
-    if (fCurrentTsTime <= epoch) { fCurrentEpochInTs = epoch - fCurrentTsTime; }
+    if (time.currentTsTime <= epoch) { time.currentEpochInTs = epoch - time.currentTsTime; }
     else {
-      fCurrentEpochInTs = epoch + critof001::kulEpochCycleEp - fCurrentTsTime;
+      time.currentEpochInTs = epoch + critof001::kulEpochCycleEp - time.currentTsTime;
     }
     //Problem if MS spans multiple epoch cycles?
   }
diff --git a/algo/detectors/tof/UnpackTof.h b/algo/detectors/tof/UnpackTof.h
index ad4453ac97bb9686ea9ae8ee55f7f5107b397271..0b4457c56f0b2b5d99b7cdbd87985c59b4fc51f1 100644
--- a/algo/detectors/tof/UnpackTof.h
+++ b/algo/detectors/tof/UnpackTof.h
@@ -19,6 +19,7 @@
 #include <vector>
 
 #include "CriGet4Mess001.h"
+#include "Prelude.h"
 
 namespace cbm::algo
 {
@@ -96,13 +97,19 @@ namespace cbm::algo
      ** @return STS digi data
      **/
     resultType operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
-                          const uint64_t tTimeslice);
+                          const uint64_t tTimeslice) const;
 
     /** @brief Set the parameter container
      ** @param params Pointer to parameter container
      **/
     void SetParams(std::unique_ptr<UnpackTofPar> params) { fParams = *(std::move(params)); }
 
+  private:  // types
+    struct TimeSpec {
+      u64 currentTsTime    = 0;  ///< Unix time of timeslice in units of epoch length
+      u32 currentEpochInTs = 0;  ///< Current epoch number relative to timeslice start epoch
+    };
+
   private:  // methods
     /** @brief Process a hit message
      ** @param message SMX message (32-bit word)
@@ -110,16 +117,14 @@ namespace cbm::algo
      ** @param monitor Reference to monitor object
      **/
     void ProcessHitMessage(const critof001::Message& message, std::vector<CbmTofDigi>& digiVec,
-                           UnpackTofMonitorData& monitor) const;
+                           UnpackTofMonitorData& monitor, TimeSpec& time) const;
 
-    /** @brief Process an epoch message 
+    /** @brief Process an epoch message
      ** @param message SMX message (32-bit word)
      **/
-    void ProcessEpochMessage(const critof001::Message& message);
+    void ProcessEpochMessage(const critof001::Message& message, TimeSpec& time) const;
 
   private:                            // members
-    uint64_t fCurrentTsTime    = 0;   ///< Unix time of timeslice in units of epoch length
-    uint32_t fCurrentEpochInTs = 0;   ///< Current epoch number relative to timeslice start epoch
     UnpackTofPar fParams       = {};  ///< Parameter container
   };