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