TOF Raw Data decoder
[u/mrichter/AliRoot.git] / TOF / AliTOFDecoder.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14 ***************************************************************************/
15
16 /*
17 $Log$
18   author: Roberto Preghenella (R+), preghenella@bo.infn.it
19 */
20
21
22 /*********************************************************************
23  *                                                                   *
24  *                                                                   *
25  *   Class for raw data decoding                                     *
26  *                                                                   *
27  *                                                                   *
28  ********************************************************************/
29                                
30
31
32 #include "AliLog.h"
33 #include "AliTOFHitData.h"
34 #include "AliTOFDecoder.h"
35
36 ClassImp(AliTOFDecoder)
37
38 //_________________________________________________________________
39
40 AliTOFDecoder::AliTOFDecoder() :
41   TObject(),
42   fVerbose(0),
43   fV2718Patch(kFALSE),
44   fDataBuffer(0x0),
45   fPackedDataBuffer(0x0),
46   fTRMGlobalHeader(0x0),
47   fTRMGlobalTrailer(0x0),
48   fTRMChainHeader(0x0),
49   fTRMChainTrailer(0x0),
50   fTDCPackedHit(0x0),
51   fTDCUnpackedHit(0x0),
52   fTRMTDCError(0x0),
53   fTRMDiagnosticErrorWord1(0x0),
54   fTRMDiagnosticErrorWord2(0x0),
55   fSpiderCurrentSlotID(-1),
56   fSpiderCurrentChain(-1),
57   fSpiderCurrentTDC(-1)
58 {
59   //default constructor
60 }
61
62 //_________________________________________________________________
63
64 AliTOFDecoder::AliTOFDecoder(AliTOFHitDataBuffer *DataBuffer, AliTOFHitDataBuffer *PackedDataBuffer) :
65   TObject(),
66   fVerbose(0),
67   fV2718Patch(kFALSE),
68   fDataBuffer(DataBuffer),
69   fPackedDataBuffer(PackedDataBuffer),
70   fTRMGlobalHeader(0x0),
71   fTRMGlobalTrailer(0x0),
72   fTRMChainHeader(0x0),
73   fTRMChainTrailer(0x0),
74   fTDCPackedHit(0x0),
75   fTDCUnpackedHit(0x0),
76   fTRMTDCError(0x0),
77   fTRMDiagnosticErrorWord1(0x0),
78   fTRMDiagnosticErrorWord2(0x0),
79   fSpiderCurrentSlotID(-1),
80   fSpiderCurrentChain(-1),
81   fSpiderCurrentTDC(-1)
82 {
83   //another constructor
84 }
85
86 //_________________________________________________________________
87
88 AliTOFDecoder::AliTOFDecoder(const AliTOFDecoder &source) : 
89   TObject(),
90   fVerbose(0),
91   fV2718Patch(kFALSE),
92   fDataBuffer(0x0),
93   fPackedDataBuffer(0x0),
94   fTRMGlobalHeader(0x0),
95   fTRMGlobalTrailer(0x0),
96   fTRMChainHeader(0x0),
97   fTRMChainTrailer(0x0),
98   fTDCPackedHit(0x0),
99   fTDCUnpackedHit(0x0),
100   fTRMTDCError(0x0),
101   fTRMDiagnosticErrorWord1(0x0),
102   fTRMDiagnosticErrorWord2(0x0),
103   fSpiderCurrentSlotID(-1),
104   fSpiderCurrentChain(-1),
105   fSpiderCurrentTDC(-1)
106 {
107   //copy constructor
108   
109   this->fVerbose = source.fVerbose;
110   this->fV2718Patch = source.fV2718Patch;
111   this->fDataBuffer = source.fDataBuffer;
112   this->fPackedDataBuffer = source.fPackedDataBuffer;
113   this->fTRMGlobalHeader = source.fTRMGlobalHeader;
114   this->fTRMGlobalTrailer = source.fTRMGlobalTrailer;
115   this->fTRMChainHeader = source.fTRMChainHeader;
116   this->fTRMChainTrailer = source.fTRMChainTrailer;
117   this->fTDCPackedHit = source.fTDCPackedHit;
118   this->fTDCUnpackedHit = source.fTDCUnpackedHit;
119   this->fTRMTDCError = source.fTRMTDCError;
120   this->fTRMDiagnosticErrorWord1 = source.fTRMDiagnosticErrorWord1;
121   this->fTRMDiagnosticErrorWord2 = source.fTRMDiagnosticErrorWord2;
122   this->fSpiderCurrentSlotID = source.fSpiderCurrentSlotID;
123   this->fSpiderCurrentChain = source.fSpiderCurrentChain;
124   this->fSpiderCurrentTDC = source.fSpiderCurrentTDC;
125 }
126
127 //_________________________________________________________________
128
129 AliTOFDecoder &
130 AliTOFDecoder::operator = (const AliTOFDecoder &source)
131 {
132   //operator =
133
134   this->fVerbose = source.fVerbose;
135   this->fV2718Patch = source.fV2718Patch;
136   this->fDataBuffer = source.fDataBuffer;
137   this->fPackedDataBuffer = source.fPackedDataBuffer;
138   this->fTRMGlobalHeader = source.fTRMGlobalHeader;
139   this->fTRMGlobalTrailer = source.fTRMGlobalTrailer;
140   this->fTRMChainHeader = source.fTRMChainHeader;
141   this->fTRMChainTrailer = source.fTRMChainTrailer;
142   this->fTDCPackedHit = source.fTDCPackedHit;
143   this->fTDCUnpackedHit = source.fTDCUnpackedHit;
144   this->fTRMTDCError = source.fTRMTDCError;
145   this->fTRMDiagnosticErrorWord1 = source.fTRMDiagnosticErrorWord1;
146   this->fTRMDiagnosticErrorWord2 = source.fTRMDiagnosticErrorWord2;
147   this->fSpiderCurrentSlotID = source.fSpiderCurrentSlotID;
148   this->fSpiderCurrentChain = source.fSpiderCurrentChain;
149   this->fSpiderCurrentTDC = source.fSpiderCurrentTDC;
150   return *this;
151 }
152
153 AliTOFDecoder::~AliTOFDecoder()
154 {}
155
156 //_________________________________________________________________
157
158 Bool_t
159 AliTOFDecoder::Decode(UInt_t *rawData, Int_t nWords)
160 {
161   /* main decoding routine.
162    * it loops over nWords 32-bit words 
163    * starting at *rawData and decodes them.
164    * it also fills some buffers in order to
165    * have the decoded data available for other
166    * classes.
167    */
168
169   AliTOFHitData hitData;
170   
171   //useful variables
172   Int_t   status;
173   Short_t tempPS;
174   Float_t tempTOT; //ns
175   Int_t   tempTOTBin; //TOT_BIN_WIDTH
176
177   //decoder variables
178   UShort_t decodeStatus = 0x0;
179   Short_t  currentDDL = -1;
180   Short_t  currentSlotID = -1;
181   Short_t  currentACQ = -1;
182   Short_t  currentChain = -1;
183   Short_t  currentBunchID = -1;
184
185   /*** V2718 patch ***/
186   if (fV2718Patch){
187     decodeStatus = decodeStatus | DRM_BIT;
188     if (fVerbose)
189       AliInfo("DRM not present: - V2718 patch decoding -");
190   }
191   /*** V2718 patch ***/
192
193   if (fVerbose==2)
194     AliInfo("Initialize SPIDER function");
195   status = InitializeSpider();
196   
197   if (fVerbose)
198     AliInfo("Start decoding");
199   
200   if (fVerbose)
201     AliInfo("Loop over the data and decode");
202   
203   if (fVerbose)
204     AliInfo("  St    Hex Word \t   Decoded Word");
205   
206   //loop over raw data
207   for (Int_t iWord = 0; iWord < nWords; iWord++, rawData++){
208     
209     //switch word type
210     switch (*rawData & WORD_TYPE_MASK){
211       
212     case GLOBAL_HEADER:
213       
214       //switch slot ID
215       switch (*rawData & SLOT_ID_MASK){
216         
217         //DRM global header (slotID=1)
218       case 1:
219         //check decode status
220         if ( decodeStatus != DRM_HEADER_STATUS ){
221           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global header",decodeStatus,*rawData));
222           return kTRUE;
223         }
224         //decode status ok
225         if (fVerbose)
226           AliInfo(Form("  %02x - 0x%08x \t  DRM global header",decodeStatus,*rawData));
227         //change decode status
228         decodeStatus = decodeStatus | DRM_BIT;
229         
230         //skip DRM data
231         for (Int_t i = 0; i < DRM_DATA_WORDS; i++, iWord++, rawData++){
232           if (fVerbose)
233             AliInfo(Form("  %02x - 0x%08x \t  DRM data",decodeStatus,*rawData));
234         }
235         break;
236         
237         //LTM global header (slotID=2)
238       case 2:
239         //check decode status
240         if ( decodeStatus != LTM_HEADER_STATUS ){
241           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global header",decodeStatus,*rawData));
242           return kTRUE;
243         }
244         //decode status ok
245         if (fVerbose)
246           AliInfo(Form("  %02x - 0x%08x \t  LTM global header",decodeStatus,*rawData));
247         //change decode status
248         decodeStatus = decodeStatus | LTM_BIT;
249         
250         //skip LTM data
251         for (Int_t i = 0; i < LTM_DATA_WORDS; i++, iWord++, rawData++){
252           if (fVerbose)
253             AliInfo(Form("  %02x - 0x%08x \t  LTM data",decodeStatus,*rawData));
254         }
255         break;
256         
257         //TRM global header (slotID=3-12)
258       case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
259         //check decode status
260         if ( decodeStatus != TRM_HEADER_STATUS ){
261           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global header",decodeStatus,*rawData));
262           return kTRUE;
263         }
264         //decode status ok
265         //set TRM global header
266         fTRMGlobalHeader = (AliTOFTRMGlobalHeader *)rawData;    
267         //set current TRM
268         currentSlotID = fTRMGlobalHeader->GetSlotID();
269         currentACQ = fTRMGlobalHeader->GetACQBits();
270         if (fVerbose)
271           AliInfo(Form("  %02x - 0x%08x \t  TRM global header \t slotID=%02d ACQ=%01d L=%01d",decodeStatus,*rawData,fTRMGlobalHeader->GetSlotID(),fTRMGlobalHeader->GetACQBits(),fTRMGlobalHeader->GetLBit()));
272         //change decode status
273         decodeStatus = decodeStatus | TRM_BIT;
274         break;
275         
276       default:
277         if (fVerbose)
278           AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID in global header",decodeStatus,*rawData));
279         return kTRUE;
280         break;
281         
282       }
283       //end switch slotID
284       break;
285       
286     case GLOBAL_TRAILER:
287       
288       //switch slot ID
289       switch (*rawData & SLOT_ID_MASK){
290         
291         //DRM global trailer (slotID=1)
292       case 1:
293         //check decode status
294         if ( decodeStatus != DRM_TRAILER_STATUS ){
295           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global trailer",decodeStatus,*rawData));
296           return kTRUE;
297         }
298         //decode status ok
299         if (fVerbose)
300           AliInfo(Form("  %02x - 0x%08x \t  DRM global trailer",decodeStatus,*rawData));
301         //change decode status
302         decodeStatus = decodeStatus & ~DRM_BIT;
303         break;
304         
305         //LTM global trailer (slotID=2)
306       case 2:
307         //check decode status
308         if ( decodeStatus != LTM_TRAILER_STATUS ){
309           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global trailer",decodeStatus,*rawData));
310           return kTRUE;
311         }
312         //decode status ok
313         if (fVerbose)
314           AliInfo(Form("  %02x - 0x%08x \t  LTM global trailer",decodeStatus,*rawData));
315         //change decode status
316         decodeStatus = decodeStatus & ~LTM_BIT;
317         break;
318         
319         //TRM global trailer (slotID=15)
320       case 15:
321         //check decode status
322         if ( decodeStatus != TRM_TRAILER_STATUS ){
323           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global trailer",decodeStatus,*rawData));
324           return kTRUE;
325         }
326         //decode status ok
327         //set TRM global trailer
328         fTRMGlobalTrailer = (AliTOFTRMGlobalTrailer *)rawData;  
329         if (fVerbose)
330           AliInfo(Form("  %02x - 0x%08x \t  TRM global trailer \t CRC=%04d eventCounter=%04d",decodeStatus,*rawData,fTRMGlobalTrailer->GetEventCRC(),fTRMGlobalTrailer->GetEventCounter()));
331         //change decode status
332         decodeStatus = decodeStatus & ~TRM_BIT;
333         break; 
334         
335       default:
336         if (fVerbose)
337           AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID/pattern in global trailer",decodeStatus,*rawData));
338         return kTRUE;
339         break;
340       }
341       break;
342       
343     case CHAIN_A_HEADER:
344       //check decode status
345       if ( (decodeStatus != CHAIN_A_HEADER_STATUS) ){
346         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A header",decodeStatus,*rawData));
347         return kTRUE;
348       }
349       //decode status ok
350       fTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
351       currentChain = 0;
352       currentBunchID = fTRMChainHeader->GetBunchID();
353       if (fVerbose)
354         AliInfo(Form("  %02x - 0x%08x \t  TRM chain A header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
355       //change decode status
356       decodeStatus = decodeStatus | CHAIN_A_BIT;
357       break;
358       
359     case CHAIN_A_TRAILER:
360       //check decode status
361       if ( decodeStatus != CHAIN_A_TRAILER_STATUS ){
362         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A trailer",decodeStatus,*rawData));
363         return kTRUE;
364       }
365       //decode status ok
366       if (fVerbose)
367         AliInfo(Form("  %02x - 0x%08x \t  TRM chain A trailer",decodeStatus,*rawData));
368       //change decode status
369       decodeStatus = decodeStatus & ~CHAIN_A_BIT;
370       break;
371       
372     case CHAIN_B_HEADER:
373       //check decode status
374       if ( decodeStatus != CHAIN_B_HEADER_STATUS ){
375         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B header",decodeStatus,*rawData));
376         return kTRUE;
377       }
378       //decode status ok
379       fTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
380       currentChain = 1;
381       currentBunchID = fTRMChainHeader->GetBunchID();
382       if (fVerbose)
383         AliInfo(Form("  %02x - 0x%08x \t  TRM chain B header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
384       //change decode status
385       decodeStatus = decodeStatus | CHAIN_B_BIT;
386       break;
387       
388     case CHAIN_B_TRAILER:
389       //check decode status
390       if ( decodeStatus != CHAIN_B_TRAILER_STATUS ){
391         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B trailer",decodeStatus,*rawData));
392         return kTRUE;
393       }
394       //decode status ok
395       if (fVerbose)
396         AliInfo(Form("  %02x - 0x%08x \t  TRM chain B trailer",decodeStatus,*rawData));
397       //change decode status
398       decodeStatus = decodeStatus & ~CHAIN_B_BIT;
399       break;
400       
401     case ERROR:
402       if (fVerbose)
403         AliInfo(Form("  %02x - 0x%08x \t  TDC error",decodeStatus,*rawData));
404       break;
405       
406     case FILLER:
407       if (fVerbose)
408         AliInfo(Form("  %02x - 0x%08x \t  Filler",decodeStatus,*rawData));
409       break;
410       
411     default:
412       //check decode status
413       if ( decodeStatus != CHAIN_A_TDC_HIT_STATUS &&
414            decodeStatus != CHAIN_B_TDC_HIT_STATUS ){
415         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected or unknown word",decodeStatus,*rawData));
416         return kTRUE;
417       }
418       //decode status ok
419       
420       //switch TRM ACQ
421       switch (currentACQ){
422         
423       case PACKING_ENABLED_ACQ:
424         //decode TDC packed hit
425         fTDCPackedHit = (AliTOFTDCPackedHit *)rawData;
426         fTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
427         //set hit in the equipment data
428         hitData.SetDDLID(currentDDL);
429         hitData.SetSlotID(currentSlotID);
430         hitData.SetACQ(currentACQ);
431         hitData.SetChain(currentChain);
432         hitData.SetPS(fTDCPackedHit->GetPSBits());
433         hitData.SetTDC(fTDCPackedHit->GetTDCID());
434         hitData.SetChan(fTDCPackedHit->GetChan());
435         hitData.SetTime((float)fTDCPackedHit->GetHitTime() * TIME_BIN_WIDTH);
436         hitData.SetTimeBin(fTDCPackedHit->GetHitTime());
437         hitData.SetTOT((float)fTDCPackedHit->GetTOTWidth() * TOT_BIN_WIDTH);
438         hitData.SetTOTBin(fTDCPackedHit->GetTOTWidth());
439         //orphane leading hit
440         if (hitData.GetPS()==LEADING_HIT_PS){
441           hitData.SetTime((float)fTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
442           hitData.SetTimeBin(fTDCUnpackedHit->GetHitTime());
443           //set TOT to zero
444           hitData.SetTOT(0);
445           hitData.SetTOTBin(0);
446           //push hit data in packed data buffer
447           if (fPackedDataBuffer != 0x0)
448             fPackedDataBuffer->Add(hitData);
449           //set TOT to not measured
450           hitData.SetTOT(-1);
451           hitData.SetTOTBin(-1);
452           //push hit data in packed data buffer
453           if (fDataBuffer != 0x0)
454             fDataBuffer->Add(hitData);
455         }
456         //orphane trailing hit
457         else if (hitData.GetPS()==TRAILING_HIT_PS){
458           hitData.SetTime((float)fTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
459           hitData.SetTimeBin(fTDCUnpackedHit->GetHitTime());
460           //set TOT to not measured
461           hitData.SetTOT(-1);
462           hitData.SetTOTBin(-1);
463           //push hit data in data buffer
464           if (fDataBuffer != 0x0)
465             fDataBuffer->Add(hitData);
466         }
467         //packed hit and OVF
468         else{
469           //push hit data in packed data buffer
470           if (fPackedDataBuffer != 0x0)
471             fPackedDataBuffer->Add(hitData);
472           //save PS temporary
473           tempPS = hitData.GetPS();
474           //save TOT temporary
475           tempTOT = hitData.GetTOT();
476           tempTOTBin = hitData.GetTOTBin();
477           //unpack the hit: leading hit
478           hitData.SetPS(LEADING_HIT_PS);
479           //set TOT to not measured
480           hitData.SetTOT(-1);
481           hitData.SetTOTBin(-1);
482           //push leading hit data in data buffer
483           if (fDataBuffer != 0x0)
484             fDataBuffer->Add(hitData);
485           //unpack the hit: trailing hit
486           hitData.SetPS(TRAILING_HIT_PS);
487           hitData.SetTime(hitData.GetTime() + tempTOT);
488           hitData.SetTimeBin(hitData.GetTimeBin() + (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
489           //push trailing hit data in data buffer
490           if (fDataBuffer != 0x0)
491             fDataBuffer->Add(hitData);
492           //restore packed hit
493           hitData.SetPS(tempPS);
494           hitData.SetTime(hitData.GetTime() - tempTOT);
495           hitData.SetTimeBin(hitData.GetTimeBin() - (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
496           hitData.SetTOT(tempTOT);
497           hitData.SetTOTBin(tempTOTBin);
498         }
499         
500         if (fVerbose)
501           switch (hitData.GetPS()){
502           case PACKED_HIT_PS:
503             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()));
504             break;
505           case LEADING_HIT_PS:
506             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()));
507             break;
508           case TRAILING_HIT_PS:
509             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()));
510             break;
511           case TOT_OVF_HIT_PS:
512             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()));
513             break;
514           }
515         break;
516         
517       case LEADING_ONLY_ACQ: case TRAILING_ONLY_ACQ:
518         //decode TDC unpacked hit
519         fTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
520         //set hit in the equipment data
521         hitData.SetDDLID(currentDDL);
522         hitData.SetSlotID(currentSlotID);
523         hitData.SetACQ(currentACQ);
524         hitData.SetChain(currentChain);
525         hitData.SetPS(fTDCUnpackedHit->GetPSBits());
526         hitData.SetTDC(fTDCUnpackedHit->GetTDCID());
527         hitData.SetChan(fTDCUnpackedHit->GetChan());
528         hitData.SetTime((float)fTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
529         hitData.SetTimeBin(fTDCUnpackedHit->GetHitTime());
530         hitData.SetTOT(-1.);
531         hitData.SetTOTBin(-1);
532         //push hit data in data buffer
533           if (fDataBuffer != 0x0)
534             fDataBuffer->Add(hitData);
535         
536         if (fVerbose)
537           switch (hitData.GetPS()){
538           case PACKED_HIT_PS:
539             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()));
540             break;
541           case LEADING_HIT_PS:
542             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()));
543             break;
544           case TRAILING_HIT_PS:
545             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()));
546             break;
547           case TOT_OVF_HIT_PS:
548             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()));
549             break;
550           }
551         break;
552         
553       case PACKING_DISABLED_ACQ:
554         //decode TDC unpacked hit
555         fTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
556         //set hit in the equipment data
557         hitData.SetDDLID(currentDDL);
558         hitData.SetSlotID(currentSlotID);
559         hitData.SetACQ(currentACQ);
560         hitData.SetChain(currentChain);
561         hitData.SetPS(fTDCUnpackedHit->GetPSBits());
562         hitData.SetTDC(fTDCUnpackedHit->GetTDCID());
563         hitData.SetChan(fTDCUnpackedHit->GetChan());
564         hitData.SetTime((float)fTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
565         hitData.SetTimeBin(fTDCUnpackedHit->GetHitTime());
566         hitData.SetTOT(-1.);
567         hitData.SetTOTBin(-1);
568         //push hit data in data buffer
569           if (fDataBuffer != 0x0)
570             fDataBuffer->Add(hitData);
571         
572         if (fVerbose)
573           switch (hitData.GetPS()){
574           case PACKED_HIT_PS:
575             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()));
576             break;
577           case LEADING_HIT_PS:
578             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()));
579             break;
580           case TRAILING_HIT_PS:
581             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()));
582             break;
583           case TOT_OVF_HIT_PS:
584             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()));
585             break;
586           }
587         //call spider function
588         if (fVerbose==2)
589           AliInfo("Calling SPIDER function");
590         Spider(hitData);
591         break;
592       }
593       //end switch TRM ACQ
594       
595       
596     }
597     //end switch word type
598     
599   }
600   //end equipment data loop
601   
602   if (fVerbose)
603     AliInfo("End of data loop");
604   
605   if (fVerbose==2)
606     AliInfo("Reset SPIDER function");
607   status = ResetSpider();
608   
609   if (fVerbose)
610     AliInfo("Decoder is exiting succesfully.");
611
612   return kFALSE;  
613 }
614
615 //_________________________________________________________________
616
617 Bool_t 
618 AliTOFDecoder::InitializeSpider(){
619
620   /* SPIDER initialization routine.
621      it initializes SPIDER variables in order
622      to have SPIDER ready to pack tof data 
623      in packed data objects
624   */
625   
626   if (fVerbose==2)
627     AliInfo("Initializing SPIDER");
628   
629   fSpiderCurrentSlotID=-1;
630   fSpiderCurrentChain=-1;
631   fSpiderCurrentTDC=-1;
632   
633   for (Int_t chan=0;chan<N_CHANNEL;chan++)
634     fSpiderLeadingFlag[chan] = kFALSE;
635   
636   return kFALSE;
637 }
638
639 //_________________________________________________________________
640
641 Bool_t 
642 AliTOFDecoder::ResetSpider(){
643
644   /* SPIDER reset routine.
645      it resets SPIDER buffers and 
646      variables in order to empty full 
647      buffers a set up SIPDER for new
648      HPTDC data
649   */
650
651   if (fVerbose==2)
652     AliInfo("Resetting SPIDER buffers");
653
654   for (Int_t chan=0;chan<N_CHANNEL;chan++){
655     if (fSpiderLeadingFlag[chan]){
656       if (fVerbose==2)
657         AliInfo("Buffer non empty: put leading hit into buffer as orphane");
658       //set TOT to zero
659       fSpiderLeadingHit[chan].SetACQ(4);
660       fSpiderLeadingHit[chan].SetPS(1);
661       fSpiderLeadingHit[chan].SetTOT(0);
662       fSpiderLeadingHit[chan].SetTOTBin(0);
663       //push hit into packed buffer
664       if (fPackedDataBuffer != 0x0)
665         fPackedDataBuffer->Add(fSpiderLeadingHit[chan]);
666       if (fVerbose==2)
667         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()));
668       
669     }
670     fSpiderLeadingFlag[chan]=kFALSE;
671   }
672   
673   return kFALSE;
674 }
675
676 //_________________________________________________________________
677
678 Bool_t 
679 AliTOFDecoder::Spider(AliTOFHitData hitData){
680
681   /* main SPIDER routine.
682      it receives, reads, stores and packs
683      unpacked HPTDC data in packed data
684      object. it also fills buffers.
685   */
686  
687   Int_t status;
688
689   if (fVerbose==2)
690     AliInfo("Hit data received");
691
692   //check if TDC is changed (slotID,chain,TDC triplet)
693   if (fSpiderCurrentSlotID!=hitData.GetSlotID() ||
694       fSpiderCurrentChain!=hitData.GetChain() ||
695       fSpiderCurrentTDC!=hitData.GetTDC() ){
696     if (fVerbose==2)
697       AliInfo("Data coming from a new TDC: reset buffers");
698     //reset spider
699     status = ResetSpider();
700     //set current TDC 
701     fSpiderCurrentSlotID=hitData.GetSlotID();
702     fSpiderCurrentChain=hitData.GetChain();
703     fSpiderCurrentTDC=hitData.GetTDC();
704   }
705   
706   //switch PS bits
707   switch (hitData.GetPS()){
708
709   case LEADING_HIT_PS:
710     if (fVerbose==2)
711       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()));
712     //check spider leading flag
713     if (fSpiderLeadingFlag[hitData.GetChan()]){
714       if (fVerbose==2)
715         AliInfo("Leading hit: buffer full, put previous in buffers as orphane and keep current");
716       //set TOT at zero for previous hit
717       fSpiderLeadingHit[hitData.GetChan()].SetACQ(4);
718       fSpiderLeadingHit[hitData.GetChan()].SetPS(1);
719       fSpiderLeadingHit[hitData.GetChan()].SetTOT(0);
720       fSpiderLeadingHit[hitData.GetChan()].SetTOTBin(0);
721       //push previous hit into packed buffer
722       if (fPackedDataBuffer != 0x0)
723         fPackedDataBuffer->Add(fSpiderLeadingHit[hitData.GetChan()]);
724       //set current hit
725       fSpiderLeadingHit[hitData.GetChan()]=hitData;
726       if (fVerbose==2)
727         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()));
728     }
729     else{
730       if (fVerbose==2)
731         AliInfo("Leading hit: buffer empty, keep current hit and set flag");
732       fSpiderLeadingHit[hitData.GetChan()]=hitData;
733       //set spider leading flag
734       fSpiderLeadingFlag[hitData.GetChan()]=kTRUE;
735     }
736     break;
737
738   case TRAILING_HIT_PS:
739     if (fVerbose==2)
740       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()));
741     //check spider leading flag
742     if (fSpiderLeadingFlag[hitData.GetChan()]){
743       if (fVerbose==2)
744         AliInfo("Trailing hit: buffer full, pack leading and trailing");
745       hitData.SetACQ(4);
746       hitData.SetPS(0);
747       hitData.SetTOT(hitData.GetTime()-fSpiderLeadingHit[hitData.GetChan()].GetTime());
748       hitData.SetTOTBin((Int_t)((hitData.GetTimeBin()-fSpiderLeadingHit[hitData.GetChan()].GetTimeBin())*TIME_TO_TOT_BIN_WIDTH));
749       hitData.SetTime(fSpiderLeadingHit[hitData.GetChan()].GetTime());
750       hitData.SetTimeBin(fSpiderLeadingHit[hitData.GetChan()].GetTimeBin());
751       //check TOT and set TOT overflow if TOT < 0
752       if (hitData.GetTOT() < 0){
753         hitData.SetPS(3);
754         hitData.SetTOT(0);
755         hitData.SetTOTBin(0);
756       }
757       if (fPackedDataBuffer != 0x0)
758         fPackedDataBuffer->Add(hitData);      
759       if (fVerbose==2)
760         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()));
761       //unset spider leading flag
762       fSpiderLeadingFlag[hitData.GetChan()]=kFALSE;
763     }
764     else{
765       if (fVerbose==2)
766         AliInfo("Trailing hit: buffer empty, throw hit away");
767     }
768     break;
769   }
770   //end switch PS bits
771
772   return kFALSE;
773 }