]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/AliTRDrawStream.cxx
Bug fix (Xianguo)
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStream.cxx
index b6b5042720a0a518c363e0bb9e8c468ff9b8da2c..ea312fcde9c6a86351eac91cf284aa220392a110 100644 (file)
 #include "AliRawReader.h"
 #include "AliTRDdigitsManager.h"
 #include "AliTRDdigitsParam.h"
 #include "AliRawReader.h"
 #include "AliTRDdigitsManager.h"
 #include "AliTRDdigitsParam.h"
+#include "AliTRDcalibDB.h"
+#include "AliTRDmcmSim.h"
 #include "AliTRDtrapConfig.h"
 #include "AliTRDarrayADC.h"
 #include "AliTRDarrayDictionary.h"
 #include "AliTRDSignalIndex.h"
 #include "AliTRDtrackletWord.h"
 #include "AliTRDtrapConfig.h"
 #include "AliTRDarrayADC.h"
 #include "AliTRDarrayDictionary.h"
 #include "AliTRDSignalIndex.h"
 #include "AliTRDtrackletWord.h"
+#include "AliTRDtrackletMCM.h"
 #include "AliESDTrdTrack.h"
 #include "AliTreeLoader.h"
 #include "AliESDTrdTrack.h"
 #include "AliTreeLoader.h"
+#include "AliLoader.h"
 
 #include "AliTRDrawStream.h"
 
 
 #include "AliTRDrawStream.h"
 
@@ -59,47 +63,52 @@ const Int_t  AliTRDrawStream::fgkNsectors = 18;
 const Int_t  AliTRDrawStream::fgkNtriggers = 12;
 const UInt_t AliTRDrawStream::fgkDataEndmarker     = 0x00000000;
 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
 const Int_t  AliTRDrawStream::fgkNtriggers = 12;
 const UInt_t AliTRDrawStream::fgkDataEndmarker     = 0x00000000;
 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
+const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
 
 const char* AliTRDrawStream::fgkErrorMessages[] = {
   "Unknown error",
   "Link monitor active",
 
 const char* AliTRDrawStream::fgkErrorMessages[] = {
   "Unknown error",
   "Link monitor active",
-  "Pretrigger counter mismatch",
+  "Event counter mismatch",
   "not a TRD equipment (1024-1041)",
   "Invalid Stack header",
   "Invalid detector number",
   "No digits could be retrieved from the digitsmanager",
   "not a TRD equipment (1024-1041)",
   "Invalid Stack header",
   "Invalid detector number",
   "No digits could be retrieved from the digitsmanager",
-  "HC header mismatch", 
+  "HC header mismatch",
   "HC check bits wrong",
   "Unexpected position in readout stream",
   "Invalid testpattern mode",
   "Testpattern mismatch",
   "Number of timebins changed",
   "HC check bits wrong",
   "Unexpected position in readout stream",
   "Invalid testpattern mode",
   "Testpattern mismatch",
   "Number of timebins changed",
-  "ADC mask inconsistent", 
-  "ADC check bits invalid", 
+  "ADC mask inconsistent",
+  "ADC check bits invalid",
   "Missing ADC data",
   "Missing expected ADC channels",
   "Missing ADC data",
   "Missing expected ADC channels",
-  "Missing MCM headers"
+  "Missing MCM headers",
+  "Missing TP data",
+  "CRC mismatch"
 };
 
 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
   0,
   0,
 };
 
 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
   0,
   0,
-  2, 
-  1, 
-  0, 
-  1, 
-  1, 
+  2,
+  1,
+  0,
+  1,
+  1,
+  1,
   1,
   1,
-  1, 
   2,
   1,
   2,
   1,
+  0,
+  1,
+  1,
+  2,
   1,
   1,
   1,
   1,
-  1, 
-  2, 
-  1, 
-  1, 
-  1
+  1,
+  0,
+  0
 };
 
 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
 };
 
 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
@@ -120,11 +129,12 @@ AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
   AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate,
+  AliTRDrawStream::kTolerate,
+  AliTRDrawStream::kTolerate,
   AliTRDrawStream::kTolerate
 };
 
 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
   AliTRDrawStream::kTolerate
 };
 
 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
-  fStats(), 
   fStoreError(&AliTRDrawStream::ForgetError),
   fRawReader(rawReader),
   fDigitsManager(0x0),
   fStoreError(&AliTRDrawStream::ForgetError),
   fRawReader(rawReader),
   fDigitsManager(0x0),
@@ -132,6 +142,7 @@ AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
   fErrors(0x0),
   fLastError(),
   fErrorFlags(0),
   fErrors(0x0),
   fLastError(),
   fErrorFlags(0),
+  fStats(),
   fPayloadStart(0x0),
   fPayloadCurr(0x0),
   fPayloadSize(0),
   fPayloadStart(0x0),
   fPayloadCurr(0x0),
   fPayloadSize(0),
@@ -148,6 +159,7 @@ AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
   fCurrTrgHeaderAvail(0),
   fCurrTrgHeaderReadout(0),
   fCurrTrkHeaderAvail(0),
   fCurrTrgHeaderAvail(0),
   fCurrTrgHeaderReadout(0),
   fCurrTrkHeaderAvail(0),
+  fCurrStackEndmarkerAvail(0),
   fCurrEvType(0),
   fCurrTriggerEnable(0),
   fCurrTriggerFired(0),
   fCurrEvType(0),
   fCurrTriggerEnable(0),
   fCurrTriggerFired(0),
@@ -156,8 +168,10 @@ AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
   fCurrStackMask(0),
   fCurrTrkHeaderIndexWord(0x0),
   fCurrTrkHeaderSize(0x0),
   fCurrStackMask(0),
   fCurrTrkHeaderIndexWord(0x0),
   fCurrTrkHeaderSize(0x0),
+  fCurrTrkFlags(0x0),
   fCurrTrgHeaderIndexWord(0x0),
   fCurrTrgHeaderSize(0x0),
   fCurrTrgHeaderIndexWord(0x0),
   fCurrTrgHeaderSize(0x0),
+  fCurrTrgFlags(0x0),
   fCurrStackIndexWord(0x0),
   fCurrStackHeaderSize(0x0),
   fCurrStackHeaderVersion(0x0),
   fCurrStackIndexWord(0x0),
   fCurrStackHeaderSize(0x0),
   fCurrStackHeaderVersion(0x0),
@@ -169,6 +183,10 @@ AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
   fCurrLinkMonitorFlags(0x0),
   fCurrLinkDataTypeFlags(0x0),
   fCurrLinkDebugFlags(0x0),
   fCurrLinkMonitorFlags(0x0),
   fCurrLinkDataTypeFlags(0x0),
   fCurrLinkDebugFlags(0x0),
+  fCurrMatchFlagsSRAM(0),
+  fCurrMatchFlagsPostBP(0),
+  fCurrChecksumStack(),
+  fCurrChecksumSIU(0),
   fCurrSpecial(-1),
   fCurrMajor(-1),
   fCurrMinor(-1),
   fCurrSpecial(-1),
   fCurrMajor(-1),
   fCurrMinor(-1),
@@ -196,18 +214,22 @@ AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
 
   fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
   fCurrTrkHeaderSize      = new UInt_t[fgkNstacks];
 
   fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
   fCurrTrkHeaderSize      = new UInt_t[fgkNstacks];
+  fCurrTrkFlags           = new ULong64_t[fgkNsectors*fgkNstacks];
   fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
   fCurrTrgHeaderSize      = new UInt_t[fgkNtriggers];
   fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
   fCurrTrgHeaderSize      = new UInt_t[fgkNtriggers];
-  fCurrStackIndexWord     = new UInt_t[fgkNstacks];     
-  fCurrStackHeaderSize    = new UInt_t[fgkNstacks];     
+  fCurrTrgFlags           = new UInt_t[fgkNsectors];
+  fCurrStackIndexWord     = new UInt_t[fgkNstacks];
+  fCurrStackHeaderSize    = new UInt_t[fgkNstacks];
   fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
   fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
-  fCurrLinkMask           = new UInt_t[fgkNstacks];             
-  fCurrCleanCheckout      = new UInt_t[fgkNstacks];     
-  fCurrBoardId            = new UInt_t[fgkNstacks];             
+  fCurrLinkMask           = new UInt_t[fgkNstacks];
+  fCurrCleanCheckout      = new UInt_t[fgkNstacks];
+  fCurrBoardId            = new UInt_t[fgkNstacks];
   fCurrHwRevTMU           = new UInt_t[fgkNstacks];
   fCurrLinkMonitorFlags   = new UInt_t[fgkNstacks * fgkNlinks];
   fCurrLinkDataTypeFlags  = new UInt_t[fgkNstacks * fgkNlinks];
   fCurrLinkDebugFlags     = new UInt_t[fgkNstacks * fgkNlinks];
   fCurrHwRevTMU           = new UInt_t[fgkNstacks];
   fCurrLinkMonitorFlags   = new UInt_t[fgkNstacks * fgkNlinks];
   fCurrLinkDataTypeFlags  = new UInt_t[fgkNstacks * fgkNlinks];
   fCurrLinkDebugFlags     = new UInt_t[fgkNstacks * fgkNlinks];
+  for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
+    fCurrTrgFlags[iSector] = 0;
   for (Int_t i = 0; i < 100; i++)
     fDumpMCM[i] = 0;
 
   for (Int_t i = 0; i < 100; i++)
     fDumpMCM[i] = 0;
 
@@ -233,8 +255,10 @@ AliTRDrawStream::~AliTRDrawStream()
 
   delete [] fCurrTrkHeaderIndexWord;
   delete [] fCurrTrkHeaderSize;
 
   delete [] fCurrTrkHeaderIndexWord;
   delete [] fCurrTrkHeaderSize;
+  delete [] fCurrTrkFlags;
   delete [] fCurrTrgHeaderIndexWord;
   delete [] fCurrTrgHeaderSize;
   delete [] fCurrTrgHeaderIndexWord;
   delete [] fCurrTrgHeaderSize;
+  delete [] fCurrTrgFlags;
   delete [] fCurrStackIndexWord;
   delete [] fCurrStackHeaderSize;
   delete [] fCurrStackHeaderVersion;
   delete [] fCurrStackIndexWord;
   delete [] fCurrStackHeaderSize;
   delete [] fCurrStackHeaderVersion;
@@ -300,17 +324,25 @@ Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
        if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
          continue;
 
        if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
          continue;
 
+       Int_t   size  = 0;
+
        fErrorFlags = 0;
        // check for link monitor error flag
        fErrorFlags = 0;
        // check for link monitor error flag
-       if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
+       if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
          LinkError(kLinkMonitor);
          LinkError(kLinkMonitor);
+         if (fgErrorBehav[kLinkMonitor] == kTolerate)
+           size += ReadLinkData();
+       }
        else
          // read the data from one HC
        else
          // read the data from one HC
-         ReadLinkData();
+         size += ReadLinkData();
 
        // read all data endmarkers
 
        // read all data endmarkers
-       SeekNextLink();
+       size += SeekNextLink();
       }
       }
+
+      // continue with next stack
+      SeekNextStack();
     }
   }
 
     }
   }
 
@@ -335,7 +367,7 @@ Bool_t AliTRDrawStream::NextDDL()
 
     fCurrEquipmentId = fRawReader->GetEquipmentId();
     AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
 
     fCurrEquipmentId = fRawReader->GetEquipmentId();
     AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
-    
+
     if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
       EquipmentError(kNonTrdEq, "Skipping");
       continue;
     if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
       EquipmentError(kNonTrdEq, "Skipping");
       continue;
@@ -363,7 +395,7 @@ Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
   // in case you only want to read the data of a single chamber
   // to read all data ReadEvent(...) is recommended
 
   // in case you only want to read the data of a single chamber
   // to read all data ReadEvent(...) is recommended
 
-  fDigitsManager = digMgr; 
+  fDigitsManager = digMgr;
   fDigitsParam   = 0x0;
 
   fErrorFlags = 0;
   fDigitsParam   = 0x0;
 
   fErrorFlags = 0;
@@ -375,9 +407,9 @@ Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
   AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
   if (trklLoader) {
     AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
   AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
   if (trklLoader) {
     AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
-    if (trklTreeLoader) 
+    if (trklTreeLoader)
       trklTree = trklTreeLoader->Tree();
       trklTree = trklTreeLoader->Tree();
-    else 
+    else
       trklTree = trklLoader->Tree();
   }
 
       trklTree = trklLoader->Tree();
   }
 
@@ -409,12 +441,15 @@ Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
   fCurrHC   = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
     fCurrSlot * fgkNlinks + fCurrLink;
 
   fCurrHC   = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
     fCurrSlot * fgkNlinks + fCurrLink;
 
-  if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
+  if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
     LinkError(kLinkMonitor);
     LinkError(kLinkMonitor);
+    if (fgErrorBehav[kLinkMonitor] == kTolerate)
+      ReadLinkData();
+  }
   else
     // read the data from one HC
     ReadLinkData();
   else
     // read the data from one HC
     ReadLinkData();
-  
+
   // read all data endmarkers
   SeekNextLink();
 
   // read all data endmarkers
   SeekNextLink();
 
@@ -423,20 +458,33 @@ Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
     fCurrLink++;
     fCurrHC++;
     if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
     fCurrLink++;
     fCurrHC++;
     if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
-      ReadLinkData();
+      if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
+       LinkError(kLinkMonitor);
+       if (fgErrorBehav[kLinkMonitor] == kTolerate)
+         ReadLinkData();
+      }
+      else {
+       ReadLinkData();
+      }
       SeekNextLink();
     }
   }
 
       SeekNextLink();
     }
   }
 
-  //??? to check 
   do {
   do {
-    fCurrLink++; 
-    if (fCurrLink >= fgkNlinks) {
+    if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
       fCurrLink = 0;
       fCurrSlot++;
     }
       fCurrLink = 0;
       fCurrSlot++;
     }
-  } while ((fCurrSlot < fgkNstacks) && 
-          (((fCurrStackMask & (1 << fCurrSlot)) == 0) || 
+    else {
+      fCurrLink++;
+      if (fCurrLink >= fgkNlinks) {
+       SeekNextStack();
+       fCurrLink = 0;
+       fCurrSlot++;
+      }
+    }
+  } while ((fCurrSlot < fgkNstacks) &&
+          (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
            ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
 
   // return chamber information from HC if it is valid
            ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
 
   // return chamber information from HC if it is valid
@@ -495,7 +543,7 @@ Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
 
 Int_t AliTRDrawStream::ReadSmHeader()
 {
 
 Int_t AliTRDrawStream::ReadSmHeader()
 {
-  // read the SMU index header at the current reading position 
+  // read the SMU index header at the current reading position
   // and store the information in the corresponding variables
 
   if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
   // and store the information in the corresponding variables
 
   if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
@@ -503,12 +551,15 @@ Int_t AliTRDrawStream::ReadSmHeader()
     return -1;
   }
 
     return -1;
   }
 
+  fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
+
   fCurrSmHeaderSize           = ((*fPayloadCurr) >> 16) & 0xffff;
   fCurrSmHeaderVersion        = ((*fPayloadCurr) >> 12) &    0xf;
   fCurrTrackEnable            = ((*fPayloadCurr) >>  6) &    0x1;
   fCurrTrackletEnable         = ((*fPayloadCurr) >>  5) &    0x1;
   fCurrStackMask              = ((*fPayloadCurr)      ) &   0x1f;
   fCurrHwRev                  = (fPayloadCurr[1] >> 12) & 0xffff;
   fCurrSmHeaderSize           = ((*fPayloadCurr) >> 16) & 0xffff;
   fCurrSmHeaderVersion        = ((*fPayloadCurr) >> 12) &    0xf;
   fCurrTrackEnable            = ((*fPayloadCurr) >>  6) &    0x1;
   fCurrTrackletEnable         = ((*fPayloadCurr) >>  5) &    0x1;
   fCurrStackMask              = ((*fPayloadCurr)      ) &   0x1f;
   fCurrHwRev                  = (fPayloadCurr[1] >> 12) & 0xffff;
+  fCurrStackEndmarkerAvail    = 0;
 
   switch (fCurrSmHeaderVersion) {
   case 0xb:
 
   switch (fCurrSmHeaderVersion) {
   case 0xb:
@@ -528,6 +579,19 @@ Int_t AliTRDrawStream::ReadSmHeader()
     fCurrTrkHeaderAvail = fCurrTrackEnable;
     fCurrTriggerEnable  = (fPayloadCurr[2] >>  8) &  0xfff;
     fCurrTriggerFired   = (fPayloadCurr[2] >>  20) &  0xfff;
     fCurrTrkHeaderAvail = fCurrTrackEnable;
     fCurrTriggerEnable  = (fPayloadCurr[2] >>  8) &  0xfff;
     fCurrTriggerFired   = (fPayloadCurr[2] >>  20) &  0xfff;
+    fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
+    break;
+
+  case 0xd:
+    fCurrTrailerReadout = ((*fPayloadCurr) >> 10) &    0x1;
+    fCurrTrgHeaderAvail = 1;
+    fCurrTrgHeaderReadout = ((*fPayloadCurr) >>  9) &    0x1;
+    fCurrEvType         = ((*fPayloadCurr) >>  7) &    0x3;
+    fCurrTrkHeaderAvail = fCurrTrackEnable;
+    fCurrTriggerEnable  = (fPayloadCurr[2] >>  8) &  0xfff;
+    fCurrTriggerFired   = (fPayloadCurr[2] >>  20) &  0xfff;
+    fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
+    fCurrStackEndmarkerAvail    = 1;
     break;
 
   default:
     break;
 
   default:
@@ -555,122 +619,259 @@ Int_t AliTRDrawStream::DecodeGTUtracks()
   // decode GTU track words
   // this depends on the hardware revision of the SMU
 
   // decode GTU track words
   // this depends on the hardware revision of the SMU
 
-  AliDebug(1, DumpRaw(Form("GTU tracks (hw rev %i)", fCurrHwRev),
+  Int_t sector = fCurrEquipmentId-kDDLOffset;
+
+  if ((sector < 0) || (sector > 17)) {
+    AliError(Form("Invalid sector %i for GTU tracks", sector));
+    return -1;
+  }
+
+  AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
                      fPayloadCurr + 4, 10, 0xffe0ffff));
 
                      fPayloadCurr + 4, 10, 0xffe0ffff));
 
+  fCurrTrgFlags[sector] = 0;
+
   if (fCurrHwRev < 1772) {
   if (fCurrHwRev < 1772) {
-    UInt_t trackWord[2] = { 0, 0 };
+    UInt_t    fastWord;                // fast trigger word
+    ULong64_t trackWord = 0;   // extended track word
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
-      if (fPayloadCurr[iWord] == 0x10000000) {
+      if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
         stack++;
         idx = 0;
       }
       else {
         if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
         stack++;
         idx = 0;
       }
       else {
         if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
-         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
+         fastWord = fPayloadCurr[iWord];
+         fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
+         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
          continue;
         }
         else if ((idx & 0x1) == 0x1) {
          continue;
         }
         else if ((idx & 0x1) == 0x1) {
-         trackWord[1] = fPayloadCurr[iWord];
-         AliDebug(1,Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-         // if (fTracks)
-         //   new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
-        }
+         trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+         AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+
+           trk->SetSector(sector);
+           trk->SetStack((trackWord >> 60) & 0x7);
+           trk->SetA(0);
+           trk->SetB(0);
+           trk->SetPID(0);
+           trk->SetLayerMask((trackWord >> 16) & 0x3f);
+           trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+           trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+           trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+           trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+           trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+           trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+           trk->SetFlags(0);
+           trk->SetReserved(0);
+           trk->SetLabel(-3);
+
+           Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+           if (TMath::Abs(pt) > 0.1) {
+             trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+           }
+         }
+       }
         else {
         else {
-         trackWord[0] = fPayloadCurr[iWord];
+         trackWord = fPayloadCurr[iWord];
         }
         idx++;
       }
     }
   }
   else if (fCurrHwRev < 1804) {
         }
         idx++;
       }
     }
   }
   else if (fCurrHwRev < 1804) {
-    UInt_t trackWord[2] = { 0, 0 };
+    UInt_t    fastWord;                // fast trigger word
+    ULong64_t trackWord = 0;   // extended track word
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
-      if (fPayloadCurr[iWord] == 0xffe0ffff) {
+      if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
         stack++;
         idx = 0;
       }
       else {
         if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
         stack++;
         idx = 0;
       }
       else {
         if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
-         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
+         fastWord = fPayloadCurr[iWord];
+         fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
+         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
          continue;
         }
         else if ((idx & 0x1) == 0x1) {
          continue;
         }
         else if ((idx & 0x1) == 0x1) {
-         trackWord[1] = fPayloadCurr[iWord];
-         AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-         Float_t pt = (trackWord[0] & 0x8000) ? -1. * ((~(trackWord[0] & 0xffff)&0xffff) + 1)/128. : (trackWord[0] & 0xffff)/128.;
-         AliDebug(1, Form("pt = %f", pt));
-         // if (fTracks) {
-         //   AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
-         //   if (TMath::Abs(pt) > 0.1) {
-         //     trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
-         //   }
-         //   trk->SetStack((trackWord[1] >> 28) & 0x7);
-         // }
+         trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+         AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+
+           trk->SetSector(fCurrEquipmentId-kDDLOffset);
+           trk->SetStack((trackWord >> 60) & 0x7);
+           trk->SetA(0);
+           trk->SetB(0);
+           trk->SetPID(0);
+           trk->SetLayerMask((trackWord >> 16) & 0x3f);
+           trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+           trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+           trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+           trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+           trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+           trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+           trk->SetFlags(0);
+           trk->SetReserved(0);
+           trk->SetLabel(-3);
+
+           Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+           if (TMath::Abs(pt) > 0.1) {
+             trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
+           }
+         }
         }
         else {
         }
         else {
-         trackWord[0] = fPayloadCurr[iWord];
+         trackWord = fPayloadCurr[iWord];
         }
         idx++;
       }
     }
   }
   else if (fCurrHwRev < 1819) {
         }
         idx++;
       }
     }
   }
   else if (fCurrHwRev < 1819) {
-    UInt_t trackWord[2];
+    UInt_t    fastWord;                // fast trigger word
+    ULong64_t trackWord = 0;   // extended track word
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
     Int_t stack = 0;
     Int_t idx = 0;
     for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
-      if (fPayloadCurr[iWord] == 0xffe0ffff) {
+      if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
        stack++;
        idx = 0;
       }
       else {
        if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
        stack++;
        idx = 0;
       }
       else {
        if ((idx == 0) &&
            ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
-         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
+         fastWord = fPayloadCurr[iWord];
+         if (fastWord & (1 << 13))
+           fCurrTrgFlags[sector] |= 1 << (stack+11);
+         AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
          continue;
        }
        else if ((idx & 0x1) == 0x1) {
          continue;
        }
        else if ((idx & 0x1) == 0x1) {
-         trackWord[idx&0x1] = fPayloadCurr[iWord];
-         AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-         printf("%4i %2i %i ",
-                fRawReader->GetEventIndex(),
-                fCurrEquipmentId-kDDLOffset, (trackWord[1] >> 28) & 0x7);
-         Float_t pt = (trackWord[0] & 0x8000) ? -1. * ((~(trackWord[0] & 0xffff)&0xffff) + 1)/128. : (trackWord[0] & 0xffff)/128.;
-         printf("%+7.2f ", pt);
-         printf("%i%i%i%i%i%i ", ((trackWord[0] >> 21) & 0x1),
-                ((trackWord[0] >> 20) & 0x1),
-                ((trackWord[0] >> 19) & 0x1),
-                ((trackWord[0] >> 18) & 0x1),
-                ((trackWord[0] >> 17) & 0x1),
-                ((trackWord[0] >> 16) & 0x1));
-         printf("0x%08x%08x\n", trackWord[1], trackWord[0]);
-         // if (fTracks) {
-         //   AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
-         //   if (TMath::Abs(pt) > 0.1) {
-         //     trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
-         //   }
-         //   trk->SetStack((trackWord[1] >> 28) & 0x7);
-         // }
+         trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+         AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+
+           trk->SetSector(fCurrEquipmentId-kDDLOffset);
+           trk->SetStack((trackWord >> 60) & 0x7);
+           trk->SetA(0);
+           trk->SetB(0);
+           // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
+           trk->SetPID(0);
+           trk->SetLayerMask((trackWord >> 16) & 0x3f);
+           trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+           trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+           trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+           trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+           trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+           trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+           trk->SetFlags(0);
+           trk->SetReserved(0);
+           trk->SetLabel(-3);
+
+           Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+           if (TMath::Abs(pt) > 0.1) {
+             trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
+           }
+         }
        }
        else {
        }
        else {
-         trackWord[idx&0x1] = fPayloadCurr[iWord];
+         trackWord = fPayloadCurr[iWord];
        }
        idx++;
       }
     }
   }
   else if (fCurrHwRev < 1860) {
        }
        idx++;
       }
     }
   }
   else if (fCurrHwRev < 1860) {
-    AliError(Form("unsupported hardware rev %i", fCurrHwRev));
+    UInt_t    fastWord;                // fast trigger word
+    ULong64_t trackWord = 0;   // extended track word
+    Int_t stack = 0;
+    Int_t idx = 0;
+    Bool_t upperWord = kFALSE;
+    Int_t word = 0;
+    for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+      if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
+        stack++;
+        idx = 0;
+       upperWord = kFALSE;
+      }
+      else {
+       // assemble the 32-bit words out of 16-bit blocks
+       if (upperWord) {
+         word |= (fPayloadCurr[iWord] & 0xffff0000);
+         upperWord = kFALSE;
+       }
+       else {
+         // lower word is read first
+         word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
+         upperWord = kTRUE;
+         continue;
+       }
+
+        if ((word & 0xffff0008) == 0x13370008) {
+         fastWord = word;
+         AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
+         if (fastWord & (1 << 13))
+           fCurrTrgFlags[sector] |= 1 << (stack+11);
+         continue;
+        }
+        else if ((idx & 0x1) == 0x1) {
+         trackWord |= ((ULong64_t) word) << 32;
+         AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+
+           trk->SetSector(fCurrEquipmentId-kDDLOffset);
+           trk->SetStack((trackWord >> 60) & 0x7);
+           trk->SetA(0);
+           trk->SetB(0);
+           trk->SetPID(0);
+           trk->SetLayerMask((trackWord >> 16) & 0x3f);
+           trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+           trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+           trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+           trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+           trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+           trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+           trk->SetFlags(0);
+           trk->SetReserved(0);
+           trk->SetLabel(-3);
+
+           Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+           if (TMath::Abs(pt) > 0.1) {
+             trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+           }
+         }
+        }
+        else {
+         trackWord = word;
+        }
+        idx++;
+      }
+    }
+
   }
   else {
   }
   else {
-    UInt_t trackWord[2] = { 0, 0 };
+    ULong64_t trackWord = 0; // this is the debug word
     Int_t stack = 0;
     Int_t idx = 0;
     Bool_t upperWord = kFALSE;
     Int_t stack = 0;
     Int_t idx = 0;
     Bool_t upperWord = kFALSE;
@@ -700,21 +901,40 @@ Int_t AliTRDrawStream::DecodeGTUtracks()
         }
         else if ((word & 0xffff0010) == 0x13370010) {
          AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
         }
         else if ((word & 0xffff0010) == 0x13370010) {
          AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
+         fCurrTrgFlags[sector] |= 1 << (stack+11);
          continue;
        }
         else if ((idx & 0x1) == 0x1) {
          continue;
        }
         else if ((idx & 0x1) == 0x1) {
-         trackWord[1] = word;
-         AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-         // if (fTracks) {
-         //   AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
-         //   if (TMath::Abs(trk->GetPt()) > 0.1) {
-         //     trk->SetA((Int_t) (0.15*51625./100./trk->GetPt() / 160e-4 * 2));
-         //   }
-         //   trk->SetStack((trackWord[1] >> 28) & 0x7);
-         // }
+         trackWord |= ((ULong64_t) word) << 32;
+         AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+           trk->SetSector(fCurrEquipmentId-kDDLOffset);
+           trk->SetStack((trackWord >> 60) & 0x7);
+           trk->SetA(0);
+           trk->SetB(0);
+           trk->SetPID(0);
+           trk->SetLayerMask((trackWord >> 16) & 0x3f);
+           trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+           trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+           trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+           trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+           trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+           trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+           trk->SetFlags(0);
+           trk->SetReserved(0);
+           trk->SetLabel(-3);
+
+           Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+           if (TMath::Abs(pt) > 0.1) {
+             trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+           }
+         }
         }
         else {
         }
         else {
-         trackWord[0] = word;
+         trackWord = word;
         }
         idx++;
       }
         }
         idx++;
       }
@@ -731,50 +951,93 @@ Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
 
   fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
   fCurrTrkHeaderSize[stack]      = ((*fPayloadCurr) >> 16) & 0x3ff;
 
   fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
   fCurrTrkHeaderSize[stack]      = ((*fPayloadCurr) >> 16) & 0x3ff;
-  fPayloadCurr++;
 
 
-  AliDebug(1, Form("tracking header index word: 0x%08x, size: %i\n",
-                  fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack]));
+  AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
+                  fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
+  Int_t trackingTime = *fPayloadCurr & 0x3ff;
+
+  fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
+  fPayloadCurr++;
 
   // data words
 
   // data words
-  UInt_t trackWord[2] = { 0, 0 };
+  ULong64_t trackWord = 0;
   Int_t idx = 0;
   Int_t idx = 0;
-  Bool_t upperWord = kFALSE;
-  Int_t word = 0;
+  Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
+
   for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
   for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
-    // assemble the 32-bit words out of 16-bit blocks
-    if (upperWord) {
-      word |= (fPayloadCurr[iWord] & 0xffff0000);
-      upperWord = kFALSE;
-    }
-    else {
-      // lower word is read first
-      word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
-      upperWord = kTRUE;
-      continue;
-    }
-    
-    if ((word & 0xffff0008) == 0x13370008) {
-      AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
-      continue;
-    }
-    else if ((word & 0xffff0010) == 0x13370010) {
-      AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
-      continue;
-    }
-    else if ((idx & 0x1) == 0x1) {
-      trackWord[1] = word;
-      AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-      // if (fTracks) {
-      //       AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
-      //       if (TMath::Abs(trk->GetPt()) > 0.1) {
-      //         trk->SetA((Int_t) (0.15*51625./100./trk->GetPt() / 160e-4 * 2));
-      //       }
-      //       trk->SetStack((trackWord[1] >> 28) & 0x7);
-      // }
+
+    if (!(idx & 0x1)) {
+      // first part of 64-bit word
+      trackWord = fPayloadCurr[iWord];
     }
     else {
     }
     else {
-      trackWord[0] = word;
+      trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+
+      if (trackWord & (1ul << 63)) {
+       if ((trackWord & (0x3ful << 56)) != 0) {
+         // track word
+         AliDebug(2, Form("track word: 0x%016llx", trackWord));
+
+         if (fTracks) {
+           AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+             AliESDTrdTrack();
+
+           trk->SetSector(fCurrEquipmentId-kDDLOffset);
+           trk->SetLayerMask((trackWord >> 56) & 0x3f);
+           trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
+           trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
+           trk->SetC( (((trackWord >> 8)  &  0xffff) ^  0x8000) -  0x8000);
+           trk->SetPID((trackWord >>  0) & 0xff);
+           trk->SetStack(stack);
+           trk->SetLabel(-3);
+
+           // now compare the track word with the one generated from the ESD information
+           if (trackWord != trk->GetTrackWord(0)) {
+             AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
+                           trk->GetTrackWord(0), trackWord));
+           }
+         }
+       }
+       else {
+         // done marker (so far only used to set trigger flag)
+         fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
+         fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
+
+         AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
+                          trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
+         AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
+                          fCurrEquipmentId - kDDLOffset, stack,
+                          (trackWord >> 20) & 0x3ff,
+                          (trackWord >> 10) & 0x3ff,
+                          (trackWord >>  0) & 0x3ff,
+                          trackingTime));
+       }
+      }
+      else {
+       // extended track word
+       AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
+
+       if (fTracks) {
+         AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
+
+         trk->SetFlags((trackWord >> 52) & 0x7ff);
+         trk->SetReserved((trackWord >> 49) & 0x7);
+         trk->SetY((trackWord >> 36) & 0x1fff);
+         trk->SetTrackletIndex((trackWord >>  0) & 0x3f, 0);
+         trk->SetTrackletIndex((trackWord >>  6) & 0x3f, 1);
+         trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
+         trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
+         trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
+         trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
+
+         if (trackWord != trk->GetExtendedTrackWord(0)) {
+           AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
+                         trk->GetExtendedTrackWord(0), trackWord));
+           }
+
+         trackIndex++;
+       }
+      }
     }
     idx++;
   }
     }
     idx++;
   }
@@ -799,7 +1062,12 @@ Int_t AliTRDrawStream::ReadTriggerHeaders()
        // index word
        AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
        fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
        // index word
        AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
        fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
-       fCurrTrgHeaderSize[iTrigger]      = ((*fPayloadCurr) >> 16) & 0xffff;
+       fCurrTrgHeaderSize[iTrigger]      = ((*fPayloadCurr) >> 16) & 0x3ff;
+       if (iTrigger == 7) {
+         // timeout trigger, use to extract tracking time
+         fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
+       }
+
        fPayloadCurr++;
        // data words
        fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
        fPayloadCurr++;
        // data words
        fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
@@ -824,7 +1092,10 @@ Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
   AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
 
   if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
   AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
 
   if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
-    LinkError(kStackHeaderInvalid, "Stack index header aborted");
+    EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
+    // dumping stack header
+    AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
+
     return -1;
   }
 
     return -1;
   }
 
@@ -879,6 +1150,27 @@ Int_t AliTRDrawStream::ReadGTUTrailer()
     Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
     AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
     // parse the trailer
     Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
     AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
     // parse the trailer
+    if (trailerSize >= 4) {
+      // match flags from GTU
+      fCurrMatchFlagsSRAM     = (trailer[1] >>  0) &    0x1f;
+      fCurrMatchFlagsPostBP   = (trailer[1] >>  5) &    0x1f;
+      // individual checksums
+      fCurrChecksumStack[0]   = (trailer[1] >> 16) &  0xffff;
+      fCurrChecksumStack[1]   = (trailer[2] >>  0) &  0xffff;
+      fCurrChecksumStack[2]   = (trailer[2] >> 16) &  0xffff;
+      fCurrChecksumStack[3]   = (trailer[3] >>  0) &  0xffff;
+      fCurrChecksumStack[4]   = (trailer[3] >> 16) &  0xffff;
+      fCurrChecksumSIU        = trailer[4];
+
+      if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
+       EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
+      if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
+       EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
+
+    }
+    else {
+      LinkError(kUnknown, "Invalid GTU trailer");
+    }
   }
   else
     EquipmentError(kUnknown, "trailer index marker mismatch");
   }
   else
     EquipmentError(kUnknown, "trailer index marker mismatch");
@@ -899,15 +1191,16 @@ Int_t AliTRDrawStream::ReadLinkData()
 
   if (fMarkers)
     new ((*fMarkers)[fMarkers->GetEntriesFast()])
 
   if (fMarkers)
     new ((*fMarkers)[fMarkers->GetEntriesFast()])
-      AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrStack, fCurrLink);
+      AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
 
   if (fErrorFlags & kDiscardHC)
     return count;
 
 
   if (fErrorFlags & kDiscardHC)
     return count;
 
-  //??? add check whether tracklets are enabled
-  count += ReadTracklets();
-  if (fErrorFlags & kDiscardHC)
-    return count;
+  if (fCurrTrackletEnable) {
+    count += ReadTracklets();
+    if (fErrorFlags & kDiscardHC)
+      return count;
+  }
 
   AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
   count += ReadHcHeader();
 
   AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
   count += ReadHcHeader();
@@ -917,40 +1210,7 @@ Int_t AliTRDrawStream::ReadLinkData()
   Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
 
   if (det > -1 && det < 540) {
   Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
 
   if (det > -1 && det < 540) {
-    
-    if ((fAdcArray = fDigitsManager->GetDigits(det))) {
-      //fAdcArray->Expand();
-      if (fAdcArray->GetNtime() != fCurrNtimebins)
-       fAdcArray->Allocate(16, 144, fCurrNtimebins);
-    }
-    else {
-      LinkError(kNoDigits);
-    }
-    
-    if (!fDigitsParam) {
-      fDigitsParam = fDigitsManager->GetDigitsParam();
-    }
-    if (fDigitsParam) {
-      fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
-      fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
-      fDigitsParam->SetADCbaseline(det, 10);
-    }
-    
-    if (fDigitsManager->UsesDictionaries()) {
-      fDigitsManager->GetDictionary(det, 0)->Reset();
-      fDigitsManager->GetDictionary(det, 1)->Reset();
-      fDigitsManager->GetDictionary(det, 2)->Reset();
-    }
 
 
-    if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
-      fSignalIndex->SetSM(fCurrSm);
-      fSignalIndex->SetStack(fCurrStack);
-      fSignalIndex->SetLayer(fCurrLayer);
-      fSignalIndex->SetDetNumber(det);
-      if (!fSignalIndex->IsAllocated())
-       fSignalIndex->Allocate(16, 144, fCurrNtimebins);
-    }
-    
     // ----- check which kind of data -----
     if (fCurrMajor & 0x40) {
       if ((fCurrMajor & 0x7) == 0x7) {
     // ----- check which kind of data -----
     if (fCurrMajor & 0x40) {
       if ((fCurrMajor & 0x7) == 0x7) {
@@ -960,24 +1220,68 @@ Int_t AliTRDrawStream::ReadLinkData()
               *fPayloadCurr != fgkDataEndmarker)
          fPayloadCurr++;
        count += fPayloadCurr - startPos;
               *fPayloadCurr != fgkDataEndmarker)
          fPayloadCurr++;
        count += fPayloadCurr - startPos;
-       
+
        // feeding TRAP config
        // feeding TRAP config
-       AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
-       trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
+       AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
+       AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
       }
       else {
        Int_t tpmode = fCurrMajor & 0x7;
        AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
       }
       else {
        Int_t tpmode = fCurrMajor & 0x7;
        AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
-       ReadTPData(tpmode);
+       count += ReadTPData(tpmode);
       }
     }
       }
     }
-    else if (fCurrMajor & 0x20) {
-      AliDebug(1, "This is a zs event");
-      count += ReadZSData();
-    }
     else {
     else {
-      AliDebug(1, "This is a nozs event");
-      count += ReadNonZSData();
+      // reading real data
+      if (fDigitsManager) {
+       if ((fAdcArray = fDigitsManager->GetDigits(det))) {
+         //fAdcArray->Expand();
+         if (fAdcArray->GetNtime() != fCurrNtimebins)
+           fAdcArray->Allocate(16, 144, fCurrNtimebins);
+       }
+       else {
+         LinkError(kNoDigits);
+       }
+
+       if (!fDigitsParam) {
+         fDigitsParam = fDigitsManager->GetDigitsParam();
+       }
+       if (fDigitsParam) {
+         fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
+         fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
+         fDigitsParam->SetADCbaseline(det, 10);
+       }
+
+       if (fDigitsManager->UsesDictionaries()) {
+         fDigitsManager->GetDictionary(det, 0)->Reset();
+         fDigitsManager->GetDictionary(det, 1)->Reset();
+         fDigitsManager->GetDictionary(det, 2)->Reset();
+       }
+
+       if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
+         fSignalIndex->SetSM(fCurrSm);
+         fSignalIndex->SetStack(fCurrStack);
+         fSignalIndex->SetLayer(fCurrLayer);
+         fSignalIndex->SetDetNumber(det);
+         if (!fSignalIndex->IsAllocated())
+           fSignalIndex->Allocate(16, 144, fCurrNtimebins);
+       }
+
+       if (fCurrMajor & 0x20) {
+         AliDebug(1, "This is a zs event");
+         count += ReadZSData();
+       }
+       else {
+         AliDebug(1, "This is a nozs event");
+         count += ReadNonZSData();
+       }
+      }
+      else {
+       // just read until data endmarkers
+       while (fPayloadCurr - fPayloadStart < fPayloadSize &&
+              *fPayloadCurr != fgkDataEndmarker)
+         fPayloadCurr++;
+      }
     }
   }
   else {
     }
   }
   else {
@@ -1004,7 +1308,7 @@ Int_t AliTRDrawStream::ReadTracklets()
   fTrackletArray->Clear();
 
   UInt_t *start = fPayloadCurr;
   fTrackletArray->Clear();
 
   UInt_t *start = fPayloadCurr;
-  while (*(fPayloadCurr) != fgkTrackletEndmarker && 
+  while (*(fPayloadCurr) != fgkTrackletEndmarker &&
         fPayloadCurr - fPayloadStart < fPayloadSize) {
     new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
 
         fPayloadCurr - fPayloadStart < fPayloadSize) {
     new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
 
@@ -1012,7 +1316,7 @@ Int_t AliTRDrawStream::ReadTracklets()
   }
 
   if (fTrackletArray->GetEntriesFast() > 0) {
   }
 
   if (fTrackletArray->GetEntriesFast() > 0) {
-    AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(), 
+    AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
                     (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
     if (fCurrSm > -1 && fCurrSm < 18) {
       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
                     (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
     if (fCurrSm > -1 && fCurrSm < 18) {
       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
@@ -1027,10 +1331,10 @@ Int_t AliTRDrawStream::ReadTracklets()
   }
 
   // loop over remaining tracklet endmarkers
   }
 
   // loop over remaining tracklet endmarkers
-  while ((*(fPayloadCurr) == fgkTrackletEndmarker && 
-         fPayloadCurr - fPayloadStart < fPayloadSize)) 
+  while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
+         fPayloadCurr - fPayloadStart < fPayloadSize))
     fPayloadCurr++;
     fPayloadCurr++;
-  
+
   return fPayloadCurr - start;
 }
 
   return fPayloadCurr - start;
 }
 
@@ -1055,28 +1359,28 @@ Int_t AliTRDrawStream::ReadHcHeader()
   fCurrSide       = (*fPayloadCurr >> 2) & 0x1;
   fCurrCheck      = (*fPayloadCurr) & 0x3;
 
   fCurrSide       = (*fPayloadCurr >> 2) & 0x1;
   fCurrCheck      = (*fPayloadCurr) & 0x3;
 
-  if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) || 
-      (fCurrStack != fCurrSlot) || 
-      (fCurrLayer != fCurrLink / 2) || 
+  if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
+      (fCurrStack != fCurrSlot) ||
+      (fCurrLayer != fCurrLink / 2) ||
       (fCurrSide != fCurrLink % 2)) {
     LinkError(kHCmismatch,
       (fCurrSide != fCurrLink % 2)) {
     LinkError(kHCmismatch,
-             "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x", 
+             "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
              fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
              fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
   }
   if (fCurrCheck != 0x1) {
     LinkError(kHCcheckFailed);
   }
              fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
              fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
   }
   if (fCurrCheck != 0x1) {
     LinkError(kHCcheckFailed);
   }
-  
+
   if (fCurrAddHcWords > 0) {
     fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
     fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
     fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
     fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
   }
   if (fCurrAddHcWords > 0) {
     fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
     fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
     fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
     fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
   }
-  
+
   fPayloadCurr += 1 + fCurrAddHcWords;
   fPayloadCurr += 1 + fCurrAddHcWords;
-  
+
   return (fPayloadCurr - start);
 }
 
   return (fPayloadCurr - start);
 }
 
@@ -1086,6 +1390,7 @@ Int_t AliTRDrawStream::ReadTPData(Int_t mode)
   // evcnt checking missing
   Int_t cpu = 0;
   Int_t cpufromchannel[] = {0, 0, 0, 0, 0,  1, 1, 1, 1, 1,  2, 2, 2, 2, 2,  3, 3, 3, 3, 3, 3};
   // evcnt checking missing
   Int_t cpu = 0;
   Int_t cpufromchannel[] = {0, 0, 0, 0, 0,  1, 1, 1, 1, 1,  2, 2, 2, 2, 2,  3, 3, 3, 3, 3, 3};
+  Int_t evno  = -1;
   Int_t evcnt = 0;
   Int_t count = 0;
   Int_t mcmcount = -1;
   Int_t evcnt = 0;
   Int_t count = 0;
   Int_t mcmcount = -1;
@@ -1099,34 +1404,45 @@ Int_t AliTRDrawStream::ReadTPData(Int_t mode)
 
   UInt_t* start = fPayloadCurr;
 
 
   UInt_t* start = fPayloadCurr;
 
-  while (*(fPayloadCurr) != fgkDataEndmarker && 
+  while (*(fPayloadCurr) != fgkDataEndmarker &&
         fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
 
     // ----- Checking MCM Header -----
         fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
 
     // ----- Checking MCM Header -----
-    AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
+    AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
+    UInt_t *startPosMCM = fPayloadCurr;
     mcmcount++;
     mcmcount++;
-    
+
     // ----- checking for proper readout order - ROB -----
     // ----- checking for proper readout order - ROB -----
+    fCurrRobPos = ROB(*fPayloadCurr);
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
+      if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
+       lastmcmpos = -1;
       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
     }
     else {
       ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
     }
       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
     }
     else {
       ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
     }
-    fCurrRobPos = ROB(*fPayloadCurr);
-    
+
     // ----- checking for proper readout order - MCM -----
     // ----- checking for proper readout order - MCM -----
-    if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
+    fCurrMcmPos = MCM(*fPayloadCurr);
+    if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
     else {
       MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
     }
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
     else {
       MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
     }
-    fCurrMcmPos = MCM(*fPayloadCurr);
-    
+
+    if (EvNo(*fPayloadCurr) != evno) {
+      if (evno == -1) {
+       evno = EvNo(*fPayloadCurr);
+      }
+      else {
+       MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+      }
+    }
 
     fPayloadCurr++;
 
     fPayloadCurr++;
-    
+
     evcnt = 0x3f & *fPayloadCurr >> 26;
     cpu = -1;
     channelcount = 0;
     evcnt = 0x3f & *fPayloadCurr >> 26;
     cpu = -1;
     channelcount = 0;
@@ -1137,13 +1453,18 @@ Int_t AliTRDrawStream::ReadTPData(Int_t mode)
        expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
        wordcount = 0;
       }
        expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
        wordcount = 0;
       }
-      
+
       while (count < 10) {
       while (count < 10) {
+       if (*fPayloadCurr == fgkDataEndmarker) {
+         MCMError(kMissTpData);
+         return (fPayloadCurr - start);
+       }
+
        if (channelcount % 2 == 0)
          expword = 0x3;
        if (channelcount % 2 == 0)
          expword = 0x3;
-       else 
+       else
          expword = 0x2;
          expword = 0x2;
-       
+
        if (mode == 1) {
          // ----- TP 1 -----
          expword |= expadcval << 2;
        if (mode == 1) {
          // ----- TP 1 -----
          expword |= expadcval << 2;
@@ -1155,14 +1476,14 @@ Int_t AliTRDrawStream::ReadTPData(Int_t mode)
        }
        else if (mode == 2) {
          // ----- TP 2 ------
        }
        else if (mode == 2) {
          // ----- TP 2 ------
-         expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) | 
-           ((fCurrStack + 1) << 15) | 
-           (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1); 
+         expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
+           ((fCurrStack + 1) << 15) |
+           (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
        }
        else if (mode == 3) {
          // ----- TP 3 -----
        }
        else if (mode == 3) {
          // ----- TP 3 -----
-         expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) | 
-           (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0); 
+         expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
+           (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
        }
        else {
          expword = 0;
        }
        else {
          expword = 0;
@@ -1170,29 +1491,43 @@ Int_t AliTRDrawStream::ReadTPData(Int_t mode)
        }
 
        diff = *fPayloadCurr ^ expword;
        }
 
        diff = *fPayloadCurr ^ expword;
+       AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
+                         channelcount, wordcount, cpu, *fPayloadCurr, expword));
+
        if (diff != 0) {
          MCMError(kTPmismatch,
        if (diff != 0) {
          MCMError(kTPmismatch,
-                  "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)", 
-                  *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
+                  "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
+                  *fPayloadCurr, expword, diff,
+                  0xffff & (diff | diff >> 16),
+                  0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
+                  wordcount, cpu, channelcount);;
        }
        fPayloadCurr++;
        count++;
        wordcount++;
        }
        fPayloadCurr++;
        count++;
        wordcount++;
+       if (*fPayloadCurr == fgkDataEndmarker)
+         return (fPayloadCurr - start);
       }
       channelcount++;
     }
     // continue with next MCM
       }
       channelcount++;
     }
     // continue with next MCM
+
+    if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
+      AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
+                     startPosMCM, fPayloadCurr - startPosMCM));
+    }
+
   }
   }
-  return fPayloadCurr - start; 
+  return fPayloadCurr - start;
 }
 
 
 Int_t AliTRDrawStream::ReadZSData()
 {
   // read the zs data from one link from the current reading position
 }
 
 
 Int_t AliTRDrawStream::ReadZSData()
 {
   // read the zs data from one link from the current reading position
-  
+
   UInt_t *start = fPayloadCurr;
   UInt_t *start = fPayloadCurr;
-  
+
   Int_t mcmcount = 0;
   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
   Int_t channelcount = 0;
   Int_t mcmcount = 0;
   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
   Int_t channelcount = 0;
@@ -1206,22 +1541,23 @@ Int_t AliTRDrawStream::ReadZSData()
   Int_t lastrobpos = -1;
 
   if (fCurrNtimebins != fNtimebins) {
   Int_t lastrobpos = -1;
 
   if (fCurrNtimebins != fNtimebins) {
-    if (fNtimebins > 0) 
+    if (fNtimebins > 0)
       LinkError(kNtimebinsChanged,
                "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
     fNtimebins = fCurrNtimebins;
   }
       LinkError(kNtimebinsChanged,
                "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
     fNtimebins = fCurrNtimebins;
   }
-  
+
   timebins = fNtimebins;
   timebins = fNtimebins;
-  
-  while (*(fPayloadCurr) != fgkDataEndmarker && 
+
+  while (*(fPayloadCurr) != fgkDataEndmarker &&
         fPayloadCurr - fPayloadStart < fPayloadSize) {
         fPayloadCurr - fPayloadStart < fPayloadSize) {
-    
+
     // ----- Checking MCM Header -----
     AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
     UInt_t *startPosMCM = fPayloadCurr;
     // ----- Checking MCM Header -----
     AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
     UInt_t *startPosMCM = fPayloadCurr;
-    
+
     // ----- checking for proper readout order - ROB -----
     // ----- checking for proper readout order - ROB -----
+    fCurrRobPos = ROB(*fPayloadCurr);
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
       if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
        lastmcmpos = -1;
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
       if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
        lastmcmpos = -1;
@@ -1231,9 +1567,9 @@ Int_t AliTRDrawStream::ReadZSData()
       ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
                               GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
     }
       ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
                               GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
     }
-    fCurrRobPos = ROB(*fPayloadCurr);
-    
+
     // ----- checking for proper readout order - MCM -----
     // ----- checking for proper readout order - MCM -----
+    fCurrMcmPos = MCM(*fPayloadCurr);
     if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
     if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
@@ -1241,30 +1577,33 @@ Int_t AliTRDrawStream::ReadZSData()
       MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
                               GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
     }
       MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
                               GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
     }
-    fCurrMcmPos = MCM(*fPayloadCurr);
-    
+
     if (EvNo(*fPayloadCurr) != evno) {
       if (evno == -1)
        evno = EvNo(*fPayloadCurr);
       else {
     if (EvNo(*fPayloadCurr) != evno) {
       if (evno == -1)
        evno = EvNo(*fPayloadCurr);
       else {
-       MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+       MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
       }
     }
     Int_t adccoloff = AdcColOffset(*fPayloadCurr);
     Int_t padcoloff = PadColOffset(*fPayloadCurr);
     Int_t row = Row(*fPayloadCurr);
     fPayloadCurr++;
       }
     }
     Int_t adccoloff = AdcColOffset(*fPayloadCurr);
     Int_t padcoloff = PadColOffset(*fPayloadCurr);
     Int_t row = Row(*fPayloadCurr);
     fPayloadCurr++;
-    
+
+    if ((row > 11) && (fCurrStack == 2)) {
+      MCMError(kUnknown, "Data in padrow > 11 for stack 2");
+    }
+
     // ----- Reading ADC channels -----
     AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
     // ----- Reading ADC channels -----
     AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
-    
+
     // ----- analysing the ADC mask -----
     channelcount = 0;
     channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
     channelcountMax = GetNActiveChannels(*fPayloadCurr);
     Int_t channelmask = GetActiveChannels(*fPayloadCurr);
     Int_t channelno = -1;
     // ----- analysing the ADC mask -----
     channelcount = 0;
     channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
     channelcountMax = GetNActiveChannels(*fPayloadCurr);
     Int_t channelmask = GetActiveChannels(*fPayloadCurr);
     Int_t channelno = -1;
-    fPayloadCurr++; 
+    fPayloadCurr++;
 
     if (channelcountExp != channelcountMax) {
       if (channelcountExp > channelcountMax) {
 
     if (channelcountExp != channelcountMax) {
       if (channelcountExp > channelcountMax) {
@@ -1272,89 +1611,90 @@ Int_t AliTRDrawStream::ReadZSData()
        channelcountExp = channelcountMax;
        channelcountMax = temp;
       }
        channelcountExp = channelcountMax;
        channelcountMax = temp;
       }
-      while (channelcountExp < channelcountMax && channelcountExp < 21 && 
+      while (channelcountExp < channelcountMax && channelcountExp < 21 &&
             fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
        MCMError(kAdcMaskInconsistent,
             fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
        MCMError(kAdcMaskInconsistent,
-                "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x", 
-                *(fPayloadCurr + 10 * channelcountExp), 
+                "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
+                *(fPayloadCurr + 10 * channelcountExp),
                 *(fPayloadCurr + 10 * channelcountExp + 1) );
                 *(fPayloadCurr + 10 * channelcountExp + 1) );
-       if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1))) 
+       if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
          channelcountExp++;
        else {
          break;
        }
       }
       MCMError(kAdcMaskInconsistent,
          channelcountExp++;
        else {
          break;
        }
       }
       MCMError(kAdcMaskInconsistent,
-              "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!", 
+              "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
               GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
     }
     AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
               GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
     }
     AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
-    
+
     // ----- reading marked ADC channels -----
     while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
       if (channelno < 20)
        channelno++;
       while (channelno < 20 && (channelmask & 1 << channelno) == 0)
        channelno++;
     // ----- reading marked ADC channels -----
     while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
       if (channelno < 20)
        channelno++;
       while (channelno < 20 && (channelmask & 1 << channelno) == 0)
        channelno++;
-      
+
       if (fCurrNtimebins > 30) {
        currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
        timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
       if (fCurrNtimebins > 30) {
        currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
        timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
-      } 
+      }
       else {
        currentTimebin = 0;
       }
       else {
        currentTimebin = 0;
       }
-      
+
       adcwc = 0;
       adcwc = 0;
-      AliDebug(3, Form("Now reading %i words for channel %2i", timebins / 3, channelno));
+      Int_t nADCwords = (timebins + 2) / 3;
+      AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
       Int_t adccol = adccoloff - channelno;
       Int_t padcol = padcoloff - channelno;
       Int_t adccol = adccoloff - channelno;
       Int_t padcol = padcoloff - channelno;
-//      if (adccol < 3 || adccol > 165) 
-//     AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i", 
+//      if (adccol < 3 || adccol > 165)
+//     AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
 //                  channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
 
 //                  channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
 
-      while (adcwc < timebins / 3 && 
-            *(fPayloadCurr) != fgkDataEndmarker && 
-            fPayloadCurr - fPayloadStart < fPayloadSize) {
+      while ((adcwc < nADCwords) &&
+            (*(fPayloadCurr) != fgkDataEndmarker) &&
+            (fPayloadCurr - fPayloadStart < fPayloadSize)) {
        int check = 0x3 & *fPayloadCurr;
        if (channelno % 2 != 0) { // odd channel
          if (check != 0x2 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
        int check = 0x3 & *fPayloadCurr;
        if (channelno % 2 != 0) { // odd channel
          if (check != 0x2 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
-                    "%i for %2i. ADC word in odd channel %i", 
+                    "%i for %2i. ADC word in odd channel %i",
                     check, adcwc+1, channelno);
          }
        }
        else {                  // even channel
          if (check != 0x3 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
                     check, adcwc+1, channelno);
          }
        }
        else {                  // even channel
          if (check != 0x3 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
-                    "%i for %2i. ADC word in even channel %i", 
+                    "%i for %2i. ADC word in even channel %i",
                     check, adcwc+1, channelno);
          }
        }
                     check, adcwc+1, channelno);
          }
        }
-       
+
        // filling the actual timebin data
        int tb2 = 0x3ff & *fPayloadCurr >> 22;
        int tb1 = 0x3ff & *fPayloadCurr >> 12;
        int tb0 = 0x3ff & *fPayloadCurr >> 2;
        // filling the actual timebin data
        int tb2 = 0x3ff & *fPayloadCurr >> 22;
        int tb1 = 0x3ff & *fPayloadCurr >> 12;
        int tb0 = 0x3ff & *fPayloadCurr >> 2;
-       if (adcwc != 0 || fCurrNtimebins <= 30) 
+       if (adcwc != 0 || fCurrNtimebins <= 30)
          fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
        else
          tb0 = -1;
        fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
        fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
          fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
        else
          tb0 = -1;
        fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
        fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
-       
+
        adcwc++;
        fPayloadCurr++;
       }
        adcwc++;
        fPayloadCurr++;
       }
-      
-      if (adcwc != timebins / 3) 
+
+      if (adcwc != nADCwords)
        MCMError(kAdcDataAbort);
        MCMError(kAdcDataAbort);
-      
-      // adding index 
+
+      // adding index
       if (padcol > 0 && padcol < 144) {
        fSignalIndex->AddIndexRC(row, padcol);
       }
       if (padcol > 0 && padcol < 144) {
        fSignalIndex->AddIndexRC(row, padcol);
       }
-      
+
       channelcount++;
     }
 
       channelcount++;
     }
 
@@ -1364,7 +1704,7 @@ Int_t AliTRDrawStream::ReadZSData()
     }
     if (channelcount != channelcountExp)
       MCMError(kAdcChannelsMiss);
     }
     if (channelcount != channelcountExp)
       MCMError(kAdcChannelsMiss);
-    
+
     mcmcount++;
     if (fCurrSm > -1 && fCurrSm < 18) {
       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
     mcmcount++;
     if (fCurrSm > -1 && fCurrSm < 18) {
       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
@@ -1382,7 +1722,7 @@ Int_t AliTRDrawStream::ReadZSData()
   // check for missing MCMs (if header suppression is inactive)
   if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
     LinkError(kMissMcmHeaders,
   // check for missing MCMs (if header suppression is inactive)
   if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
     LinkError(kMissMcmHeaders,
-             "No. of MCM headers %i not as expected: %i", 
+             "No. of MCM headers %i not as expected: %i",
              mcmcount, mcmcountExp);
   }
 
              mcmcount, mcmcountExp);
   }
 
@@ -1392,9 +1732,9 @@ Int_t AliTRDrawStream::ReadZSData()
 Int_t AliTRDrawStream::ReadNonZSData()
 {
   // read the non-zs data from one link from the current reading position
 Int_t AliTRDrawStream::ReadNonZSData()
 {
   // read the non-zs data from one link from the current reading position
-  
+
   UInt_t *start = fPayloadCurr;
   UInt_t *start = fPayloadCurr;
-  
+
   Int_t mcmcount = 0;
   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
   Int_t channelcount = 0;
   Int_t mcmcount = 0;
   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
   Int_t channelcount = 0;
@@ -1407,46 +1747,48 @@ Int_t AliTRDrawStream::ReadNonZSData()
   Int_t lastrobpos = -1;
 
   if (fCurrNtimebins != fNtimebins) {
   Int_t lastrobpos = -1;
 
   if (fCurrNtimebins != fNtimebins) {
-    if (fNtimebins > 0) 
+    if (fNtimebins > 0)
       LinkError(kNtimebinsChanged,
                "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
     fNtimebins = fCurrNtimebins;
   }
       LinkError(kNtimebinsChanged,
                "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
     fNtimebins = fCurrNtimebins;
   }
-  
+
   timebins = fNtimebins;
   timebins = fNtimebins;
-  
-  while (*(fPayloadCurr) != fgkDataEndmarker && 
+
+  while (*(fPayloadCurr) != fgkDataEndmarker &&
         fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
         fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
-    
+
     // ----- Checking MCM Header -----
     AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
     // ----- Checking MCM Header -----
     AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
-    
+
     // ----- checking for proper readout order - ROB -----
     // ----- checking for proper readout order - ROB -----
+    fCurrRobPos = ROB(*fPayloadCurr);
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
+      if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
+       lastmcmpos = -1;
       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
     }
     else {
       ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
     }
       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
     }
     else {
       ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
     }
-    fCurrRobPos = ROB(*fPayloadCurr);
-    
+
     // ----- checking for proper readout order - MCM -----
     // ----- checking for proper readout order - MCM -----
-    if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
+    fCurrMcmPos = MCM(*fPayloadCurr);
+    if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
     else {
       MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
     }
       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
     }
     else {
       MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
     }
-    fCurrMcmPos = MCM(*fPayloadCurr);
-    
+
     if (EvNo(*fPayloadCurr) != evno) {
       if (evno == -1)
        evno = EvNo(*fPayloadCurr);
       else {
     if (EvNo(*fPayloadCurr) != evno) {
       if (evno == -1)
        evno = EvNo(*fPayloadCurr);
       else {
-       MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+       MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
       }
     }
       }
     }
-    
+
     channelcount = 0;
     channelcountExp = 21;
     int channelno = -1;
     channelcount = 0;
     channelcountExp = 21;
     int channelno = -1;
@@ -1458,41 +1800,42 @@ Int_t AliTRDrawStream::ReadNonZSData()
     fPayloadCurr++;
 
     // ----- reading marked ADC channels -----
     fPayloadCurr++;
 
     // ----- reading marked ADC channels -----
-    while (channelcount < channelcountExp && 
+    while (channelcount < channelcountExp &&
           *(fPayloadCurr) != fgkDataEndmarker) {
       if (channelno < 20)
        channelno++;
           *(fPayloadCurr) != fgkDataEndmarker) {
       if (channelno < 20)
        channelno++;
-      
+
       currentTimebin = 0;
       currentTimebin = 0;
-      
+
       adcwc = 0;
       adcwc = 0;
-      AliDebug(2, Form("Now looking %i words", timebins / 3));
+      Int_t nADCwords = (timebins + 2) / 3;
+      AliDebug(2, Form("Now looking %i words", nADCwords));
       Int_t adccol = adccoloff - channelno;
       Int_t padcol = padcoloff - channelno;
       Int_t adccol = adccoloff - channelno;
       Int_t padcol = padcoloff - channelno;
-      while (adcwc < timebins / 3 && 
-            *(fPayloadCurr) != fgkDataEndmarker && 
-            fPayloadCurr - fPayloadStart < fPayloadSize) {
+      while ((adcwc < nADCwords) &&
+            (*(fPayloadCurr) != fgkDataEndmarker) &&
+            (fPayloadCurr - fPayloadStart < fPayloadSize)) {
        int check = 0x3 & *fPayloadCurr;
        if (channelno % 2 != 0) { // odd channel
          if (check != 0x2 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
        int check = 0x3 & *fPayloadCurr;
        if (channelno % 2 != 0) { // odd channel
          if (check != 0x2 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
-                    "%i for %2i. ADC word in odd channel %i", 
+                    "%i for %2i. ADC word in odd channel %i",
                     check, adcwc+1, channelno);
          }
        }
        else {                  // even channel
          if (check != 0x3 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
                     check, adcwc+1, channelno);
          }
        }
        else {                  // even channel
          if (check != 0x3 && channelno < 21) {
            MCMError(kAdcCheckInvalid,
-                    "%i for %2i. ADC word in even channel %i", 
+                    "%i for %2i. ADC word in even channel %i",
                     check, adcwc+1, channelno);
          }
        }
                     check, adcwc+1, channelno);
          }
        }
-       
+
        // filling the actual timebin data
        int tb2 = 0x3ff & *fPayloadCurr >> 22;
        int tb1 = 0x3ff & *fPayloadCurr >> 12;
        int tb0 = 0x3ff & *fPayloadCurr >> 2;
        // filling the actual timebin data
        int tb2 = 0x3ff & *fPayloadCurr >> 22;
        int tb1 = 0x3ff & *fPayloadCurr >> 12;
        int tb0 = 0x3ff & *fPayloadCurr >> 2;
-       if (adcwc != 0 || fCurrNtimebins <= 30) 
+       if (adcwc != 0 || fCurrNtimebins <= 30)
          fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
        else
          tb0 = -1;
          fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
        else
          tb0 = -1;
@@ -1503,10 +1846,10 @@ Int_t AliTRDrawStream::ReadNonZSData()
        fPayloadCurr++;
       }
 
        fPayloadCurr++;
       }
 
-      if (adcwc != timebins / 3) 
+      if (adcwc != nADCwords)
        MCMError(kAdcDataAbort);
        MCMError(kAdcDataAbort);
-      
-      // adding index 
+
+      // adding index
       if (padcol > 0 && padcol < 144) {
        fSignalIndex->AddIndexRC(row, padcol);
       }
       if (padcol > 0 && padcol < 144) {
        fSignalIndex->AddIndexRC(row, padcol);
       }
@@ -1529,6 +1872,33 @@ Int_t AliTRDrawStream::ReadNonZSData()
   return (fPayloadCurr - start);
 }
 
   return (fPayloadCurr - start);
 }
 
+Int_t AliTRDrawStream::SeekNextStack()
+{
+  // proceed in raw data stream till the next stack
+
+  if (!fCurrStackEndmarkerAvail)
+    return 0;
+
+  UInt_t *start = fPayloadCurr;
+
+  // read until data endmarkers
+  while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
+        ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
+         (fPayloadCurr[1] != fgkStackEndmarker[1])))
+    fPayloadCurr++;
+
+  if ((fPayloadCurr - start) != 0)
+    StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
+
+  AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
+
+  // goto next stack
+  fPayloadCurr++;
+  fPayloadCurr++;
+
+  return (fPayloadCurr-start);
+}
+
 Int_t AliTRDrawStream::SeekNextLink()
 {
   // proceed in raw data stream till the next link
 Int_t AliTRDrawStream::SeekNextLink()
 {
   // proceed in raw data stream till the next link
@@ -1548,22 +1918,22 @@ Int_t AliTRDrawStream::SeekNextLink()
   return (fPayloadCurr - start);
 }
 
   return (fPayloadCurr - start);
 }
 
-Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree) 
+Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
 {
   // connect the tracklet tree used to store the tracklet output
 
   fTrackletTree = trklTree;
 {
   // connect the tracklet tree used to store the tracklet output
 
   fTrackletTree = trklTree;
-  if (!fTrackletTree) 
+  if (!fTrackletTree)
     return kTRUE;
 
     return kTRUE;
 
-  if (!fTrackletTree->GetBranch("hc")) 
+  if (!fTrackletTree->GetBranch("hc"))
     fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
     fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
-  else 
+  else
     fTrackletTree->SetBranchAddress("hc", &fCurrHC);
 
     fTrackletTree->SetBranchAddress("hc", &fCurrHC);
 
-  if (!fTrackletTree->GetBranch("trkl")) 
+  if (!fTrackletTree->GetBranch("trkl"))
     fTrackletTree->Branch("trkl", &fTrackletArray);
     fTrackletTree->Branch("trkl", &fTrackletArray);
-  else 
+  else
     fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
 
   return kTRUE;
     fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
 
   return kTRUE;
@@ -1571,8 +1941,8 @@ Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
 
 
 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
 
 
 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
-{ 
-  // register error according to error code on equipment level 
+{
+  // register error according to error code on equipment level
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
@@ -1584,22 +1954,22 @@ void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...
   (this->*fStoreError)();
 
   va_list ap;
   (this->*fStoreError)();
 
   va_list ap;
-  if (fgErrorDebugLevel[err] > 10) 
+  if (fgErrorDebugLevel[err] > 10)
     AliDebug(fgErrorDebugLevel[err],
     AliDebug(fgErrorDebugLevel[err],
-            Form("Event %6i: Eq. %2d - %s : %s", 
+            Form("Event %6i: Eq. %2d - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
-  else 
-    AliError(Form("Event %6i: Eq. %2d - %s : %s", 
+  else
+    AliError(Form("Event %6i: Eq. %2d - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
-}                                                                              
+}
 
 
 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
 
 
 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
-{ 
-  // register error according to error code on stack level 
+{
+  // register error according to error code on stack level
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
@@ -1611,22 +1981,22 @@ void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
   (this->*fStoreError)();
 
   va_list ap;
   (this->*fStoreError)();
 
   va_list ap;
-  if (fgErrorDebugLevel[err] > 0) 
-    AliDebug(fgErrorDebugLevel[err], 
-            Form("Event %6i: Eq. %2d S %i - %s : %s", 
+  if (fgErrorDebugLevel[err] > 0)
+    AliDebug(fgErrorDebugLevel[err],
+            Form("Event %6i: Eq. %2d S %i - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
-  else 
-    AliError(Form("Event %6i: Eq. %2d S %i - %s : %s", 
+  else
+    AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
-} 
+}
 
 
 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
 
 
 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
-{ 
-  // register error according to error code on link level 
+{
+  // register error according to error code on link level
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
@@ -1639,21 +2009,21 @@ void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
 
   va_list ap;
   if (fgErrorDebugLevel[err] > 0)
 
   va_list ap;
   if (fgErrorDebugLevel[err] > 0)
-    AliDebug(fgErrorDebugLevel[err], 
-            Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", 
+    AliDebug(fgErrorDebugLevel[err],
+            Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
-  else 
-    AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", 
+  else
+    AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
-} 
+}
 
 
 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
 
 
 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
-{ 
-  // register error according to error code on ROB level 
+{
+  // register error according to error code on ROB level
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
@@ -1665,22 +2035,22 @@ void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
   (this->*fStoreError)();
 
   va_list ap;
   (this->*fStoreError)();
 
   va_list ap;
-  if (fgErrorDebugLevel[err] > 0) 
-    AliDebug(fgErrorDebugLevel[err], 
-            Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", 
+  if (fgErrorDebugLevel[err] > 0)
+    AliDebug(fgErrorDebugLevel[err],
+            Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
                  fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
-  else 
-    AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", 
-                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err], 
+  else
+    AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
+                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
-} 
+}
 
 
 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
 
 
 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
-{ 
-  // register error according to error code on MCM level 
+{
+  // register error according to error code on MCM level
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
   // and return the corresponding error message
 
   fLastError.fSector = fCurrEquipmentId - kDDLOffset;
@@ -1692,27 +2062,27 @@ void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
   (this->*fStoreError)();
 
   va_list ap;
   (this->*fStoreError)();
 
   va_list ap;
-  if (fgErrorDebugLevel[err] > 0) 
-    AliDebug(fgErrorDebugLevel[err], 
+  if (fgErrorDebugLevel[err] > 0)
+    AliDebug(fgErrorDebugLevel[err],
             Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
             Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
-                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err], 
+                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
-  else 
+  else
     AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
     AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
-                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err], 
+                 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
 }
 
 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
                  (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
   fErrorFlags |= fgErrorBehav[err];
 }
 
 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
-{ 
+{
   // return the error message for the given error code
 
   // return the error message for the given error code
 
-  if (errCode > 0 && errCode < kLastErrorCode) 
+  if (errCode > 0 && errCode < kLastErrorCode)
     return fgkErrorMessages[errCode];
     return fgkErrorMessages[errCode];
-  else 
-    return ""; 
-} 
+  else
+    return "";
+}
 
 void AliTRDrawStream::AliTRDrawStats::ClearStats()
 {
 
 void AliTRDrawStream::AliTRDrawStats::ClearStats()
 {
@@ -1752,11 +2122,11 @@ void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::Cl
 }
 
 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
 }
 
 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
-{ 
+{
   // mark MCM for dumping of raw data
 
   if (dump) {
   // mark MCM for dumping of raw data
 
   if (dump) {
-    fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm; 
+    fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
   }
   else {
     Int_t iMCM;
   }
   else {
     Int_t iMCM;
@@ -1784,7 +2154,7 @@ Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm)  const
   return kFALSE;
 }
 
   return kFALSE;
 }
 
-TString AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length, UInt_t endmarker)
+TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
 {
   // dump raw data
 
 {
   // dump raw data
 
@@ -1794,25 +2164,25 @@ TString AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length, UIn
       if ((start[pos+1] != endmarker && pos+1 < length))
        if ((start[pos+2] != endmarker && pos+2 < length))
          if ((start[pos+3] != endmarker && pos+3 < length))
       if ((start[pos+1] != endmarker && pos+1 < length))
        if ((start[pos+2] != endmarker && pos+2 < length))
          if ((start[pos+3] != endmarker && pos+3 < length))
-           title += Form("   0x%08x 0x%08x 0x%08x 0x%08x\n", 
+           title += Form("   0x%08x 0x%08x 0x%08x 0x%08x\n",
                          start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
          else {
                          start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
          else {
-           title += Form("   0x%08x 0x%08x 0x%08x 0x%08x\n", 
+           title += Form("   0x%08x 0x%08x 0x%08x 0x%08x\n",
                          start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
            return title;
          }
        else {
                          start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
            return title;
          }
        else {
-         title += Form("   0x%08x 0x%08x 0x%08x\n", 
+         title += Form("   0x%08x 0x%08x 0x%08x\n",
                        start[pos+0], start[pos+1], start[pos+2]);
          return title;
        }
       else {
                        start[pos+0], start[pos+1], start[pos+2]);
          return title;
        }
       else {
-       title += Form("   0x%08x 0x%08x\n", 
+       title += Form("   0x%08x 0x%08x\n",
                      start[pos+0], start[pos+1]);
        return title;
       }
     else {
                      start[pos+0], start[pos+1]);
        return title;
       }
     else {
-      title += Form("   0x%08x\n", 
+      title += Form("   0x%08x\n",
                    start[pos+0]);
       return title;
     }
                    start[pos+0]);
       return title;
     }
@@ -1834,14 +2204,95 @@ TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
   return title;
 }
 
   return title;
 }
 
-AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) : 
+AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
   fError(error),
   fSector(sector),
   fStack(stack),
   fError(error),
   fSector(sector),
   fStack(stack),
-  fLink(link), 
+  fLink(link),
   fRob(rob),
   fMcm(mcm)
 {
   // ctor
 
 }
   fRob(rob),
   fMcm(mcm)
 {
   // ctor
 
 }
+
+void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
+{
+  // sort tracklets for referencing from GTU tracks
+
+  Int_t nTracklets = trklArray->GetEntriesFast();
+
+  Int_t lastHC = -1;
+  for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
+    AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
+    Int_t hc = trkl->GetHCId();
+    if ((hc < 0) || (hc >= 1080)) {
+      AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
+      continue;
+    }
+    AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
+    if (hc != lastHC) {
+      AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
+      indices[hc] = iTracklet + 1;
+      lastHC = hc;
+    }
+  }
+
+  for (Int_t iDet = 0; iDet < 540; iDet++) {
+    Int_t trklIndexA = indices[2*iDet + 0] - 1;
+    Int_t trklIndexB = indices[2*iDet + 1] - 1;
+    Int_t trklIndex  = sortedTracklets.GetEntries();
+    AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+    AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+    AliTRDtrackletBase *trklNext = 0x0;
+    while (trklA != 0x0 || trklB != 0x0) {
+      AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
+                      iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
+      if (trklA == 0x0) {
+       trklNext = trklB;
+       trklIndexB++;
+       trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+       if (trklB && trklB->GetHCId() != 2*iDet + 1)
+         trklB = 0x0;
+      }
+      else if (trklB == 0x0) {
+       trklNext = trklA;
+       trklIndexA++;
+       trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+       if (trklA && trklA->GetHCId() != 2*iDet)
+         trklA = 0x0;
+      }
+      else {
+       if ((trklA->GetZbin() < trklB->GetZbin()) ||
+           ((trklA->GetZbin() == trklB->GetZbin()) && (trklA->GetYbin() < trklB->GetYbin()))) {
+         trklNext = trklA;
+         trklIndexA++;
+         trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+         if (trklA && trklA->GetHCId() != 2*iDet)
+           trklA = 0x0;
+       }
+       else {
+         trklNext = trklB;
+         trklIndexB++;
+         trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+         if (trklB && trklB->GetHCId() != 2*iDet + 1)
+           trklB = 0x0;
+       }
+      }
+      if (trklNext) {
+       Int_t label = -2; // mark raw tracklets with label -2
+       if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext))
+         label = trklMCM->GetLabel();
+       AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label);
+       sortedTracklets.Add(esdTracklet);
+      }
+
+      // updating tracklet indices as in output
+      if (sortedTracklets.GetEntries() != trklIndex) {
+       indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex;
+      }
+      else
+       indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
+    }
+  }
+}