LTM data payload change from 33 to 48 words propagated into decoder + coding conventions
[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 Revision 1.5  2007/11/24 14:58:34  zampolli
19 New Method implemented (#DDL <-> TOF channels)
20
21 Revision 1.4  2007/05/18 13:08:57  decaro
22 Coding convention: RS1 violation -> suppression
23
24 Revision 1.3  2007/05/08 11:56:05  arcelli
25 improved verbosity in verbose mode (R.Preghenella)
26
27 Revision 1.2  2007/05/03 11:34:43  decaro
28 Coding convention: RS1 violation -> suppression
29
30 Revision 1.1  2007/04/27 11:00:32  arcelli
31 TOF Raw Data decoder
32
33   author: Roberto Preghenella (R+), preghenella@bo.infn.it
34 */
35
36
37 //////////////////////////////////////////////////////////////////////
38 //                                                                  //
39 //                                                                  //
40 //   Class for raw data decoding                                    //
41 //                                                                  //
42 //                                                                  //
43 //////////////////////////////////////////////////////////////////////
44                                
45
46
47 #include "AliLog.h"
48 #include "AliTOFHitData.h"
49 #include "AliTOFHitDataBuffer.h"
50 #include "AliTOFDecoder.h"
51 #include "AliTOFGeometry.h"
52 #include "AliRawDataHeader.h"
53 #include "AliTOFRawDataFormat.h"
54
55 ClassImp(AliTOFDecoder)
56
57 //_________________________________________________________________
58
59 AliTOFDecoder::AliTOFDecoder() :
60   TObject(),
61   fVerbose(0),
62   fV2718Patch(kFALSE),
63   fDataBuffer(0x0),
64   fPackedDataBuffer(0x0),
65   //fTRMGlobalHeader(0x0),
66   //fTRMGlobalTrailer(0x0),
67   //fTRMChainHeader(0x0),
68   //fTRMChainTrailer(0x0),
69   //fTDCPackedHit(0x0),
70   //fTDCUnpackedHit(0x0),
71   //fTRMTDCError(0x0),
72   //fTRMDiagnosticErrorWord1(0x0),
73   //fTRMDiagnosticErrorWord2(0x0),
74   fSpiderCurrentSlotID(-1),
75   fSpiderCurrentChain(-1),
76   fSpiderCurrentTDC(-1)
77 {
78   //default constructor
79 }
80
81 //_________________________________________________________________
82
83 AliTOFDecoder::AliTOFDecoder(AliTOFHitDataBuffer *DataBuffer, AliTOFHitDataBuffer *PackedDataBuffer) :
84   TObject(),
85   fVerbose(0),
86   fV2718Patch(kFALSE),
87   fDataBuffer(DataBuffer),
88   fPackedDataBuffer(PackedDataBuffer),
89   //fTRMGlobalHeader(0x0),
90   //fTRMGlobalTrailer(0x0),
91   //fTRMChainHeader(0x0),
92   //fTRMChainTrailer(0x0),
93   //fTDCPackedHit(0x0),
94   //fTDCUnpackedHit(0x0),
95   //fTRMTDCError(0x0),
96   //fTRMDiagnosticErrorWord1(0x0),
97   //fTRMDiagnosticErrorWord2(0x0),
98   fSpiderCurrentSlotID(-1),
99   fSpiderCurrentChain(-1),
100   fSpiderCurrentTDC(-1)
101 {
102   //another constructor
103 }
104
105 //_________________________________________________________________
106
107 AliTOFDecoder::AliTOFDecoder(const AliTOFDecoder &source) : 
108   TObject(source),
109   fVerbose(source.fVerbose),
110   fV2718Patch(source.fV2718Patch),
111   fDataBuffer(source.fDataBuffer),
112   fPackedDataBuffer(source.fPackedDataBuffer),
113   //fTRMGlobalHeader(source.fTRMGlobalHeader),
114   //fTRMGlobalTrailer(source.fTRMGlobalTrailer),
115   //fTRMChainHeader(source.fTRMChainHeader),
116   //fTRMChainTrailer(source.fTRMChainTrailer),
117   //fTDCPackedHit(source.fTDCPackedHit),
118   //fTDCUnpackedHit(source.fTDCUnpackedHit),
119   //fTRMTDCError(source.fTRMTDCError),
120   //fTRMDiagnosticErrorWord1(source.fTRMDiagnosticErrorWord1),
121   //fTRMDiagnosticErrorWord2(source.fTRMDiagnosticErrorWord2),
122   fSpiderCurrentSlotID(source.fSpiderCurrentSlotID),
123   fSpiderCurrentChain(source.fSpiderCurrentChain),
124   fSpiderCurrentTDC(source.fSpiderCurrentTDC)
125 {
126   //copy constructor
127   
128 }
129
130 //_________________________________________________________________
131
132 AliTOFDecoder &
133 AliTOFDecoder::operator = (const AliTOFDecoder &source)
134 {
135   //operator =
136
137   if (this == &source)
138     return *this;
139
140   TObject::operator=(source);
141   fVerbose = source.fVerbose;
142   fV2718Patch = source.fV2718Patch;
143   fDataBuffer = source.fDataBuffer;
144   fPackedDataBuffer = source.fPackedDataBuffer;
145   //fTRMGlobalHeader = source.fTRMGlobalHeader;
146   //fTRMGlobalTrailer = source.fTRMGlobalTrailer;
147   //fTRMChainHeader = source.fTRMChainHeader;
148   //fTRMChainTrailer = source.fTRMChainTrailer;
149   //fTDCPackedHit = source.fTDCPackedHit;
150   //fTDCUnpackedHit = source.fTDCUnpackedHit;
151   //fTRMTDCError = source.fTRMTDCError;
152   //fTRMDiagnosticErrorWord1 = source.fTRMDiagnosticErrorWord1;
153   //fTRMDiagnosticErrorWord2 = source.fTRMDiagnosticErrorWord2;
154   fSpiderCurrentSlotID = source.fSpiderCurrentSlotID;
155   fSpiderCurrentChain = source.fSpiderCurrentChain;
156   fSpiderCurrentTDC = source.fSpiderCurrentTDC;
157   return *this;
158 }
159
160 AliTOFDecoder::~AliTOFDecoder()
161 {}
162
163 //_________________________________________________________________
164
165 Bool_t
166 AliTOFDecoder::Decode(const UInt_t *rawData, Int_t nWords, const AliRawDataHeader *cdh)
167 {
168   /* main decoding routine.
169    * it loops over nWords 32-bit words 
170    * starting at *rawData and decodes them.
171    * it also fills some buffers in order to
172    * have the decoded data available for other
173    * classes.
174    */
175
176   AliTOFTRMGlobalHeader          *lTRMGlobalHeader; //TRM global header
177   AliTOFTRMGlobalTrailer         *lTRMGlobalTrailer; //TRM global trailer
178   AliTOFTRMChainHeader           *lTRMChainHeader; //TRM chain header
179   //AliTOFTRMChainTrailer          *lTRMChainTrailer; //TRM chain trailer
180   AliTOFTDCPackedHit             *lTDCPackedHit; //TDC packed hit
181   AliTOFTDCUnpackedHit           *lTDCUnpackedHit; //TDC unpacked hit
182   //AliTOFTRMTDCError              *lTRMTDCError; //TRM TDC error
183   //AliTOFTRMDiagnosticErrorWord1  *lTRMDiagnosticErrorWord1; //TRM diagnostic error word 1
184   //AliTOFTRMDiagnosticErrorWord2  *lTRMDiagnosticErrorWord2; //TRM diagnostica error word 2
185
186
187   AliTOFHitData hitData;
188   
189   //useful variables
190   Int_t   status;
191   Short_t tempPS;
192   Float_t tempTOT; //ns
193   Int_t   tempTOTBin; //TOT_BIN_WIDTH
194
195   //decoder variables
196   UShort_t decodeStatus = 0x0;
197   Short_t  currentDDL = -1;
198   Short_t  currentSlotID = -1;
199   Short_t  currentACQ = -1;
200   Short_t  currentChain = -1;
201   Short_t  currentBunchID = -1;
202   Short_t  currentMiniEventID = cdh ? cdh->GetMiniEventID() : (Short_t)-1;
203   Short_t  currentEventID1 = cdh ? cdh->GetEventID1() : (Short_t)-1;
204   AliDebug(1, Form("EvID1 = %d, EvID2 = %d, currentMiniEventID = %d", currentEventID1, cdh->GetEventID2(), currentMiniEventID));
205   if (!cdh)
206     AliWarning("CDH not valid: deltaBunchID not reliable ");
207
208   /*** V2718 patch ***/
209   if (fV2718Patch){
210     decodeStatus = decodeStatus | DRM_BIT;
211     if (fVerbose)
212       AliInfo("DRM not present: - V2718 patch decoding -");
213   }
214   /*** V2718 patch ***/
215
216   if (fVerbose==2)
217     AliInfo("Initialize SPIDER function");
218   status = InitializeSpider();
219   
220   if (fVerbose)
221     AliInfo("Start decoding");
222   
223   if (fVerbose)
224     AliInfo("Loop over the data and decode");
225   
226   if (fVerbose)
227     AliInfo("  St    Hex Word \t   Decoded Word");
228   
229   //loop over raw data
230   for (Int_t iWord = 0; iWord < nWords; iWord++, rawData++){
231     
232     //switch word type
233     switch (*rawData & WORD_TYPE_MASK){
234       
235     case GLOBAL_HEADER:
236       
237       //switch slot ID
238       switch (*rawData & SLOT_ID_MASK){
239         
240         //DRM global header (slotID=1)
241       case 1:
242         //check decode status
243         if ( decodeStatus != DRM_HEADER_STATUS ){
244           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global header",decodeStatus,*rawData));
245           return kTRUE;
246         }
247         //decode status ok
248         if (fVerbose)
249           AliInfo(Form("  %02x - 0x%08x \t  DRM global header",decodeStatus,*rawData));
250         //change decode status
251         decodeStatus = decodeStatus | DRM_BIT;
252         
253         //skip DRM data
254         for (Int_t i = 0; i < DRM_DATA_WORDS; i++, iWord++, rawData++){
255           if (fVerbose)
256             AliInfo(Form("  %02x - 0x%08x \t  DRM data",decodeStatus,*rawData));
257         }
258         break;
259         
260         //LTM global header (slotID=2)
261       case 2:
262         //check decode status
263         if ( decodeStatus != LTM_HEADER_STATUS ){
264           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global header",decodeStatus,*rawData));
265           return kTRUE;
266         }
267         //decode status ok
268         if (fVerbose)
269           AliInfo(Form("  %02x - 0x%08x \t  LTM global header",decodeStatus,*rawData));
270         //change decode status
271         decodeStatus = decodeStatus | LTM_BIT;
272         
273         //skip LTM data
274         for (Int_t i = 0; i < LTM_DATA_WORDS; i++, iWord++, rawData++){
275           if (fVerbose)
276             AliInfo(Form("  %02x - 0x%08x \t  LTM data",decodeStatus,*rawData));
277         }
278         break;
279         
280         //TRM global header (slotID=3-12)
281       case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
282         //check decode status
283         if ( decodeStatus != TRM_HEADER_STATUS ){
284           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global header",decodeStatus,*rawData));
285           return kTRUE;
286         }
287         //decode status ok
288         //set TRM global header
289         lTRMGlobalHeader = (AliTOFTRMGlobalHeader*)rawData;     
290         //set current TRM
291         currentSlotID = lTRMGlobalHeader->GetSlotID();
292         currentACQ = lTRMGlobalHeader->GetACQBits();
293         if (fVerbose)
294           AliInfo(Form("  %02x - 0x%08x \t  TRM global header \t slotID=%02d ACQ=%01d L=%01d",decodeStatus,*rawData,lTRMGlobalHeader->GetSlotID(),lTRMGlobalHeader->GetACQBits(),lTRMGlobalHeader->GetLBit()));
295         //change decode status
296         decodeStatus = decodeStatus | TRM_BIT;
297         break;
298         
299       default:
300         AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID in global header",decodeStatus,*rawData));
301         return kTRUE;
302         break;
303         
304       }
305       //end switch slotID
306       break;
307       
308     case GLOBAL_TRAILER:
309       
310       //switch slot ID
311       switch (*rawData & SLOT_ID_MASK){
312         
313         //DRM global trailer (slotID=1)
314       case 1:
315         //check decode status
316         if ( decodeStatus != DRM_TRAILER_STATUS ){
317           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected DRM global trailer",decodeStatus,*rawData));
318           return kTRUE;
319         }
320         //decode status ok
321         if (fVerbose)
322           AliInfo(Form("  %02x - 0x%08x \t  DRM global trailer",decodeStatus,*rawData));
323         //change decode status
324         decodeStatus = decodeStatus & ~DRM_BIT;
325         break;
326         
327         //LTM global trailer (slotID=2)
328       case 2:
329         //check decode status
330         if ( decodeStatus != LTM_TRAILER_STATUS ){
331           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected LTM global trailer",decodeStatus,*rawData));
332           return kTRUE;
333         }
334         //decode status ok
335         if (fVerbose)
336           AliInfo(Form("  %02x - 0x%08x \t  LTM global trailer",decodeStatus,*rawData));
337         //change decode status
338         decodeStatus = decodeStatus & ~LTM_BIT;
339         break;
340         
341         //TRM global trailer (slotID=15)
342       case 15:
343         //check decode status
344         if ( decodeStatus != TRM_TRAILER_STATUS ){
345           AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM global trailer",decodeStatus,*rawData));
346           return kTRUE;
347         }
348         //decode status ok
349         //set TRM global trailer
350         lTRMGlobalTrailer = (AliTOFTRMGlobalTrailer *)rawData;  
351         if (fVerbose)
352           AliInfo(Form("  %02x - 0x%08x \t  TRM global trailer \t CRC=%04d eventCounter=%04d",decodeStatus,*rawData,lTRMGlobalTrailer->GetEventCRC(),lTRMGlobalTrailer->GetEventCounter()));
353         //change decode status
354         decodeStatus = decodeStatus & ~TRM_BIT;
355         break; 
356         
357       default:
358         AliError(Form("  %02x - 0x%08x [ERROR] Not valid slotID/pattern in global trailer",decodeStatus,*rawData));
359         return kTRUE;
360         break;
361       }
362       break;
363       
364     case CHAIN_A_HEADER:
365       //check decode status
366       if ( (decodeStatus != CHAIN_A_HEADER_STATUS) ){
367         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A header",decodeStatus,*rawData));
368         return kTRUE;
369       }
370       //decode status ok
371       lTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
372       currentChain = 0;
373       currentBunchID = lTRMChainHeader->GetBunchID();
374       if (fVerbose)
375         AliInfo(Form("  %02x - 0x%08x \t  TRM chain A header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
376       //change decode status
377       decodeStatus = decodeStatus | CHAIN_A_BIT;
378       break;
379       
380     case CHAIN_A_TRAILER:
381       //check decode status
382       if ( decodeStatus != CHAIN_A_TRAILER_STATUS ){
383         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain A trailer",decodeStatus,*rawData));
384         return kTRUE;
385       }
386       //decode status ok
387       if (fVerbose)
388         AliInfo(Form("  %02x - 0x%08x \t  TRM chain A trailer",decodeStatus,*rawData));
389       //change decode status
390       decodeStatus = decodeStatus & ~CHAIN_A_BIT;
391       break;
392       
393     case CHAIN_B_HEADER:
394       //check decode status
395       if ( decodeStatus != CHAIN_B_HEADER_STATUS ){
396         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B header",decodeStatus,*rawData));
397         return kTRUE;
398       }
399       //decode status ok
400       lTRMChainHeader = (AliTOFTRMChainHeader *)rawData;
401       currentChain = 1;
402       currentBunchID = lTRMChainHeader->GetBunchID();
403       if (fVerbose)
404         AliInfo(Form("  %02x - 0x%08x \t  TRM chain B header \t chain=%01d bunchID=%04d",decodeStatus,*rawData,currentChain,currentBunchID));
405       //change decode status
406       decodeStatus = decodeStatus | CHAIN_B_BIT;
407       break;
408       
409     case CHAIN_B_TRAILER:
410       //check decode status
411       if ( decodeStatus != CHAIN_B_TRAILER_STATUS ){
412         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected TRM chain B trailer",decodeStatus,*rawData));
413         return kTRUE;
414       }
415       //decode status ok
416       if (fVerbose)
417         AliInfo(Form("  %02x - 0x%08x \t  TRM chain B trailer",decodeStatus,*rawData));
418       //change decode status
419       decodeStatus = decodeStatus & ~CHAIN_B_BIT;
420       break;
421       
422     case ERROR:
423       if (fVerbose)
424         AliInfo(Form("  %02x - 0x%08x \t  TDC error",decodeStatus,*rawData));
425       break;
426       
427     case FILLER:
428       if (fVerbose)
429         AliInfo(Form("  %02x - 0x%08x \t  Filler",decodeStatus,*rawData));
430       break;
431       
432     default:
433       //check decode status
434       if ( decodeStatus != CHAIN_A_TDC_HIT_STATUS &&
435            decodeStatus != CHAIN_B_TDC_HIT_STATUS ){
436         AliError(Form("  %02x - 0x%08x [ERROR] Unexpected or unknown word",decodeStatus,*rawData));
437         return kTRUE;
438       }
439       //decode status ok
440       
441       //switch TRM ACQ
442       switch (currentACQ){
443         
444       case PACKING_ENABLED_ACQ:
445         //decode TDC packed hit
446         lTDCPackedHit = (AliTOFTDCPackedHit *)rawData;
447         lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
448         //set hit in the equipment data
449         hitData.SetDDLID(currentDDL);
450         hitData.SetSlotID(currentSlotID);
451         hitData.SetACQ(currentACQ);
452         hitData.SetChain(currentChain);
453         hitData.SetPS(lTDCPackedHit->GetPSBits());
454         hitData.SetTDC(lTDCPackedHit->GetTDCID());
455         hitData.SetChan(lTDCPackedHit->GetChan());
456         hitData.SetTime((float)lTDCPackedHit->GetHitTime() * TIME_BIN_WIDTH);
457         hitData.SetTimeBin(lTDCPackedHit->GetHitTime());
458         hitData.SetTOT((float)lTDCPackedHit->GetTOTWidth() * TOT_BIN_WIDTH);
459         hitData.SetTOTBin(lTDCPackedHit->GetTOTWidth());
460         hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
461         //orphane leading hit
462         if (hitData.GetPS()==LEADING_HIT_PS){
463           hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
464           hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
465           //set TOT to zero
466           hitData.SetTOT(0);
467           hitData.SetTOTBin(0);
468           //push hit data in packed data buffer
469           if (fPackedDataBuffer != 0x0)
470             fPackedDataBuffer->Add(hitData);
471           //set TOT to not measured
472           hitData.SetTOT(-1);
473           hitData.SetTOTBin(-1);
474           //push hit data in packed data buffer
475           if (fDataBuffer != 0x0)
476             fDataBuffer->Add(hitData);
477         }
478         //orphane trailing hit
479         else if (hitData.GetPS()==TRAILING_HIT_PS){
480           hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
481           hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
482           //set TOT to not measured
483           hitData.SetTOT(-1);
484           hitData.SetTOTBin(-1);
485           //push hit data in data buffer
486           if (fDataBuffer != 0x0)
487             fDataBuffer->Add(hitData);
488         }
489         //packed hit and OVF
490         else{
491           //push hit data in packed data buffer
492           if (fPackedDataBuffer != 0x0)
493             fPackedDataBuffer->Add(hitData);
494           //save PS temporary
495           tempPS = hitData.GetPS();
496           //save TOT temporary
497           tempTOT = hitData.GetTOT();
498           tempTOTBin = hitData.GetTOTBin();
499           //unpack the hit: leading hit
500           hitData.SetPS(LEADING_HIT_PS);
501           //set TOT to not measured
502           hitData.SetTOT(-1);
503           hitData.SetTOTBin(-1);
504           //push leading hit data in data buffer
505           if (fDataBuffer != 0x0)
506             fDataBuffer->Add(hitData);
507           //unpack the hit: trailing hit
508           hitData.SetPS(TRAILING_HIT_PS);
509           hitData.SetTime(hitData.GetTime() + tempTOT);
510           hitData.SetTimeBin(hitData.GetTimeBin() + (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
511           //push trailing hit data in data buffer
512           if (fDataBuffer != 0x0)
513             fDataBuffer->Add(hitData);
514           //restore packed hit
515           hitData.SetPS(tempPS);
516           hitData.SetTime(hitData.GetTime() - tempTOT);
517           hitData.SetTimeBin(hitData.GetTimeBin() - (Int_t)(tempTOTBin * TOT_TO_TIME_BIN_WIDTH));
518           hitData.SetTOT(tempTOT);
519           hitData.SetTOTBin(tempTOTBin);
520         }
521         
522         if (fVerbose)
523           switch (hitData.GetPS()){
524           case PACKED_HIT_PS:
525             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()));
526             break;
527           case LEADING_HIT_PS:
528             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()));
529             break;
530           case TRAILING_HIT_PS:
531             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()));
532             break;
533           case TOT_OVF_HIT_PS:
534             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()));
535             break;
536           }
537         break;
538         
539       case LEADING_ONLY_ACQ: case TRAILING_ONLY_ACQ:
540         //decode TDC unpacked hit
541         lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
542         //set hit in the equipment data
543         hitData.SetDDLID(currentDDL);
544         hitData.SetSlotID(currentSlotID);
545         hitData.SetACQ(currentACQ);
546         hitData.SetChain(currentChain);
547         hitData.SetPS(lTDCUnpackedHit->GetPSBits());
548         hitData.SetTDC(lTDCUnpackedHit->GetTDCID());
549         hitData.SetChan(lTDCUnpackedHit->GetChan());
550         hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
551         hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
552         hitData.SetTOT(-1.);
553         hitData.SetTOTBin(-1);
554         hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
555         //push hit data in data buffer
556           if (fDataBuffer != 0x0)
557             fDataBuffer->Add(hitData);
558         
559         if (fVerbose)
560           switch (hitData.GetPS()){
561           case PACKED_HIT_PS:
562             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()));
563             break;
564           case LEADING_HIT_PS:
565             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()));
566             break;
567           case TRAILING_HIT_PS:
568             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()));
569             break;
570           case TOT_OVF_HIT_PS:
571             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()));
572             break;
573           }
574         break;
575         
576       case PACKING_DISABLED_ACQ:
577         //decode TDC unpacked hit
578         lTDCUnpackedHit = (AliTOFTDCUnpackedHit *)rawData;
579         //set hit in the equipment data
580         hitData.SetDDLID(currentDDL);
581         hitData.SetSlotID(currentSlotID);
582         hitData.SetACQ(currentACQ);
583         hitData.SetChain(currentChain);
584         hitData.SetPS(lTDCUnpackedHit->GetPSBits());
585         hitData.SetTDC(lTDCUnpackedHit->GetTDCID());
586         hitData.SetChan(lTDCUnpackedHit->GetChan());
587         hitData.SetTime((float)lTDCUnpackedHit->GetHitTime() * TIME_BIN_WIDTH);
588         hitData.SetTimeBin(lTDCUnpackedHit->GetHitTime());
589         hitData.SetTOT(-1.);
590         hitData.SetTOTBin(-1);
591         hitData.SetDeltaBunchID(currentBunchID - currentEventID1);
592         //push hit data in data buffer
593           if (fDataBuffer != 0x0)
594             fDataBuffer->Add(hitData);
595         
596         if (fVerbose)
597           switch (hitData.GetPS()){
598           case PACKED_HIT_PS:
599             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()));
600             break;
601           case LEADING_HIT_PS:
602             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()));
603             break;
604           case TRAILING_HIT_PS:
605             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()));
606             break;
607           case TOT_OVF_HIT_PS:
608             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()));
609             break;
610           }
611         //call spider function
612         if (fVerbose==2)
613           AliInfo("Calling SPIDER function");
614         Spider(hitData);
615         break;
616       }
617       //end switch TRM ACQ
618       
619       
620     }
621     //end switch word type
622     
623   }
624   //end equipment data loop
625   
626   if (fVerbose)
627     AliInfo("End of data loop");
628   
629   if (fVerbose==2)
630     AliInfo("Reset SPIDER function");
631   status = ResetSpider();
632   
633   if (fVerbose)
634     AliInfo("Decoder is exiting succesfully.");
635
636   return kFALSE;  
637 }
638
639 //_________________________________________________________________
640
641 Bool_t 
642 AliTOFDecoder::InitializeSpider(){
643
644   /* SPIDER initialization routine.
645      it initializes SPIDER variables in order
646      to have SPIDER ready to pack tof data 
647      in packed data objects
648   */
649   
650   if (fVerbose==2)
651     AliInfo("Initializing SPIDER");
652   
653   fSpiderCurrentSlotID=-1;
654   fSpiderCurrentChain=-1;
655   fSpiderCurrentTDC=-1;
656   
657   for (Int_t chan=0;chan<N_CHANNEL;chan++)
658     fSpiderLeadingFlag[chan] = kFALSE;
659   
660   return kFALSE;
661 }
662
663 //_________________________________________________________________
664
665 Bool_t 
666 AliTOFDecoder::ResetSpider(){
667
668   /* SPIDER reset routine.
669      it resets SPIDER buffers and 
670      variables in order to empty full 
671      buffers a set up SIPDER for new
672      HPTDC data
673   */
674
675   if (fVerbose==2)
676     AliInfo("Resetting SPIDER buffers");
677
678   for (Int_t chan=0;chan<N_CHANNEL;chan++){
679     if (fSpiderLeadingFlag[chan]){
680       if (fVerbose==2)
681         AliInfo("Buffer non empty: put leading hit into buffer as orphane");
682       //set TOT to zero
683       fSpiderLeadingHit[chan].SetACQ(4);
684       fSpiderLeadingHit[chan].SetPS(1);
685       fSpiderLeadingHit[chan].SetTOT(0);
686       fSpiderLeadingHit[chan].SetTOTBin(0);
687       //push hit into packed buffer
688       if (fPackedDataBuffer != 0x0)
689         fPackedDataBuffer->Add(fSpiderLeadingHit[chan]);
690       if (fVerbose==2)
691         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()));
692       
693     }
694     fSpiderLeadingFlag[chan]=kFALSE;
695   }
696   
697   return kFALSE;
698 }
699
700 //_________________________________________________________________
701
702 Bool_t 
703 AliTOFDecoder::Spider(AliTOFHitData &hitData){
704
705   /* main SPIDER routine.
706      it receives, reads, stores and packs
707      unpacked HPTDC data in packed data
708      object. it also fills buffers.
709   */
710  
711   Int_t status;
712
713   if (fVerbose==2)
714     AliInfo("Hit data received");
715
716   //check if TDC is changed (slotID,chain,TDC triplet)
717   if (fSpiderCurrentSlotID!=hitData.GetSlotID() ||
718       fSpiderCurrentChain!=hitData.GetChain() ||
719       fSpiderCurrentTDC!=hitData.GetTDC() ){
720     if (fVerbose==2)
721       AliInfo("Data coming from a new TDC: reset buffers");
722     //reset spider
723     status = ResetSpider();
724     //set current TDC 
725     fSpiderCurrentSlotID=hitData.GetSlotID();
726     fSpiderCurrentChain=hitData.GetChain();
727     fSpiderCurrentTDC=hitData.GetTDC();
728   }
729   
730   //switch PS bits
731   switch (hitData.GetPS()){
732
733   case LEADING_HIT_PS:
734     if (fVerbose==2)
735       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()));
736     //check spider leading flag
737     if (fSpiderLeadingFlag[hitData.GetChan()]){
738       if (fVerbose==2)
739         AliInfo("Leading hit: buffer full, put previous in buffers as orphane and keep current");
740       //set TOT at zero for previous hit
741       fSpiderLeadingHit[hitData.GetChan()].SetACQ(4);
742       fSpiderLeadingHit[hitData.GetChan()].SetPS(1);
743       fSpiderLeadingHit[hitData.GetChan()].SetTOT(0);
744       fSpiderLeadingHit[hitData.GetChan()].SetTOTBin(0);
745       //push previous hit into packed buffer
746       if (fPackedDataBuffer != 0x0)
747         fPackedDataBuffer->Add(fSpiderLeadingHit[hitData.GetChan()]);
748       //set current hit
749       fSpiderLeadingHit[hitData.GetChan()]=hitData;
750       if (fVerbose==2)
751         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()));
752     }
753     else{
754       if (fVerbose==2)
755         AliInfo("Leading hit: buffer empty, keep current hit and set flag");
756       fSpiderLeadingHit[hitData.GetChan()]=hitData;
757       //set spider leading flag
758       fSpiderLeadingFlag[hitData.GetChan()]=kTRUE;
759     }
760     break;
761
762   case TRAILING_HIT_PS:
763     if (fVerbose==2)
764       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()));
765     //check spider leading flag
766     if (fSpiderLeadingFlag[hitData.GetChan()]){
767       if (fVerbose==2)
768         AliInfo("Trailing hit: buffer full, pack leading and trailing");
769       hitData.SetACQ(4);
770       hitData.SetPS(0);
771       hitData.SetTOT(hitData.GetTime()-fSpiderLeadingHit[hitData.GetChan()].GetTime());
772       hitData.SetTOTBin((Int_t)((hitData.GetTimeBin()-fSpiderLeadingHit[hitData.GetChan()].GetTimeBin())*TIME_TO_TOT_BIN_WIDTH));
773       hitData.SetTime(fSpiderLeadingHit[hitData.GetChan()].GetTime());
774       hitData.SetTimeBin(fSpiderLeadingHit[hitData.GetChan()].GetTimeBin());
775       //check TOT and set TOT overflow if TOT < 0
776       if (hitData.GetTOT() < 0){
777         hitData.SetPS(3);
778         hitData.SetTOT(0);
779         hitData.SetTOTBin(0);
780       }
781       if (fPackedDataBuffer != 0x0)
782         fPackedDataBuffer->Add(hitData);      
783       if (fVerbose==2)
784         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()));
785       //unset spider leading flag
786       fSpiderLeadingFlag[hitData.GetChan()]=kFALSE;
787     }
788     else{
789       if (fVerbose==2)
790         AliInfo("Trailing hit: buffer empty, throw hit away");
791     }
792     break;
793   }
794   //end switch PS bits
795
796   return kFALSE;
797 }
798 //_____________________________________________________________________________
799 void AliTOFDecoder::GetArrayDDL(Int_t* array, Int_t ddl){
800
801   // method that fills array with the
802   // TOF channels indexes corresponding
803   // to DDL iDDL
804
805   AliTOFGeometry *geom = new AliTOFGeometry();
806   Int_t indexDDL = ddl%4;
807   Int_t iSector = Int_t(ddl/4);
808   if (fVerbose)
809     AliInfo(Form(" Sector = %i, DDL within sector = %i",iSector, indexDDL));
810
811   Int_t volume[5];
812   volume[0]=iSector;
813   Int_t minPlate=0, maxPlate=0, minStrip2=0, maxStrip2=0, minPadz=0, maxPadz=0, minPadx=0, maxPadx=0;
814
815   if (indexDDL==0){
816     minPlate=kMinPlate0;
817     maxPlate=kMaxPlate0;
818     minStrip2=kMinStrip0;
819     maxStrip2=kMaxStrip0;
820     minPadz=kMinPadz0;
821     maxPadz=kMaxPadz0;
822     minPadx=kMinPadx0;
823     maxPadx=kMaxPadx0;
824   }
825
826   else if (indexDDL==1){
827     minPlate=kMinPlate1;
828     maxPlate=kMaxPlate1;
829     minStrip2=kMinStrip1;
830     maxStrip2=kMaxStrip1;
831     minPadz=kMinPadz1;
832     maxPadz=kMaxPadz1;
833     minPadx=kMinPadx1;
834     maxPadx=kMaxPadx1;
835   }
836
837   else if (indexDDL==2){
838     minPlate=kMinPlate2;
839     maxPlate=kMaxPlate2;
840     minStrip2=kMinStrip2;
841     maxStrip2=kMaxStrip2;
842     minPadz=kMinPadz2;
843     maxPadz=kMaxPadz2;
844     minPadx=kMinPadx2;
845     maxPadx=kMaxPadx2;
846   }
847
848   else if (indexDDL==3){
849     minPlate=kMinPlate3;
850     maxPlate=kMaxPlate3;
851     minStrip2=kMinStrip3;
852     maxStrip2=kMaxStrip3;
853     minPadz=kMinPadz3;
854     maxPadz=kMaxPadz3;
855     minPadx=kMinPadx3;
856     maxPadx=kMaxPadx3;
857   }
858
859   Int_t ichTOF=0;
860
861   Int_t minStrip=0;
862   Int_t maxStrip=18;  
863   for (Int_t iPlate=minPlate;iPlate<=maxPlate;iPlate++){
864     if (iPlate==2) {
865       maxStrip = maxStrip2;
866       minStrip = minStrip2;
867     }
868     else {
869       maxStrip = 18;
870       minStrip = 0;
871     }
872     for (Int_t iStrip=minStrip;iStrip<=maxStrip;iStrip++){
873       for (Int_t iPadz=minPadz;iPadz<=maxPadz;iPadz++){
874         for (Int_t iPadx=minPadx;iPadx<=maxPadx;iPadx++){
875           volume[1]=iPlate;
876           volume[2]=iStrip;
877           volume[3]=iPadz;
878           volume[4]=iPadx;
879           if (fVerbose)
880             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]));
881
882           if (indexDDL==0 || indexDDL==2){
883             array[ichTOF]=geom->GetIndex(volume);
884             if (fVerbose)
885               AliInfo(Form(" ichTOF = %i, TOFChannel = %i",ichTOF,array[ichTOF]));
886
887           }
888           else {
889             array[ichTOF]=geom->GetIndex(volume);
890             if (fVerbose)
891               AliInfo(Form(" ichTOF = %i, TOFChannel = %i",ichTOF,array[ichTOF]));
892
893           }
894           ichTOF++;
895         }
896       }
897     }
898   }
899   //AliInfo(Form("ichTOF = %i",ichTOF));
900   if ((indexDDL%2==0 && ichTOF!=2160) ||
901       (indexDDL%2==1 && ichTOF!=2208)) {
902     AliWarning(Form("Something strange occurred, number of entries in array different from expected! Please, check! ichTOF = %i",ichTOF));
903   }
904   return;
905 }