]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDRawStreamTB.cxx
Test beam raw data reading
[u/mrichter/AliRoot.git] / TRD / AliTRDRawStreamTB.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 #include "AliTRDRawStreamTB.h"
34 #include "AliTRDgeometry.h"
35 #include "AliTRDcalibDB.h"
36 #include "AliTRDfeeParam.h"
37
38 #include "AliTRDdigitsManager.h"
39 #include "AliTRDdataArrayI.h"
40 #include "AliTRDSignalIndex.h"
41
42 #include "TMath.h"
43
44 using namespace AliTRDrawDataUtilsTB;
45
46 ClassImp(AliTRDRawStreamTB)
47
48 Bool_t AliTRDRawStreamTB::fgStackIndexBug=kFALSE;
49 Int_t  AliTRDRawStreamTB::fgForceRawVersion = -1;
50 Bool_t AliTRDRawStreamTB::fgSupressWarnings=kFALSE;
51 Bool_t AliTRDRawStreamTB::fgRawDataHack=kFALSE;
52 Bool_t AliTRDRawStreamTB::fgExtraDebug=kFALSE;
53
54 //_____________________________________________________________________________
55 AliTRDRawStreamTB::AliTRDRawStreamTB() 
56   :TObject()
57   ,fSig()
58   ,fADC(0)
59   ,fMaxADCgeom(-1)
60   ,fTB(0)
61   ,fEv(0)
62   ,fROB(0)
63   ,fMCM(0)
64   ,fSM(0)
65   ,fLAYER(0)
66   ,fSTACK(0)
67   ,fROC(0)
68   ,fSIDE(0)
69   ,fDCS(0)
70   ,fROW(0)
71   ,fCOL(0)
72   ,fDET(-1)
73   ,fLastDET(-1)
74   ,fBCctr(0)
75   ,fPTctr(0)
76   ,fPTphase(0)
77   ,fRVmajor(0)
78   ,fRVminor(0)
79   ,fHCHWords(0)
80   ,fTBins(0)
81   ,fTCon(0)
82   ,fPEDon(0)
83   ,fGAINon(0)
84   ,fXTon(0)
85   ,fNonLinOn(0)
86   ,fBypass(0)
87   ,fCommonAdditive(0)
88   ,fZeroSuppressed(0)
89   ,fHCHctr1(0)
90   ,fHCHctr2(0)
91   ,fMCMHctr1(0)
92   ,fMCMHctr2(0)
93   ,fGTUctr1(0)
94   ,fGTUctr2(0)
95   ,fHCdataCtr(0)
96   ,fTracklPID(0.)
97   ,fTracklDefL(0.)
98   ,fTracklPadPos(0.)
99   ,fTracklPadRow(0)
100   ,fGTUlinkMask()
101   ,fMCMWordCrt(0)
102   ,fMCMWordsExpected(0)
103   ,fRawReader(NULL)
104   ,fRawVersion(0)
105   ,fRawDigitThreshold(0)
106   ,fNextStatus(0)
107   ,fLastStatus(0)
108   ,fTbSwitch(0)
109   ,fTbSwitchCtr(0)
110   ,fTimeWords(0)
111   ,fWordCtr(0)
112   ,fRowMax(0)
113   ,fColMax(0)
114   ,fADCmask()
115   ,fLastADCmask(0)
116   ,fChamberDone()
117   ,fRetVal(0)
118   ,fEqID(0)
119   ,fDataSize(0)
120   ,fSizeOK(kFALSE)
121   ,fCountBytes(0)
122   ,fBufSize(0)
123   ,fkBufferSet(kFALSE)
124   ,fPos(NULL)
125   ,fDataWord(NULL)
126   ,fTimeBinsCalib(0)
127   ,fADClookup()
128   ,fNActiveADCs(0)
129   ,fEndOfDataFlag(kFALSE)
130   ,fHCInfo()
131   ,fMCMInfo()
132   ,fiSMx(0)
133   ,fSharedPadsOn(kFALSE)
134   ,fIsPadShared(kFALSE)
135   ,fGeo(NULL) 
136 {
137   //
138   // Default constructor
139   //
140
141   for (Int_t i = 0; i < 540; i++) {
142     fChamberDone[i] = 0;
143   }
144
145 }
146
147 //_____________________________________________________________________________
148 AliTRDRawStreamTB::AliTRDRawStreamTB(AliRawReader *rawReader) 
149   :TObject()
150   ,fSig()
151   ,fADC(0)
152   ,fMaxADCgeom(-1)
153   ,fTB(0)
154   ,fEv(0)
155   ,fROB(0)
156   ,fMCM(0)
157   ,fSM(0)
158   ,fLAYER(0)
159   ,fSTACK(0)
160   ,fROC(0)
161   ,fSIDE(0)
162   ,fDCS(0)
163   ,fROW(0)
164   ,fCOL(0)
165   ,fDET(-1)
166   ,fLastDET(-1)
167   ,fBCctr(0)
168   ,fPTctr(0)
169   ,fPTphase(0)
170   ,fRVmajor(0)
171   ,fRVminor(0)
172   ,fHCHWords(0)
173   ,fTBins(0)
174   ,fTCon(0)
175   ,fPEDon(0)
176   ,fGAINon(0)
177   ,fXTon(0)
178   ,fNonLinOn(0)
179   ,fBypass(0)
180   ,fCommonAdditive(0)
181   ,fZeroSuppressed(0)
182   ,fHCHctr1(0)
183   ,fHCHctr2(0)
184   ,fMCMHctr1(0)
185   ,fMCMHctr2(0)
186   ,fGTUctr1(0)
187   ,fGTUctr2(0)
188   ,fHCdataCtr(0)
189   ,fTracklPID(0.)
190   ,fTracklDefL(0.)
191   ,fTracklPadPos(0.)
192   ,fTracklPadRow(0)
193   ,fGTUlinkMask()
194   ,fMCMWordCrt(0)
195   ,fMCMWordsExpected(0)
196   ,fRawReader(rawReader)
197   ,fRawVersion(0)
198   ,fRawDigitThreshold(0)
199   ,fNextStatus(0)
200   ,fLastStatus(0)
201   ,fTbSwitch(0)
202   ,fTbSwitchCtr(0)
203   ,fTimeWords(0)
204   ,fWordCtr(0)
205   ,fRowMax(0)
206   ,fColMax(0)
207   ,fADCmask()
208   ,fLastADCmask(0)
209   ,fChamberDone()
210   ,fRetVal(0)
211   ,fEqID(0)
212   ,fDataSize(0)
213   ,fSizeOK(kFALSE)
214   ,fCountBytes(0)
215   ,fBufSize(0)
216   ,fkBufferSet(kFALSE)
217   ,fPos(NULL)
218   ,fDataWord(NULL)
219   ,fTimeBinsCalib(0)
220   ,fADClookup()
221   ,fNActiveADCs(0)
222   ,fEndOfDataFlag(kFALSE)
223   ,fHCInfo()
224   ,fMCMInfo()
225   ,fiSMx(0)
226   ,fSharedPadsOn(kFALSE)
227   ,fIsPadShared(kFALSE)
228   ,fGeo(NULL) 
229 {
230   //
231   // Create an object to read TRD raw digits
232   //
233
234   fRawReader->Select("TRD");
235
236   for (Int_t i = 0; i < 540; i++) {
237     fChamberDone[i] = 0;
238   }
239
240 }
241
242 //_____________________________________________________________________________
243 AliTRDRawStreamTB::AliTRDRawStreamTB(const AliTRDRawStreamTB& stream)
244   :TObject(stream)
245   ,fSig()
246   ,fADC(-1)
247   ,fMaxADCgeom(-1)
248   ,fTB(-1)
249   ,fEv(-1)
250   ,fROB(-1)
251   ,fMCM(-1)
252   ,fSM(-1)
253   ,fLAYER(-1)
254   ,fSTACK(-1)
255   ,fROC(-1)
256   ,fSIDE(-1)
257   ,fDCS(-1)
258   ,fROW(-1)
259   ,fCOL(-1)
260   ,fDET(-1)
261   ,fLastDET(-1)
262   ,fBCctr(-1)
263   ,fPTctr(-1)
264   ,fPTphase(-1)
265   ,fRVmajor(-1)
266   ,fRVminor(-1)
267   ,fHCHWords(-1)
268   ,fTBins(-1)
269   ,fTCon(0)
270   ,fPEDon(0)
271   ,fGAINon(0)
272   ,fXTon(0)
273   ,fNonLinOn(-1)
274   ,fBypass(-1)
275   ,fCommonAdditive(-1)
276   ,fZeroSuppressed(0)
277   ,fHCHctr1(-1)
278   ,fHCHctr2(-1)
279   ,fMCMHctr1(-1)
280   ,fMCMHctr2(-1)
281   ,fGTUctr1(-1)
282   ,fGTUctr2(-1)
283   ,fHCdataCtr(-1)
284   ,fTracklPID(-1.)
285   ,fTracklDefL(-1.)
286   ,fTracklPadPos(-1.)
287   ,fTracklPadRow(-1)
288   ,fGTUlinkMask()
289   ,fMCMWordCrt(0)
290   ,fMCMWordsExpected(0)
291   ,fRawReader(NULL)
292   ,fRawVersion(0)
293   ,fRawDigitThreshold(0)
294   ,fNextStatus(0)
295   ,fLastStatus(0)
296   ,fTbSwitch(0)
297   ,fTbSwitchCtr(0)
298   ,fTimeWords(0)
299   ,fWordCtr(0)
300   ,fRowMax(-1)
301   ,fColMax(-1)
302   ,fADCmask()
303   ,fLastADCmask(0)
304   ,fChamberDone()
305   ,fRetVal(0)
306   ,fEqID(0)
307   ,fDataSize(0)
308   ,fSizeOK(kFALSE)
309   ,fCountBytes(0)
310   ,fBufSize(0)
311   ,fkBufferSet(kFALSE)
312   ,fPos(NULL)
313   ,fDataWord(NULL)
314   ,fTimeBinsCalib(0)
315   ,fADClookup()
316   ,fNActiveADCs(0)
317   ,fEndOfDataFlag(kFALSE)
318   ,fHCInfo()
319   ,fMCMInfo()
320   ,fiSMx(0)
321   ,fSharedPadsOn(kFALSE)
322   ,fIsPadShared(kFALSE)
323   ,fGeo(NULL)
324 {
325   //
326   // Copy constructor
327   //
328
329   AliFatal("Copy constructor not implemented");
330
331 }
332
333 //_____________________________________________________________________________
334 AliTRDRawStreamTB& AliTRDRawStreamTB::operator = (const AliTRDRawStreamTB& 
335                                               /* stream */)
336 {
337   //
338   // Assigment operator
339   //
340
341   Fatal("operator =", "assignment operator not implemented");
342   return *this;
343
344 }
345
346 //_____________________________________________________________________________
347 AliTRDRawStreamTB::~AliTRDRawStreamTB()
348 {
349   //
350   // Destructor
351   //
352
353   if (fGeo) 
354     {  
355       delete fGeo;
356     }
357
358 }
359
360 //_____________________________________________________________________________
361 void AliTRDRawStreamTB::SetRawReader(AliRawReader *rawReader) 
362 {
363   //
364   // Set the rawreader
365   //
366
367   if (rawReader)
368     {
369       fRawReader = rawReader;
370     }
371 }
372
373 //_____________________________________________________________________________
374 Bool_t AliTRDRawStreamTB::SetRawVersion(Int_t rv)
375 {
376   //
377   // Set the raw data version
378   //
379
380   if ( rv >= 0 && rv <= 3 ) {
381     fRawVersion = rv;
382     return kTRUE;
383   }
384
385   return kFALSE;
386
387 }
388
389
390 //____________________________________________________________________________
391 Int_t AliTRDRawStreamTB::Init()
392 {
393   //
394   // Initialization
395   //
396
397   if (!AliTRDcalibDB::Instance()) {
398     AliError("Could not get calibration object");
399     return 0;
400   }
401
402   if (!fGeo) {
403     fGeo = new AliTRDgeometry();
404   }
405
406   fMaxADCgeom = (Int_t)fGeo->ADCmax();
407   
408   fTimeBinsCalib = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
409   //AliDebug(2, Form("Number of Timebins read from CDB: %d", fTimeBinsCalib));
410
411   // The number of data words needed for this number of time bins (there
412   // are 3 time bins in one word)
413   fTimeWords = (fTimeBinsCalib-1)/3 + 1;
414
415   fTbSwitch    = 3;
416   fTbSwitchCtr = 0;
417
418   fHCHctr1 = fHCHctr2 =  0;
419   fGTUctr1 = fGTUctr2 = -1;
420
421   fHCdataCtr = 0;
422   fWordCtr   = 0;  
423
424   fDET     =  -1;
425   fLastDET =  -1;
426   fRetVal = 0;
427   fEqID     = 0;
428   fDataSize = 0;
429   fSizeOK = kFALSE;
430   
431   fLastStatus = fkStart;
432   fNextStatus = fkStart;
433
434   fCountBytes = 0;
435   fBufSize = 0;
436   fDataWord = NULL;
437   fPos = NULL;
438   fWordCtr = 0;
439   fkBufferSet = kFALSE;
440
441   fMCMWordCrt = 0;
442   fMCMWordsExpected = 0;
443
444   fEndOfDataFlag = kFALSE;
445   // set all ADC active
446   fNActiveADCs = ChannelsToRead(0x1fffff); // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
447
448   fLastADCmask = 0;
449
450   //default value overwritten by HC header word h[2]
451   fCommonAdditive = 10;
452   //fSharedPadsOn = kFALSE;
453   //fSharedPadsOn = kTRUE;
454   fIsPadShared = kFALSE;
455   fZeroSuppressed = kFALSE;
456
457   return kTRUE;
458 }
459
460 //____________________________________________________________________________
461 void AliTRDRawStreamTB::SwapOnEndian()
462 {
463   //
464   // Check the endian and swap if needed
465   //
466
467   int itemp = 1;
468   char* ptemp = (char*) &itemp;
469   if (ptemp[0] != 1)
470     {
471       // need to swap...
472       // assume we are at the begining of the buffer!
473       //AliDebug(5, "Swapping.");
474       UInt_t *pbegin = (UInt_t*)fPos;
475       UInt_t iutmp = 0;
476       for (UInt_t i = 0; i < fBufSize / AliTRDrawDataUtilsTB::kSizeWord; i++)
477         {
478           fDataWord = pbegin + i;
479           iutmp = (((*fDataWord & 0x000000ffU) << 24) | ((*fDataWord & 0x0000ff00U) <<  8) |
480                    ((*fDataWord & 0x00ff0000U) >>  8) | ((*fDataWord & 0xff000000U) >> 24));
481           // here we override the value in the buffer!
482           *fDataWord = iutmp;
483         }
484       fDataWord = pbegin;
485     }
486 }
487
488 //____________________________________________________________________________
489 Int_t AliTRDRawStreamTB::NextData()
490 {
491   //
492   // Updates the next data word pointer
493   //
494
495   if (fCountBytes + kSizeWord >= fBufSize)
496     {
497       fkBufferSet = fRawReader->ReadNextData(fPos);
498       if (fkBufferSet == kTRUE)
499         {
500           fBufSize = fRawReader->GetDataSize();
501           fCountBytes = 0;        
502           fDataWord = (UInt_t*)fPos;
503           SwapOnEndian();
504           if (fgRawDataHack == kTRUE)
505             {
506               SkipWords(24);
507               fCountBytes += 24 * kSizeWord;
508               //fgRawDataHack = kFALSE;
509             }
510           ChangeStatus(fkNextSM);
511           fWordCtr = 0;
512           AliDebug(3, "NextSM. Buffer is set.");
513           return fkNextSM;
514         }
515       else
516         {
517           //AliDebug(3, "No more data!");
518           ChangeStatus(fkStop);
519           ChangeStatus(fkNoMoreData);
520           return fkNoMoreData;
521         }
522     }
523   else
524     {
525       fPos += kSizeWord;
526       fCountBytes += kSizeWord;   
527       fDataWord = (UInt_t*)fPos;
528       fWordCtr++;
529       AliDebug(10, Form("Current word %d : 0x%x at 0x%x. Count bytes %d of %d", 
530                         fWordCtr, *fDataWord, fPos, fCountBytes, fBufSize));
531       //       if (fCountBytes > 3080000)
532       //        printf("Current word %d : 0x%x at 0x%x. Count bytes %d of %d\n", 
533       //               fWordCtr, *fDataWord, fPos, fCountBytes, fBufSize);
534       return fkWordOK;
535     }
536 }
537
538 //____________________________________________________________________________
539 Int_t AliTRDRawStreamTB::RewindWord()
540 {
541   //
542   // Updates the next data word pointer
543   //
544   
545   if (fkBufferSet == kFALSE)
546     return fkStart;
547
548   if (fCountBytes > 0)
549     {
550       fPos -= kSizeWord;
551       fCountBytes -= kSizeWord;   
552       fDataWord = (UInt_t*)fPos;
553       fWordCtr--;      
554     }
555   else
556     {
557       AliWarning("Already at the begining of the buffer");
558     }
559   
560   return fkWordOK;
561 }
562
563 //============================================================================
564 // Decoding functions
565 //============================================================================
566
567 //____________________________________________________________________________
568 void AliTRDRawStreamTB::DecodeHCheader(Int_t timeBins)
569 {
570   //
571   // Decode the HC header (fRawVersion == 2, 3, 4, ???)
572   //
573   //AliDebug(3, "Here");
574     
575   // 1st word (h[0])
576   if ( (*fDataWord & 0x3) == 1 ) 
577     {
578       
579       fHCInfo.DecodeH0(fDataWord);
580       if (fgExtraDebug)
581         fHCInfo.Dump();
582       
583       fHCHWords = fHCInfo.fNExtraWords;
584       fSM       = fHCInfo.fSM;
585       fLAYER    = fHCInfo.fLayer;
586       fSTACK    = fHCInfo.fStack;
587       fSIDE     = fHCInfo.fSide;
588
589       fRVmajor  = fHCInfo.fRawVMajor;
590       fRVminor  = fHCInfo.fRawVMinor;
591       
592       //assuming valid raw version w/o ZS
593       if (fRVmajor <= 0)
594         fRVmajor = 2;
595
596       if ( fRawVersion != fRVmajor ) 
597         {
598           if (fgSupressWarnings == kTRUE)
599             {
600               if (fgForceRawVersion > 0)
601                 {
602                   fRawVersion = fgForceRawVersion;
603                 }
604               else
605                 {
606                   fRawVersion = fRVmajor;       
607                 }      
608             }
609           else
610             {
611               AliWarning("===============================================================================");
612               AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
613                               ,fRawVersion,fRVmajor));
614               if (fgForceRawVersion > 0)
615                 {
616                   AliWarning(Form("Forcing fRawVersion to %d", fgForceRawVersion));
617                   fRawVersion = fgForceRawVersion;
618                 }
619               else
620                 {
621                   AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
622                   fRawVersion = fRVmajor;       
623                 }
624               AliWarning("===============================================================================");
625             } //warn or not
626         }//if raw version missmatch
627
628       //AliInfo(Form("Raw Version %d", fRawVersion));
629       
630       //
631       // check for zero suppression
632       if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
633       else                                        fZeroSuppressed = kFALSE;
634     
635       fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
636       
637       AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", *fDataWord, fSM, fROC, fSIDE+10));
638       AliDebug(5, Form("0x%08x: HC header: expecting %d HC words", *fDataWord, fHCHWords));
639
640       if ((fSM    <  0) || 
641           (fSM    > 17) || 
642           (fLAYER <  0) || 
643           (fLAYER >  5) || 
644           (fSTACK <  0) || 
645           (fSTACK >  4) || 
646           (fSIDE  <  0) || 
647           (fSIDE  >  1)) 
648         {
649           AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
650                           *fDataWord, fDCS, fSM, fLAYER, fSTACK));
651           fRawReader->AddMajorErrorLog(kHCHeaderCorrupt,Form("0x%08x:dcs=%d; sm=%d; layer=%d; stack=%d.",
652                                                              *fDataWord, fDCS, fSM, fLAYER, fSTACK));
653         } 
654       else 
655         {
656           fHCHctr1++;
657           fHCHctr2++;
658         }
659     } 
660   else 
661     { 
662       AliWarning(Form("0x%08x: No HC header when it was expected.", *fDataWord)); 
663       fRawReader->AddMajorErrorLog(kHCHeaderMissing,Form("0x%08x", *fDataWord));
664     }
665
666   // 2nd word (h[1])
667   if ( fHCHWords >= 1 ) 
668     {
669       // read one more word
670       if (NextData() != fkWordOK)
671         {
672           AliWarning("Next HC ( H[1] ) word missing");
673           fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC ( H[1] )word missing"); 
674           ChangeStatus(fkNextHC);
675           return;
676         }
677
678       if ( (*fDataWord & 0x3) == 1 ) 
679         {
680
681           fHCInfo.DecodeH1(fDataWord);
682           
683           fBCctr   = fHCInfo.fBunchCrossCounter;
684           fPTctr   = fHCInfo.fPreTriggerCounter;
685           fPTphase = fHCInfo.fPreTriggerPhase;
686           fTBins   = fHCInfo.fTimeBins;
687           
688           fTimeWords = (fTBins - 1)/3 + 1;      
689           
690           AliDebug(3, Form("0x%08x: HC header [1]: BCctr=%d PTctr=%d PTph=%d TB=%d"
691                            , *fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
692
693           if( fTBins != timeBins ) 
694             {         
695               if (fgSupressWarnings == kTRUE)
696                 {
697                   fTimeWords = (fTBins - 1)/3 + 1;      
698                 }
699               else
700                 {
701                   AliWarning("===============================================================================");
702                   AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
703                                 , timeBins, fTBins));
704                   AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
705                   AliWarning("===============================================================================");                  
706                   fTimeWords = (fTBins - 1)/3 + 1;      
707                 }
708             }
709         }      
710     }
711
712   // 3nd word (h[2])
713   if ( fHCHWords >= 2 ) 
714     {
715       // read one more word
716       if (NextData() != fkWordOK)
717         {
718           AliWarning("Next HC ( [2] )word missing");
719           fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC ( [2] ) word missing"); 
720           ChangeStatus(fkNextHC);
721           return;
722         }
723
724       if ( (*fDataWord & 0x3) == 1 ) 
725         {
726        
727           fTCon     = (*fDataWord >> 29) & 0x1;
728           fPEDon    = (*fDataWord >> 31) & 0x1;
729           fGAINon   = (*fDataWord >> 30) & 0x1;
730           fXTon     = (*fDataWord >> 28) & 0x1;
731           fNonLinOn = (*fDataWord >> 27) & 0x1;
732           fBypass   = (*fDataWord >> 26) & 0x1;
733
734           fCommonAdditive = (*fDataWord >> 20) & 0x3f;
735
736           AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
737                            , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
738         }
739     }
740
741   if (fTBins <= 0)
742     {
743       fTBins = 30;
744       fTimeWords = (fTBins - 1)/3 + 1;  
745       AliDebug(5, Form("Forced tbins %d timewords %d", fTBins, fTimeWords));
746     }
747 }  
748
749 //____________________________________________________________________________
750 Int_t AliTRDRawStreamTB::ChannelsToRead(Int_t ADCmask)
751 {
752   //AliDebug(3, "Here");
753   memset(fADClookup, -1, 32 * sizeof(Int_t));
754   fADClookup[0] = 0; // count entries
755   fADClookup[1] = 2; // index - data start at 2
756   UInt_t mask = 0;
757   for (Int_t i = 0; i < 30; i++)
758     {
759       mask = 1 << i;
760       if ((ADCmask & mask))
761         {
762           //AliDebug(9, Form("fDataWord=0x%08x mask=0x%08x i=%d", *fDataWord, mask, i));
763           fADClookup[fADClookup[1]] = i;
764           ++fADClookup[0];
765           ++fADClookup[1];
766         }
767     }
768
769   // test the iteration - comment out for production
770   // begin of comment out section
771 //   char schannels[512];
772 //   sprintf(schannels, "ADC Channels to read: ");
773 //   fADClookup[1] = 2;
774 //   while(fADClookup[1] - 2 < fADClookup[0])
775 //     {
776 //       AliDebug(9, Form("max=%d index=%d adc=%d", fADClookup[0], fADClookup[1], fADClookup[fADClookup[1]]));
777 //       strcat(schannels, Form("%d ", fADClookup[fADClookup[1]]));
778 //       fADClookup[1]++;
779 //     }
780   //AliDebug(9, Form("%s", schannels));
781   //AliDebug(9, Form("ADC channels = %d", fADClookup[0]));
782   // end of comment out section
783
784   fADClookup[1] = 2;
785   return fADClookup[0];
786 }
787
788 //____________________________________________________________________________
789 void AliTRDRawStreamTB::DecodeTracklet()
790 {
791
792   //
793   // Decode the Tracklet
794   //
795   // this function is not tested yet on real tracklets
796   //
797   //AliDebug(3, "Here");
798 //   if ( fRawVersion < 1 || fRawVersion > 3 ) 
799 //     {
800 //       AliError(Form(" Unsupported raw version: %d", fRawVersion));      
801 //     }
802
803   fTracklPID    = (*fDataWord >> 24) & 0xff;
804   fTracklPadRow = (*fDataWord >> 20) & 0xf;    // 0:15
805   fTracklDefL   = (*fDataWord >> 13) & 0x7f;
806   fTracklPadPos = (*fDataWord)       & 0x1fff;
807
808   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
809   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
810   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
811
812   AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
813                    , *fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
814                    , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
815
816   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
817       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
818     AliWarning(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
819     fRawReader->AddMajorErrorLog(kTrackletRowMismatch,Form("Word: %d", fTracklPadRow));
820   }
821
822 }
823
824 //____________________________________________________________________________
825 void AliTRDRawStreamTB::DecodeMCMheader()
826 {
827
828   //
829   // Decode the MCM header
830   //
831   //AliDebug(3, "Here");
832
833   if ( fRawVersion < 0 || fRawVersion > 3 ) 
834     {
835       AliError(Form(" Unsupported raw version: %d", fRawVersion));      
836     }
837
838   fMCMInfo.Decode(fDataWord);
839   
840   fMCM = fMCMInfo.fMCM;
841   fROB = fMCMInfo.fROB;
842   fEv  = fMCMInfo.fEvCounter;
843   if (fgExtraDebug)
844     fMCMInfo.Dump();
845
846   fROW  = AliTRDfeeParam::Instance()->GetPadRowFromMCM(fROB, fMCM);
847   
848   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
849                    , *fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
850
851   if ( fROB % 2 == 0 && fSIDE == 1 ) 
852     {
853       AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
854                       , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
855       fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
856                                                          , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
857     }
858
859   if ( fROB % 2 != 0 && fSIDE == 0 ) 
860     {
861       AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
862                       , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
863       fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
864                                                          , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
865     }
866
867   if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
868        (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 ) 
869     {
870       AliWarning(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
871                       , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
872       fRawReader->AddMajorErrorLog(kWrongPadrow,Form("SM%d L%dS%d: Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
873                                                      , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
874     }
875   
876   fMCMHctr1++;
877   fMCMHctr2++;
878
879   fMCMWordCrt = 1; // MCM header
880
881   // AdcMask for Zero supressed data
882   if ( fRawVersion == 3 ) 
883     {
884       // read one more word
885       if (NextData() != fkWordOK)
886         {
887           AliWarning("MCM ADC mask missing");
888           fRawReader->AddMajorErrorLog(kMCMADCMaskMissing,"Missing"); 
889           fNextStatus = fkNextHC;
890           return;
891         }
892       else
893         {
894           ++fMCMWordCrt;
895
896           for ( Int_t ctr = 0; ctr < fMaxADCgeom; ctr++ ) {
897             if ( (*fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
898             else                                  fADCmask[ctr] = kFALSE;
899           }
900
901           if (*fDataWord & 0xf != 0xc)
902             {
903               AliWarning(Form("ADC mask does not end with 0xc : 0x%x", *fDataWord));
904             }
905
906           //AliDebug(4, Form("0x%08x: ADC mask", *fDataWord));
907           // 7 MSbits are ignored!
908           UInt_t maskWord = (*fDataWord >> 4) & 0x1fffff;
909           fNActiveADCs = ChannelsToRead(maskWord);        
910         }
911     }
912
913   if (fRawVersion <= 2)
914     {
915       fNActiveADCs = ChannelsToRead(0x1fffff); // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
916       //directly get it like that:
917       fMCMWordsExpected = 1 + fNActiveADCs * fTBins / 3;      
918     }
919
920   if (fRawVersion >= 3)
921     {
922       // raw version 3:
923       //directly get it like that:
924       fMCMWordsExpected = 1 + 1 + (fTBins * fNActiveADCs) / 3;
925     }
926   
927   AliDebug(8, Form("TBins %d fNActiveADCs %d => We expect %d MCM words. We read %d so far.", fTBins, fNActiveADCs, fMCMWordsExpected, fMCMWordCrt));
928 }
929
930 //____________________________________________________________________________
931 Bool_t AliTRDRawStreamTB::DecodeADCWord()
932 {
933   // Decode ADC word for any pad
934   // Rearange this function!!!
935   //AliDebug(3, "Here");
936   Bool_t kIsDataOK = kFALSE;
937   
938   // Get Pad column
939   // fCOL = fFee->GetPadColFromADC(fROB, fMCM, fADC);
940   if ( fADC >= fMaxADCgeom - 1)
941     {
942       // let us guess the Column
943       // take the one before last ADC and shift by one column
944       // later we check if we are inside the limits of the chamber
945       fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fROB, fMCM, fADC - 1);
946       fCOL--;
947       //AliDebug(8, Form("-x fADC %d fCOL %d", fADC, fCOL));
948       if (fCOL >= fColMax || fCOL < 0)
949         {
950           //AliDebug(8, Form("-xx fADC %d fCOL %d", fADC, fCOL));
951           fCOL = -1;
952           kIsDataOK = kFALSE;
953           return kIsDataOK;
954         }
955     }
956   else
957     {
958       //AliDebug(8, Form("-y fADC %d fCOL %d", fADC, fCOL));
959       fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fROB, fMCM, fADC);
960       if (fCOL >= fColMax || fCOL < 0)
961         {
962           //AliDebug(8, Form("-xx fADC %d fCOL %d", fADC, fCOL));
963           fCOL = -1;
964           kIsDataOK = kFALSE;
965           return kIsDataOK;
966         }
967     }
968
969   // We have only 144 Pad Columns
970   //if ( fCOL > fColMax-1 || fCOL < 0 ) 
971   if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax ) 
972     {
973       // Decode 32 bit data words with information from 3 time bins and copy the data
974       fSig[0] = (*fDataWord & 0x00000ffc) >> 2;
975       fSig[1] = (*fDataWord & 0x003ff000) >> 12;
976       fSig[2] = (*fDataWord & 0xffc00000) >> 22;
977             
978       // Print data to screen:
979       AliDebug(5, Form("DATA : 0x%x tTbin %d", *fDataWord, fTB));
980       AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
981                        fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));        
982       kIsDataOK = kTRUE;
983     }
984   else
985     {
986       AliWarning(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
987                       fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
988       fRawReader->AddMajorErrorLog(kWrongPadcolumn,Form("SM%d L%dS%d: column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
989                                                         fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
990       kIsDataOK = kFALSE;
991     }
992   
993   return kIsDataOK;
994 }
995
996 //____________________________________________________________________________
997 Bool_t AliTRDRawStreamTB::DecodeNextRawWord()
998 {
999   //AliDebug(8, Form("-----------------------------------------"));
1000   //AliDebug(8, Form("DATA IS 0x%x", *fDataWord));
1001   
1002   //AliDebug(3, "Here");
1003   if ( *fDataWord == kEndOfRawDataMarker ) 
1004     {  // End of half-chamber data, finished
1005       AliDebug(3, "We have reached the eof data. Next should be HC header.");
1006       fGTUctr1 = -1;
1007       ChangeStatus(fkNextHC);
1008       fEndOfDataFlag = kTRUE;
1009       return kFALSE;
1010     }
1011
1012   if (fADClookup[1] - 2 > fADClookup[0])
1013     {
1014       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?", 
1015                        fADClookup[1] - 2, fADClookup[0], fADClookup[fADClookup[1]], *fDataWord));
1016       fTB = 0;    
1017       fTbSwitchCtr = 0;
1018       fMCMWordsExpected = 0;
1019       AliWarning("Trying to recover. Fall back to DecodeMCM.");
1020       RewindWord();
1021       ChangeStatus(fkNextMCM);
1022       return kFALSE;
1023     }
1024
1025   if ( (*fDataWord & 0x00000003) != 0x2 && (*fDataWord & 0x00000003) != 0x3) 
1026     {
1027       AliWarning(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)*fDataWord));
1028       fRawReader->AddMinorErrorLog(kDataMaskError,Form("Data %08x", (Int_t)*fDataWord));
1029       fMCMWordsExpected = 0;
1030       fTB = 0;    
1031       fTbSwitchCtr = 0;
1032       AliWarning("Trying to recover. Fall back to DecodeMCM.");
1033       RewindWord();
1034       ChangeStatus(fkNextMCM);
1035       return kFALSE;
1036   }
1037
1038   if ( (*fDataWord & 0x3) != fLastADCmask || fTbSwitchCtr >= fTimeWords) 
1039     {    
1040       fADC = fADClookup[fADClookup[1]];
1041       AliDebug(8, Form("Next fADC = %d at index = %d MCM Word Number: %d Max MCM Words is %d", 
1042                        fADC, fADClookup[1] - 2, fMCMWordCrt, fMCMWordsExpected));
1043       AliDebug(10, Form("LastMask 0x%x this data 0x%x OR fTbSwitchCtr %d  >= fTimeWords %d", 
1044                         fLastADCmask, (*fDataWord) & 0x3, fTbSwitchCtr, fTimeWords));
1045       if ((*fDataWord & 0x3) != fLastADCmask && fTbSwitchCtr < fTimeWords && fTbSwitchCtr > 0)
1046         {
1047           AliWarning(Form("Change of mask! But not all words read!"));
1048           AliWarning(Form("Next fADC = %d at index = %d MCM Word Number: %d Max MCM Words is %d", 
1049                              fADC, fADClookup[1] - 2, fMCMWordCrt, fMCMWordsExpected));
1050           AliWarning(Form("LastMask 0x%x this data 0x%x OR fTbSwitchCtr %d  >= fTimeWords %d", 
1051                           fLastADCmask, (*fDataWord) & 0x3, fTbSwitchCtr, fTimeWords));
1052         }
1053       ++fADClookup[1];
1054       fTB = 0;    
1055       fTbSwitchCtr = 0;
1056       ChangeStatus(fkNextData);
1057       fLastADCmask = (*fDataWord) & 0x3;
1058     }
1059
1060   ++fTbSwitchCtr;
1061
1062   //decode data here
1063   Bool_t kIsDataOK = kFALSE;
1064
1065   // We have only 21 ADC channels.
1066   if ( fADC > fMaxADCgeom - 1 || fADC < 0) 
1067     {
1068       AliWarning(Form("Data 0x%08x : Data is strange. fADC is %d", (Int_t)*fDataWord, (Int_t)fADC));
1069       AliWarning(Form("fADClookup[0] %d fADClookup[1] %d", fADClookup[0], fADClookup[1]));
1070       fRawReader->AddMinorErrorLog(kADCChannelOverflow,Form("Data %08x : fADC=%d", (Int_t)*fDataWord, (Int_t)fADC));
1071     }
1072   else
1073     {
1074       // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
1075       // MCMs and are good for online tracking in the MCM.
1076       if (fSharedPadsOn == kTRUE)
1077         {
1078           kIsDataOK = DecodeADCWord();
1079           if (fADC <= 1 || fADC == fMaxADCgeom - 1)
1080             {
1081               AliDebug(9, Form("Shared Pad fADC == %d", fADC));
1082               fIsPadShared = kTRUE;
1083             }
1084           else
1085             {
1086               fIsPadShared = kFALSE;          
1087             }
1088         }
1089       else
1090         {
1091           if ( fADC > 1 && fADC < fMaxADCgeom - 1 ) 
1092             {
1093               kIsDataOK = DecodeADCWord();
1094             }
1095           else 
1096             {      
1097               AliDebug(9, Form("fADC not accepted - shared pad %d - DATA : 0x%x", fADC, *fDataWord));
1098               fCOL = -1;
1099               kIsDataOK = kFALSE;
1100             }
1101         }
1102     }// if fADC is ok
1103
1104   ++fMCMWordCrt;
1105   AliDebug(8, Form("We expect %d MCM words. We read %d so far.Current word is 0x%x", fMCMWordsExpected, fMCMWordCrt, *fDataWord));
1106
1107   // all mcm data processed go to next one
1108   if ( fMCMWordCrt >= fMCMWordsExpected)
1109     {
1110       AliDebug(8, Form("We expect %d MCM words. We read %d so far. Going to next MCM.", fMCMWordsExpected, fMCMWordCrt));
1111       ChangeStatus(fkNextMCM);
1112     }
1113   
1114   return kIsDataOK;
1115 }
1116
1117 //____________________________________________________________________________
1118 Bool_t AliTRDRawStreamTB::DecodeMCM()
1119 {
1120   fTbSwitch    = 3;  // For first adc channel we expect: (*fDataWord & 3) = 3
1121   fTbSwitchCtr = 0;  // 
1122   fADC = fTB   = 0;  // Reset Counter
1123   fLastADCmask = 0; // Reset
1124
1125   //AliDebug(3, "Here");
1126
1127   //if( ((*fDataWord & 0x80000000) == 0x0) && ((*fDataWord & 0x0000000f) == 0xC) )
1128   //if( ((*fDataWord & 0xf0000000) == 0x80000000) && ((*fDataWord & 0x0000000f) == 0xC) )
1129   if( (*fDataWord & 0x0000000f) == 0xC ) 
1130     { // MCM Header
1131       // this changed the status
1132       DecodeMCMheader();
1133       if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 ) 
1134         {
1135           AliWarning("Wrong fMCM or fROB. Skip this data");
1136           fRawReader->AddMajorErrorLog(kWrongMCMorROB,Form("MCM=%d, ROB=%d",fMCM,fROB));
1137           ChangeStatus(fkNextHC);
1138           return kFALSE;
1139         }
1140
1141       if (fMCMWordCrt < fMCMWordsExpected)
1142         {
1143           AliDebug(5, Form("Going to read data."));
1144           ChangeStatus(fkNextData);
1145         }
1146       else
1147         {
1148           //AliDebug(5, Form("! fMCMWordCrt < fMCMWordsExpected"));
1149           ChangeStatus(fkNextMCM);
1150         }
1151       //fEndOfDataFlag = kFALSE;
1152       return kTRUE;
1153     }
1154
1155   if ( *fDataWord == kEndOfRawDataMarker ) 
1156     {  // End of half-chamber data, finished
1157       AliDebug(10, "We have reached the eof data. Next should be HC header.");
1158       fGTUctr1 = -1;
1159
1160       ChangeStatus(fkNextHC);
1161       fEndOfDataFlag = kTRUE;
1162       //AliDebug(5, "Expecting MCM header but got End-Of-Raw-Data Marker");
1163       if (fMCMWordsExpected == 0 || fMCMWordsExpected == fMCMWordCrt)
1164         {
1165           AliDebug(5, Form("Got all mcm words. Returning true."));
1166           return kTRUE;
1167         }
1168       else
1169         {
1170           AliDebug(5, Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));      
1171           //AliWarning(Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));     
1172           return kFALSE;
1173         }
1174     }
1175
1176   //AliDebug(3, Form("Expecting MCM header but got 0x%x. Going to Next MCM header.", *fDataWord));
1177   AliWarning(Form("Expecting MCM header but got 0x%x. Fall back: Next MCM header.", *fDataWord));
1178   ChangeStatus(fkNextMCM);      
1179
1180   return kFALSE;
1181 }
1182
1183 //____________________________________________________________________________
1184 Bool_t AliTRDRawStreamTB::DecodeHC()
1185 {
1186   //AliDebug(3, "Here");
1187
1188   // left overs from the last chamber?
1189   if (*fDataWord == kEndOfRawDataMarker)
1190     {
1191       AliDebug(3, "We have reached the eof data. Next should be HC header or end of the event!");
1192       ChangeStatus(fkNextHC);
1193       return kFALSE;
1194     }
1195
1196 //   if (kFALSE == fSMinfo[fiSMx].fTrackletEnable)
1197 //     {
1198 //       // jump to data decoding - no traklets to expect
1199 //       ChangeStatus(fkDecodeHC);
1200 //     }
1201 //   else
1202 //     {
1203 //       ChangeStatus(fkNextHC);
1204 //     }
1205
1206   if ( fNextStatus == fkNextHC && fSMinfo[fiSMx].fTrackletEnable == kTRUE)
1207     {
1208       //AliDebug(5, "fkNextHC");
1209       //
1210       // 1) Find end_of_tracklet_marker if tracklets present!
1211       //
1212       // GTU Link Mask?
1213
1214       // endoftrackletmarker?
1215       if ( *fDataWord == kEndOfTrackletMarker ) 
1216         {
1217           AliDebug(3, "End-of-tracklet-marker found");
1218           AliDebug(5, Form("Data 0x%x", *fDataWord));
1219           ChangeStatus(fkSeekNonEoTracklet);
1220           return kTRUE;
1221         } 
1222       else 
1223         {
1224           // Tracklets found
1225           //AliDebug(3, "Tracklet found");
1226           AliDebug(5, Form("Tracklet data 0x%x", *fDataWord));
1227           DecodeTracklet();
1228           return kTRUE;
1229         }
1230     } // if next HC
1231   else
1232     {
1233       if (fSMinfo[fiSMx].fTrackletEnable == kFALSE)
1234         ChangeStatus(fkDecodeHC);
1235     }
1236
1237   if (fNextStatus == fkSeekNonEoTracklet)
1238     {
1239       AliDebug(5, "fkSeekNonEoTracklet");
1240
1241       //
1242       // 2) Look for non-end_of_tracklet_marker
1243       //
1244       //printf("Word %d: 0x%08x\n", fWordCtr, *fDataWord); 
1245       
1246       if ( *fDataWord != kEndOfTrackletMarker ) 
1247         {
1248           ChangeStatus(fkDecodeHC);
1249           AliDebug(3, "NON end-of-tracklet-marker found");
1250           AliDebug(5, Form("Data 0x%x", *fDataWord));
1251           //// no do not continue - this should be the hcheader
1252         }
1253       else
1254         {
1255           //just go on and find the non-end_of_tracklet_marker
1256           return kTRUE;
1257         }
1258     }
1259
1260   if ( fNextStatus == fkDecodeHC )
1261     {
1262       AliDebug(5, "fkDecodeHC");
1263       
1264       //
1265       // 3) This Word must be Half Chamber Header
1266       //
1267       if ( (*fDataWord & 0xf0000000) == 0x80000000 && (*fDataWord & 0x00000003) == 1 ) 
1268         { // HC header
1269           AliDebug(5, Form("Is this the HC header? 0x%x", *fDataWord));
1270           DecodeHCheader(fTimeBinsCalib); // This is the new header!
1271           fLastDET = fDET;
1272           fDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
1273           fRowMax = fGeo->GetRowMax(fLAYER,fSTACK,fSM);
1274           fColMax = fGeo->GetColMax(fROC);
1275           
1276           fMCMHctr2 = 0;
1277           fHCdataCtr = 0;
1278           fChamberDone[fDET]++;
1279           AliDebug(2, Form("--------------      DET %d fChamberDone[fDET]=%d", fDET, fChamberDone[fDET]));
1280
1281           ChangeStatus(fkNextMCM);
1282           return kTRUE;
1283         } //HC header
1284       else
1285         {
1286           AliWarning(Form("Expecting HC header mask but got 0x%x. Fall back: Next HC.", *fDataWord));
1287           ChangeStatus(fkNextHC);
1288           // before we went to //ChangeStatus(fkNextSM);
1289         }
1290     } // if decode HC
1291   
1292   return kFALSE;
1293 }
1294 //____________________________________________________________________________
1295 Bool_t AliTRDRawStreamTB::DecodeGTUlinkMask()
1296 {
1297   //
1298   // Decode the link masks sent by the GTU. These marke the active optical links
1299   // between GTU and Super Module. Up to now only fully active links are found
1300   // (0xfff = 12 active links).
1301   //
1302
1303   if ( (*fDataWord & 0xfffff000) ==  0xe0000000 )
1304     {
1305       if ( fRawVersion < 1 || fRawVersion > 3 ) 
1306         {
1307           AliError(Form(" Unsupported raw version: %d", fRawVersion));      
1308         }
1309       
1310       if ( fGTUctr1 == -1 ) fGTUctr2++;
1311       fGTUctr1++;
1312
1313       if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) 
1314         {
1315           fGTUlinkMask[fGTUctr2][fGTUctr1] = (*fDataWord & 0xfff);
1316         }
1317      
1318       //AliDebug(5, Form("GTU link mask 0x%x decoded 0x%x", *fDataWord, fGTUlinkMask[fGTUctr2][fGTUctr1]));
1319       return kTRUE;
1320     }
1321
1322   return kFALSE;
1323 }
1324
1325 // //____________________________________________________________________________
1326 void AliTRDRawStreamTB::ChangeStatus(Int_t kstat)
1327 {
1328   fLastStatus = fNextStatus;
1329   fNextStatus = kstat;  
1330 }
1331
1332 //____________________________________________________________________________
1333 Bool_t AliTRDRawStreamTB::DecodeSM()
1334 {
1335   fLastDET  = -1;
1336   fDET      = -1;
1337   fRetVal   = 0;
1338   fEqID     = 0;
1339   fDataSize = 0;
1340   fSizeOK = kFALSE;
1341
1342   Int_t status = DecodeHeadingInfo();
1343   if (status == fkWordOK)
1344     {    
1345       ChangeStatus(fkNextHC);
1346       return kTRUE;
1347     } 
1348   else 
1349     {
1350       AliWarning(Form("Decoding SM info failed. Fall back: None. Stop.", fEqID));
1351       fRawReader->AddMajorErrorLog(kGTULinkMaskMissing,Form("Equipment %d",fEqID));
1352       ChangeStatus(fkStop);
1353     }       
1354
1355   return kFALSE;
1356 }
1357
1358 //____________________________________________________________________________
1359 Bool_t AliTRDRawStreamTB::Next()
1360 {
1361   //
1362   // Updates the next data word pointer
1363   //
1364
1365   if (fNextStatus == fkStart)
1366     {
1367       Init();
1368     }
1369
1370   while (fNextStatus != fkStop && fNextStatus != fkNoMoreData)
1371     { // !fkStop
1372       NextData();
1373       
1374       switch (fNextStatus)
1375         {
1376         case fkNextData:
1377           {
1378             if (DecodeNextRawWord() == kTRUE)
1379               {
1380                 fTB += 3;
1381                 if (fTB - 3 > 29)
1382                   {
1383                     AliWarning(Form("Invalid time bin %d. sm %d det %d rob %d col %d row %d mcm=%d adc=%d ", fTB-3, fSM, fDET, fROB, fCOL, fROW, fMCM, fADC));
1384                     AliWarning(Form("max=%d index=%d adc=%d", fADClookup[0], fADClookup[1], fADClookup[fADClookup[1]-1]));
1385                   }
1386                 if (fSig[0] > fRawDigitThreshold || fSig[1] > fRawDigitThreshold || fSig[2] > fRawDigitThreshold) 
1387                   return kTRUE;
1388               }
1389           }; break;
1390         case fkNextMCM:
1391           {
1392             if (DecodeMCM() == kFALSE)
1393               AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));      
1394           }; break;
1395         case fkNextHC:
1396         case fkSeekNonEoTracklet:
1397         case fkDecodeHC:
1398           {
1399             if (DecodeHC() == kFALSE)
1400               {
1401                 if (*fDataWord == kEndOfRawDataMarker)
1402                   {
1403                     AliDebug(2, Form("End of data at 0x%x", fPos));
1404                   }
1405                 else
1406                   {
1407                     AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));         
1408                   }
1409               }
1410           }; break;
1411         case fkNextSM:
1412           {
1413             if (DecodeSM() == kFALSE)
1414                 AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));     
1415           }; break;
1416         case fkNoMoreData:
1417         case fkStop:
1418           ; break;
1419         default:
1420           AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));  
1421           ChangeStatus(fkStop);
1422         };
1423
1424     } // not fkStop
1425
1426   //AliDebug(1, Form("That's all folks! %d", fSM));
1427   return kFALSE;
1428 }
1429
1430 //____________________________________________________________________________
1431 Int_t AliTRDRawStreamTB::NextChamber(AliTRDdigitsManager *man)
1432 {
1433   //
1434   // Fills single chamber digit array 
1435   // Return value is the detector number
1436   //
1437
1438   AliTRDdataArrayI *digits = 0;
1439   AliTRDdataArrayI *track0 = 0;
1440   AliTRDdataArrayI *track1 = 0;
1441   AliTRDdataArrayI *track2 = 0; 
1442   AliTRDSignalIndex *indexes = 0;
1443           
1444   if (fNextStatus == fkStart)
1445     {
1446       Init();
1447     }
1448
1449 //   while (fNextStatus != fkStop)
1450 //     { // !fkStop
1451 //       NextData();
1452 //       // catch 3 things
1453 //       // 1) if end of raw data - if chamber complete return
1454 //       // 2) fill the data with signals if data decoded ok
1455 //       // 3) initialize (destroy old) after the det has changed -> just after HC header decoding
1456 //     } // not fkStop
1457
1458   while (fNextStatus != fkStop)
1459     { // !fkStop
1460       NextData();
1461
1462       if (fNextStatus == fkStop)
1463         {
1464           if (fLastStatus == fkStart)
1465             {
1466               AliWarning("Stop just on the first word!");
1467               continue;
1468             }
1469 //        else
1470 //          {
1471 //            if (fEndOfDataFlag == kTRUE)
1472 //              {
1473 //                if (fChamberDone[fDET] == 2)
1474 //                  {
1475 //                    return fDET;
1476 //                  }                           
1477 //              }
1478 //          }
1479         }
1480
1481       if ( *fDataWord == kEndOfRawDataMarker ) 
1482         {  // End of half-chamber data, finished
1483           AliDebug(3, "We have reached the eof data. Next should be HC header or we are done.");
1484           fGTUctr1 = -1;
1485
1486           if (fNextStatus != fkStop)
1487             ChangeStatus(fkNextHC);
1488           fEndOfDataFlag = kTRUE;
1489
1490           if (fChamberDone[fDET] == 2)
1491             {
1492               fChamberDone[fDET] = -1;
1493               AliDebug(5, Form("Return %d", fDET));
1494               return fDET;
1495             }                              
1496           continue;
1497         }
1498
1499       switch (fNextStatus)
1500         {         
1501         case fkNextData:
1502           {
1503             if (DecodeNextRawWord() == kTRUE)
1504               {
1505                 for (Int_t it = 0; it < 3; it++)
1506                   {
1507                     if ( fTB + it < fTBins )
1508                       {
1509                         if ( fSig[it] > fRawDigitThreshold )
1510                           {
1511                             digits->SetDataUnchecked(fROW, fCOL, fTB + it, fSig[it]);
1512                             indexes->AddIndexTBin(fROW, fCOL, fTB + it);
1513                             if (man->UsesDictionaries())
1514                               {
1515                                 track0->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1516                                 track1->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1517                                 track2->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
1518                               } // if dictionaries
1519                           } // signal above zero
1520                       } // check the tbins range
1521                   } // for each tbin of current 3             
1522                 fTB += 3;
1523               }
1524             else
1525               {
1526                 // can be here as a fall back from decode raw data calling decodemcm
1527                 if (fEndOfDataFlag == kTRUE)
1528                   {
1529                     if (fChamberDone[fDET] == 2)
1530                       {
1531                         fChamberDone[fDET] = -1;
1532                         AliDebug(5, Form("Return %d", fDET));
1533                         return fDET;
1534                       }                         
1535                     fEndOfDataFlag = kFALSE;
1536                   }             
1537               }
1538           }; break;
1539
1540         case fkNextMCM:
1541           {
1542             if (DecodeMCM() == kFALSE)
1543               {
1544                 AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));    
1545               }
1546             // default place for end of raw data...
1547             if (fEndOfDataFlag == kTRUE)
1548               {
1549                 if (fChamberDone[fDET] == 2)
1550                   {
1551                     fChamberDone[fDET] = -1;
1552                     return fDET;
1553                   }                             
1554                 fEndOfDataFlag = kFALSE;
1555               }      
1556           }; break;
1557
1558         case fkNextHC:
1559         case fkSeekNonEoTracklet:
1560         case fkDecodeHC:
1561           {
1562             if (DecodeHC() == kFALSE)
1563               {
1564                 AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));     
1565               }
1566             else
1567               {
1568                 AliWarning(Form("Decode HC successfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));       
1569                 //the hc header should be decoded by now
1570                 //if (fLastStatus == fkDecodeHC && fNextStatus != fkNextHC)
1571                 AliDebug(3, Form("Status last %d %d det %d lastdet %d", fLastStatus,fkDecodeHC, fDET, fLastDET));
1572                 if (fLastStatus == fkDecodeHC && fDET != fLastDET)
1573                   {
1574                     AliDebug(4, Form("???? New DET ???? %d last %d", fDET, fLastDET));
1575                     fLastDET = fDET;
1576                     // allocate stuff for the new det
1577                     //man->ResetArrays();
1578                     digits = man->GetDigits(fDET);
1579                     track0 = man->GetDictionary(fDET,0);
1580                     track1 = man->GetDictionary(fDET,1);
1581                     track2 = man->GetDictionary(fDET,2);
1582                     
1583                     // Allocate memory space for the digits buffer
1584                     if (digits->GetNtime() == 0) 
1585                       {
1586                         AliDebug(5, Form("Alloc digits for det %d rows %d cols %d tbins %d", fDET, fRowMax, fColMax, fTBins));
1587                         digits->Allocate(fRowMax, fColMax, fTBins);
1588                         if (man->UsesDictionaries())
1589                           {
1590                             track0->Allocate(fRowMax, fColMax, fTBins);
1591                             track1->Allocate(fRowMax, fColMax, fTBins);
1592                             track2->Allocate(fRowMax, fColMax, fTBins);
1593                           }
1594                       }
1595                     
1596                     indexes = man->GetIndexes(fDET);
1597                     indexes->SetSM(fSM);
1598                     indexes->SetStack(fSTACK);
1599                     indexes->SetLayer(fLAYER);
1600                     indexes->SetDetNumber(fDET);
1601                     
1602                     if (indexes->IsAllocated() == kFALSE)
1603                       {
1604                         AliDebug(4, "Allocating indexes");            
1605                         indexes->Allocate(fRowMax, fColMax, fTBins);
1606                       }
1607                   } // is the HC header already decoded?
1608               } // decode hc ok
1609           }; break;
1610
1611         case fkNextSM:
1612           {
1613             if (DecodeSM() == kFALSE)
1614               AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));       
1615           }; break;
1616
1617         case fkStop:
1618           ; break;
1619
1620         default:
1621           AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));  
1622           ChangeStatus(fkStop);
1623         };
1624
1625     } // not fkStop
1626
1627   // we do not return chambers for which the end-of-data was not received twice (for each HC)
1628
1629   //AliDebug(1, Form("That's all folks! %d", fSM));
1630   //return kFALSE;
1631   return -1;
1632 }
1633
1634 // new stuff
1635 //____________________________________________________________________________
1636 Int_t AliTRDRawStreamTB::SkipWords(UInt_t iw)
1637 {
1638   Int_t status = fkWordOK;
1639   for (UInt_t i = 0; i < iw; i++)
1640     {
1641       status = NextData();
1642       AliDebug(5, Form("Skipping word %d of %d [0x%x]", i+1, iw, *fDataWord));
1643       if (status != fkWordOK)
1644         return status;
1645     }
1646
1647   //status = NextData();
1648   return status;
1649 }
1650
1651 //____________________________________________________________________________
1652 Int_t AliTRDRawStreamTB::DecodeHeadingInfo()
1653 {
1654   // SM info...
1655   fSMinfo[fiSMx].Decode(fDataWord);
1656   if (fgExtraDebug)
1657     fSMinfo[fiSMx].Dump();
1658
1659   Int_t status = SkipWords(fSMinfo[fiSMx].fHeaderSize);
1660   if (status != fkWordOK)
1661     return status;
1662   else
1663     status = NextData();
1664
1665   //fSMinfo[fiSMx].fStackActive[0] = kTRUE;
1666   // now stack info..
1667   if (status == fkWordOK)
1668     {
1669       for (Int_t i = 0; i < 5; i++)
1670         {
1671           if (fSMinfo[fiSMx].fStackActive[i] == kFALSE)
1672             continue;
1673           AliDebug(5, Form("Decode stack info %d 0x%x", i, *fDataWord));
1674           if (fgStackIndexBug == kFALSE)
1675             fStackInfo[fiSMx][i].Decode(fDataWord);
1676           else
1677             fStackInfo[fiSMx][i].DecodeBug(fDataWord);
1678           
1679           if (fgExtraDebug)
1680             fStackInfo[fiSMx][i].Dump();
1681           
1682           status = SkipWords(fStackInfo[fiSMx][i].fHeaderSize);
1683           if (status != fkWordOK)
1684             return status;      
1685           else
1686             if (i < 4)
1687               status = NextData();
1688
1689           if (status != fkWordOK)
1690             return status;      
1691         }
1692     }
1693
1694   RewindWord();
1695   return status;
1696 }