]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TOF/TOFbase/AliTOFDecoder.cxx
TOF + macros to each detector folder
[u/mrichter/AliRoot.git] / TOF / TOFbase / AliTOFDecoder.cxx
diff --git a/TOF/TOFbase/AliTOFDecoder.cxx b/TOF/TOFbase/AliTOFDecoder.cxx
new file mode 100644 (file)
index 0000000..c71d00a
--- /dev/null
@@ -0,0 +1,966 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+***************************************************************************/
+
+/*
+$Log$
+Revision 1.5  2007/11/24 14:58:34  zampolli
+New Method implemented (#DDL <-> TOF channels)
+
+Revision 1.4  2007/05/18 13:08:57  decaro
+Coding convention: RS1 violation -> suppression
+
+Revision 1.3  2007/05/08 11:56:05  arcelli
+improved verbosity in verbose mode (R.Preghenella)
+
+Revision 1.2  2007/05/03 11:34:43  decaro
+Coding convention: RS1 violation -> suppression
+
+Revision 1.1  2007/04/27 11:00:32  arcelli
+TOF Raw Data decoder
+
+  author: Roberto Preghenella (R+), preghenella@bo.infn.it
+*/
+
+
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//                                                                  //
+//   Class for raw data decoding                                    //
+//                                                                  //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+                               
+
+
+#include "AliLog.h"
+#include "AliTOFHitData.h"
+#include "AliTOFHitDataBuffer.h"
+#include "AliTOFDecoder.h"
+#include "AliTOFGeometry.h"
+#include "AliRawDataHeader.h"
+#include "AliRawDataHeaderV3.h"
+#include "AliTOFRawDataFormat.h"
+
+ClassImp(AliTOFDecoder)
+
+//_________________________________________________________________
+
+AliTOFDecoder::AliTOFDecoder() :
+  TObject(),
+  fVerbose(0),
+  fV2718Patch(kFALSE),
+  fDataBuffer(0x0),
+  fPackedDataBuffer(0x0),
+  //fTRMGlobalHeader(0x0),
+  //fTRMGlobalTrailer(0x0),
+  //fTRMChainHeader(0x0),
+  //fTRMChainTrailer(0x0),
+  //fTDCPackedHit(0x0),
+  //fTDCUnpackedHit(0x0),
+  //fTRMTDCError(0x0),
+  //fTRMDiagnosticErrorWord1(0x0),
+  //fTRMDiagnosticErrorWord2(0x0),
+  fSpiderCurrentSlotID(-1),
+  fSpiderCurrentChain(-1),
+  fSpiderCurrentTDC(-1)
+{
+  //default constructor
+
+  for (Int_t chan=0;chan<N_CHANNEL;chan++)
+    fSpiderLeadingFlag[chan] = kFALSE;
+
+}
+
+//_________________________________________________________________
+
+AliTOFDecoder::AliTOFDecoder(AliTOFHitDataBuffer *DataBuffer, AliTOFHitDataBuffer *PackedDataBuffer) :
+  TObject(),
+  fVerbose(0),
+  fV2718Patch(kFALSE),
+  fDataBuffer(DataBuffer),
+  fPackedDataBuffer(PackedDataBuffer),
+  //fTRMGlobalHeader(0x0),
+  //fTRMGlobalTrailer(0x0),
+  //fTRMChainHeader(0x0),
+  //fTRMChainTrailer(0x0),
+  //fTDCPackedHit(0x0),
+  //fTDCUnpackedHit(0x0),
+  //fTRMTDCError(0x0),
+  //fTRMDiagnosticErrorWord1(0x0),
+  //fTRMDiagnosticErrorWord2(0x0),
+  fSpiderCurrentSlotID(-1),
+  fSpiderCurrentChain(-1),
+  fSpiderCurrentTDC(-1)
+{
+  //another constructor
+
+  for (Int_t chan=0;chan<N_CHANNEL;chan++)
+    fSpiderLeadingFlag[chan] = kFALSE;
+
+}
+
+//_________________________________________________________________
+
+AliTOFDecoder::AliTOFDecoder(const AliTOFDecoder &source) : 
+  TObject(source),
+  fVerbose(source.fVerbose),
+  fV2718Patch(source.fV2718Patch),
+  fDataBuffer(source.fDataBuffer),
+  fPackedDataBuffer(source.fPackedDataBuffer),
+  //fTRMGlobalHeader(source.fTRMGlobalHeader),
+  //fTRMGlobalTrailer(source.fTRMGlobalTrailer),
+  //fTRMChainHeader(source.fTRMChainHeader),
+  //fTRMChainTrailer(source.fTRMChainTrailer),
+  //fTDCPackedHit(source.fTDCPackedHit),
+  //fTDCUnpackedHit(source.fTDCUnpackedHit),
+  //fTRMTDCError(source.fTRMTDCError),
+  //fTRMDiagnosticErrorWord1(source.fTRMDiagnosticErrorWord1),
+  //fTRMDiagnosticErrorWord2(source.fTRMDiagnosticErrorWord2),
+  fSpiderCurrentSlotID(source.fSpiderCurrentSlotID),
+  fSpiderCurrentChain(source.fSpiderCurrentChain),
+  fSpiderCurrentTDC(source.fSpiderCurrentTDC)
+{
+  //copy constructor
+
+  for (Int_t chan=0;chan<N_CHANNEL;chan++)
+    fSpiderLeadingFlag[chan] = source.fSpiderLeadingFlag[chan];
+  
+}
+
+//_________________________________________________________________
+
+AliTOFDecoder &
+AliTOFDecoder::operator = (const AliTOFDecoder &source)
+{
+  //operator =
+
+  if (this == &source)
+    return *this;
+
+  TObject::operator=(source);
+  fVerbose = source.fVerbose;
+  fV2718Patch = source.fV2718Patch;
+  fDataBuffer = source.fDataBuffer;
+  fPackedDataBuffer = source.fPackedDataBuffer;
+  //fTRMGlobalHeader = source.fTRMGlobalHeader;
+  //fTRMGlobalTrailer = source.fTRMGlobalTrailer;
+  //fTRMChainHeader = source.fTRMChainHeader;
+  //fTRMChainTrailer = source.fTRMChainTrailer;
+  //fTDCPackedHit = source.fTDCPackedHit;
+  //fTDCUnpackedHit = source.fTDCUnpackedHit;
+  //fTRMTDCError = source.fTRMTDCError;
+  //fTRMDiagnosticErrorWord1 = source.fTRMDiagnosticErrorWord1;
+  //fTRMDiagnosticErrorWord2 = source.fTRMDiagnosticErrorWord2;
+  fSpiderCurrentSlotID = source.fSpiderCurrentSlotID;
+  fSpiderCurrentChain = source.fSpiderCurrentChain;
+  fSpiderCurrentTDC = source.fSpiderCurrentTDC;
+  for (Int_t chan=0;chan<N_CHANNEL;chan++)
+    fSpiderLeadingFlag[chan] = source.fSpiderLeadingFlag[chan];
+  
+  return *this;
+}
+
+AliTOFDecoder::~AliTOFDecoder()
+{}
+
+//_________________________________________________________________
+
+Bool_t
+AliTOFDecoder::Decode(const UInt_t *rawData, Int_t nWords, const AliRawDataHeader *cdh, const AliRawDataHeaderV3 *cdhV3)
+{
+  /* main decoding routine.
+   * it loops over nWords 32-bit words 
+   * starting at *rawData and decodes them.
+   * it also fills some buffers in order to
+   * have the decoded data available for other
+   * classes.
+   */
+
+  AliTOFDRMStatusHeader3 *lDRMStatusHeader3;
+  AliTOFTRMGlobalHeader          *lTRMGlobalHeader; //TRM global header
+  AliTOFTRMGlobalTrailer         *lTRMGlobalTrailer; //TRM global trailer
+  AliTOFTRMChainHeader           *lTRMChainHeader; //TRM chain header
+  //AliTOFTRMChainTrailer          *lTRMChainTrailer; //TRM chain trailer
+  AliTOFTDCPackedHit             *lTDCPackedHit; //TDC packed hit
+  AliTOFTDCUnpackedHit           *lTDCUnpackedHit; //TDC unpacked hit
+  //AliTOFTRMTDCError              *lTRMTDCError; //TRM TDC error
+  //AliTOFTRMDiagnosticErrorWord1  *lTRMDiagnosticErrorWord1; //TRM diagnostic error word 1
+  //AliTOFTRMDiagnosticErrorWord2  *lTRMDiagnosticErrorWord2; //TRM diagnostica error word 2
+
+
+  AliTOFHitData hitData;
+  
+  //useful variables
+  Int_t   status;
+  Short_t tempPS;
+  Float_t tempTOT; //ns
+  Int_t   tempTOTBin; //TOT_BIN_WIDTH
+
+  //decoder variables
+  UShort_t decodeStatus = 0x0;
+  Short_t  currentDDL = -1;
+  Short_t  currentSlotID = -1;
+  Short_t  currentACQ = -1;
+  Short_t  currentChain = -1;
+  Short_t  currentBunchID = -1;
+  Short_t  currentL0BCID = -1;
+  Short_t  currentMiniEventID = cdh ? cdh->GetMiniEventID() : (Short_t)(-1);
+  currentMiniEventID = cdhV3 ? cdhV3->GetMiniEventID() : currentMiniEventID;
+  Short_t  currentEventID1 = cdh ? cdh->GetEventID1() : (Short_t)(-1);
+  currentEventID1 = cdhV3 ? cdhV3->GetEventID1() : currentEventID1;
+  if (!cdh && !cdhV3)
+    AliWarning("CDH not valid: deltaBunchID not reliable ");
+  else
+    AliDebug(1, Form("EvID1 = %d, EvID2 = %d, currentMiniEventID = %d", currentEventID1, cdh? cdh->GetEventID2() : cdhV3->GetEventID2(), currentMiniEventID));
+
+  /*** V2718 patch ***/
+  if (fV2718Patch){
+    decodeStatus = decodeStatus | DRM_BIT;
+    if (fVerbose)
+      AliInfo("DRM not present: - V2718 patch decoding -");
+  }
+  /*** V2718 patch ***/
+
+  if (fVerbose==2)
+    AliInfo("Initialize SPIDER function");
+  status = InitializeSpider();
+  
+  if (fVerbose)
+    AliInfo("Start decoding");
+  
+  if (fVerbose)
+    AliInfo("Loop over the data and decode");
+  
+  if (fVerbose)
+    AliInfo("  St    Hex Word \t   Decoded Word");
+  
+  //loop over raw data
+  for (Int_t iWord = 0; iWord < nWords; iWord++, rawData++){
+    
+    //switch word type
+    switch (*rawData & WORD_TYPE_MASK){
+      
+    case GLOBAL_HEADER:
+      
+      //switch slot ID
+      switch (*rawData & SLOT_ID_MASK){
+       
+       //DRM global header (slotID=1)
+      case 1:
+       //check decode status
+       if ( decodeStatus != DRM_HEADER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global header",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  DRM global header",decodeStatus,*rawData));
+       //change decode status
+       decodeStatus = decodeStatus | DRM_BIT;
+       
+       //skip DRM data
+       for (Int_t i = 0; i < DRM_DATA_WORDS; i++, iWord++){
+         rawData++;
+         if (fVerbose)
+             AliInfo(Form("  %02x - 0x%08x \t  DRM data",decodeStatus,*rawData));
+         switch (i) {
+         case 2:
+           lDRMStatusHeader3 = (AliTOFDRMStatusHeader3*)rawData;
+           currentL0BCID = lDRMStatusHeader3->GetL0BCID();
+           break;
+         default:
+           break;
+         }
+       }
+       break;
+       
+       //LTM global header (slotID=2)
+      case 2:
+       //check decode status
+       if ( decodeStatus != LTM_HEADER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global header",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  LTM global header",decodeStatus,*rawData));
+       //change decode status
+       decodeStatus = decodeStatus | LTM_BIT;
+       
+       //skip LTM data
+       for (Int_t i = 0; i < LTM_DATA_WORDS; i++, iWord++){
+         rawData++;
+         if (fVerbose)
+           AliInfo(Form("  %02x - 0x%08x \t  LTM data",decodeStatus,*rawData));
+       }
+       break;
+       
+       //TRM global header (slotID=3-12)
+      case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
+       //check decode status
+       if ( decodeStatus != TRM_HEADER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global header",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       //set TRM global header
+       lTRMGlobalHeader = (AliTOFTRMGlobalHeader*)rawData;     
+       //set current TRM
+       currentSlotID = lTRMGlobalHeader->GetSlotID();
+       currentACQ = lTRMGlobalHeader->GetACQBits();
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  TRM global header \t slotID=%02d ACQ=%01d L=%01d",decodeStatus,*rawData,lTRMGlobalHeader->GetSlotID(),lTRMGlobalHeader->GetACQBits(),lTRMGlobalHeader->GetLBit()));
+       //change decode status
+       decodeStatus = decodeStatus | TRM_BIT;
+       break;
+       
+      default:
+       AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID in global header",decodeStatus,*rawData));
+       return kTRUE;
+       break;
+       
+      }
+      //end switch slotID
+      break;
+      
+    case GLOBAL_TRAILER:
+      
+      //switch slot ID
+      switch (*rawData & SLOT_ID_MASK){
+       
+       //DRM global trailer (slotID=1)
+      case 1:
+       //check decode status
+       if ( decodeStatus != DRM_TRAILER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global trailer",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  DRM global trailer",decodeStatus,*rawData));
+       //change decode status
+       decodeStatus = decodeStatus & ~DRM_BIT;
+       break;
+       
+       //LTM global trailer (slotID=2)
+      case 2:
+       //check decode status
+       if ( decodeStatus != LTM_TRAILER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global trailer",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  LTM global trailer",decodeStatus,*rawData));
+       //change decode status
+       decodeStatus = decodeStatus & ~LTM_BIT;
+       break;
+       
+       //TRM global trailer (slotID=15)
+      case 15:
+       //check decode status
+       if ( decodeStatus != TRM_TRAILER_STATUS ){
+         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global trailer",decodeStatus,*rawData));
+         return kTRUE;
+       }
+       //decode status ok
+       //set TRM global trailer
+       lTRMGlobalTrailer = (AliTOFTRMGlobalTrailer *)rawData;  
+       if (fVerbose)
+         AliInfo(Form("  %02x - 0x%08x \t  TRM global trailer \t CRC=%04d eventCounter=%04d",decodeStatus,*rawData,lTRMGlobalTrailer->GetEventCRC(),lTRMGlobalTrailer->GetEventCounter()));
+       //change decode status
+       decodeStatus = decodeStatus & ~TRM_BIT;
+       break; 
+       
+      default:
+       AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID/pattern in global trailer",decodeStatus,*rawData));
+       return kTRUE;
+       break;
+      }
+      break;
+      
+    case CHAIN_A_HEADER:
+      //check decode status
+      if ( (decodeStatus != CHAIN_A_HEADER_STATUS) ){
+       AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A header",decodeStatus,*rawData));
+       return kTRUE;
+      }
+      //decode status ok
+      lTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
+      currentChain = 0;
+      currentBunchID = lTRMChainHeader->GetBunchID();
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  TRM chain A header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
+      //change decode status
+      decodeStatus = decodeStatus | CHAIN_A_BIT;
+      break;
+      
+    case CHAIN_A_TRAILER:
+      //check decode status
+      if ( decodeStatus != CHAIN_A_TRAILER_STATUS ){
+       AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A trailer",decodeStatus,*rawData));
+       return kTRUE;
+      }
+      //decode status ok
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  TRM chain A trailer",decodeStatus,*rawData));
+      //change decode status
+      decodeStatus = decodeStatus & ~CHAIN_A_BIT;
+      break;
+      
+    case CHAIN_B_HEADER:
+      //check decode status
+      if ( decodeStatus != CHAIN_B_HEADER_STATUS ){
+       AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B header",decodeStatus,*rawData));
+       return kTRUE;
+      }
+      //decode status ok
+      lTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
+      currentChain = 1;
+      currentBunchID = lTRMChainHeader->GetBunchID();
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  TRM chain B header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
+      //change decode status
+      decodeStatus = decodeStatus | CHAIN_B_BIT;
+      break;
+      
+    case CHAIN_B_TRAILER:
+      //check decode status
+      if ( decodeStatus != CHAIN_B_TRAILER_STATUS ){
+       AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B trailer",decodeStatus,*rawData));
+       return kTRUE;
+      }
+      //decode status ok
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  TRM chain B trailer",decodeStatus,*rawData));
+      //change decode status
+      decodeStatus = decodeStatus & ~CHAIN_B_BIT;
+      break;
+      
+    case ERROR:
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  TDC error",decodeStatus,*rawData));
+      break;
+      
+    case FILLER:
+      if (fVerbose)
+       AliInfo(Form("  %02x - 0x%08x \t  Filler",decodeStatus,*rawData));
+      break;
+      
+    default:
+      //check decode status
+      if ( decodeStatus != CHAIN_A_TDC_HIT_STATUS &&
+          decodeStatus != CHAIN_B_TDC_HIT_STATUS ){
+       AliError(Form("  %02x - 0x%08x [ERROR] Unexpected or unknown word",decodeStatus,*rawData));
+       return kTRUE;
+      }
+      //decode status ok
+      
+      //switch TRM ACQ
+      switch (currentACQ){
+       
+      case PACKING_ENABLED_ACQ:
+       //decode TDC packed hit
+       lTDCPackedHit = (AliTOFTDCPackedHit *)rawData;
+       lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
+       //set hit in the equipment data
+       hitData.SetDDLID(currentDDL);
+       hitData.SetSlotID(currentSlotID);
+       hitData.SetACQ(currentACQ);
+       hitData.SetChain(currentChain);
+       hitData.SetPS(lTDCPackedHit->GetPSBits());
+       hitData.SetTDC(lTDCPackedHit->GetTDCID());
+       hitData.SetChan(lTDCPackedHit->GetChan());
+       hitData.SetTime((float)lTDCPackedHit->GetHitTime() * TIME_BIN_WIDTH);
+       hitData.SetTimeBin(lTDCPackedHit->GetHitTime());
+       hitData.SetTOT((float)lTDCPackedHit->GetTOTWidth() * TOT_BIN_WIDTH);
+       hitData.SetTOTBin(lTDCPackedHit->GetTOTWidth());
+       hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
+       hitData.SetL0L1Latency(currentMiniEventID - currentL0BCID);
+       //orphane leading hit
+       if (hitData.GetPS()==LEADING_HIT_PS){
+         hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
+         hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
+         //set TOT to zero
+         hitData.SetTOT(0);
+         hitData.SetTOTBin(0);
+         //push hit data in packed data buffer
+         if (fPackedDataBuffer != 0x0)
+           fPackedDataBuffer->Add(hitData);
+         //set TOT to not measured
+         hitData.SetTOT(-1);
+         hitData.SetTOTBin(-1);
+         //push hit data in packed data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+       }
+       //orphane trailing hit
+       else if (hitData.GetPS()==TRAILING_HIT_PS){
+         hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
+         hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
+         //set TOT to not measured
+         hitData.SetTOT(-1);
+         hitData.SetTOTBin(-1);
+         //push hit data in data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+       }
+       //packed hit and OVF
+       else{
+         //push hit data in packed data buffer
+         if (fPackedDataBuffer != 0x0)
+           fPackedDataBuffer->Add(hitData);
+         //save PS temporary
+         tempPS = hitData.GetPS();
+         //save TOT temporary
+         tempTOT = hitData.GetTOT();
+         tempTOTBin = hitData.GetTOTBin();
+         //unpack the hit: leading hit
+         hitData.SetPS(LEADING_HIT_PS);
+         //set TOT to not measured
+         hitData.SetTOT(-1);
+         hitData.SetTOTBin(-1);
+         //push leading hit data in data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+         //unpack the hit: trailing hit
+         hitData.SetPS(TRAILING_HIT_PS);
+         hitData.SetTime(hitData.GetTime() + tempTOT);
+         hitData.SetTimeBin(hitData.GetTimeBin() + (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
+         //push trailing hit data in data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+         //restore packed hit
+         hitData.SetPS(tempPS);
+         hitData.SetTime(hitData.GetTime() - tempTOT);
+         hitData.SetTimeBin(hitData.GetTimeBin() - (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
+         hitData.SetTOT(tempTOT);
+         hitData.SetTOTBin(tempTOTBin);
+       }
+       
+       if (fVerbose)
+         switch (hitData.GetPS()){
+         case PACKED_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [packed] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case LEADING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [orp.lead] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TRAILING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [orp.trai] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TOT_OVF_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [TOT ovfl] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         }
+       break;
+       
+      case LEADING_ONLY_ACQ: case TRAILING_ONLY_ACQ:
+       //decode TDC unpacked hit
+       lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
+       //set hit in the equipment data
+       hitData.SetDDLID(currentDDL);
+       hitData.SetSlotID(currentSlotID);
+       hitData.SetACQ(currentACQ);
+       hitData.SetChain(currentChain);
+       hitData.SetPS(lTDCUnpackedHit->GetPSBits());
+       hitData.SetTDC(lTDCUnpackedHit->GetTDCID());
+       hitData.SetChan(lTDCUnpackedHit->GetChan());
+       hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
+       hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
+       hitData.SetTOT(-1.);
+       hitData.SetTOTBin(-1);
+       hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
+       hitData.SetL0L1Latency(currentMiniEventID - currentL0BCID);
+       //push hit data in data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+       
+       if (fVerbose)
+         switch (hitData.GetPS()){
+         case PACKED_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [packed] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case LEADING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [leading] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TRAILING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [trailing] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TOT_OVF_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [TOT ovfl] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         }
+       break;
+       
+      case PACKING_DISABLED_ACQ:
+       //decode TDC unpacked hit
+       lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
+       //set hit in the equipment data
+       hitData.SetDDLID(currentDDL);
+       hitData.SetSlotID(currentSlotID);
+       hitData.SetACQ(currentACQ);
+       hitData.SetChain(currentChain);
+       hitData.SetPS(lTDCUnpackedHit->GetPSBits());
+       hitData.SetTDC(lTDCUnpackedHit->GetTDCID());
+       hitData.SetChan(lTDCUnpackedHit->GetChan());
+       hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
+       hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
+       hitData.SetTOT(-1.);
+       hitData.SetTOTBin(-1);
+       hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
+       hitData.SetL0L1Latency(currentMiniEventID - currentL0BCID);
+       //push hit data in data buffer
+         if (fDataBuffer != 0x0)
+           fDataBuffer->Add(hitData);
+       
+       if (fVerbose)
+         switch (hitData.GetPS()){
+         case PACKED_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [packed] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case LEADING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [leading] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TRAILING_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [trailing] \t PS=%01d TDC=%01d chan=%01d time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         case TOT_OVF_HIT_PS:
+           AliInfo(Form("  %02x - 0x%08x \t  TDC hit [TOT ovfl] \t PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",decodeStatus,*rawData,hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+           break;
+         }
+       //call spider function
+       if (fVerbose==2)
+         AliInfo("Calling SPIDER function");
+       Spider(hitData);
+       break;
+      }
+      //end switch TRM ACQ
+      
+      
+    }
+    //end switch word type
+    
+  }
+  //end equipment data loop
+  
+  if (fVerbose)
+    AliInfo("End of data loop");
+  
+  if (fVerbose==2)
+    AliInfo("Reset SPIDER function");
+  status = ResetSpider();
+  
+  if (fVerbose)
+    AliInfo("Decoder is exiting succesfully.");
+
+  return kFALSE;  
+}
+
+//_________________________________________________________________
+
+Bool_t 
+AliTOFDecoder::InitializeSpider(){
+
+  /* SPIDER initialization routine.
+     it initializes SPIDER variables in order
+     to have SPIDER ready to pack tof data 
+     in packed data objects
+  */
+  
+  if (fVerbose==2)
+    AliInfo("Initializing SPIDER");
+  
+  fSpiderCurrentSlotID=-1;
+  fSpiderCurrentChain=-1;
+  fSpiderCurrentTDC=-1;
+  
+  for (Int_t chan=0;chan<N_CHANNEL;chan++)
+    fSpiderLeadingFlag[chan] = kFALSE;
+  
+  return kFALSE;
+}
+
+//_________________________________________________________________
+
+Bool_t 
+AliTOFDecoder::ResetSpider(){
+
+  /* SPIDER reset routine.
+     it resets SPIDER buffers and 
+     variables in order to empty full 
+     buffers a set up SIPDER for new
+     HPTDC data
+  */
+
+  if (fVerbose==2)
+    AliInfo("Resetting SPIDER buffers");
+
+  for (Int_t chan=0;chan<N_CHANNEL;chan++){
+    if (fSpiderLeadingFlag[chan]){
+      if (fVerbose==2)
+       AliInfo("Buffer non empty: put leading hit into buffer as orphane");
+      //set TOT to zero
+      fSpiderLeadingHit[chan].SetACQ(4);
+      fSpiderLeadingHit[chan].SetPS(1);
+      fSpiderLeadingHit[chan].SetTOT(0);
+      fSpiderLeadingHit[chan].SetTOTBin(0);
+      //push hit into packed buffer
+      if (fPackedDataBuffer != 0x0)
+       fPackedDataBuffer->Add(fSpiderLeadingHit[chan]);
+      if (fVerbose==2)
+       AliInfo(Form("Packed hit: slotID=%d chain=%d PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",fSpiderLeadingHit[chan].GetSlotID(),fSpiderLeadingHit[chan].GetChain(),fSpiderLeadingHit[chan].GetPS(),fSpiderLeadingHit[chan].GetTDC(),fSpiderLeadingHit[chan].GetChan(),fSpiderLeadingHit[chan].GetTOT(),fSpiderLeadingHit[chan].GetTOTBin(),fSpiderLeadingHit[chan].GetTime(),fSpiderLeadingHit[chan].GetTimeBin()));
+      
+    }
+    fSpiderLeadingFlag[chan]=kFALSE;
+  }
+  
+  return kFALSE;
+}
+
+//_________________________________________________________________
+
+Bool_t 
+AliTOFDecoder::Spider(AliTOFHitData &hitData){
+
+  /* main SPIDER routine.
+     it receives, reads, stores and packs
+     unpacked HPTDC data in packed data
+     object. it also fills buffers.
+  */
+  Int_t status;
+
+  if (fVerbose==2)
+    AliInfo("Hit data received");
+
+  //check if TDC is changed (slotID,chain,TDC triplet)
+  if (fSpiderCurrentSlotID!=hitData.GetSlotID() ||
+      fSpiderCurrentChain!=hitData.GetChain() ||
+      fSpiderCurrentTDC!=hitData.GetTDC() ){
+    if (fVerbose==2)
+      AliInfo("Data coming from a new TDC: reset buffers");
+    //reset spider
+    status = ResetSpider();
+    //set current TDC 
+    fSpiderCurrentSlotID=hitData.GetSlotID();
+    fSpiderCurrentChain=hitData.GetChain();
+    fSpiderCurrentTDC=hitData.GetTDC();
+  }
+  
+  //switch PS bits
+  switch (hitData.GetPS()){
+
+  case LEADING_HIT_PS:
+    if (fVerbose==2)
+      AliInfo(Form("Leading hit: slotID=%d chain=%d PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",hitData.GetSlotID(),hitData.GetChain(),hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+    //check spider leading flag
+    if (fSpiderLeadingFlag[hitData.GetChan()]){
+      if (fVerbose==2)
+       AliInfo("Leading hit: buffer full, put previous in buffers as orphane and keep current");
+      //set TOT at zero for previous hit
+      fSpiderLeadingHit[hitData.GetChan()].SetACQ(4);
+      fSpiderLeadingHit[hitData.GetChan()].SetPS(1);
+      fSpiderLeadingHit[hitData.GetChan()].SetTOT(0);
+      fSpiderLeadingHit[hitData.GetChan()].SetTOTBin(0);
+      //push previous hit into packed buffer
+      if (fPackedDataBuffer != 0x0)
+       fPackedDataBuffer->Add(fSpiderLeadingHit[hitData.GetChan()]);
+      //set current hit
+      fSpiderLeadingHit[hitData.GetChan()]=hitData;
+      if (fVerbose==2)
+       AliInfo(Form("Packed hit: slotID=%d chain=%d PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",fSpiderLeadingHit[hitData.GetChan()].GetSlotID(),fSpiderLeadingHit[hitData.GetChan()].GetChain(),fSpiderLeadingHit[hitData.GetChan()].GetPS(),fSpiderLeadingHit[hitData.GetChan()].GetTDC(),fSpiderLeadingHit[hitData.GetChan()].GetChan(),fSpiderLeadingHit[hitData.GetChan()].GetTOT(),fSpiderLeadingHit[hitData.GetChan()].GetTOTBin(),fSpiderLeadingHit[hitData.GetChan()].GetTime(),fSpiderLeadingHit[hitData.GetChan()].GetTimeBin()));
+    }
+    else{
+      if (fVerbose==2)
+       AliInfo("Leading hit: buffer empty, keep current hit and set flag");
+      fSpiderLeadingHit[hitData.GetChan()]=hitData;
+      //set spider leading flag
+      fSpiderLeadingFlag[hitData.GetChan()]=kTRUE;
+    }
+    break;
+
+  case TRAILING_HIT_PS:
+    if (fVerbose==2)
+      AliInfo(Form("Trailing hit: slotID=%d chain=%d PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",hitData.GetSlotID(),hitData.GetChain(),hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+    //check spider leading flag
+    if (fSpiderLeadingFlag[hitData.GetChan()]){
+      if (fVerbose==2)
+       AliInfo("Trailing hit: buffer full, pack leading and trailing");
+      hitData.SetACQ(4);
+      hitData.SetPS(0);
+      hitData.SetTOT(hitData.GetTime()-fSpiderLeadingHit[hitData.GetChan()].GetTime());
+      hitData.SetTOTBin((Int_t)((hitData.GetTimeBin()-fSpiderLeadingHit[hitData.GetChan()].GetTimeBin())*TIME_TO_TOT_BIN_WIDTH));
+      hitData.SetTime(fSpiderLeadingHit[hitData.GetChan()].GetTime());
+      hitData.SetTimeBin(fSpiderLeadingHit[hitData.GetChan()].GetTimeBin());
+      //check TOT and set TOT overflow if TOT < 0
+      if (hitData.GetTOT() < 0){
+       hitData.SetPS(3);
+       hitData.SetTOT(0);
+       hitData.SetTOTBin(0);
+      }
+      if (fPackedDataBuffer != 0x0)
+       fPackedDataBuffer->Add(hitData);      
+      if (fVerbose==2)
+       AliInfo(Form("Packed hit: slotID=%d chain=%d PS=%01d TDC=%01d chan=%01d TOT=%3.1fns (%d) time=%4.1fns (%d)",hitData.GetSlotID(),hitData.GetChain(),hitData.GetPS(),hitData.GetTDC(),hitData.GetChan(),hitData.GetTOT(),hitData.GetTOTBin(),hitData.GetTime(),hitData.GetTimeBin()));
+      //unset spider leading flag
+      fSpiderLeadingFlag[hitData.GetChan()]=kFALSE;
+    }
+    else{
+      if (fVerbose==2)
+       AliInfo("Trailing hit: buffer empty, throw hit away");
+    }
+    break;
+  }
+  //end switch PS bits
+
+  return kFALSE;
+}
+//_____________________________________________________________________________
+void AliTOFDecoder::GetArrayDDL(Int_t* array, Int_t ddl){
+
+  // method that fills array with the
+  // TOF channels indexes corresponding
+  // to DDL iDDL
+
+  AliTOFGeometry *geom = new AliTOFGeometry();
+  Int_t indexDDL = ddl%4;
+  Int_t iSector = Int_t(ddl/4);
+  if (fVerbose)
+    AliInfo(Form(" Sector = %i, DDL within sector = %i",iSector, indexDDL));
+
+  Int_t volume[5];
+  volume[0]=iSector;
+  Int_t minPlate=0, maxPlate=0, minStrip2=0, maxStrip2=0, minPadz=0, maxPadz=0, minPadx=0, maxPadx=0;
+
+  if (indexDDL==0){
+    minPlate=kMinPlate0;
+    maxPlate=kMaxPlate0;
+    minStrip2=kMinStrip0;
+    maxStrip2=kMaxStrip0;
+    minPadz=kMinPadz0;
+    maxPadz=kMaxPadz0;
+    minPadx=kMinPadx0;
+    maxPadx=kMaxPadx0;
+  }
+
+  else if (indexDDL==1){
+    minPlate=kMinPlate1;
+    maxPlate=kMaxPlate1;
+    minStrip2=kMinStrip1;
+    maxStrip2=kMaxStrip1;
+    minPadz=kMinPadz1;
+    maxPadz=kMaxPadz1;
+    minPadx=kMinPadx1;
+    maxPadx=kMaxPadx1;
+  }
+
+  else if (indexDDL==2){
+    minPlate=kMinPlate2;
+    maxPlate=kMaxPlate2;
+    minStrip2=kMinStrip2;
+    maxStrip2=kMaxStrip2;
+    minPadz=kMinPadz2;
+    maxPadz=kMaxPadz2;
+    minPadx=kMinPadx2;
+    maxPadx=kMaxPadx2;
+  }
+
+  else if (indexDDL==3){
+    minPlate=kMinPlate3;
+    maxPlate=kMaxPlate3;
+    minStrip2=kMinStrip3;
+    maxStrip2=kMaxStrip3;
+    minPadz=kMinPadz3;
+    maxPadz=kMaxPadz3;
+    minPadx=kMinPadx3;
+    maxPadx=kMaxPadx3;
+  }
+
+  Int_t ichTOF=0;
+
+  Int_t minStrip=0;
+  Int_t maxStrip=18;  
+  for (Int_t iPlate=minPlate;iPlate<=maxPlate;iPlate++){
+    if (iPlate==2) {
+      maxStrip = maxStrip2;
+      minStrip = minStrip2;
+    }
+    else {
+      maxStrip = 18;
+      minStrip = 0;
+    }
+    for (Int_t iStrip=minStrip;iStrip<=maxStrip;iStrip++){
+      for (Int_t iPadz=minPadz;iPadz<=maxPadz;iPadz++){
+       for (Int_t iPadx=minPadx;iPadx<=maxPadx;iPadx++){
+         volume[1]=iPlate;
+         volume[2]=iStrip;
+         volume[3]=iPadz;
+         volume[4]=iPadx;
+         if (fVerbose)
+           AliInfo(Form(" volume[0] = %i, volume[1] = %i, volume[2] = %i, volume[3] = %i, volume[4] = %i",volume[0],volume[1],volume[2],volume[3],volume[4]));
+
+         if (indexDDL==0 || indexDDL==2){
+           array[ichTOF]=geom->GetIndex(volume);
+           if (fVerbose)
+             AliInfo(Form(" ichTOF = %i, TOFChannel = %i",ichTOF,array[ichTOF]));
+
+         }
+         else {
+           array[ichTOF]=geom->GetIndex(volume);
+           if (fVerbose)
+             AliInfo(Form(" ichTOF = %i, TOFChannel = %i",ichTOF,array[ichTOF]));
+
+         }
+         ichTOF++;
+       }
+      }
+    }
+  }
+  //AliInfo(Form("ichTOF = %i",ichTOF));
+  if ((indexDDL%2==0 && ichTOF!=2160) ||
+      (indexDDL%2==1 && ichTOF!=2208)) {
+    AliWarning(Form("Something strange occurred, number of entries in array different from expected! Please, check! ichTOF = %i",ichTOF));
+  }
+  return;
+}
+
+//------------------------------------------------------------
+void AliTOFDecoder::PrintStack(const UInt_t *rawData, Int_t nWords, const AliRawDataHeader *cdh, const AliRawDataHeaderV3 *cdhV3)
+{
+  /* It loops over nWords 32-bit words 
+   * starting at *rawData and prints them in 0x format.
+   * It does not decode them!
+   */
+
+ Short_t  currentMiniEventID = cdh ? cdh->GetMiniEventID() : (Short_t)(-1);
+ currentMiniEventID = cdhV3 ? cdhV3->GetMiniEventID() : currentMiniEventID;
+ Short_t  currentEventID1 = cdh ? cdh->GetEventID1() : (Short_t)(-1);
+ currentEventID1 = cdhV3 ? cdhV3->GetEventID1() : currentEventID1;
+ if (!cdh && !cdhV3)
+   AliWarning("CDH not valid: deltaBunchID not reliable ");
+ else
+   AliDebug(1, Form("EvID1 = %d, EvID2 = %d, currentMiniEventID = %d", currentEventID1, cdh ? cdh->GetEventID2() : cdhV3->GetEventID2(), currentMiniEventID));
+
+ AliInfo("Printing raw data stack for current equipment\n");
+ AliInfo("  wordN  -  Hex Word "); 
+ //loop over raw data
+ for (Int_t iWord = 0; iWord < nWords; iWord++, rawData++){
+     if (iWord<10)            AliInfo(Form("      %i   - 0x%08x",iWord,*rawData));
+     if (iWord>9 &&iWord<100) AliInfo(Form("     %i   - 0x%08x",iWord,*rawData)); 
+     if (iWord>99)            AliInfo(Form("    %i   - 0x%08x",iWord,*rawData)); 
+ }
+ return;
+}