diff --git a/macro/reco/reco_steer.C b/macro/reco/reco_steer.C
index 853356e24f3f8f1287d0a47c119fe09c71c3b368..1fc55ceec3e590049c8579a74c54b14cea58c588 100644
--- a/macro/reco/reco_steer.C
+++ b/macro/reco/reco_steer.C
@@ -22,8 +22,8 @@ using std::string;
  ** @author Volker Friese <v.friese@gsi.de>
  ** @since  12 March 2022
  ** @param tsaFile    Name of input file (w/o extension .tsa)
- ** @param numTs      Number of timeslice to process. If -1, all available will be used.
  ** @param outFile    Name of output file (w/o extension .digi.root)
+ ** @param numTs      Number of timeslices to process. If not specified, all available will be used.
  **
  ** Reconstruction from timeslice level, making use of the steering class CbmReco.
  ** Currently included stages:
@@ -36,7 +36,7 @@ using std::string;
  ** the extension .tsa by .digi.root
  **/
 
-void reco_steer(TString tsaFile = "", int32_t numTs = -1, TString outFile = "")
+void reco_steer(TString tsaFile = "", TString outFile = "", int32_t numTs = std::numeric_limits<int32_t>::max())
 {
 
   // ========================================================================
diff --git a/reco/tasks/CbmReco.cxx b/reco/tasks/CbmReco.cxx
index b9f34ace604dd55aa1417ce08916440b1acdd736..ccfd00a3167782bea1354549e17e8d5f2de8b7db 100644
--- a/reco/tasks/CbmReco.cxx
+++ b/reco/tasks/CbmReco.cxx
@@ -129,19 +129,22 @@ int32_t CbmReco::Run()
 
   // --- Run log
   std::cout << std::endl;
+  auto src = dynamic_cast<CbmSourceTs*>(run.GetSource());
+  assert(src);
+  size_t numTs     = src->GetNumTs();
   double timeTotal = timeSetup + timeInit + timeRun;
   LOG(info) << "=====================================";
   LOG(info) << "Reco: Run summary";
-  LOG(info) << "Timeslices  : " << fNumTs;
+  LOG(info) << "Timeslices  : " << numTs;
   LOG(info) << "Time setup  : " << timeSetup << " s";
   LOG(info) << "Time init   : " << timeInit << " s";
   LOG(info) << "Time run    : " << timeRun << " s";
   LOG(info) << "Time total  : " << timeTotal << " s"
-            << " (" << timeTotal / fNumTs << " s/ts)";
+            << " (" << timeTotal / numTs << " s/ts)";
   LOG(info) << "Output file : " << fOutputFileName;
   LOG(info) << "=====================================";
 
-  return fNumTs;
+  return numTs;
 }
 // ----------------------------------------------------------------------------
 
diff --git a/reco/tasks/CbmReco.h b/reco/tasks/CbmReco.h
index b0e806ef76c96555fd3f96aed126eeb9121a2717..32dbdb004859a5bf490afc24718b816418c000e9 100644
--- a/reco/tasks/CbmReco.h
+++ b/reco/tasks/CbmReco.h
@@ -95,9 +95,9 @@ public:
 
 private:
   std::vector<std::string> fSourceNames = {};  ///< Sources (input files or stream)
-  TString fOutputFileName               = "";
-  int32_t fNumTs                        = -1;
-  CbmRecoConfig fConfig                 = {};
+  TString fOutputFileName               = "";  ///< Output file
+  int32_t fNumTs                        = 0;   ///< Number of timeslices to process
+  CbmRecoConfig fConfig                 = {};  ///< Configuration parameters
 
   ClassDef(CbmReco, 1);
 };
diff --git a/reco/tasks/CbmSourceTs.cxx b/reco/tasks/CbmSourceTs.cxx
index f5c89275a6b561db982688c9e721f66b6cdc59aa..17fc083a9965dad5e32124397e2967f1bc5efed6 100644
--- a/reco/tasks/CbmSourceTs.cxx
+++ b/reco/tasks/CbmSourceTs.cxx
@@ -54,15 +54,22 @@ Bool_t CbmSourceTs::Init()
 // -----   Read one time slice from archive   ---------------------------------
 Int_t CbmSourceTs::ReadEvent(UInt_t)
 {
+  // Timeslices can only be read sequentially, so the argument is ignored.
+  // It appears that the first call to this method from FairRunOnline is in the
+  // init stage. In order not to always lose the first timeslice, a call to
+  // TimesliceSource::get is avoided in the first call.
   std::cout << std::endl;
-  fFlesTs = fFlesSource->get();
-  if (!fFlesTs) {
-    LOG(info) << "SourceTs: End of archive reached; stopping run.";
-    return 1;
+  if (fNumCalls == 0) LOG(info) << "SourceTs: Init call to ReadEvent";
+  else {
+    fFlesTs = fFlesSource->get();
+    if (!fFlesTs) {
+      LOG(info) << "SourceTs: End of archive reached; stopping run.";
+      return 1;
+    }
+    LOG(info) << "SourceTs: Reading time slice " << GetNumTs() << " (index " << fFlesTs->index()
+              << ") at t = " << fFlesTs->start_time() << " ns";
   }
-  LOG(info) << "SourceTs: Reading time slice " << fNumTs << " (index " << fFlesTs->index()
-            << ") at t = " << fFlesTs->start_time() << " ns";
-  fNumTs++;
+  fNumCalls++;
   return 0;
 }
 // ----------------------------------------------------------------------------
diff --git a/reco/tasks/CbmSourceTs.h b/reco/tasks/CbmSourceTs.h
index b5c48a6205aca7ea8872fc29e2f600acca8b1e58..a5541f7d2ee1d4c54c679541582e3f7b8ddd4506 100644
--- a/reco/tasks/CbmSourceTs.h
+++ b/reco/tasks/CbmSourceTs.h
@@ -64,6 +64,14 @@ public:
   virtual void Close();
 
 
+  /** @brief Number of processed timeslices
+   ** @return Number of timeslices
+   **
+   ** The first call to ReadEvent is in Init, so not timeslice is processed.
+   **/
+  size_t GetNumTs() const { return fNumCalls - 1; }
+
+
   /** @brief Demanded by base class **/
   virtual Source_Type GetSourceType() { return kFILE; }
 
@@ -111,8 +119,8 @@ private:  // member variables
   /** Pointer to current time slice **/
   std::unique_ptr<fles::Timeslice> fFlesTs = nullptr;  //!
 
-  /** Time-slice counter **/
-  size_t fNumTs = 0;
+  /** ReadEvent call counter **/
+  size_t fNumCalls = 0;
 
 
   ClassDef(CbmSourceTs, 1)