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