diff --git a/core/data/raw/StsXyterMessage.cxx b/core/data/raw/StsXyterMessage.cxx
index f0a84c32d730f51728a2ef65ed494285926e17db..ca0c66cd13a30027b7f1dbb77b6be093acfffcc9 100644
--- a/core/data/raw/StsXyterMessage.cxx
+++ b/core/data/raw/StsXyterMessage.cxx
@@ -30,7 +30,7 @@ MessSubType Message::GetSubType() const
   }  // switch( static_cast< uint16_t>( GetField( kFieldSubtype ) ) )
 }
 //----------------------------------------------------------------------------
-bool Message::PrintMess(std::ostream& os, MessagePrintMask ctrl) const
+bool Message::PrintMess(std::ostream& os, MessagePrintMask ctrl, bool bBinning) const
 {
   bool bPrintHex    = static_cast<bool>(ctrl & MessagePrintMask::msg_print_Hex);
   bool bPrintHuman  = static_cast<bool>(ctrl & MessagePrintMask::msg_print_Human);
@@ -62,14 +62,15 @@ bool Message::PrintMess(std::ostream& os, MessagePrintMask ctrl) const
       }  // case MessType::TsMsb
       case MessType::Hit: {
         os << " Hit => "
-           << " Lnk: " << std::setw(3) << GetLinkIndex() << " Ch: " << std::setw(3) << GetHitChannel()
-           << " Adc: " << std::setw(2) << GetHitAdc() << " Ts Full: " << std::setw(4) << GetHitTimeFull()
-           << " Ts Over: " << std::hex << GetHitTimeOver() << std::dec << " Ts: " << std::setw(3) << GetHitTime()
-           << " Missed? " << IsHitMissedEvts();
+           << " Lnk: " << std::setw(3) << (bBinning ? GetLinkIndexHitBinning() : GetLinkIndex())
+           << " Ch: " << std::setw(3) << GetHitChannel() << " Adc: " << std::setw(2) << GetHitAdc()
+           << " Ts Full: " << std::setw(4) << GetHitTimeFull() << " Ts Over: " << std::hex << GetHitTimeOver()
+           << std::dec << " Ts: " << std::setw(3) << (bBinning ? GetHitTimeBinning() : GetHitTime()) << " Missed? "
+           << IsHitMissedEvts();
         break;
       }  // case MessType::Hit
       case MessType::TsMsb: {
-        os << " TS_MSB => " << std::setw(12) << GetTsMsbVal();
+        os << " TS_MSB => " << std::setw(12) << (bBinning ? GetTsMsbValBinning() : GetTsMsbVal());
         break;
       }  // case MessType::TsMsb
       case MessType::Epoch: {
diff --git a/core/data/raw/StsXyterMessage.h b/core/data/raw/StsXyterMessage.h
index b5abab64ba2df9bd9ddf00f29fd7632cf0dc2675..1333545f41e4632c3bd85cfc8ffa2d465bc19074 100644
--- a/core/data/raw/StsXyterMessage.h
+++ b/core/data/raw/StsXyterMessage.h
@@ -375,7 +375,8 @@ namespace stsxyter
     inline void SetMsErrorType(uint16_t usVal) { SetField(kFieldMsErrType, usVal); }
 
     // ------------------------ General OP ---------------------------------------
-    bool PrintMess(std::ostream& os, MessagePrintMask ctrl = MessagePrintMask::msg_print_Human) const;
+    bool PrintMess(std::ostream& os, MessagePrintMask ctrl = MessagePrintMask::msg_print_Human,
+                   bool bBinning = true) const;
   };
 }  // namespace stsxyter
 #endif  // STSXYTERMESSAGE_H
diff --git a/macro/run/run_unpack_online.C b/macro/run/run_unpack_online.C
index 3eb427bdea8428aaeea07e19f25fd43b98400ba4..3d1c9bf7ebd6997bfac97bb45e967c04df10c10e 100644
--- a/macro/run/run_unpack_online.C
+++ b/macro/run/run_unpack_online.C
@@ -1,3 +1,7 @@
+/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Jan de Cuveland, Volker Friese, Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith, Adrian A. Weber  */
+
 /** @file run_unpack_tsa.C
  ** @author Volker Friese <v.friese@gsi.de>
  ** @since May 2021
@@ -47,7 +51,7 @@ std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline = false);
  ** selects the ideal raw event builder, which associates digis to events
  ** based on the MC truth. The option "Real" selects a real raw event builder
  ** (latest version, for older versions use "Real2018" or "Real2019").
- ** 
+ **
  **
  ** The file names must be specified without extensions. The convention is
  ** that the raw (input) file is [input].raw.root. The output file
@@ -169,7 +173,7 @@ void run_unpack_online(std::string publisher = "localhost", Int_t serverHttpPort
 
 /**
  * @brief Get the Trd Monitor. Extra function to keep default macro part more silent.
- * @return std::shared_ptr<CbmTrdUnpackMonitor> 
+ * @return std::shared_ptr<CbmTrdUnpackMonitor>
 */
 std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename)
 {
@@ -224,7 +228,7 @@ std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename)
 
 /**
  * @brief Get the Trd Spadic
- * @return std::shared_ptr<CbmTrdSpadic> 
+ * @return std::shared_ptr<CbmTrdSpadic>
 */
 std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline)
 {
diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C
index f44fdbca1a56a539f4d21cca289ae41f716c6d91..c6035e9da4cee5428bacc2c2d1757dd5e44c3a62 100644
--- a/macro/run/run_unpack_tsa.C
+++ b/macro/run/run_unpack_tsa.C
@@ -1,3 +1,7 @@
+/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Jan de Cuveland, Volker Friese, Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith, Adrian A. Weber  */
+
 /** @file run_unpack_tsa.C
  ** @author Volker Friese <v.friese@gsi.de>
  ** @since May 2021
@@ -120,6 +124,9 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha
     stsconfig->SetDoWriteOutput();
     std::string parfilesbasepathSts = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data());
     stsconfig->SetParFilesBasePath(parfilesbasepathSts);
+    /// Enable duplicates rejection, Ignores the ADC for duplicates check
+    //stsconfig->SetDuplicatesRejection ( true, true );
+    /// Enable Monitor plots
     //stsconfig->SetMonitor(GetStsMonitor(outfilename));
     stsconfig->SetSystemTimeOffset(-2221);  // [ns] value to be updated
   }
@@ -195,6 +202,8 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha
   auto unpack = source->GetRecoUnpack();
   unpack->SetDoPerfProfiling(doPerfProfiling);
   unpack->SetOutputFilename(perfProfFileName);
+  /// Enable full time sorting instead of time sorting per FLIM link
+  //unpack->SetTimeSorting(true);
   if (psdconfig) unpack->SetUnpackConfig(psdconfig);
   if (richconfig) unpack->SetUnpackConfig(richconfig);
   if (stsconfig) unpack->SetUnpackConfig(stsconfig);
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
index 917c66b4aeb7fab8b4d5bb29ba40e5eb3ddc93bd..e3362c73dd419c83e1e12198a2b627fb9b14ce7b 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
@@ -1,3 +1,6 @@
+/* Copyright (C) 2021 Goethe-University, Frankfurt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith */
 
 #include "CbmStsUnpackAlgo.h"
 
@@ -71,7 +74,7 @@ Bool_t CbmStsUnpackAlgo::initParSet(FairParGenericSet* parset)
   // If we do not know the derived ParSet class we return false
   LOG(error)
     << fName << "::initParSet - for container " << parset->ClassName()
-    << " failed, since CbmTrdUnpackAlgoBaseR::initParSet() does not know the derived ParSet and what to do with it!";
+    << " failed, since CbmStsUnpackAlgo::initParSet() does not know the derived ParSet and what to do with it!";
   return kFALSE;
 }
 
@@ -320,7 +323,7 @@ void CbmStsUnpackAlgo::loopMsMessages(const uint8_t* msContent, const uint32_t u
       case stsxyter::MessType::Epoch: {
         processEpochInfo(pMess[uIdx]);
         if (0 < uIdx) {
-          LOG(warning) << "CbmAlgoUnpackSts::loopMsMessages => "
+          LOG(warning) << "CbmStsUnpackAlgo::loopMsMessages => "
                        << "EPOCH message at unexpected position in MS: message " << uIdx << " VS message 0 expected!";
         }
         break;
@@ -340,7 +343,7 @@ void CbmStsUnpackAlgo::loopMsMessages(const uint8_t* msContent, const uint32_t u
         break;
       }
       default: {
-        LOG(fatal) << "CbmAlgoUnpackSts::DoUnpack => "
+        LOG(fatal) << "CbmStsUnpackAlgo::loopMsMessages => "
                    << "Unknown message type, should never happen, stopping "
                       "here! Type found was: "
                    << static_cast<int>(typeMess);
@@ -361,7 +364,7 @@ void CbmStsUnpackAlgo::MaskNoisyChannel(const uint32_t uFeb, const uint32_t uCha
   }
   if (uFeb < fuNbFebs && uChan < fNrChsPerFeb) fvvbMaskedChannels[uFeb][uChan] = bMasked;
   else
-    LOG(fatal) << "CbmAlgoUnpackSts::MaskNoisyChannel => Invalid FEB "
+    LOG(fatal) << "CbmStsUnpackAlgo::MaskNoisyChannel => Invalid FEB "
                   "and/or CHAN index:"
                << Form(" %u vs %u and %u vs %u", uFeb, fuNbFebs, uChan, fNrChsPerFeb);
 }
@@ -431,7 +434,7 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess)
   const uint32_t uCrobIdx   = usElinkIdx / fNrElinksPerCrob;
   int32_t uFebIdx           = fElinkIdxToFebIdxVec.at(usElinkIdx);
   if (-1 == uFebIdx) {
-    LOG(warning) << "CbmAlgoUnpackSts::DoUnpack => "
+    LOG(warning) << "CbmStsUnpackAlgo::processHitInfo => "
                  << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
     return;
   }
@@ -446,20 +449,6 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess)
   const uint16_t usRawTs    = mess.GetHitTimeBinning();
   const uint32_t uChanInFeb = usChan + fNrChsPerAsic * (uAsicIdx % fNrAsicsPerFeb);
 
-  /// Duplicate hits rejection
-  if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan] &&
-      //       usRawAdc                           == fvvusLastAdcChan[ uAsicIdx ][ usChan ] &&
-      fvulCurrentTsMsb[fuCurrDpbIdx] - fvvusLastTsMsbChan[uAsicIdx][usChan] < kuMaxTsMsbDiffDuplicates
-      && fvuCurrentTsMsbCycle[fuCurrDpbIdx] == fvvusLastTsMsbCycleChan[uAsicIdx][usChan]) {
-    /// FIXME: add plots to check what is done in this rejection
-    return;
-  }  // if SMX 2.0 DPB and same TS, ADC, TS MSB, TS MSB cycle!
-  fvvusLastTsChan[uAsicIdx][usChan]         = usRawTs;
-  fvvusLastAdcChan[uAsicIdx][usChan]        = usRawAdc;
-  fvvusLastTsMsbChan[uAsicIdx][usChan]      = fvulCurrentTsMsb[fuCurrDpbIdx];
-  fvvusLastTsMsbCycleChan[uAsicIdx][usChan] = fvuCurrentTsMsbCycle[fuCurrDpbIdx];
-
-
   // Compute the Full time stamp
   const int64_t ulHitTime = getFullTimeStamp(usRawTs);
 
@@ -470,6 +459,24 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess)
     if (false == fbUseChannelMask || false == fvvbMaskedChannels[uFebIdx][uChanInFeb]) {
       // If you want to store this as well, add it to the template as TOptOut, otherwise I do not see a reason to create it at all
       // auto finalhit       = stsxyter::FinalHit(ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx);
+
+      /// Duplicate hits rejection
+      if (fbRejectDuplicateDigis) {
+        if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan]
+            && (fbDupliWithoutAdc || usRawAdc == fvvusLastAdcChan[uAsicIdx][usChan])
+            && fulTsMsbIndexInTs[fuCurrDpbIdx] == fvvusLastTsMsbChan[uAsicIdx][usChan]) {
+          /// FIXME: add plots to check what is done in this rejection
+          LOG(debug) << "CbmStsUnpackAlgo::processHitInfo => "
+                     << Form("Rejecting duplicate on Asic %3d channel %3d, TS %3d, ADC %2d", uAsicIdx, usChan, usRawTs,
+                             usRawAdc);
+          return;
+        }  // if same TS, (ADC,) TS MSB, TS MSB cycle, reject
+        fvvusLastTsChan[uAsicIdx][usChan]         = usRawTs;
+        fvvusLastAdcChan[uAsicIdx][usChan]        = usRawAdc;
+        fvvusLastTsMsbChan[uAsicIdx][usChan]      = fulTsMsbIndexInTs[fuCurrDpbIdx];
+        fvvusLastTsMsbCycleChan[uAsicIdx][usChan] = fvuCurrentTsMsbCycle[fuCurrDpbIdx];
+      }  // if (fbRejectDuplicateDigis)
+
       uint32_t uChanInMod = usChan + fNrChsPerAsic * (uAsicIdx % fNrAsicsPerFeb);
 
       /// FIXME: see issue #1549
@@ -497,18 +504,18 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess)
                            fviFebSide[uFebIdx]);
       }
       fOutputVec.emplace_back(CbmStsDigi(fviFebAddress[uFebIdx], uChanInMod, ulTimeInNs, dCalAdc));
+
+      /// If EM flag ON, store a corresponding error message with the next flag after all other possible status flags set
+      if (mess.IsHitMissedEvts())
+        if (fOptOutAVec)
+          fOptOutAVec->emplace_back(
+            CbmErrorMessage(ECbmModuleId::kSts, dTimeInNs, uAsicIdx, 1 << stsxyter::kusLenStatStatus, usChan));
     }
   }
 
   // Convert the Hit time in bins to Hit time in ns
   const double dHitTimeNs = ulHitTime * stsxyter::kdClockCycleNs;
 
-  /// If EM flag ON, store a corresponding error message with the next flag after all other possible status flags set
-  if (mess.IsHitMissedEvts())
-    if (fOptOutAVec)
-      fOptOutAVec->emplace_back(
-        CbmErrorMessage(ECbmModuleId::kSts, dHitTimeNs, uAsicIdx, 1 << stsxyter::kusLenStatStatus, usChan));
-
   if (fMonitor) {
     // Check Starting point of histos with time as X axis
     if (-1 == fdStartTime) { fdStartTime = dHitTimeNs; }
@@ -538,7 +545,7 @@ void CbmStsUnpackAlgo::processStatusInfo(const stsxyter::Message& mess, uint32_t
   const uint32_t uCrobIdx   = usElinkIdx / fNrElinksPerCrob;
   const int32_t uFebIdx     = fElinkIdxToFebIdxVec.at(usElinkIdx);
   if (-1 == uFebIdx) {
-    LOG(warning) << "CbmAlgoUnpackSts::DoUnpack => "
+    LOG(warning) << "CbmStsUnpackAlgo::processStatusInfo => "
                  << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
     return;
   }
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
index ec0d26f9efa2e57c90a277f1f3c725902d80d04c..517932d27716508485d6f1153e40ea46babfbafb 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
@@ -1,18 +1,18 @@
-/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt
+/* Copyright (C) 2021 Goethe-University, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Pascal Raisig */
+   Authors: Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith */
 
 /**
  * @file CbmStsUnpackAlgo.h
  * @author Pascal Raisig (praisig@ikf.uni-frankfurt.de)
- * @brief Baseclass for the TrdR unpacker algorithms
+ * @brief Baseclass for the STS unpacker algorithms
  * @version 0.1
  * @date 2021-04-21
  *
  * @copyright Copyright (c) 2021
  *
  * This is the base class for the algorithmic part of the tsa data unpacking
- * processes of the CbmTrd.
+ * processes of the Cbm Sts.
  * The actual translation from tsa to digi happens in the derived classes.
  *
  *
@@ -27,10 +27,10 @@
 
 class CbmStsUnpackAlgo : public CbmStsUnpackAlgoBase {
 public:
-  /** @brief Create the Cbm Trd Unpack AlgoBase object */
+  /** @brief Create the Cbm Sts Unpack AlgoBase object */
   CbmStsUnpackAlgo();
 
-  /** @brief Destroy the Cbm Trd Unpack Task object */
+  /** @brief Destroy the Cbm Sts Unpack Task object */
   virtual ~CbmStsUnpackAlgo();
 
   /** @brief Copy constructor - not implemented **/
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.cxx
index 379c30452452f4f6e8f97cde6d2ee679f0be4d3d..bc021b48a27f977df5cfae6fd740626b4f5e5771 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.cxx
@@ -1,6 +1,6 @@
-/* Copyright (C) 2010 - 2021 Fair GmbH 
+/* Copyright (C) 2021 Fair GmbH, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Dominik Smith */
+   Authors: Pierre-Alain Loizeau, Dominik Smith [committer] */
 
 #include "CbmStsUnpackAlgoBase.h"
 
@@ -12,7 +12,7 @@ CbmStsUnpackAlgoBase::~CbmStsUnpackAlgoBase() {}
 std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
   CbmStsUnpackAlgoBase::GetParContainerRequest(std::string /*geoTag*/, std::uint32_t /*runId*/)
 {
-  // Basepath for default Trd parameter sets (those connected to a geoTag)
+  // Basepath for default Sts parameter sets (those connected to a geoTag)
   std::string basepath = Form("%s", fParFilesBasePath.data());
   std::string temppath = "";
 
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.h b/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.h
index d6a8acace16ef945e00eaa4b1f77b92c5c9b0285..285b65395b8f80d45093db57a76e94f47d54758d 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgoBase.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2010 - 2021 Fair GmbH 
+/* Copyright (C) 2021 Fair GmbH, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Dominik Smith */
+   Authors: Pierre-Alain Loizeau, Dominik Smith [committer] */
 
 /**
  * @file CbmStsUnpackAlgoBase.h
@@ -8,14 +8,14 @@
  * @brief Baseclass for the Sts unpacker algorithms
  * @version 0.1
  * @date 2021-04-21
- * 
+ *
  * @copyright Copyright (c) 2021
- * 
- * This is the base class for the algorithmic part of the tsa data unpacking 
+ *
+ * This is the base class for the algorithmic part of the tsa data unpacking
  * processes of the CbmSts.
- * The actual translation from tsa to digi happens in the derived classes. 
- * 
- * 
+ * The actual translation from tsa to digi happens in the derived classes.
+ *
+ *
 */
 
 #ifndef CbmStsUnpackAlgoBase_H
@@ -62,6 +62,13 @@ public:
   /** @brief Set the time offset per Asic */
   void SetAsicTimeOffsetVec(std::vector<double> value) { fvdTimeOffsetNsAsics.swap(value); }
 
+  /** @brief Enable/Disable the duplicate digis rejection, without or with same ADC checks */
+  void SetDuplicatesRejection(bool bIn = true, bool bDiffAdc = true)
+  {
+    fbRejectDuplicateDigis = bIn;
+    fbDupliWithoutAdc      = bDiffAdc;
+  }
+
   /**
    * @brief Get the requested parameter containers. To be defined in the derived classes!
    * Return the required parameter containers together with the paths to the ascii
@@ -106,6 +113,12 @@ protected:
   /** @brief Time offsets per Asic??? @todo expert confirmation required */
   std::vector<double> fvdTimeOffsetNsAsics = {};
 
+  /** @brief Enables the rejection of duplicate digis */
+  bool fbRejectDuplicateDigis = false;
+
+  /** @brief If rejecting duplicate digis, enables rejection even if ADC differs*/
+  bool fbDupliWithoutAdc = true;
+
 private:
   ClassDef(CbmStsUnpackAlgoBase, 2)
 };
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.cxx
index 4332a646c695ce68ecabb1fb0552d721e142f530..1b67fb04a862715ed3469275c21948aec4d14d55 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.cxx
@@ -1,9 +1,7 @@
-// -----------------------------------------------------------------------------
-// -----                                                                   -----
-// -----                  CbmStsUnpackAlgoLegacy                                 -----
-// -----               Created 26.01.2019 by P.-A. Loizeau                 -----
-// -----                                                                   -----
-// -----------------------------------------------------------------------------
+/* Copyright (C) 2019-2021 Fair GmbH, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Pierre-Alain Loizeau, Dominik Smith [committer] */
+
 
 #include "CbmStsUnpackAlgoLegacy.h"
 
@@ -545,7 +543,7 @@ void CbmStsUnpackAlgoLegacy::ProcessHitInfo(const stsxyter::Message& mess)
   const uint32_t uCrobIdx   = usElinkIdx / fUnpackPar->GetNbElinkPerCrob();
   const int32_t uFebIdx     = fUnpackPar->ElinkIdxToFebIdx(usElinkIdx);
   if (-1 == uFebIdx) {
-    LOG(warning) << "CbmStsUnpackAlgoLegacy::DoUnpack => "
+    LOG(warning) << "CbmStsUnpackAlgoLegacy::ProcessHitInfo => "
                  << "Wrong elink Idx! Elink raw " << Form("%d remap %d", usElinkIdx, uFebIdx);
     return;
   }
@@ -561,13 +559,18 @@ void CbmStsUnpackAlgoLegacy::ProcessHitInfo(const stsxyter::Message& mess)
   const uint32_t uChanInFeb = usChan + fUnpackPar->GetNbChanPerAsic() * (uAsicIdx % fUnpackPar->GetNbAsicsPerFeb());
 
   /// Duplicate hits rejection
-  if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan] &&
-      //       usRawAdc                           == fvvusLastAdcChan[ uAsicIdx ][ usChan ] &&
-      fvulCurrentTsMsb[fuCurrDpbIdx] - fvvusLastTsMsbChan[uAsicIdx][usChan] < kuMaxTsMsbDiffDuplicates
-      && fvuCurrentTsMsbCycle[fuCurrDpbIdx] == fvvusLastTsMsbCycleChan[uAsicIdx][usChan]) {
-    /// FIXME: add plots to check what is done in this rejection
-    return;
-  }  // if SMX 2.0 DPB and same TS, ADC, TS MSB, TS MSB cycle!
+  if (fbRejectDuplicateDigis) {
+    if (usRawTs == fvvusLastTsChan[uAsicIdx][usChan]
+        && (fbDupliWithoutAdc || usRawAdc == fvvusLastAdcChan[uAsicIdx][usChan])
+        && fvulCurrentTsMsb[fuCurrDpbIdx] - fvvusLastTsMsbChan[uAsicIdx][usChan] < kuMaxTsMsbDiffDuplicates
+        && fvuCurrentTsMsbCycle[fuCurrDpbIdx] == fvvusLastTsMsbCycleChan[uAsicIdx][usChan]) {
+      /// FIXME: add plots to check what is done in this rejection
+      LOG(debug) << "CbmStsUnpackAlgoLegacy::ProcessHitInfo => "
+                 << Form("Rejecting duplicate on Asic %3d channel %3d, TS %3d, MSB %d, Cycle %d, ADC %2d", uAsicIdx,
+                         usChan, usRawTs, fvulCurrentTsMsb[fuCurrDpbIdx], fvuCurrentTsMsbCycle[fuCurrDpbIdx], usRawAdc);
+      return;
+    }  // if SMX 2.0 DPB and same TS, ADC, TS MSB, TS MSB cycle!
+  }    // if (fbRejectDuplicateDigis)
   fvvusLastTsChan[uAsicIdx][usChan]         = usRawTs;
   fvvusLastAdcChan[uAsicIdx][usChan]        = usRawAdc;
   fvvusLastTsMsbChan[uAsicIdx][usChan]      = fvulCurrentTsMsb[fuCurrDpbIdx];
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.h b/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.h
index b38f4b9a20ffe666e5182770c035a47f7493b03c..39a404b53c5c86a65d8d6e0802632e632e606b4c 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgoLegacy.h
@@ -1,9 +1,6 @@
-// -----------------------------------------------------------------------------
-// -----                                                                   -----
-// -----                  CbmStsUnpackAlgoLegacy                       -----
-// -----               Created 26.01.2019 by P.-A. Loizeau                 -----
-// -----                                                                   -----
-// -----------------------------------------------------------------------------
+/* Copyright (C) 2019-2021 Fair GmbH, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Pierre-Alain Loizeau, Dominik Smith [committer] */
 
 #ifndef CbmStsUnpackAlgoLegacy_H
 #define CbmStsUnpackAlgoLegacy_H
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx b/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
index 2e073eccb414643c5d220410f562e1e6cfef2070..3c12a48db0c9fe8da20237de57b1805501f562a8 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
@@ -1,6 +1,6 @@
-/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt
+/* Copyright (C) 2021 Goethe-University, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Pascal Raisig */
+   Authors: Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith */
 
 #include "CbmStsUnpackConfig.h"
 
@@ -47,6 +47,9 @@ void CbmStsUnpackConfig::InitUnpacker()
   // Set the single asics time offsets
   algo->SetAsicTimeOffsetVec(fvdTimeOffsetNsAsics);
 
+  // Set the flags for duplicate digis rejections
+  algo->SetDuplicatesRejection(fbRejectDuplicateDigis, fbDupliWithoutAdc);
+
   // Now we have all information required to initialise the algorithm
   algo->Init();
 
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackConfig.h b/reco/detectors/sts/unpack/CbmStsUnpackConfig.h
index 8fb6d904689ee0c898a9b2efa1a9e47eae9f0c51..94a55ea104b2c7c9ac755d72aa32b57c122160f7 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackConfig.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackConfig.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2010 - 2021 Goethe-University Frankfurt
+/* Copyright (C) 2021 Goethe-University, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Pascal Raisig */
+   Authors: Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith */
 
 /**
  * @file CbmStsUnpackConfig.h
@@ -8,11 +8,11 @@
  * @brief Configuration class for an unpacker algorithm
  * @version 0.1
  * @date 2021-04-21
- * 
+ *
  * @copyright Copyright (c) 2021
- * 
+ *
  * This is the common configuration class for unpacking algorithms
- * 
+ *
 */
 
 #ifndef CbmStsUnpackConfig_H
@@ -39,8 +39,8 @@ class CbmStsUnpackConfig : public CbmRecoUnpackConfig<CbmStsUnpackAlgoBase, CbmS
 
 public:
   /**
-   * @brief Create the Cbm Trd Unpack Task object
-   * 
+   * @brief Create the Cbm Sts Unpack Task object
+   *
    * @param geoSetupTag Geometry setup tag for the given detector as used by CbmSetup objects
    * @param runid set if unpacker is rerun on a special run with special parameters
    *@remark We use the string instead of CbmSetup here, to not having to link against sim/steer...
@@ -48,8 +48,8 @@ public:
   CbmStsUnpackConfig(std::string detGeoSetupTag, UInt_t runid = 0);
 
   /**
-   * @brief Destroy the Cbm Trd Unpack Task object
-   * 
+   * @brief Destroy the Cbm Sts Unpack Task object
+   *
   */
   virtual ~CbmStsUnpackConfig();
 
@@ -80,11 +80,10 @@ public:
     fvChanMasks.emplace_back(FebChanMaskReco {uFeb, uChan, bMasked});
   }
 
-
   // Setters
   /**
    * @brief Set the Asic Time Offset
-   * 
+   *
    * @param asicid Idx of the ASIC with the given time offset
    * @param value time offset
   */
@@ -94,6 +93,13 @@ public:
     fvdTimeOffsetNsAsics.at(asicid) = value;
   }
 
+  /** @brief Enable/Disable the duplicate digis rejection, without or with same ADC checks */
+  void SetDuplicatesRejection(bool bIn = true, bool bDiffAdc = true)
+  {
+    fbRejectDuplicateDigis = bIn;
+    fbDupliWithoutAdc      = bDiffAdc;
+  }
+
   /** @brief Set the minimum adc cut value @param[in] value */
   void SetMinAdcCut(uint32_t value) { fdAdcCut = value; }
 
@@ -104,8 +110,8 @@ public:
 protected:
   /**
    * @brief Choose the derived unpacker algorithm to be used for the DAQ output to Digi translation. If algo was already set manually by the user this algorithm is used.
-   * 
-   * @return Bool_t initOk 
+   *
+   * @return Bool_t initOk
   */
   virtual std::shared_ptr<CbmStsUnpackAlgoBase> chooseAlgo();
 
@@ -118,6 +124,12 @@ protected:
   /** @brief Vector with the Asic time offsets */
   std::vector<double> fvdTimeOffsetNsAsics = {};
 
+  /** @brief Enables the rejection of duplicate digis */
+  bool fbRejectDuplicateDigis = false;
+
+  /** @brief If rejecting duplicate digis, enables rejection even if ADC differs*/
+  bool fbDupliWithoutAdc = true;
+
   /// Temporary storage of user parameters
   std::vector<FebChanMaskReco> fvChanMasks = {};
 
diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx
index 2e38369d414b427efbb73d0f53d1dbee61b0f4f4..5224f36de9253220b2f71b0a8358594f1af4394c 100644
--- a/reco/steer/CbmRecoUnpack.cxx
+++ b/reco/steer/CbmRecoUnpack.cxx
@@ -1,3 +1,7 @@
+/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Volker Friese [committer], Pierre-Alain Loizeau, Pascal Raisig  */
+
 /** @file CbmRecoUnpack.cxx
  ** @copyright Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
  ** @license SPDX-License-Identifier: GPL-3.0-only
@@ -301,6 +305,24 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts)
       }
     }
   }
+
+  if (bOutputFullTimeSorting) {
+    /// Time sort the output vectors of all unpackers present
+    if (fPsdConfig->GetOutputVec()) { timesort(fPsdConfig->GetOutputVec()); }
+    if (fRichConfig->GetOutputVec()) { timesort(fRichConfig->GetOutputVec()); }
+    if (fStsConfig->GetOutputVec()) { timesort(fStsConfig->GetOutputVec()); }
+    if (fTofConfig->GetOutputVec()) { timesort(fTofConfig->GetOutputVec()); }
+    if (fTrd1DConfig->GetOutputVec()) { timesort(fTrd1DConfig->GetOutputVec()); }
+    if (fTrd2DConfig->GetOutputVec()) { timesort(fTrd2DConfig->GetOutputVec()); }
+
+    /// Time sort the output vectors of all unpackers present
+    if (fPsdConfig->GetOptOutAVec()) { timesort(fPsdConfig->GetOptOutAVec()); }
+    if (fRichConfig->GetOptOutAVec()) { timesort(fRichConfig->GetOptOutAVec()); }
+    if (fStsConfig->GetOptOutAVec()) { timesort(fStsConfig->GetOptOutAVec()); }
+    if (fTofConfig->GetOptOutAVec()) { timesort(fTofConfig->GetOptOutAVec()); }
+    if (fTrd1DConfig->GetOptOutAVec()) { timesort(fTrd1DConfig->GetOptOutAVec()); }
+    if (fTrd2DConfig->GetOptOutAVec()) { timesort(fTrd2DConfig->GetOptOutAVec()); }
+  }
 }
 // ----------------------------------------------------------------------------
 
diff --git a/reco/steer/CbmRecoUnpack.h b/reco/steer/CbmRecoUnpack.h
index 5b9ffeefcdc071a0c78d8d387948e88a3149c511..5e131a4b2e67bd41d3d4ccb104e325ac878aa898 100644
--- a/reco/steer/CbmRecoUnpack.h
+++ b/reco/steer/CbmRecoUnpack.h
@@ -1,3 +1,7 @@
+/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Volker Friese [committer], Pierre-Alain Loizeau, Pascal Raisig  */
+
 /** @file CbmRecoUnpack.h
  ** @copyright Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
  ** @license SPDX-License-Identifier: GPL-3.0-only
@@ -76,21 +80,28 @@ public:
 
   /**
    * @brief (De)Activate the performance profiling based on histograms
-   * 
-   * @param value 
+   *
+   * @param value
   */
   void SetDoPerfProfiling(bool value = true) { fDoPerfProf = value; }
 
   /**
    * @brief Set the performance profiling Output Filename
-   * 
-   * @param value 
+   *
+   * @param value
   */
   void SetOutputFilename(std::string value)
   {
     if (!value.empty()) fOutfilename = value;
   }
 
+  /**
+   * @brief Enable/disable a full time sorting. If off, time sorting happens per link/FLIM source
+   *
+   * @param value
+  */
+  void SetTimeSorting(bool bIn = true) { bOutputFullTimeSorting = bIn; }
+
   /** @brief Set the Psd Unpack Config @param config */
   void SetUnpackConfig(std::shared_ptr<CbmPsdUnpackConfig> config) { fPsdConfig = config; }
 
@@ -142,9 +153,9 @@ private:
 
   /**
    * @brief Init the performance profiling maps for a given unpacker
-   * 
-   * @param subsysid Subsystem Identifier casted to std::uint16_t 
-   * @param name Name of the unpacker 
+   *
+   * @param subsysid Subsystem Identifier casted to std::uint16_t
+   * @param name Name of the unpacker
   */
   void initPerformanceMaps(std::uint16_t subsysid, std::string name);
 
@@ -211,8 +222,8 @@ private:
 
     // Check if we want to write the output to somewhere (in pure online monitoring mode for example this can/would/should be skipped)
     if (config->GetOutputVec()) {
-      // Lets do some timesorting
-      timesort(&digivec);
+      // Lets do some time-sorting if we are not doing it later
+      if (!bOutputFullTimeSorting) timesort(&digivec);
 
       // Transfer the data from the timeslice vector to the target branch vector
       // Digis/default output retrieved as offered by the algorithm
@@ -221,7 +232,7 @@ private:
     }
     if (optouttargetvecA) {
       // Lets do some timesorting
-      timesort(&optoutAvec);
+      if (!bOutputFullTimeSorting) timesort(&optoutAvec);
       // Transfer the data from the timeslice vector to the target branch vector
       for (auto optoutA : optoutAvec)
         optouttargetvecA->emplace_back(optoutA);
@@ -292,6 +303,9 @@ private:
   /** @brief Name of the performance profiling output file */
   std::string fOutfilename = "CbmRecoUnpack.perf.root";
 
+  /** @brief Flag to Enable/disable a full time sorting. If off, time sorting happens per link/FLIM source */
+  bool bOutputFullTimeSorting = false;
+
 
   ClassDef(CbmRecoUnpack, 1);
 };