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