]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDRawStreamV2.cxx
Patch to deal with big endians (MAC)
[u/mrichter/AliRoot.git] / TRD / AliTRDRawStreamV2.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // This class provides access to TRD digits in raw data.                     //
21 //                                                                           //
22 // It loops over all TRD digits in the raw data given by the AliRawReader.   //
23 // The Next method goes to the next digit. If there are no digits left       //
24 // it returns kFALSE.                                                        //
25 // Several getters provide information about the current digit.              //
26 //                                                                           //
27 // Author: C. Lippmann (C.Lippmann@gsi.de)                                   //
28 //                                                                           //
29 ///////////////////////////////////////////////////////////////////////////////
30
31 #include "AliLog.h"
32 #include "AliRawReader.h"
33
34 #include "AliTRDRawStreamV2.h"
35 #include "AliTRDgeometry.h"
36 #include "AliTRDcalibDB.h"
37 #include "AliTRDfeeParam.h"
38 #include "AliTRDdigitsManager.h"
39 #include "AliTRDdataArrayI.h"
40 #include "AliTRDSignalIndex.h"
41
42 ClassImp(AliTRDRawStreamV2)
43
44 //_____________________________________________________________________________
45 AliTRDRawStreamV2::AliTRDRawStreamV2() 
46   :TObject()
47   ,fGeo(NULL) 
48   ,fSig()
49   ,fADC(0)
50   ,fTB(0)
51   ,fEv(0)
52   ,fROB(0)
53   ,fMCM(0)
54   ,fSM(0)
55   ,fLAYER(0)
56   ,fSTACK(0)
57   ,fROC(0)
58   ,fSIDE(0)
59   ,fDCS(0)
60   ,fROW(0)
61   ,fCOL(0)
62   ,fDET(0)
63   ,fLastDET(-1)
64   ,fBCctr(0)
65   ,fPTctr(0)
66   ,fPTphase(0)
67   ,fRVmajor(0)
68   ,fRVminor(0)
69   ,fHCHWords(0)
70   ,fTBins(0)
71   ,fTCon(0)
72   ,fPEDon(0)
73   ,fGAINon(0)
74   ,fXTon(0)
75   ,fNonLinOn(0)
76   ,fBypass(0)
77   ,fCommonAdditive(0)
78   ,fZeroSuppressed(0)
79   ,fHCHctr1(0)
80   ,fHCHctr2(0)
81   ,fMCMHctr1(0)
82   ,fMCMHctr2(0)
83   ,fGTUctr1(0)
84   ,fGTUctr2(0)
85   ,fHCdataCtr(0)
86   ,fTracklPID(0.)
87   ,fTracklDefL(0.)
88   ,fTracklPadPos(0.)
89   ,fTracklPadRow(0)
90   ,fGTUlinkMask()
91   ,fMCMWordCrt(0)
92   ,fMCMWordsExpected(0)
93   ,fRawReader(NULL)
94   ,fRawVersion(2)
95   ,fRawDigitThreshold(0)
96   ,fNextStatus(0)
97   ,fLastStatus(0)
98   ,fTbSwitch(0)
99   ,fTbSwitchCtr(0)
100   ,fTimeWords(0)
101   ,fWordCtr(0)
102   ,fRowMax(0)
103   ,fColMax(0)
104   ,fADCmask()
105   ,fLastADCmask(0)
106   ,fChamberDone()
107   ,fRetVal(0)
108   ,fEqID(0)
109   ,fDataSize(0)
110   ,fSizeOK(kFALSE)
111   ,fCountBytes(0)
112   ,fBufSize(0)
113   ,fkBufferSet(kFALSE)
114   ,fPos(NULL)
115   ,fDataWord(NULL)
116   ,fTimeBinsCalib(0)
117   ,fADClookup()
118   ,fNActiveADCs(0)
119   ,fEndOfDataFlag(kFALSE)
120 {
121   //
122   // Default constructor
123   //
124
125   for (Int_t i = 0; i < 540; i++) {
126     fChamberDone[i] = 0;
127   }
128
129 }
130
131 //_____________________________________________________________________________
132 AliTRDRawStreamV2::AliTRDRawStreamV2(AliRawReader *rawReader) 
133   :TObject()
134   ,fGeo(NULL) 
135   ,fADC(0)
136   ,fTB(0)
137   ,fEv(0)
138   ,fROB(0)
139   ,fMCM(0)
140   ,fSM(0)
141   ,fLAYER(0)
142   ,fSTACK(0)
143   ,fROC(0)
144   ,fSIDE(0)
145   ,fDCS(0)
146   ,fROW(0)
147   ,fCOL(0)
148   ,fDET(0)
149   ,fLastDET(-1)
150   ,fBCctr(0)
151   ,fPTctr(0)
152   ,fPTphase(0)
153   ,fRVmajor(0)
154   ,fRVminor(0)
155   ,fHCHWords(0)
156   ,fTBins(0)
157   ,fTCon(0)
158   ,fPEDon(0)
159   ,fGAINon(0)
160   ,fXTon(0)
161   ,fNonLinOn(0)
162   ,fBypass(0)
163   ,fCommonAdditive(0)
164   ,fZeroSuppressed(0)
165   ,fHCHctr1(0)
166   ,fHCHctr2(0)
167   ,fMCMHctr1(0)
168   ,fMCMHctr2(0)
169   ,fGTUctr1(0)
170   ,fGTUctr2(0)
171   ,fHCdataCtr(0)
172   ,fTracklPID(0.)
173   ,fTracklDefL(0.)
174   ,fTracklPadPos(0.)
175   ,fTracklPadRow(0)
176   ,fGTUlinkMask()
177   ,fMCMWordCrt(0)
178   ,fMCMWordsExpected(0)
179   ,fRawReader(rawReader)
180   ,fRawVersion(2)
181   ,fRawDigitThreshold(0)
182   ,fNextStatus(0)
183   ,fLastStatus(0)
184   ,fTbSwitch(0)
185   ,fTbSwitchCtr(0)
186   ,fTimeWords(0)
187   ,fWordCtr(0)
188   ,fRowMax(0)
189   ,fColMax(0)
190   ,fADCmask()
191   ,fLastADCmask(0)
192   ,fChamberDone()
193   ,fRetVal(0)
194   ,fEqID(0)
195   ,fDataSize(0)
196   ,fSizeOK(kFALSE)
197   ,fCountBytes(0)
198   ,fBufSize(0)
199   ,fkBufferSet(kFALSE)
200   ,fPos(NULL)
201   ,fDataWord(NULL)
202   ,fTimeBinsCalib(0)
203   ,fADClookup()
204   ,fNActiveADCs(0)
205   ,fEndOfDataFlag(kFALSE)
206 {
207   //
208   // Create an object to read TRD raw digits
209   //
210
211   fRawReader->Select("TRD");
212
213   for (Int_t i = 0; i < 540; i++) {
214     fChamberDone[i] = 0;
215   }
216
217 }
218
219 //_____________________________________________________________________________
220 AliTRDRawStreamV2::AliTRDRawStreamV2(const AliTRDRawStreamV2& stream)
221   :TObject(stream)
222   ,fGeo(NULL)
223   ,fSig()
224   ,fADC(-1)
225   ,fTB(-1)
226   ,fEv(-1)
227   ,fROB(-1)
228   ,fMCM(-1)
229   ,fSM(-1)
230   ,fLAYER(-1)
231   ,fSTACK(-1)
232   ,fROC(-1)
233   ,fSIDE(-1)
234   ,fDCS(-1)
235   ,fROW(-1)
236   ,fCOL(-1)
237   ,fDET(0)
238   ,fLastDET(-1)
239   ,fBCctr(-1)
240   ,fPTctr(-1)
241   ,fPTphase(-1)
242   ,fRVmajor(-1)
243   ,fRVminor(-1)
244   ,fHCHWords(-1)
245   ,fTBins(-1)
246   ,fTCon(0)
247   ,fPEDon(0)
248   ,fGAINon(0)
249   ,fXTon(0)
250   ,fNonLinOn(-1)
251   ,fBypass(-1)
252   ,fCommonAdditive(-1)
253   ,fZeroSuppressed(0)
254   ,fHCHctr1(-1)
255   ,fHCHctr2(-1)
256   ,fMCMHctr1(-1)
257   ,fMCMHctr2(-1)
258   ,fGTUctr1(-1)
259   ,fGTUctr2(-1)
260   ,fHCdataCtr(-1)
261   ,fTracklPID(-1.)
262   ,fTracklDefL(-1.)
263   ,fTracklPadPos(-1.)
264   ,fTracklPadRow(-1)
265   ,fGTUlinkMask()
266   ,fMCMWordCrt(0)
267   ,fMCMWordsExpected(0)
268   ,fRawReader(NULL)
269   ,fRawVersion(-1)
270   ,fRawDigitThreshold(0)
271   ,fNextStatus(0)
272   ,fLastStatus(0)
273   ,fTbSwitch(0)
274   ,fTbSwitchCtr(0)
275   ,fTimeWords(0)
276   ,fWordCtr(0)
277   ,fRowMax(-1)
278   ,fColMax(-1)
279   ,fADCmask()
280   ,fLastADCmask(0)
281   ,fChamberDone()
282   ,fRetVal(0)
283   ,fEqID(0)
284   ,fDataSize(0)
285   ,fSizeOK(kFALSE)
286   ,fCountBytes(0)
287   ,fBufSize(0)
288   ,fkBufferSet(kFALSE)
289   ,fPos(NULL)
290   ,fDataWord(NULL)
291   ,fTimeBinsCalib(0)
292   ,fADClookup()
293   ,fNActiveADCs(0)
294   ,fEndOfDataFlag(kFALSE)
295 {
296   //
297   // Copy constructor
298   //
299
300   AliFatal("Copy constructor not implemented");
301
302 }
303
304 //_____________________________________________________________________________
305 AliTRDRawStreamV2& AliTRDRawStreamV2::operator = (const AliTRDRawStreamV2& 
306                                               /* stream */)
307 {
308   //
309   // Assigment operator
310   //
311
312   Fatal("operator =", "assignment operator not implemented");
313   return *this;
314
315 }
316
317 //_____________________________________________________________________________
318 AliTRDRawStreamV2::~AliTRDRawStreamV2()
319 {
320   //
321   // Destructor
322   //
323
324   if (fGeo) {  
325     delete fGeo;
326   }
327
328 }
329
330 //_____________________________________________________________________________
331 void AliTRDRawStreamV2::SetRawReader(AliRawReader *rawReader) 
332 {
333   //
334   // Set the rawreader
335   //
336
337   if (rawReader)
338     {
339       fRawReader = rawReader;
340     }
341 }
342
343 //_____________________________________________________________________________
344 Bool_t AliTRDRawStreamV2::SetRawVersion(Int_t rv)
345 {
346   //
347   // Set the raw data version
348   //
349
350   if ( rv >= 0 && rv <= 3 ) {
351     fRawVersion = rv;
352     return kTRUE;
353   }
354
355   return kFALSE;
356
357 }
358
359 //____________________________________________________________________________
360 Int_t AliTRDRawStreamV2::Init()
361 {
362   //
363   // Initialization
364   //
365
366   if (!AliTRDcalibDB::Instance()) {
367     AliError("Could not get calibration object");
368     return 0;
369   }
370
371   if (!fGeo) {
372     fGeo = new AliTRDgeometry();
373   }
374   
375   fTimeBinsCalib = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
376   //AliDebug(2, Form("Number of Timebins read from CDB: %d", fTimeBinsCalib));
377
378   // The number of data words needed for this number of time bins (there
379   // are 3 time bins in one word)
380   fTimeWords = (fTimeBinsCalib-1)/3 + 1;
381
382   fTbSwitch    = 3;
383   fTbSwitchCtr = 0;
384
385   fHCHctr1 = fHCHctr2 =  0;
386   fGTUctr1 = fGTUctr2 = -1;
387
388   fHCdataCtr = 0;
389   fWordCtr   = 0;  
390
391   fDET     = 0;
392   fLastDET     = -1;
393   fRetVal = 0;
394   fEqID     = 0;
395   fDataSize = 0;
396   fSizeOK = kFALSE;
397   
398   fLastStatus = kStart;
399   fNextStatus = kStart;
400
401   fCountBytes = 0;
402   fBufSize = 0;
403   fDataWord = NULL;
404   fPos = NULL;
405   fWordCtr = 0;
406   fkBufferSet = kFALSE;
407
408   fMCMWordCrt = 0;
409   fMCMWordsExpected = 0;
410
411   fEndOfDataFlag = kFALSE;
412   // set all ADC active
413   // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
414   fNActiveADCs = ChannelsToRead(0x1fffff); 
415
416   fLastADCmask = 0;
417
418   return kTRUE;
419 }
420
421 //____________________________________________________________________________
422 void AliTRDRawStreamV2::SwapOnEndian()
423 {
424   //
425   // Check the endian and swap if needed
426   //
427
428   int itemp = 1;
429   char* ptemp = (char*) &itemp;
430   if (ptemp[0] != 1)
431     {
432       // need to swap...
433       // assume we are at the begining of the buffer!
434       //AliDebug(5, "Swapping.");
435       UInt_t *pbegin = (UInt_t*)fPos;
436       UInt_t iutmp = 0;
437       for (UInt_t i = 0; i < fBufSize / fgkSizeWord; i++)
438         {
439           fDataWord = pbegin + i;
440           iutmp = (((*fDataWord & 0x000000ffU) << 24) | ((*fDataWord & 0x0000ff00U) <<  8) |
441                    ((*fDataWord & 0x00ff0000U) >>  8) | ((*fDataWord & 0xff000000U) >> 24));
442           // here we override the value in the buffer!
443           *fDataWord = iutmp;
444         }
445       fDataWord = pbegin;
446     }
447 }
448 //____________________________________________________________________________
449 Int_t AliTRDRawStreamV2::NextData()
450 {
451   //
452   // Updates the next data word pointer
453   //
454
455   if (fCountBytes + fgkSizeWord >= fBufSize)
456     {
457       fkBufferSet = fRawReader->ReadNextData(fPos);
458       if (fkBufferSet == kTRUE)
459         {
460           fBufSize = fRawReader->GetDataSize();
461           fCountBytes = 0;        
462           fDataWord = (UInt_t*)fPos;
463           SwapOnEndian();
464           ChangeStatus(kNextSM);
465           fWordCtr = 0;
466           return kNextSM;
467         }
468       else
469         {
470           ChangeStatus(kStop);
471           return kNoMoreData;
472         }
473     }
474   else
475     {
476       fPos += fgkSizeWord;
477       fCountBytes += fgkSizeWord;         
478       fDataWord = (UInt_t*)fPos;
479       fWordCtr++;
480       return kWordOK;
481     }
482 }
483
484 //============================================================================
485 // Decoding functions
486 //============================================================================
487
488 //____________________________________________________________________________
489 void AliTRDRawStreamV2::DecodeHCheader(Int_t timeBins)
490 {
491   //
492   // Decode the HC header (fRawVersion == 2, 3, 4, ???)
493   //
494
495   fRVmajor = (*fDataWord >> 24) & 0x7f;
496   fRVminor = (*fDataWord >> 17) & 0x7f;
497
498   if (fRVmajor < 2 || fRVmajor > 4)
499     AliError(Form(" Unsupported raw version: %d", fRawVersion))
500   
501   if ( fRawVersion != fRVmajor ) {
502     
503     AliWarning("===============================================================================");
504     AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
505                     ,fRawVersion,fRVmajor));
506     AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
507     AliWarning("===============================================================================");
508     fRawVersion = fRVmajor;
509
510   }
511
512   //
513   // check for zero suppression
514   if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
515   else                                        fZeroSuppressed = kFALSE;
516   
517   // 1st word (h[0])
518   if ( (*fDataWord & 0x3) == 1 ) {
519
520     fHCHWords = (*fDataWord >> 14) & 0x7;
521     fSM       = (*fDataWord >>  9) & 0x1f;
522     fLAYER    = (*fDataWord >>  6) & 0x7;
523     fSTACK    = (*fDataWord >>  3) & 0x7;
524     fSIDE     = (*fDataWord >>  2) & 0x1;
525
526     fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
527
528     //AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", *fDataWord, fSM, fROC, fSIDE+10));
529     //AliDebug(5, Form("0x%08x: HC header: expecting %d HC words", *fDataWord, fHCHWords));
530
531     if ((fSM    <  0) || 
532         (fSM    > 17) || 
533         (fLAYER <  0) || 
534         (fLAYER >  5) || 
535         (fSTACK <  0) || 
536         (fSTACK >  4) || 
537         (fSIDE  <  0) || 
538         (fSIDE  >  1)) 
539       {
540         AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
541                         *fDataWord, fDCS, fSM, fLAYER, fSTACK));
542         fRawReader->AddMajorErrorLog(kHCHeaderCorrupt,Form("0x%08x:dcs=%d; sm=%d; layer=%d; stack=%d.",
543                                                            *fDataWord, fDCS, fSM, fLAYER, fSTACK));
544       } 
545     else 
546       {
547         fHCHctr1++;
548         fHCHctr2++;
549       }
550   } 
551   else 
552     { 
553       AliWarning(Form("0x%08x: No HC header when it was expected.", *fDataWord)); 
554       fRawReader->AddMajorErrorLog(kHCHeaderMissing,Form("0x%08x", *fDataWord));
555     }
556
557   // 2nd word (h[1])
558   if ( fHCHWords >= 1 ) 
559     {
560       // read one more word
561       if (NextData() != kWordOK)
562         {
563           AliWarning("Next HC word missing");
564           fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC word missing"); 
565           fNextStatus = kNextHC;
566           return;
567         }
568
569       if ( (*fDataWord & 0x3) == 1 ) 
570         {
571           
572           fBCctr   =  (*fDataWord >> 16);
573           fPTctr   =  (*fDataWord >> 12) & 0xf;
574           fPTphase =  (*fDataWord >>  8) & 0xf;
575           fTBins   = ((*fDataWord >>  2) & 0x3f) + 1;
576           fTimeWords = (fTBins - 1)/3 + 1;      
577           
578 //        AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
579 //                         , *fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
580
581           if( fTBins != timeBins ) 
582             {         
583               AliWarning("===============================================================================");
584               AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
585                             , timeBins, fTBins));
586               AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
587               AliWarning("===============================================================================");          
588
589               fTimeWords = (fTBins - 1)/3 + 1;  
590             }
591         }      
592     }
593
594   // 3nd word (h[2])
595   if ( fHCHWords >= 2 ) {
596     // read one more word
597     if (NextData() != kWordOK)
598       {
599         AliWarning("Next HC word missing");
600         fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC word missing"); 
601         fNextStatus = kNextHC;
602         return;
603       }
604     if ( (*fDataWord & 0x3) == 1 ) {
605        
606       fTCon     = (*fDataWord >> 29) & 0x1;
607       fPEDon    = (*fDataWord >> 31) & 0x1;
608       fGAINon   = (*fDataWord >> 30) & 0x1;
609       fXTon     = (*fDataWord >> 28) & 0x1;
610       fNonLinOn = (*fDataWord >> 27) & 0x1;
611       fBypass   = (*fDataWord >> 26) & 0x1;
612
613       fCommonAdditive = (*fDataWord >> 20) & 0x3f;
614
615 //       AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
616 //                    , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
617     }
618   }
619
620 }  
621
622 //____________________________________________________________________________
623 Int_t AliTRDRawStreamV2::ChannelsToRead(Int_t ADCmask)
624 {
625   //
626   // Return the channels to read
627   //
628
629   memset(fADClookup, -1, 32 * sizeof(Int_t));
630   fADClookup[0] = 0; // count entries
631   fADClookup[1] = 2; // index - data start at 2
632   UInt_t mask = 0;
633   for (Int_t i = 0; i < 30; i++)
634     {
635       mask = 1 << i;
636       if ((ADCmask & mask))
637         {
638           //AliDebug(9, Form("fDataWord=0x%08x mask=0x%08x i=%d", *fDataWord, mask, i));
639           fADClookup[fADClookup[1]] = i;
640           ++fADClookup[0];
641           ++fADClookup[1];
642         }
643     }
644
645   // test the iteration - comment out for production
646   // begin of comment out section
647   char schannels[512];
648   sprintf(schannels, "ADC Channels to read: ");
649   fADClookup[1] = 2;
650   while(fADClookup[1] - 2 < fADClookup[0])
651     {
652       //AliDebug(9, Form("max=%d index=%d adc=%d", fADClookup[0], fADClookup[1], fADClookup[fADClookup[1]]));
653       strcat(schannels, Form("%d ", fADClookup[fADClookup[1]]));
654       fADClookup[1]++;
655     }
656   //AliDebug(9, Form("%s", schannels));
657   //AliDebug(9, Form("ADC channels = %d", fADClookup[0]));
658   // end of comment out section
659
660   fADClookup[1] = 2;
661   return fADClookup[0];
662 }
663
664 //____________________________________________________________________________
665 void AliTRDRawStreamV2::DecodeTracklet()
666 {
667   //
668   // Decode the Tracklet
669   //
670   // this function is not tested yet on real tracklets
671   //
672
673   if ( fRawVersion < 1 || fRawVersion > 3 ) 
674     {
675       AliError(Form(" Unsupported raw version: %d", fRawVersion));      
676     }
677
678   fTracklPID    = (*fDataWord >> 24) & 0xff;
679   fTracklPadRow = (*fDataWord >> 20) & 0xf;    // 0:15
680   fTracklDefL   = (*fDataWord >> 13) & 0x7f;
681   fTracklPadPos = (*fDataWord)       & 0x1fff;
682
683   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
684   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
685   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
686
687   //AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
688   //              , *fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
689   //                , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
690
691   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
692       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
693     AliWarning(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
694     fRawReader->AddMajorErrorLog(kTrackletRowMismatch,Form("Word: %d", fTracklPadRow));
695   }
696
697 }
698
699 //____________________________________________________________________________
700 void AliTRDRawStreamV2::DecodeMCMheader()
701 {
702   //
703   // Decode the MCM header
704   //
705
706   if ( fRawVersion < 1 || fRawVersion > 3 ) 
707     {
708       AliError(Form(" Unsupported raw version: %d", fRawVersion));      
709     }
710
711   fMCM  = (*fDataWord & 0xff000000) >> 24;
712   fEv   = (*fDataWord & 0x00fffff0) >> 4;
713
714   fROB  = fMCM / 16;
715   fMCM  = fMCM % 16;
716
717   fROW  = AliTRDfeeParam::Instance()->GetPadRowFromMCM(fROB, fMCM);
718
719 //   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
720 //                , *fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
721
722   if ( fROB % 2 == 0 && fSIDE == 1 ) {
723     AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
724                    , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
725     fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
726                                                        , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
727   }
728   if ( fROB % 2 != 0 && fSIDE == 0 ) {
729     AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
730                    , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
731     fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
732                                                        , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
733   }
734   if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
735        (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 ) {
736     AliWarning(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
737                    , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
738     fRawReader->AddMajorErrorLog(kWrongPadrow,Form("SM%d L%dS%d: Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
739                                                   , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
740   }
741   
742   fMCMHctr1++;
743   fMCMHctr2++;
744
745   fMCMWordCrt = 1; // MCM header
746
747   // AdcMask for Zero supressed data
748   if ( fRawVersion == 3 ) 
749     {
750       // read one more word
751       if (NextData() != kWordOK)
752         {
753           AliWarning("MCM ADC mask missing");
754           fRawReader->AddMajorErrorLog(kMCMADCMaskMissing,"Missing"); 
755           fNextStatus = kNextHC;
756           return;
757         }
758       else
759         {
760           ++fMCMWordCrt;
761
762           for ( Int_t ctr = 0; ctr < fGeo->ADCmax(); ctr++ ) {
763             if ( (*fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
764             else                                  fADCmask[ctr] = kFALSE;
765           }
766           
767           //AliDebug(4, Form("0x%08x: ADC mask", *fDataWord));
768           fNActiveADCs = ChannelsToRead(*fDataWord);      
769         }
770     }
771
772   if (fRawVersion <= 2)
773     {
774       // no zero suppression
775       // raw version 2:
776       // 1 MCM header + 21 * ( Ntimebin/3)
777       // If NTimebin = 30, it is 211 words. 
778       //fMCMWordsExpected = 1 + 21 * (fTBins / 3);
779       //fNActiveADCs = 21;
780       fNActiveADCs = ChannelsToRead(0x1fffff); // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
781       //fMCMWordsExpected = 1 + fNActiveADCs * ((fTBins-1) / 3. + 1.);      
782       //directly get it like that:
783       fMCMWordsExpected = 1 + fNActiveADCs * fTBins / 3;      
784     }
785
786   if (fRawVersion >= 3)
787     {
788       // raw version 3:
789       // 1 MCM header + 1 ADC mask + NofActiveADCs * ( Ntimebin/3 )
790       //directly get it like that:
791       fMCMWordsExpected = 1 + 1 + (fTBins * fNActiveADCs) / 3;
792     }
793   
794   //AliDebug(5, Form("We expect %d MCM words. We read %d so far.", fMCMWordsExpected, fMCMWordCrt));
795 }
796 //____________________________________________________________________________
797 Bool_t AliTRDRawStreamV2::DecodeNextRawWord()
798 {
799   //
800   // Decode the next raw data word
801   //
802
803   //AliDebug(8, Form("-----------------------------------------"));
804   //AliDebug(8, Form("DATA IS 0x%x", *fDataWord));
805
806   if (fADClookup[1] - 2 > fADClookup[0])
807     {
808 //       AliDebug(8, Form("Overflow Index ADC = %d Max Index = %d Value = %d. Done with ADCs in this MCM. Is this already MCM header 0x%x?", 
809 //                     fADClookup[1] - 2, fADClookup[0], fADClookup[fADClookup[1]], *fDataWord));
810       fTbSwitchCtr = 0;
811       fMCMWordsExpected = 0;
812       AliWarning("Trying to recover. Fall back to DecodeMCM.");
813       DecodeMCM();
814       //ChangeStatus(kNextMCM);
815       return kFALSE;
816     }
817
818   if ( (*fDataWord & 0x00000003) != 0x2 && (*fDataWord & 0x00000003) != 0x3) {
819     AliWarning(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)*fDataWord));
820     fRawReader->AddMinorErrorLog(kDataMaskError,Form("Data %08x", (Int_t)*fDataWord));
821     fMCMWordsExpected = 0;
822     AliWarning("Trying to recover. Fall back to DecodeMCM.");
823     DecodeMCM();
824     //ChangeStatus(kNextMCM);
825     return kFALSE;
826   }
827
828   if ( (*fDataWord & 0x3) != fLastADCmask || fTbSwitchCtr > fTimeWords) 
829     {    
830       fADC = fADClookup[fADClookup[1]];
831 //       AliDebug(8, Form("Next fADC = %d at index = %d MCM Word Number: %d Max MCM Words is %d", 
832 //                     fADC, fADClookup[1] - 2, fMCMWordCrt, fMCMWordsExpected));
833       ++fADClookup[1];
834       fTB = 0;    
835       fTbSwitchCtr = 0;
836       fLastStatus = kNextData;
837       fLastADCmask = (*fDataWord) & 0x3;
838     }
839
840   ++fTbSwitchCtr;
841
842   //decode data here
843   Bool_t kIsDataOK = kFALSE;
844
845   // We have only 21 ADC channels.
846   if ( fADC > (Int_t)fGeo->ADCmax() - 1 ) 
847     {
848       AliWarning(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)*fDataWord, (Int_t)fADC));
849       fRawReader->AddMinorErrorLog(kADCChannelOverflow,Form("Data %08x : fADC=%d", (Int_t)*fDataWord, (Int_t)fADC));
850     }
851   else
852     {
853       // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
854       // MCMs and are good for online tracking in the MCM.
855       if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax() - 1 ) 
856         {
857           
858           // Get Pad column
859           // fCOL = fFee->GetPadColFromADC(fROB, fMCM, fADC);
860           fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fROB, fMCM, fADC);
861           
862           // We have only 144 Pad Columns
863           //if ( fCOL > fColMax-1 || fCOL < 0 ) 
864           if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax ) 
865             {
866               // Decode 32 bit data words with information from 3 time bins and copy the data
867               fSig[0] = (*fDataWord & 0x00000ffc) >> 2;
868               fSig[1] = (*fDataWord & 0x003ff000) >> 12;
869               fSig[2] = (*fDataWord & 0xffc00000) >> 22;
870               
871               // Print data to screen:
872               //AliDebug(5, Form("DATA : 0x%x", *fDataWord));
873               //          AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
874               //                           fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));            
875               kIsDataOK = kTRUE;
876             }
877           else
878             {
879               AliWarning(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
880                               fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
881               fRawReader->AddMajorErrorLog(kWrongPadcolumn,Form("SM%d L%dS%d: column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
882                                                                 fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
883               kIsDataOK = kFALSE;
884             }
885         }
886       else 
887         {      
888           //AliDebug(5, Form("fADC not accepted %d - DATA : 0x%x", fADC, *fDataWord));
889           fCOL = -1;
890           kIsDataOK = kFALSE;
891         }
892     }// if fADC is ok
893
894   ++fMCMWordCrt;
895   //AliDebug(5, Form("We expect %d MCM words. We read %d so far.", fMCMWordsExpected, fMCMWordCrt));
896
897   // all mcm data processed go to next one
898   if ( fMCMWordCrt >= fMCMWordsExpected)
899     {
900       ChangeStatus(kNextMCM);
901     }
902
903   return kIsDataOK;
904 }
905
906 //____________________________________________________________________________
907 Bool_t AliTRDRawStreamV2::DecodeMCM()
908 {
909   //
910   // Decode a single MCM
911   //
912
913   if( ((*fDataWord & 0x80000000) == 0x0) && ((*fDataWord & 0x0000000f) == 0xC) )
914     { // MCM Header
915       DecodeMCMheader();
916       if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 ) 
917         {
918           AliWarning("Wrong fMCM or fROB. Skip this data");
919           fRawReader->AddMajorErrorLog(kWrongMCMorROB,Form("MCM=%d, ROB=%d",fMCM,fROB));
920           ChangeStatus(kNextHC);
921           return kFALSE;
922         }
923
924       fTbSwitch    = 3;  // For first adc channel we expect: (*fDataWord & 3) = 3
925       fTbSwitchCtr = 0;  // 
926       fADC = fTB   = 0;  // Reset Counter
927       fLastADCmask = 0; // Reset
928
929       if (fMCMWordCrt < fMCMWordsExpected)
930         {
931           ChangeStatus(kNextData);
932         }
933       else
934         {
935           ChangeStatus(kNextMCM);
936         }
937       return kTRUE;
938     }
939
940   if ( *fDataWord == fgkEndofrawdatamarker ) 
941     {  // End of half-chamber data, finished
942       fGTUctr1 = -1;
943       ChangeStatus(kNextHC);
944       fEndOfDataFlag = kTRUE;
945       //AliDebug(5, "Expecting MCM header but got End-Of-Raw-Data Marker");
946       if (fMCMWordsExpected == 0 || fMCMWordsExpected == fMCMWordCrt)
947         return kTRUE;
948       else
949         {
950           //AliDebug(5, Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));    
951           //AliWarning(Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));     
952           return kFALSE;
953         }
954     }
955
956   //AliDebug(3, Form("Expecting MCM header but got 0x%x. Going to Next MCM header.", *fDataWord));
957   AliWarning(Form("Expecting MCM header but got 0x%x. Fall back: Next MCM header.", *fDataWord));
958   ChangeStatus(kNextMCM);      
959
960   return kFALSE;
961 }
962
963 //____________________________________________________________________________
964 Bool_t AliTRDRawStreamV2::DecodeHC()
965 {
966   //
967   // Decode a half chamber
968   //
969
970   if ( fNextStatus == kNextHC )
971     {
972       //AliDebug(5, "kNextHC");
973       //
974       // 1) Find end_of_tracklet_marker
975       //
976       // GTU Link Mask?
977       if (DecodeGTUlinkMask())
978         {
979           return kTRUE;
980         }
981       
982       // endoftrackletmarker?
983       if ( *fDataWord == fgkEndoftrackletmarker ) 
984         {
985           //AliDebug(3, "End-of-tracklet-marker found");
986           //AliDebug(5, Form("Data 0x%x", *fDataWord));
987           ChangeStatus(kSeekNonEoTracklet);
988           return kTRUE;
989         } 
990       else 
991         {
992           // Tracklets found
993           //AliDebug(3, "Tracklet found");
994           //AliDebug(5, Form("Tracklet data 0x%x", *fDataWord));
995           DecodeTracklet();
996           return kTRUE;
997         }
998     } // if next HC
999
1000   if (fNextStatus == kSeekNonEoTracklet)
1001     {
1002       //AliDebug(5, "kSeekNonEoTracklet");
1003
1004       //
1005       // 2) Look for non-end_of_tracklet_marker
1006       //
1007       //printf("Word %d: 0x%08x\n", fWordCtr, *fDataWord); 
1008       
1009       if ( *fDataWord != fgkEndoftrackletmarker ) 
1010         {
1011           ChangeStatus(kDecodeHC);
1012           //AliDebug(3, "NON end-of-tracklet-marker found");
1013           //AliDebug(5, Form("Data 0x%x", *fDataWord));
1014           //// no do not continue - this should be the hcheader
1015         }
1016       else
1017         {
1018           //just go on and find the non-end_of_tracklet_marker
1019           return kTRUE;
1020         }
1021     }
1022
1023   if ( fNextStatus == kDecodeHC )
1024     {
1025       //AliDebug(5, "kDecodeHC");
1026       
1027       //
1028       // 3) This Word must be Half Chamber Header
1029       //
1030       if ( (*fDataWord & 0x00000003) == 1 ) 
1031         { // HC header
1032           DecodeHCheader(fTimeBinsCalib); // This is the new header!
1033           fLastDET = fDET;
1034           fDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
1035           fRowMax = fGeo->GetRowMax(fLAYER,fSTACK,fSM);
1036           fColMax = fGeo->GetColMax(fROC);
1037           
1038           fMCMHctr2 = 0;
1039           fHCdataCtr = 0;
1040           fChamberDone[fDET]++;
1041           //AliDebug(6, Form("--------------      DET %d fChamberDone[fDET]=%d", fDET, fChamberDone[fDET]));
1042
1043           ChangeStatus(kNextMCM);
1044           return kTRUE;
1045         } //HC header
1046       else
1047         {
1048           AliWarning(Form("Expecting HC header mask but got 0x%x. Fall back: Next HC.", *fDataWord));
1049           ChangeStatus(kNextHC);
1050           // before we went to //ChangeStatus(kNextSM);
1051         }
1052     } // if decode HC
1053   
1054   return kFALSE;
1055 }
1056
1057 //____________________________________________________________________________
1058 Bool_t AliTRDRawStreamV2::DecodeGTUlinkMask()
1059 {
1060   //
1061   // Decode the link masks sent by the GTU. These marke the active optical links
1062   // between GTU and Super Module. Up to now only fully active links are found
1063   // (0xfff = 12 active links).
1064   //
1065
1066   if ( (*fDataWord & 0xfffff000) ==  0xe0000000 )
1067     {
1068       if ( fRawVersion < 1 || fRawVersion > 3 ) 
1069         {
1070           AliError(Form(" Unsupported raw version: %d", fRawVersion));      
1071         }
1072       
1073       if ( fGTUctr1 == -1 ) fGTUctr2++;
1074       fGTUctr1++;
1075
1076       if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) 
1077         {
1078           fGTUlinkMask[fGTUctr2][fGTUctr1] = (*fDataWord & 0xfff);
1079         }
1080      
1081       //AliDebug(5, Form("GTU link mask 0x%x decoded 0x%x", *fDataWord, fGTUlinkMask[fGTUctr2][fGTUctr1]));
1082       return kTRUE;
1083     }
1084
1085   return kFALSE;
1086 }
1087
1088 //____________________________________________________________________________
1089 void AliTRDRawStreamV2::ChangeStatus(Int_t kstat)
1090 {
1091   //
1092   // Change the status
1093   //
1094
1095   fLastStatus = fNextStatus;
1096   fNextStatus = kstat;  
1097 }
1098
1099 //____________________________________________________________________________
1100 Bool_t AliTRDRawStreamV2::DecodeSM()
1101 {
1102   //
1103   // Decode a supermodule
1104   //
1105
1106   fDET     = 0;
1107   fRetVal = 0;
1108   fEqID     = 0;
1109   fDataSize = 0;
1110   fSizeOK = kFALSE;
1111   
1112   // After reading the first word check for size of this data and get Eq. ID
1113   if ( fWordCtr == 1 ) 
1114     {
1115       fDataSize = fRawReader->GetDataSize()/4;  // Size of this payload in 32bit words
1116       fEqID     = fRawReader->GetEquipmentId(); // Get Equipment ID
1117       if ( fDataSize > 0 ) fSizeOK = kTRUE;
1118       //AliDebug(3, Form("fDataSize=%d fEqID=%d", fDataSize, fEqID));
1119     }
1120   
1121   // GTU Link Mask?
1122   if ( DecodeGTUlinkMask() ) 
1123     {
1124       ChangeStatus(kNextHC);
1125       return kTRUE;
1126     } 
1127   else 
1128     {
1129       AliWarning(Form("Equipment %d: First data word is not GTU Link Mask! Fall back: None. Stop.", fEqID));
1130       fRawReader->AddMajorErrorLog(kGTULinkMaskMissing,Form("Equipment %d",fEqID));
1131       ChangeStatus(kStop);
1132     }       
1133
1134   return kFALSE;
1135 }
1136
1137 //____________________________________________________________________________
1138 Bool_t AliTRDRawStreamV2::Next()
1139 {
1140   //
1141   // Updates the next data word pointer
1142   //
1143
1144   if (fNextStatus == kStart)
1145     {
1146       Init();
1147     }
1148
1149   while (fNextStatus != kStop)
1150     { // !kStop
1151       NextData();
1152       
1153       switch (fNextStatus)
1154         {
1155         case kNextData:
1156           {
1157           if (DecodeNextRawWord() == kTRUE)
1158             {
1159               fTB += 3;
1160               if (fSig[0] > fRawDigitThreshold || fSig[1] > fRawDigitThreshold || fSig[2] > fRawDigitThreshold) 
1161                 return kTRUE;
1162             }
1163           }; break;
1164         case kNextMCM:
1165           {
1166             if (DecodeMCM() == kFALSE)
1167               AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));      
1168           }; break;
1169         case kNextHC:
1170         case kSeekNonEoTracklet:
1171         case kDecodeHC:
1172           {
1173             if (DecodeHC() == kFALSE)
1174               {
1175                 AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));     
1176               }
1177             else
1178               {
1179                 //the hc header should be decoded by now
1180                 if (fLastStatus == kDecodeHC)
1181                   {
1182                     fLastDET = fDET;
1183                     fChamberDone[fDET]++;
1184                   }
1185               }
1186           }; break;
1187         case kNextSM:
1188           {
1189             if (DecodeSM() == kFALSE)
1190                 AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));     
1191           }; break;
1192         case kStop:
1193           ; break;
1194         default:
1195           AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));  
1196           ChangeStatus(kStop);
1197         };
1198
1199     } // not kStop
1200
1201   //AliDebug(1, Form("That's all folks! %d", fSM));
1202   return kFALSE;
1203 }
1204
1205 //____________________________________________________________________________
1206 Int_t AliTRDRawStreamV2::NextChamber(AliTRDdigitsManager *man)
1207 {
1208   //
1209   // Fills single chamber digit array 
1210   // Return value is the detector number
1211   //
1212
1213   AliTRDdataArrayI *digits = 0;
1214   AliTRDdataArrayI *track0 = 0;
1215   AliTRDdataArrayI *track1 = 0;
1216   AliTRDdataArrayI *track2 = 0; 
1217   AliTRDSignalIndex *indexes = 0;
1218           
1219   if (fNextStatus == kStart)
1220     {
1221       Init();
1222     }
1223
1224 //   while (fNextStatus != kStop)
1225 //     { // !kStop
1226 //       NextData();
1227 //       // catch 3 things
1228 //       // 1) if end of raw data - if chamber complete return
1229 //       // 2) fill the data with signals if data decoded ok
1230 //       // 3) initialize (destroy old) after the det has changed -> just after HC header decoding
1231 //     } // not kStop
1232
1233   while (fNextStatus != kStop)
1234     { // !kStop
1235       NextData();
1236
1237       switch (fNextStatus)
1238         {
1239           
1240         case kNextData:
1241           {
1242             if (DecodeNextRawWord() == kTRUE)
1243               {
1244                 for (Int_t it = 0; it < 3; it++)
1245                   {
1246                     if ( fTB + it < fTBins )
1247                       {
1248                         if ( fSig[it] > fRawDigitThreshold )
1249                           {
1250                             digits->SetDataUnchecked(fROW, fCOL, fTB + it, fSig[it]);
1251                             indexes->AddIndexTBin(fROW, fCOL, fTB + it);
1252                             if (man->UsesDictionaries())
1253                               {
1254                                 track0->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1255                                 track1->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1256                                 track2->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1257                               } // if dictionaries
1258                           } // signal above zero
1259                       } // check the tbins range
1260                   } // for each tbin of current 3             
1261                 fTB += 3;
1262               }
1263             else
1264               {
1265                 // can be here as a fall back from decode raw data calling decodemcm
1266                 if (fEndOfDataFlag == kTRUE)
1267                   {
1268                     if (fChamberDone[fDET] == 2)
1269                       {
1270                         return fDET;
1271                       }                         
1272                     fEndOfDataFlag = kFALSE;
1273                   }             
1274               }
1275           }; break;
1276
1277         case kNextMCM:
1278           {
1279             if (DecodeMCM() == kFALSE)
1280               {
1281                 AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));    
1282               }
1283             // default place for end of raw data...
1284             if (fEndOfDataFlag == kTRUE)
1285               {
1286                 if (fChamberDone[fDET] == 2)
1287                   {
1288                     return fDET;
1289                   }                             
1290                 fEndOfDataFlag = kFALSE;
1291               }      
1292           }; break;
1293
1294         case kNextHC:
1295         case kSeekNonEoTracklet:
1296         case kDecodeHC:
1297           {
1298             if (DecodeHC() == kFALSE)
1299               {
1300                 AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));     
1301               }
1302             else
1303               {
1304                 //the hc header should be decoded by now
1305                 if (fLastStatus == kDecodeHC)
1306                   {
1307 //                  AliDebug(4, Form("???? New DET ???? %d last %d", fDET, fLastDET));
1308                     // allocate stuff for the new det
1309                     //man->ResetArrays();
1310                     digits = man->GetDigits(fDET);
1311                     track0 = man->GetDictionary(fDET,0);
1312                     track1 = man->GetDictionary(fDET,1);
1313                     track2 = man->GetDictionary(fDET,2);
1314                     
1315                     // Allocate memory space for the digits buffer
1316                     if (digits->GetNtime() == 0) 
1317                       {
1318 //                      AliDebug(5, Form("Alloc digits for det %d rows %d cols %d tbins %d", fDET, fRowMax, fColMax, fTBins));
1319                         digits->Allocate(fRowMax, fColMax, fTBins);
1320                         if (man->UsesDictionaries())
1321                           {
1322                             track0->Allocate(fRowMax, fColMax, fTBins);
1323                             track1->Allocate(fRowMax, fColMax, fTBins);
1324                             track2->Allocate(fRowMax, fColMax, fTBins);
1325                           }
1326                       }
1327                     
1328                     indexes = man->GetIndexes(fDET);
1329                     indexes->SetSM(fSM);
1330                     indexes->SetStack(fSTACK);
1331                     indexes->SetLayer(fLAYER);
1332                     indexes->SetDetNumber(fDET);
1333                     
1334                     if (indexes->IsAllocated() == kFALSE)
1335                       {
1336 //                      AliDebug(4, "Allocating indexes");            
1337                         indexes->Allocate(fRowMax, fColMax, fTBins);
1338                       }
1339                   } // is the HC header already decoded?
1340               } // decode hc ok
1341           }; break;
1342
1343         case kNextSM:
1344           {
1345             if (DecodeSM() == kFALSE)
1346               AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));       
1347           }; break;
1348
1349         case kStop:
1350           ; break;
1351
1352         default:
1353           AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));  
1354           ChangeStatus(kStop);
1355         };
1356
1357     } // not kStop
1358
1359   // we do not return chambers for which the end-of-data was not received twice (for each HC)
1360
1361   //AliDebug(1, Form("That's all folks! %d", fSM));
1362   //return kFALSE;
1363   return -1;
1364 }