index 25406a2..5b65761 100644 (file)
/* \$Id\$ */

///////////////////////////////////////////////////////////////////////////////
-///
-/// This class provides access to TRD digits in raw data.
-///
-/// It loops over all TRD digits in the raw data given by the AliRawReader.
-/// The Next method goes to the next digit. If there are no digits left
-/// it returns kFALSE.
-/// Several getters provide information about the current digit.
-///
+//                                                                           //
+// This class provides access to TRD digits in raw data.                     //
+//                                                                           //
+// It loops over all TRD digits in the raw data given by the AliRawReader.   //
+// The Next method goes to the next digit. If there are no digits left       //
+// it returns kFALSE.                                                        //
+// Several getters provide information about the current digit.              //
+//                                                                           //
+// Author: C. Lippmann (C.Lippmann@gsi.de)                                   //
+//                                                                           //
///////////////////////////////////////////////////////////////////////////////

-#include "AliTRDRawStream.h"
+#include "AliLog.h"
-#include "AliTRDparameter.h"
+#include "AliTRDRawStream.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDcalibDB.h"

ClassImp(AliTRDRawStream)

+//_____________________________________________________________________________
+AliTRDRawStream::AliTRDRawStream()
+  :TObject()
+  ,fSig()
+  ,fTB(0)
+  ,fEv(0)
+  ,fROB(0)
+  ,fMCM(0)
+  ,fSM(0)
+  ,fLAYER(0)
+  ,fSTACK(0)
+  ,fROC(0)
+  ,fSIDE(0)
+  ,fDCS(0)
+  ,fROW(0)
+  ,fCOL(0)
+  ,fDET(0)
+  ,fBCctr(0)
+  ,fPTctr(0)
+  ,fPTphase(0)
+  ,fRVmajor(0)
+  ,fRVminor(0)
+  ,fHCHWords(0)
+  ,fTBins(0)
+  ,fTCon(0)
+  ,fPEDon(0)
+  ,fGAINon(0)
+  ,fXTon(0)
+  ,fNonLinOn(0)
+  ,fBypass(0)
+  ,fZeroSuppressed(0)
+  ,fHCHctr1(0)
+  ,fHCHctr2(0)
+  ,fMCMHctr1(0)
+  ,fMCMHctr2(0)
+  ,fGTUctr1(0)
+  ,fGTUctr2(0)
+  ,fHCdataCtr(0)
+  ,fTracklPID(0.)
+  ,fTracklDefL(0.)
+  ,fRawVersion(2)
+  ,fNextStatus(0)
+  ,fTbSwitch(0)
+  ,fTbSwitchCtr(0)
+  ,fTimeWords(0)
+  ,fWordCtr(0)
+  ,fRowMax(0)
+  ,fColMax(0)
+  ,fChamberDone()
+  ,fRetVal(0)
+  ,fEqID(0)
+  ,fDataSize(0)
+  ,fSizeOK(kFALSE)
+  ,fCountBytes(0)
+  ,fBufSize(0)
+  ,fkBufferSet(kFALSE)
+  ,fPos(NULL)
+  ,fDataWord(NULL)
+  ,fTimeBinsCalib(0)
+  ,fGeo(NULL)
+{
+  //
+  // Default constructor
+  //
+
+  for (Int_t i = 0; i < 540; i++) {
+    fChamberDone[i] = 0;
+  }
+
+}

-  fTimeTotal(parameter->GetTimeTotal()),
-  fCount(0),
-  fDetector(-1),
-  fPrevDetector(-1),
-  fRow(-1),
-  fPrevRow(-1),
-  fColumn(-1),
-  fPrevColumn(-1),
-  fTime(-1),
-  fSignal(-1)
+//_____________________________________________________________________________
+  :TObject()
+  ,fSig()
+  ,fTB(0)
+  ,fEv(0)
+  ,fROB(0)
+  ,fMCM(0)
+  ,fSM(0)
+  ,fLAYER(0)
+  ,fSTACK(0)
+  ,fROC(0)
+  ,fSIDE(0)
+  ,fDCS(0)
+  ,fROW(0)
+  ,fCOL(0)
+  ,fDET(0)
+  ,fBCctr(0)
+  ,fPTctr(0)
+  ,fPTphase(0)
+  ,fRVmajor(0)
+  ,fRVminor(0)
+  ,fHCHWords(0)
+  ,fTBins(0)
+  ,fTCon(0)
+  ,fPEDon(0)
+  ,fGAINon(0)
+  ,fXTon(0)
+  ,fNonLinOn(0)
+  ,fBypass(0)
+  ,fZeroSuppressed(0)
+  ,fHCHctr1(0)
+  ,fHCHctr2(0)
+  ,fMCMHctr1(0)
+  ,fMCMHctr2(0)
+  ,fGTUctr1(0)
+  ,fGTUctr2(0)
+  ,fHCdataCtr(0)
+  ,fTracklPID(0.)
+  ,fTracklDefL(0.)
+  ,fRawVersion(2)
+  ,fNextStatus(0)
+  ,fTbSwitch(0)
+  ,fTbSwitchCtr(0)
+  ,fTimeWords(0)
+  ,fWordCtr(0)
+  ,fRowMax(0)
+  ,fColMax(0)
+  ,fChamberDone()
+  ,fRetVal(0)
+  ,fEqID(0)
+  ,fDataSize(0)
+  ,fSizeOK(kFALSE)
+  ,fCountBytes(0)
+  ,fBufSize(0)
+  ,fkBufferSet(kFALSE)
+  ,fPos(NULL)
+  ,fDataWord(NULL)
+  ,fTimeBinsCalib(0)
+  ,fGeo(NULL)
{
-// create an object to read TRD raw digits
+  //
+  // Create an object to read TRD raw digits
+  //
+
+
+  for (Int_t i = 0; i < 540; i++) {
+    fChamberDone[i] = 0;
+  }

}

-AliTRDRawStream::AliTRDRawStream(const AliTRDRawStream& stream) :
-  TObject(stream),
-  fTimeTotal(0),
-  fCount(0),
-  fDetector(-1),
-  fPrevDetector(-1),
-  fRow(-1),
-  fPrevRow(-1),
-  fColumn(-1),
-  fPrevColumn(-1),
-  fTime(-1),
-  fSignal(-1)
+//_____________________________________________________________________________
+AliTRDRawStream::AliTRDRawStream(const AliTRDRawStream& stream)
+  :TObject(stream)
+  ,fSig()
+  ,fTB(-1)
+  ,fEv(-1)
+  ,fROB(-1)
+  ,fMCM(-1)
+  ,fSM(-1)
+  ,fLAYER(-1)
+  ,fSTACK(-1)
+  ,fROC(-1)
+  ,fSIDE(-1)
+  ,fDCS(-1)
+  ,fROW(-1)
+  ,fCOL(-1)
+  ,fDET(0)
+  ,fBCctr(-1)
+  ,fPTctr(-1)
+  ,fPTphase(-1)
+  ,fRVmajor(-1)
+  ,fRVminor(-1)
+  ,fHCHWords(-1)
+  ,fTBins(-1)
+  ,fTCon(0)
+  ,fPEDon(0)
+  ,fGAINon(0)
+  ,fXTon(0)
+  ,fNonLinOn(-1)
+  ,fBypass(-1)
+  ,fZeroSuppressed(0)
+  ,fHCHctr1(-1)
+  ,fHCHctr2(-1)
+  ,fMCMHctr1(-1)
+  ,fMCMHctr2(-1)
+  ,fGTUctr1(-1)
+  ,fGTUctr2(-1)
+  ,fHCdataCtr(-1)
+  ,fTracklPID(-1.)
+  ,fTracklDefL(-1.)
+  ,fRawVersion(-1)
+  ,fNextStatus(0)
+  ,fTbSwitch(0)
+  ,fTbSwitchCtr(0)
+  ,fTimeWords(0)
+  ,fWordCtr(0)
+  ,fRowMax(-1)
+  ,fColMax(-1)
+  ,fChamberDone()
+  ,fRetVal(0)
+  ,fEqID(0)
+  ,fDataSize(0)
+  ,fSizeOK(kFALSE)
+  ,fCountBytes(0)
+  ,fBufSize(0)
+  ,fkBufferSet(kFALSE)
+  ,fPos(NULL)
+  ,fDataWord(NULL)
+  ,fTimeBinsCalib(0)
+  ,fGeo(NULL)
{
-  Fatal("AliTRDRawStream", "copy constructor not implemented");
+  //
+  // Copy constructor
+  //
+
+  AliFatal("Copy constructor not implemented");
+
}

+//_____________________________________________________________________________
AliTRDRawStream& AliTRDRawStream::operator = (const AliTRDRawStream&
/* stream */)
{
+  //
+  // Assigment operator
+  //
+
Fatal("operator =", "assignment operator not implemented");
return *this;
+
}

+//_____________________________________________________________________________
AliTRDRawStream::~AliTRDRawStream()
{
-// clean up
+  //
+  // Destructor
+  //
+
+  if (fGeo) {
+    delete fGeo;
+  }
+
+}
+
+//_____________________________________________________________________________
+{
+    {
+    }
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDRawStream::SetRawVersion(Int_t rv)
+{
+  //
+  // Set the raw data version
+  //
+
+  if ( rv >= 0 && rv <= 3 ) {
+    fRawVersion = rv;
+    return kTRUE;
+  }
+
+  return kFALSE;

}

+//____________________________________________________________________________
+Int_t AliTRDRawStream::Init()
+{
+  //
+  // Initialization
+  //
+
+  if (!AliTRDcalibDB::Instance()) {
+    AliError("Could not get calibration object");
+    return 0;
+  }
+
+  if (!fGeo) {
+    fGeo = new AliTRDgeometry();
+  }
+
+  fTimeBinsCalib = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
+  AliDebug(2, Form("Number of Timebins read from CDB: %d", fTimeBinsCalib));
+
+  // The number of data words needed for this number of time bins (there
+  // are 3 time bins in one word)
+  fTimeWords = (fTimeBinsCalib-1)/3 + 1;
+
+  fTbSwitch    = 3;
+  fTbSwitchCtr = 0;
+
+  fHCHctr1 = fHCHctr2 =  0;
+  fGTUctr1 = fGTUctr2 = -1;
+
+  fHCdataCtr = 0;
+  fWordCtr   = 0;
+
+  fDET     = 0;
+  fRetVal = 0;
+  fEqID     = 0;
+  fDataSize = 0;
+  fSizeOK = kFALSE;
+
+  fNextStatus = fkStart;
+
+  fCountBytes = 0;
+  fBufSize = 0;
+  fDataWord = NULL;
+  fPos = NULL;
+  fWordCtr = 0;
+  fkBufferSet = kFALSE;
+  return kTRUE;
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStream::NextData()
+{
+  //
+  // Updates the next data word pointer
+  //
+
+  if (fCountBytes + kSizeWord >= fBufSize)
+    {
+      if (fkBufferSet == kTRUE)
+       {
+         fCountBytes = 0;
+         fDataWord = (UInt_t*)fPos;
+         fNextStatus = fkNextSM;
+         fWordCtr = 0;
+         return fkNextSM;
+       }
+      else
+       {
+         fNextStatus = fkStop;
+         return fkNoMoreData;
+       }
+    }
+  else
+    {
+
+      fPos += kSizeWord;
+      fCountBytes += kSizeWord;
+      fDataWord = (UInt_t*)fPos;
+      fWordCtr++;
+      return fkWordOK;
+    }
+}
+
+//____________________________________________________________________________
Bool_t AliTRDRawStream::Next()
{
-// read the next raw digit
-// returns kFALSE if there is no digit left
+  //
+  // Updates the next data word pointer
+  //

-  fPrevDetector = fDetector;
-  fPrevRow = fRow;
-  fPrevColumn = fColumn;
-  UChar_t data;
+  if (fNextStatus == fkStart)
+    {
+      Init();
+    }

-  while (fCount >= 0) {
+  while (fNextStatus != fkStop)
+    { // !fkStop
+      NextData();
+      if (fNextStatus == fkNextMCM || fNextStatus == fkNextData)
+       {
+         fHCdataCtr += 4;

-    while (fCount == 0) {  // next detector
-      if (data != 0xBB) {
-       Error("Next", "wrong flag: %x", data);
-       fCount = -1;
-       return kFALSE;
-      }
+       if( ((*fDataWord & 0x80000000) == 0x0) && ((*fDataWord & 0x0000000f) == 0xC) )
+           if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 )
+             {
+               AliWarning("Wrong fMCM or fROB. Skip this data");
+               fNextStatus = fkNextHC;
+               continue;
+             }
+           fTbSwitch    = 3;  // For first adc channel we expect: (*fDataWord & 3) = 3
+           fTbSwitchCtr = 0;  //
+           fADC = fTB   = 0;  // Reset Counter
+           fNextStatus = fkNextData;
+           continue;
+         }
+
+       if ( *fDataWord == kEndofrawdatamarker )
+         {  // End of half-chamber data, finished
+           fGTUctr1 = -1;
+           fNextStatus = fkNextHC;
+           continue;
+         }

-      // read the detector number
-       Error("Next", "could not read detector number");
-       fCount = -1;
-       return kFALSE;
-      }
-      fDetector = data;
-       Error("Next", "could not read detector number");
-       fCount = -1;
-       return kFALSE;
-      }
-      fDetector += (UInt_t(data) << 8);
+       if (fNextStatus == fkNextData )
+
+           // Found some data. Decode it now:
+           fRetVal = DecodeDataWord();
+           if ( fRetVal ==  0 ) continue;
+           if ( fRetVal == -1 )
+             {
+               fNextStatus = fkNextHC;
+               continue;
+             }
+             {
+               // Write Digits
+               if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax )
+                 {  // A real pad
+                   fTB += 3;
+                   return kTRUE;
+                 }
+             }
+           else
+             {
+               fCOL = -1;
+             }
+         }// fkNextData
+
+       continue;
+       } //next mcm

-      // read the number of byts
-       Error("Next", "could not read number of bytes");
-       fCount = -1;
-       return kFALSE;
-      }
-      fCount = data;
-       Error("Next", "could not read number of bytes");
-       fCount = -1;
-       return kFALSE;
-      }
-      fCount += (UInt_t(data) << 8);
-        Error("Next", "could not read number of bytes");
-        fCount = -1;
-        return kFALSE;
+      if ( fNextStatus == fkNextHC )
+       {
+         //
+         // 1) Find end_of_tracklet_marker
+         //
+         if ( (*fDataWord & 0xfffff000) ==  0xe0000000 )
+           {
+             continue;
+           }
+
+         // endoftrackletmarker?
+         if ( *fDataWord == kEndoftrackletmarker )
+           {
+             AliDebug(3, "end-of-tracklet-marker found");
+             fNextStatus = fkSeekNonEoTracklet;
+             continue;
+           }
+         else
+           {
+             // Tracklets found
+             AliDebug(3, "Tracklet found");
+             DecodeTracklet();
+             continue;
+           }
+       } //if next HC
+
+      if (fNextStatus == fkSeekNonEoTracklet)
+       {
+         //
+         // 2) Look for non-end_of_tracklet_marker
+         //
+         //printf("Word %d: 0x%08x\n", fWordCtr, *fDataWord);
+
+         if ( *fDataWord != kEndoftrackletmarker )
+           {
+             fNextStatus = fkDecodeHC;
+             AliDebug(3, "NON end-of-tracklet-marker found");
+             //// no do not continue - this should be the hcheader
+           }
+         else
+           {
+             //just go on and find the non-end_of_tracklet_marker
+             continue;
+           }
+       }
+
+      if ( fNextStatus == fkDecodeHC )
+       {
+         AliDebug(3, "Decode HC");
+
+         //
+         // 3) This Word must be Half Chamber Header
+         //
+         if ( (*fDataWord & 0x00000003) == 1 )
+             fDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
+             fRowMax = fGeo->GetRowMax(fLAYER,fSTACK,fSM);
+             fColMax = fGeo->GetColMax(fROC);
+
+             fMCMHctr2 = 0;
+             fHCdataCtr = 0;
+
+             fChamberDone[fDET]++;
+             fNextStatus = fkNextMCM;
+             AliDebug(3, "Decode HC OK");
+             continue;
+         else
+           {
+             AliDebug(3, "Decode HC NOT OK");
+             fNextStatus = fkNextSM;
+             continue;
+           }
+       } // if decode HC
+
+      if (fNextStatus == fkNextSM)
+       {
+
+         fDET     = 0;
+         fRetVal = 0;
+         fEqID     = 0;
+         fDataSize = 0;
+         fSizeOK = kFALSE;
+
+         // After reading the first word check for size of this data and get Eq. ID
+         if ( fWordCtr == 1 )
+           {
+             fDataSize = fRawReader->GetDataSize()/4;  // Size of this payload in 32bit words
+             fEqID     = fRawReader->GetEquipmentId(); // Get Equipment ID
+             if ( fDataSize > 0 ) fSizeOK = kTRUE;
+           }
+
+         if ( (*fDataWord & 0xfffff000) ==  0xe0000000 )
+           {
+             fNextStatus = fkNextHC;
+             continue;
+           }
+         else
+           {
+             AliWarning(Form("Equipment %d: First data word is not GTU Link Mask!", fEqID));
+             fNextStatus = fkStop;
+           }
+       }// if nextSM
+
+    } // not fkStop
+
+  AliDebug(1, Form("That's all folks! %d", fSM));
+  return kFALSE;
+}
+
+//============================================================================
+// Decoding functions
+//============================================================================
+
+
+//____________________________________________________________________________
+{
+  //
+  // Decode the HC header (fRawVersion == 2, 3, 4, ???)
+  //
+
+  fRVmajor = (*fDataWord >> 24) & 0x7f;
+  fRVminor = (*fDataWord >> 17) & 0x7f;
+
+  if (fRVmajor < 2 || fRVmajor > 4)
+    AliError(Form(" Unsupported raw version: %d", fRawVersion))
+
+  if ( fRawVersion != fRVmajor ) {
+
+    AliWarning("===============================================================================");
+    AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
+                   ,fRawVersion,fRVmajor));
+    AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
+    AliWarning("===============================================================================");
+    fRawVersion = fRVmajor;
+
+  }
+
+  //
+  // check for zero suppression
+  if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
+  else                                        fZeroSuppressed = kFALSE;
+
+  // 1st word (h[0])
+  if ( (*fDataWord & 0x3) == 1 ) {
+
+    fHCHWords = (*fDataWord >> 14) & 0x7;
+    fSM       = (*fDataWord >>  9) & 0x1f;
+    fLAYER    = (*fDataWord >>  6) & 0x7;
+    fSTACK    = (*fDataWord >>  3) & 0x7;
+    fSIDE     = (*fDataWord >>  2) & 0x1;
+
+    fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
+
+    AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", *fDataWord, fSM, fROC, fSIDE+10));
+
+    if ((fSM    <  0) ||
+        (fSM    > 17) ||
+        (fLAYER <  0) ||
+        (fLAYER >  5) ||
+        (fSTACK <  0) ||
+        (fSTACK >  4) ||
+        (fSIDE  <  0) ||
+        (fSIDE  >  1)) {
+      AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
+                    *fDataWord, fDCS, fSM, fLAYER, fSTACK));
+                                                        *fDataWord, fDCS, fSM, fLAYER, fSTACK));
+    }
+    else {
+      fHCHctr1++;
+      fHCHctr2++;
+    }
+  }
+  else {
+    AliWarning(Form("0x%08x: No HC header when it was expected.", *fDataWord));
+  }
+
+  // 2nd word (h[1])
+  if ( fHCHWords >= 1 ) {
+    // read one more word
+    if (NextData() != fkWordOK)
+      {
+       AliWarning("Next HC word missing");
+       fNextStatus = fkNextHC;
+       return;
}
-      fCount += (UInt_t(data) << 16);
+    if ( (*fDataWord & 0x3) == 1 ) {
+
+      fBCctr   =  (*fDataWord >> 16);
+      fPTctr   =  (*fDataWord >> 12) & 0xf;
+      fPTphase =  (*fDataWord >>  8) & 0xf;
+      fTBins   = ((*fDataWord >>  2) & 0x3f) + 1;
+
+      AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
+                      , *fDataWord, fBCctr, fPTctr, fPTphase, fTBins));

-       fCount = -1;
-       return kFALSE;
+      if( fTBins != timeBins ) {
+
+       AliWarning("===============================================================================");
+       AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
+                     , timeBins, fTBins));
+       AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
+       AliWarning("===============================================================================");
+
+       fTimeWords = (fTBins - 1)/3 + 1;
}
-       fCount = -1;
-       return kFALSE;
+
+    }
+
+  }
+
+  // 3nd word (h[2])
+  if ( fHCHWords >= 2 ) {
+    // read one more word
+    if (NextData() != fkWordOK)
+      {
+       AliWarning("Next HC word missing");
+       fNextStatus = fkNextHC;
+       return;
}
-      fNPads += (UInt_t(data) << 8);
+    if ( (*fDataWord & 0x3) == 1 ) {
+
+      fTCon     = (*fDataWord >> 29) & 0x1;
+      fPEDon    = (*fDataWord >> 31) & 0x1;
+      fGAINon   = (*fDataWord >> 30) & 0x1;
+      fXTon     = (*fDataWord >> 28) & 0x1;
+      fNonLinOn = (*fDataWord >> 27) & 0x1;
+      fBypass   = (*fDataWord >> 26) & 0x1;
+
+      fCommonAdditive = (*fDataWord >> 20) & 0x3f;
+
+      AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
+                     , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
+    }
+  }

-      fTime = fTimeTotal;
+}

+//____________________________________________________________________________
+{
+
+  //
+  // Decode the MCM header
+  //
+
+  if ( fRawVersion < 1 || fRawVersion > 3 )
+    {
+      AliError(Form(" Unsupported raw version: %d", fRawVersion));
}

-    if ((fTime >= fTimeTotal) && (fCount > 2)) {
-       Error("Next", "could not read row number");
-       fCount = -1;
-       return kFALSE;
+  fMCM  = (*fDataWord & 0xff000000) >> 24;
+  fEv   = (*fDataWord & 0x00fffff0) >> 4;
+
+  fROB  = fMCM / 16;
+  fMCM  = fMCM % 16;
+
+
+  AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
+                 , *fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
+
+  if ( fROB % 2 == 0 && fSIDE == 1 ) {
+    AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
+                   , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+                                                      , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+  }
+  if ( fROB % 2 != 0 && fSIDE == 0 ) {
+    AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
+                   , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+                                                      , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+  }
+  if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
+       (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 ) {
+    AliWarning(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
+                   , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
+                                                 , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
+  }
+
+  fMCMHctr1++;
+  fMCMHctr2++;
+
+  if ( fRawVersion == 3 ) {
+    // read one more word
+    if (NextData() != fkWordOK)
+      {
+       fNextStatus = fkNextHC;
+       return;
}
-      fCount--;
-      fRow = data - 1;
-       Error("Next", "could not read column number");
-       fCount = -1;
-       return kFALSE;
+    if ( (*fDataWord & 0x000007ff) == 0xC ) {     // at the moment bits 4-10 are empty
+
+      for ( Int_t ctr = 0; ctr < fGeo->ADCmax(); ctr++ ) {
+       if ( (*fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
}
-      fCount--;
-      fColumn = data - 1;
-      fTime = 0;
+
+
+    }
+    else {
}

-    // read the next data byte
-      Error("Next", "could not read data");
-      fCount = -1;
-      return kFALSE;
+  }
+
+}
+
+//____________________________________________________________________________
+void AliTRDRawStream::DecodeTracklet()
+{
+
+  //
+  // Decode the Tracklet
+  //
+  // this function is not tested yet on real tracklets
+  //
+
+  if ( fRawVersion < 1 || fRawVersion > 3 )
+    {
+      AliError(Form(" Unsupported raw version: %d", fRawVersion));
}
-    fCount--;

-    if (data == 0) {  // zeros
-       Error("Next", "could not read time value");
-       fCount = -1;
-       return kFALSE;
-      }
-      fCount--;
-      fTime += data + 1;
-
-    } else {          // signal
-      fSignal = (UInt_t(data & 0x7F) << 8);
-       fCount = -1;
-       return kFALSE;
-      }
-      fCount--;
-      fSignal += data;
-      fTime++;
-      return kTRUE;
+  fTracklPID    = (*fDataWord >> 24) & 0xff;
+  fTracklPadRow = (*fDataWord >> 20) & 0xf;    // 0:15
+  fTracklDefL   = (*fDataWord >> 13) & 0x7f;
+  fTracklPadPos = (*fDataWord)       & 0x1fff;
+
+  fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
+  fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm
+
+  //AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
+  //             , *fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
+
+  if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
+      (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
+  }
+
+}
+
+//____________________________________________________________________________
+{
+
+  //
+  // between GTU and Super Module. Up to now only fully active links are found
+  // (0xfff = 12 active links).
+  //
+
+  if ( fRawVersion < 1 || fRawVersion > 3 )
+    {
+      AliError(Form(" Unsupported raw version: %d", fRawVersion));
}
+
+  if ( fGTUctr1 == -1 ) fGTUctr2++;
+  fGTUctr1++;
+
+  if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) {
}

-  return kFALSE;
+}
+
+//____________________________________________________________________________
+Int_t  AliTRDRawStream::DecodeDataWord()
+{
+
+  //
+  // Decode the Data
+  //
+
+  if      ( fRawVersion >= 1 && fRawVersion <= 2 ) {
+    return DecodeDataWordV1V2();
+  }
+  else if ( fRawVersion >= 3 && fRawVersion <= 3 ) {
+    return DecodeDataWordV3();
+  }
+
+  AliError(Form(" Unsupported raw version: %d", fRawVersion));
+  return -1;
+
+}
+
+//____________________________________________________________________________
+Int_t  AliTRDRawStream::DecodeDataWordV1V2()
+{
+
+  //
+  // Decode the Data (full raw data. No zero suppression. 21 adc channels)
+  //
+  // return  0 means continue to next data word
+  // return -1 means break data loop
+  //
+
+  if ( (*fDataWord & 0x00000003) != 0x2 && (*fDataWord & 0x00000003) != 0x3) {
+    AliWarning(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)*fDataWord));
+    return -1;
+  }
+
+  if ( (*fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
+    fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
+    fTbSwitchCtr = 0;
+    fTB=0;
+  }
+
+  fTbSwitchCtr++; // Just read one word
+
+  // We have only timeTotal time bins
+  if ( fTbSwitchCtr > fTimeWords ) {
+    AliWarning(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
+    return 0;
+  }
+
+  // We have only 21 ADC channels.
+    return 0;
+  }
+
+  // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
+  // MCMs and are good for online tracking in the MCM.
+
+
+    // We have only 144 Pad Columns
+    if ( fCOL > fColMax-1 || fCOL < 0 ) {
+      AliWarning(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
+                   fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+                   fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+    }
+
+    // Decode 32 bit data words with information from 3 time bins and copy the data
+    fSig[0] = (*fDataWord & 0x00000ffc) >> 2;
+    fSig[1] = (*fDataWord & 0x003ff000) >> 12;
+    fSig[2] = (*fDataWord & 0xffc00000) >> 22;
+
+    // Print data to screen:
+    // Do NOT switch on for default production, it is VERY slow
+    //    AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
+    //              fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
+
+  }
+  else {
+
+    fCOL = -1;
+
+  }
+
+  return 1;
+
+}
+
+//____________________________________________________________________________
+Int_t  AliTRDRawStream::DecodeDataWordV3()
+{
+
+  //
+  // Decode the data (Zero suppresses data. 21 adc channels)
+  //
+  // return  0 means continue to next data word
+  // return -1 means break data loop
+  //
+  // NOT TESTED YET!!!!!!!!
+  //
+
+  if ( (*fDataWord & 0x00000003) != 0x2 && (*fDataWord & 0x00000003) != 0x3) {
+    AliWarning(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)*fDataWord));
+    return -1;
+  }
+
+  if ( (*fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
+    fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
+    fTbSwitchCtr = 0;
+    //
+    do {
+    fTB=0;
+  }
+
+  fTbSwitchCtr++; // Just read one word
+
+  // We have only timeTotal time bins
+  if ( fTbSwitchCtr > fTimeWords ) {
+    AliWarning(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
+    return 0;
+  }
+
+  // We have only 21 ADC channels.
+    return 0;
+  }
+
+  // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
+  // MCMs and are good for online tracking in the MCM.
+
+
+    // We have only 144 Pad Columns
+    if ( fCOL > fColMax-1 || fCOL < 0 ) {
+      AliWarning(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
+                   fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+                   fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+    }
+
+    // Decode 32 bit data words with information from 3 time bins and copy the data
+    fSig[0] = (*fDataWord & 0x00000ffc) >> 2;
+    fSig[1] = (*fDataWord & 0x003ff000) >> 12;
+    fSig[2] = (*fDataWord & 0xffc00000) >> 22;
+
+    // Print data to screen:
+    AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
+                    fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
+
+  }
+  else {
+
+    fCOL = -1;
+
+  }
+
+  return 1;
+
}