47ba63e4e2d3a9021013872c82df93ab06c0fd4f
[u/mrichter/AliRoot.git] / TRD / AliTRDRawStream.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 "AliTRDdigitsManager.h"
34 #include "AliTRDdataArrayI.h"
35
36 #include "AliTRDRawStream.h"
37 #include "AliTRDgeometry.h"
38 #include "AliTRDCommonParam.h"
39 #include "AliTRDcalibDB.h"
40
41 ClassImp(AliTRDRawStream)
42
43 //_____________________________________________________________________________
44 AliTRDRawStream::AliTRDRawStream() 
45   :TObject()
46   ,fSig()
47   ,fADC(0)
48   ,fTB(0)
49   ,fEv(0)
50   ,fROB(0)
51   ,fMCM(0)
52   ,fSM(0)
53   ,fLAYER(0)
54   ,fSTACK(0)
55   ,fROC(0)
56   ,fSIDE(0)
57   ,fDCS(0)
58   ,fROW(0)
59   ,fCOL(0)
60   ,fBCctr(0)
61   ,fPTctr(0)
62   ,fPTphase(0)
63   ,fRVmajor(0)
64   ,fRVminor(0)
65   ,fHCHWords(0)
66   ,fTBins(0)
67   ,fTCon(0)
68   ,fPEDon(0)
69   ,fGAINon(0)
70   ,fXTon(0)
71   ,fNonLinOn(0)
72   ,fBypass(0)
73   ,fCommonAdditive(0)
74   ,fZeroSuppressed(0)
75   ,fHCHctr1(0)
76   ,fHCHctr2(0)
77   ,fMCMHctr1(0)
78   ,fMCMHctr2(0)
79   ,fGTUctr1(0)
80   ,fGTUctr2(0)
81   ,fHCdataCtr(0)
82   ,fTracklPID(0.)
83   ,fTracklDefL(0.)
84   ,fTracklPadPos(0.)
85   ,fTracklPadRow(0)
86   ,fGTUlinkMask()
87   ,fRawReader(NULL)
88   ,fCount(0)
89   ,fDetector(-1)
90   ,fPrevDetector(-1)
91   ,fNPads(-1)
92   ,fRow(-1)
93   ,fPrevRow(-1)
94   ,fColumn(-1)
95   ,fPrevColumn(-1)
96   ,fTime(-1)
97   ,fSignal(-1)
98   ,fRawVersion(2)
99   ,fDataWord(0)
100   ,fStatus(0)
101   ,fTbSwitch(0)
102   ,fTbSwitchCtr(0)
103   ,fTimeWords(0)
104   ,fWordCtr(0)
105   ,fRowMax(0)
106   ,fColMax(0)
107   ,fADCmask()
108   ,fChamberDone()
109   ,fGeo(NULL)
110   ,fDigitsManager(NULL) 
111   ,fDigits(NULL) 
112   ,fTrack0(NULL) 
113   ,fTrack1(NULL) 
114   ,fTrack2(NULL) 
115 {
116   //
117   // Default constructor
118   //
119
120   for (Int_t i = 0; i < 540; i++) {
121     fChamberDone[i] = 0;
122   }
123
124 }
125
126 //_____________________________________________________________________________
127 AliTRDRawStream::AliTRDRawStream(AliRawReader *rawReader
128                                , AliTRDdigitsManager *man
129                                , AliTRDdataArrayI *dig) 
130   :TObject()
131   ,fSig()
132   ,fADC(0)
133   ,fTB(0)
134   ,fEv(0)
135   ,fROB(0)
136   ,fMCM(0)
137   ,fSM(0)
138   ,fLAYER(0)
139   ,fSTACK(0)
140   ,fROC(0)
141   ,fSIDE(0)
142   ,fDCS(0)
143   ,fROW(0)
144   ,fCOL(0)
145   ,fBCctr(0)
146   ,fPTctr(0)
147   ,fPTphase(0)
148   ,fRVmajor(0)
149   ,fRVminor(0)
150   ,fHCHWords(0)
151   ,fTBins(0)
152   ,fTCon(0)
153   ,fPEDon(0)
154   ,fGAINon(0)
155   ,fXTon(0)
156   ,fNonLinOn(0)
157   ,fBypass(0)
158   ,fCommonAdditive(0)
159   ,fZeroSuppressed(0)
160   ,fHCHctr1(0)
161   ,fHCHctr2(0)
162   ,fMCMHctr1(0)
163   ,fMCMHctr2(0)
164   ,fGTUctr1(0)
165   ,fGTUctr2(0)
166   ,fHCdataCtr(0)
167   ,fTracklPID(0.)
168   ,fTracklDefL(0.)
169   ,fTracklPadPos(0.)
170   ,fTracklPadRow(0)
171   ,fGTUlinkMask()
172   ,fRawReader(rawReader)
173   ,fCount(0)
174   ,fDetector(-1)
175   ,fPrevDetector(-1)
176   ,fNPads(-1)
177   ,fRow(-1)
178   ,fPrevRow(-1)
179   ,fColumn(-1)
180   ,fPrevColumn(-1)
181   ,fTime(-1)
182   ,fSignal(-1)
183   ,fRawVersion(2)
184   ,fDataWord(0)
185   ,fStatus(0)
186   ,fTbSwitch(0)
187   ,fTbSwitchCtr(0)
188   ,fTimeWords(0)
189   ,fWordCtr(0)
190   ,fRowMax(0)
191   ,fColMax(0)
192   ,fADCmask()
193   ,fChamberDone()
194   ,fGeo(NULL) 
195   ,fDigitsManager(man) 
196   ,fDigits(dig) 
197   ,fTrack0(NULL) 
198   ,fTrack1(NULL) 
199   ,fTrack2(NULL) 
200
201 {
202   //
203   // Create an object to read TRD raw digits
204   //
205
206   fGeo = new AliTRDgeometry();
207
208   fRawReader->Select("TRD");
209
210   for (Int_t i = 0; i < 540; i++) {
211     fChamberDone[i] = 0;
212   }
213
214 }
215
216 //_____________________________________________________________________________
217 AliTRDRawStream::AliTRDRawStream(AliRawReader *rawReader) 
218   :TObject()
219   ,fSig()
220   ,fADC(0)
221   ,fTB(0)
222   ,fEv(0)
223   ,fROB(0)
224   ,fMCM(0)
225   ,fSM(0)
226   ,fLAYER(0)
227   ,fSTACK(0)
228   ,fROC(0)
229   ,fSIDE(0)
230   ,fDCS(0)
231   ,fROW(0)
232   ,fCOL(0)
233   ,fBCctr(0)
234   ,fPTctr(0)
235   ,fPTphase(0)
236   ,fRVmajor(0)
237   ,fRVminor(0)
238   ,fHCHWords(0)
239   ,fTBins(0)
240   ,fTCon(0)
241   ,fPEDon(0)
242   ,fGAINon(0)
243   ,fXTon(0)
244   ,fNonLinOn(0)
245   ,fBypass(0)
246   ,fCommonAdditive(0)
247   ,fZeroSuppressed(0)
248   ,fHCHctr1(0)
249   ,fHCHctr2(0)
250   ,fMCMHctr1(0)
251   ,fMCMHctr2(0)
252   ,fGTUctr1(0)
253   ,fGTUctr2(0)
254   ,fHCdataCtr(0)
255   ,fTracklPID(0.)
256   ,fTracklDefL(0.)
257   ,fTracklPadPos(0.)
258   ,fTracklPadRow(0)
259   ,fGTUlinkMask()
260   ,fRawReader(rawReader)
261   ,fCount(0)
262   ,fDetector(-1)
263   ,fPrevDetector(-1)
264   ,fNPads(-1)
265   ,fRow(-1)
266   ,fPrevRow(-1)
267   ,fColumn(-1)
268   ,fPrevColumn(-1)
269   ,fTime(-1)
270   ,fSignal(-1)
271   ,fRawVersion(2)
272   ,fDataWord(0)
273   ,fStatus(0)
274   ,fTbSwitch(0)
275   ,fTbSwitchCtr(0)
276   ,fTimeWords(0)
277   ,fWordCtr(0)
278   ,fRowMax(0)
279   ,fColMax(0)
280   ,fADCmask()
281   ,fChamberDone()
282   ,fGeo(NULL) 
283   ,fDigitsManager(NULL) 
284   ,fDigits(NULL) 
285   ,fTrack0(NULL) 
286   ,fTrack1(NULL) 
287   ,fTrack2(NULL) 
288
289 {
290   //
291   // Create an object to read TRD raw digits
292   //
293
294   fRawReader->Select("TRD");
295
296   for (Int_t i = 0; i < 540; i++) {
297     fChamberDone[i] = 0;
298   }
299
300 }
301
302 //_____________________________________________________________________________
303 AliTRDRawStream::AliTRDRawStream(const AliTRDRawStream& stream)
304   :TObject(stream)
305   ,fSig()
306   ,fADC(-1)
307   ,fTB(-1)
308   ,fEv(-1)
309   ,fROB(-1)
310   ,fMCM(-1)
311   ,fSM(-1)
312   ,fLAYER(-1)
313   ,fSTACK(-1)
314   ,fROC(-1)
315   ,fSIDE(-1)
316   ,fDCS(-1)
317   ,fROW(-1)
318   ,fCOL(-1)
319   ,fBCctr(-1)
320   ,fPTctr(-1)
321   ,fPTphase(-1)
322   ,fRVmajor(-1)
323   ,fRVminor(-1)
324   ,fHCHWords(-1)
325   ,fTBins(-1)
326   ,fTCon(0)
327   ,fPEDon(0)
328   ,fGAINon(0)
329   ,fXTon(0)
330   ,fNonLinOn(-1)
331   ,fBypass(-1)
332   ,fCommonAdditive(-1)
333   ,fZeroSuppressed(0)
334   ,fHCHctr1(-1)
335   ,fHCHctr2(-1)
336   ,fMCMHctr1(-1)
337   ,fMCMHctr2(-1)
338   ,fGTUctr1(-1)
339   ,fGTUctr2(-1)
340   ,fHCdataCtr(-1)
341   ,fTracklPID(-1.)
342   ,fTracklDefL(-1.)
343   ,fTracklPadPos(-1.)
344   ,fTracklPadRow(-1)
345   ,fGTUlinkMask()
346   ,fRawReader(NULL)
347   ,fCount(-1)
348   ,fDetector(-1)
349   ,fPrevDetector(-1)
350   ,fNPads(-1)
351   ,fRow(-1)
352   ,fPrevRow(-1)
353   ,fColumn(-1)
354   ,fPrevColumn(-1)
355   ,fTime(-1)
356   ,fSignal(-1)
357   ,fRawVersion(-1)
358   ,fDataWord(0)
359   ,fStatus(-1)
360   ,fTbSwitch(0)
361   ,fTbSwitchCtr(0)
362   ,fTimeWords(0)
363   ,fWordCtr(0)
364   ,fRowMax(-1)
365   ,fColMax(-1)
366   ,fADCmask()
367   ,fChamberDone()
368   ,fGeo(NULL) 
369   ,fDigitsManager(NULL) 
370   ,fDigits(NULL) 
371   ,fTrack0(NULL) 
372   ,fTrack1(NULL) 
373   ,fTrack2(NULL) 
374
375 {
376   //
377   // Copy constructor
378   //
379
380   AliFatal("Copy constructor not implemented");
381
382 }
383
384 //_____________________________________________________________________________
385 AliTRDRawStream& AliTRDRawStream::operator = (const AliTRDRawStream& 
386                                               /* stream */)
387 {
388   //
389   // Assigment operator
390   //
391
392   Fatal("operator =", "assignment operator not implemented");
393   return *this;
394
395 }
396
397 //_____________________________________________________________________________
398 AliTRDRawStream::~AliTRDRawStream()
399 {
400   //
401   // Destructor
402   //
403
404 }
405
406 //_____________________________________________________________________________
407 Bool_t AliTRDRawStream::SetRawVersion(Int_t rv)
408 {
409   //
410   // Set the raw data version
411   //
412
413   if ( rv >= 0 && rv <= 3 ) {
414     fRawVersion = rv;
415     return kTRUE;
416   }
417
418   return kFALSE;
419
420 }
421
422 //_____________________________________________________________________________
423 Bool_t AliTRDRawStream::Next()
424 {
425   //
426   // This is Bogdans code for reading raw data (offline use only).
427   // It is used for fRawVersion == 0. This funcyion read the next raw digit.
428   // Returns kFALSE if there is no digit left
429   //
430
431   fPrevDetector = fDetector;
432   fPrevRow      = fRow;
433   fPrevColumn   = fColumn;
434   UChar_t data;
435
436   AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
437   if (!calibration) return kFALSE;
438   
439   Int_t timeBins = calibration->GetNumberOfTimeBins();
440   
441   while (fCount >= 0) {
442
443     while (fCount == 0) {  // next detector
444
445       // read the flag
446       if (!fRawReader->ReadNextChar(data)) {
447         return kFALSE;
448       }
449       if (data != 0xBB) {
450         AliError(Form("wrong flag: %x", data));
451         fCount = -1;
452         return kFALSE;
453       }
454
455       // read the detector number
456       if (!fRawReader->ReadNextChar(data)) {
457         AliError("Could not read detector number");
458         fCount = -1;
459         return kFALSE;
460       }
461       fDetector = data;
462       if (!fRawReader->ReadNextChar(data)) {
463         AliError("Could not read detector number");
464         fCount = -1;
465         return kFALSE;
466       }
467       fDetector += (UInt_t(data) << 8);
468
469       // read the number of byts
470       if (!fRawReader->ReadNextChar(data)) {
471         AliError("Could not read number of bytes");
472         fCount = -1;
473         return kFALSE;
474       }
475       fCount = data;
476       if (!fRawReader->ReadNextChar(data)) {
477         AliError("Could not read number of bytes");
478         fCount = -1;
479         return kFALSE;
480       }
481       fCount += (UInt_t(data) << 8);
482       if (!fRawReader->ReadNextChar(data)) {
483         AliError("Could not read number of bytes");
484         fCount = -1;
485         return kFALSE;
486       }
487       fCount += (UInt_t(data) << 16);
488
489       // read the number of active pads
490       if (!fRawReader->ReadNextChar(data)) {
491         AliError("Could not read number of active pads");
492         fCount = -1;
493         return kFALSE;
494       }
495       fNPads = data;
496       if (!fRawReader->ReadNextChar(data)) {
497         AliError("Could not read number of active pads");
498         fCount = -1;
499         return kFALSE;
500       }
501       fNPads += (UInt_t(data) << 8);
502
503       fTime = timeBins;
504
505     }
506
507     // read the pad row and column number
508     if ((fTime >= timeBins) && (fCount > 2)) {
509       if (!fRawReader->ReadNextChar(data)) {
510         AliError("Could not read row number");
511         fCount = -1;
512         return kFALSE;
513       }
514       fCount--;
515       fRow = data - 1;
516       if (!fRawReader->ReadNextChar(data)) {
517         AliError("Could not read column number");
518         fCount = -1;
519         return kFALSE;
520       }
521       fCount--;
522       fColumn = data - 1;
523       fTime = 0;
524     }
525
526     // read the next data byte
527     if (!fRawReader->ReadNextChar(data)) {
528       AliError("Could not read data");
529       fCount = -1;
530       return kFALSE;
531     }
532     fCount--;
533
534     if (data == 0) {  // zeros
535       if (!fRawReader->ReadNextChar(data)) {
536         AliError("Could not read time value");
537         fCount = -1;
538         return kFALSE;
539       }
540       fCount--;
541       fTime += data + 1;
542
543     } 
544     else {          // signal
545       fSignal = (UInt_t(data & 0x7F) << 8);
546       if (!fRawReader->ReadNextChar(data)) {
547         AliError("Could not read ADC value");
548         fCount = -1;
549         return kFALSE;
550       }
551       fCount--;
552       fSignal += data;
553       fTime++;
554       return kTRUE;
555     }
556   }
557
558   return kFALSE;
559
560 }
561
562 //____________________________________________________________________________
563 Int_t AliTRDRawStream::ReadAll()
564 {
565
566   //
567   // Read all TRD raw data word (32 bits). This is for all fRawVersion > 0.
568   // Return 0 if something is not cool, 2 if data seems empty
569   //
570   // by C. Lippmann
571   //
572  
573   AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
574   if (!commonParam) {
575     AliError("Could not get common parameters");
576     return 0;
577   }
578
579   AliTRDcalibDB     *calibration = AliTRDcalibDB::Instance();
580   if (!calibration) {
581     AliError("Could not get calibration object");
582     return 0;
583   }
584   
585   UInt_t timeTotal = calibration->GetNumberOfTimeBins();
586   AliDebug(2, Form("Number of Timebins read from CDB: %d", timeTotal));
587
588   // The number of data words needed for this number of time bins (there
589   // are 3 time bins in one word)
590   fTimeWords = (timeTotal-1)/3 + 1;
591
592   fTbSwitch    = 3;
593   fTbSwitchCtr = 0;
594
595   Int_t  EqID     = 0;
596   UInt_t datasize = 0;
597   Int_t  iDET     = 0;
598
599   Int_t retval = 0;
600
601   Bool_t sizeOK = kFALSE;
602
603   fHCHctr1 = fHCHctr2 =  0;
604   fGTUctr1 = fGTUctr2 = -1;
605
606   fHCdataCtr = 0;
607   fWordCtr   = 0;
608
609   AliInfo("Converting TRD raw data to digits ...");
610
611   while ( 1 ) { // loop over all supermodules
612
613     fWordCtr   = 0;
614     fHCHctr1  = 0;
615     fMCMHctr1 = 0;
616
617     //
618     // 0) Find first GTU Link Mask and test if we can read data
619     //
620     do {
621
622       if ( !fRawReader->ReadNextInt( fDataWord ) ) {  // This is the standard exit point
623         // Compress also the digits from the last detector
624         if ( fChamberDone[iDET] == 2 ) {
625           //printf("Compressing data for det %d\n", iDET);
626           fDigits->Compress(1,0);
627           fTrack0->Compress(1,0);
628           fTrack1->Compress(1,0);
629           fTrack2->Compress(1,0);
630         }
631         AliInfo(Form("Finished processing TRD raw data: Found %d Half-Chambers", fHCHctr2));
632         //
633         /*
634         fDigits = fDigitsManager->GetDigits(iDET+1);
635         fTrack0 = fDigitsManager->GetDictionary(iDET+1,0);
636         fTrack1 = fDigitsManager->GetDictionary(iDET+1,1);
637         fTrack2 = fDigitsManager->GetDictionary(iDET+1,2);
638         fDigits->Allocate(fRowMax,fColMax,timeTotal);
639         fTrack0->Allocate(fRowMax,fColMax,timeTotal);
640         fTrack1->Allocate(fRowMax,fColMax,timeTotal);
641         fTrack2->Allocate(fRowMax,fColMax,timeTotal);
642         fDigits->SetDataUnchecked(0, 0, 0, 50);
643         fTrack0->SetDataUnchecked(0, 0, 0, 0);
644         fTrack1->Set
645         fTrack2->SetDataUnchecked(0, 0, 0, 0);  
646         fDigits->Compress(1,0);
647         fTrack0->Compress(1,0);
648         fTrack1->Compress(1,0);
649         fTrack2->Compress(1,0);
650         */
651         //
652         if ( sizeOK ) return 1;
653         else          return 2;
654       }
655
656       fWordCtr++;
657
658       // After reading the first word check for size of this data and get Eq. ID
659       if ( fWordCtr == 1 ) {
660         datasize = fRawReader->GetDataSize()/4;  // Size of this payload in 32bit words
661         EqID     = fRawReader->GetEquipmentId(); // Get Equipment ID
662         //if ( sizeOK = kFALSE && datasize > 0 ) { sizeOK = kTRUE; printf("Yo\n"); }
663         if ( datasize > 0 ) sizeOK = kTRUE;
664       }
665
666       // GTU Link Mask?
667       if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
668         fStatus = 1;      // GTU link mask found
669         DecodeGTUlinkMask();
670         break;
671       } 
672       else {
673         AliError(Form("Equipment %d: First data word is not GTU Link Mask!", EqID));
674         return 0;
675       }
676
677     } 
678     while ( fWordCtr < datasize );
679
680     //
681     // loop over all half chambers in one supermodule
682     //
683     while ( fWordCtr < datasize ) {
684
685       //
686       // 1) Find end_of_tracklet_marker
687       //
688       while ( fWordCtr < datasize ) {
689
690         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
691           AliError("Could not read data");
692           return 0;
693         }
694         fWordCtr++;
695
696         // GTU Link Mask?
697         if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
698           DecodeGTUlinkMask();
699           continue;
700         }
701
702         // endoftrackletmarker?
703         if ( fDataWord == kEndoftrackletmarker ) {
704           AliDebug(3, "end-of-tracklet-marker found");
705           fStatus = 1;
706           break;
707         } 
708         else {
709           // Tracklets found
710           AliDebug(3, "Tracklet found");
711           DecodeTracklet();
712         }
713
714       }
715
716       if ( fStatus == 0 ) break;
717     
718       //
719       // 2) Look for non-end_of_tracklet_marker
720       //
721       fStatus = 0;
722       while ( fWordCtr < datasize ) { 
723
724         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
725           AliError("Could not read data");
726           return 0;
727         }
728         fWordCtr++;
729         //printf("Word %d: 0x%08x\n", fWordCtr, fDataWord); 
730
731         if ( fDataWord != kEndoftrackletmarker ) {
732           fStatus = 1;
733           break;
734         }
735
736       }
737
738       if ( fStatus == 0 ) break;
739     
740       //
741       // 3) This Word must be Half Chamber Header
742       //
743       fStatus = 0;
744       if ( (fDataWord & 0x00000003) == 1 ) { // HC header
745
746         // If both half chambers of chamber corresponding to previous header
747         // were already processed, we can compress these digits
748         iDET = fGeo->GetDetector(fLAYER, fSTACK, fSM); // !!this is still the previous HC!!
749         if ( fChamberDone[iDET] == 2 ) {
750           //printf("Compressing data for det %d\n", iDET);
751           fDigits->Compress(1,0);
752           fTrack0->Compress(1,0);
753           fTrack1->Compress(1,0);
754           fTrack2->Compress(1,0);
755         }
756         // Read from new HC header the chamber position (fLAYER, fSTACK, fSM)
757         DecodeHCheader(timeTotal); // This is the new header!
758         iDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
759         fRowMax = commonParam->GetRowMax(fLAYER,fSTACK,fSM);
760         fColMax = commonParam->GetColMax(fROC);
761
762         // The container for the digits of this detector
763         fDigits = fDigitsManager->GetDigits(iDET);
764         fTrack0 = fDigitsManager->GetDictionary(iDET,0);
765         fTrack1 = fDigitsManager->GetDictionary(iDET,1);
766         fTrack2 = fDigitsManager->GetDictionary(iDET,2);
767         
768         // Allocate memory if it was not already done
769         if (fDigits->GetNtime() == 0) {
770           //printf("Allocating digits memory for det %d\n", iDET);
771           fDigits->Allocate(fRowMax, fColMax, fTBins);
772           fTrack0->Allocate(fRowMax, fColMax, fTBins);
773           fTrack1->Allocate(fRowMax, fColMax, fTBins);
774           fTrack2->Allocate(fRowMax, fColMax, fTBins);
775         }
776         if ( fZeroSuppressed ) {  // Make sure digits in this HC are 0
777           for ( Int_t colctr = fSIDE*fColMax/2; colctr < fColMax*(1+fSIDE)/2; colctr++ ) {
778             for ( Int_t rowctr = 0; rowctr < fRowMax; rowctr++ ) {
779               for ( Int_t timectr = 0; timectr < fTBins; timectr++ ) {
780                 fDigits->SetDataUnchecked(rowctr, colctr, timectr, 0);
781                 fTrack0->SetDataUnchecked(rowctr, colctr, timectr, 0);
782                 fTrack1->SetDataUnchecked(rowctr, colctr, timectr, 0);
783                 fTrack2->SetDataUnchecked(rowctr, colctr, timectr, 0);
784               }
785             }
786           }
787         }
788         fMCMHctr2 = 0;
789         fHCdataCtr = 0;
790
791         fChamberDone[iDET]++;
792
793       }
794     
795       //
796       // 4) Scan MCM data
797       //
798       fStatus = 0;
799       while ( fWordCtr < datasize ) {
800
801         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
802           AliError("Could not read data");
803           return 0;
804         }
805         fWordCtr++;
806         //printf("Word %d: 0x%08x\n", fWordCtr, fDataWord); 
807       
808         fHCdataCtr += 4;
809
810         //if( (fDataWord & 0x0000000f) == 0xC ) { // MCM Header
811         if( ((fDataWord & 0x80000000) == 0x0) && ((fDataWord & 0x0000000f) == 0xC) ) { // MCM Header
812           DecodeMCMheader();
813           if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 ) {
814             AliError("Wrong fMCM or fROB. Skip this data");
815             break;
816           }
817           fTbSwitch    = 3;  // For first adc channel we expect: (fDataWord & 3) = 3
818           fTbSwitchCtr = 0;  // 
819           fADC = fTB   = 0;  // Reset Counter
820           fStatus      = 1;  // Now 1 means MCM header is found
821           continue;
822         }
823     
824         if ( fDataWord == kEndofrawdatamarker ) {  // End of half-chamber data, finished
825           fGTUctr1 = -1;
826           break;
827         }
828
829         if ( fStatus == 1 ) {       // MCM header is set, ADC data is valid.
830     
831           // Found some data. Decode it now:
832           retval = DecodeDataWord();
833           if ( retval ==  0 ) continue;
834           if ( retval == -1 ) break;
835           
836           if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
837
838             // Write Digits
839             if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax ) {  // A real pad
840               for ( Int_t ctr = 0; ctr < 3; ctr++ ) {
841                 if ( fTB+ctr < (Int_t)timeTotal ) {
842                   /*
843                   fDigits->SetDataUnchecked(fROW, fCOL, fTB+ctr, fSig[ctr]);
844                   fTrack0->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
845                   fTrack1->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
846                   fTrack2->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
847                   */
848
849                   //
850                   // Pedestal subtraction done here (???):
851                   //
852                   //fDigits->SetData(fROW, fCOL, fTB+ctr, fSig[ctr] - fCommonAdditive);
853                   fDigits->SetData(fROW, fCOL, fTB+ctr, fSig[ctr]);
854                   fTrack0->SetData(fROW, fCOL, fTB+ctr, 0);
855                   fTrack1->SetData(fROW, fCOL, fTB+ctr, 0);
856                   fTrack2->SetData(fROW, fCOL, fTB+ctr, 0);
857                 }
858               }
859             }
860
861             fTB += 3;
862
863           }
864           else {
865
866             fCOL = -1;
867
868           }
869
870         }
871
872       }
873
874       AliDebug(2, Form("SM%02d L%dS%d side %x: Processed %dMCMs=%dbyte", fSM, fLAYER, fSTACK, fSIDE+10,
875                        fMCMHctr2, fHCdataCtr));
876
877     } // End Half-Chamber loop
878
879     AliDebug(1, Form("SM%02d (Eq %d): Processed %d HC (%dMCMs=%dbyte)", fSM, EqID, fHCHctr1, fMCMHctr1,
880                      datasize*4));
881     
882   } // End Super Module loop
883
884   // Compress also the digits from the last detector
885   if ( fChamberDone[iDET] == 2 ) {
886     //printf("Compressing data for det %d\n", iDET);
887     fDigits->Compress(1,0);
888     fTrack0->Compress(1,0);
889     fTrack1->Compress(1,0);
890     fTrack2->Compress(1,0);
891   }
892
893   if ( sizeOK ) return 1;
894   else          return 2;
895
896 }
897
898 //============================================================================
899 // Decoding functions
900 //============================================================================
901
902 //____________________________________________________________________________
903 void AliTRDRawStream::DecodeHCheader(Int_t timeBins)
904 {
905   //
906   // Decode a half chamber header
907   //
908
909   if ( (fDataWord >> 31) == 0 )  { // Can only happen for fRawVersion == 1
910
911     if ( fRawVersion != 1 ) {
912
913       AliWarning("===============================================================================");
914       AliWarning(Form("Mismatch between fRawVersion (%d) and HC header signature", fRawVersion));
915       AliWarning("Setting fRawVersion to 1");
916       AliWarning("===============================================================================");
917       fRawVersion = 1;
918
919     }
920
921     DecodeHCheaderV1();
922     return;
923
924   } 
925   else {
926
927     fRVmajor = (fDataWord >> 24) & 0x7f;
928     fRVminor = (fDataWord >> 17) & 0x7f;
929
930     if ( fRawVersion != fRVmajor ) {
931
932       AliWarning("===============================================================================");
933       AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
934                       ,fRawVersion,fRVmajor));
935       AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
936       AliWarning("===============================================================================");
937       fRawVersion = fRVmajor;
938
939     }
940     if ( fRawVersion >= 2 && fRawVersion <= 3 ) {
941       DecodeHCheaderV2V3(timeBins);
942     }
943
944     //
945     // check for zero suppression
946     if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
947     else                                        fZeroSuppressed = kFALSE;
948
949     return;
950
951   }
952
953   AliError(Form(" Unsupported raw version: %d", fRawVersion));
954   return;
955
956 }
957
958 //____________________________________________________________________________
959 void AliTRDRawStream::DecodeHCheaderV1()
960 {
961
962   //
963   // Decode the HC header (fRawVersion == 1, SM I Commissioning 06)
964   //
965
966   if ( (fDataWord & 0x3) == 1 ) {
967
968     fDCS   = (fDataWord >> 20);
969     fSM    = (fDataWord >> 15) & 0x1f;
970     fLAYER = (fDataWord >> 12) & 0x7;
971     fSTACK = (fDataWord >>  9) & 0x7;
972     fSIDE  = (fDataWord >>  8) & 0x1;
973
974     fROC   = fGeo->GetDetectorSec(fLAYER, fSTACK);
975
976     //AliDebug(3, Form("0x%08x: HC header: dcs=%d; sm=%d; roc=%d; side=%x", fDataWord, fDCS, fSM, fROC, fSIDE+10));
977
978     if ((fSM    <  0) || 
979         (fSM    > 17) || 
980         (fLAYER <  0) || 
981         (fLAYER >  5) || 
982         (fSTACK <  0) || 
983         (fSTACK >  4) || 
984         (fSIDE  <  0) || 
985         (fSIDE  >  1)) {
986       AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
987                       fDataWord, fDCS, fSM, fLAYER, fSTACK));
988     } 
989     else {
990       fStatus = 1;
991       fHCHctr1++;
992       fHCHctr2++;
993     }
994     fHCHWords = 0;
995
996   } 
997   else { 
998
999     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
1000
1001   }
1002
1003 }
1004
1005
1006 //____________________________________________________________________________
1007 void AliTRDRawStream::DecodeHCheaderV2V3(Int_t timeBins)
1008 {
1009   //
1010   // Decode the HC header (fRawVersion == 2, 3, 4, ???)
1011   //
1012
1013   // 1st word (h[0])
1014   if ( (fDataWord & 0x3) == 1 ) {
1015
1016     fHCHWords = (fDataWord >> 14) & 0x7;
1017     fSM       = (fDataWord >>  9) & 0x1f;
1018     fLAYER    = (fDataWord >>  6) & 0x7;
1019     fSTACK    = (fDataWord >>  3) & 0x7;
1020     fSIDE     = (fDataWord >>  2) & 0x1;
1021
1022     fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
1023
1024     AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", fDataWord, fSM, fROC, fSIDE+10));
1025
1026     if ((fSM    <  0) || 
1027         (fSM    > 17) || 
1028         (fLAYER <  0) || 
1029         (fLAYER >  5) || 
1030         (fSTACK <  0) || 
1031         (fSTACK >  4) || 
1032         (fSIDE  <  0) || 
1033         (fSIDE  >  1)) {
1034       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
1035                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
1036     } 
1037     else {
1038       fStatus = 1;
1039       fHCHctr1++;
1040       fHCHctr2++;
1041     }
1042   } 
1043   else { 
1044     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
1045   }
1046
1047   // 2nd word (h[1])
1048   if ( fHCHWords >= 1 ) {
1049     // read one more word
1050     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1051       AliError("Could not read data");
1052       return;
1053     }
1054     fWordCtr++;
1055     if ( (fDataWord & 0x3) == 1 ) {
1056       
1057       fBCctr   =  (fDataWord >> 16);
1058       fPTctr   =  (fDataWord >> 12) & 0xf;
1059       fPTphase =  (fDataWord >>  8) & 0xf;
1060       fTBins   = ((fDataWord >>  2) & 0x3f) + 1;
1061
1062       AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
1063                       , fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
1064
1065       if( fTBins != timeBins ) {
1066
1067         AliWarning("===============================================================================");
1068         AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
1069                       , timeBins, fTBins));
1070         AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
1071         AliWarning("===============================================================================");
1072
1073       }
1074
1075     }
1076
1077   }
1078
1079   // 3nd word (h[2])
1080   if ( fHCHWords >= 2 ) {
1081     // read one more word
1082     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1083       AliError("Could not read data");
1084       return;
1085     }
1086     fWordCtr++;
1087     if ( (fDataWord & 0x3) == 1 ) {
1088        
1089       fTCon     = (fDataWord >> 29) & 0x1;
1090       fPEDon    = (fDataWord >> 31) & 0x1;
1091       fGAINon   = (fDataWord >> 30) & 0x1;
1092       fXTon     = (fDataWord >> 28) & 0x1;
1093       fNonLinOn = (fDataWord >> 27) & 0x1;
1094       fBypass   = (fDataWord >> 26) & 0x1;
1095
1096       fCommonAdditive = (fDataWord >> 20) & 0x3f;
1097
1098       AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
1099                       , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
1100
1101       if( fTBins != timeBins ) {
1102         AliError(Form("Mismatch between Number of Time Bins from CDB (%d) and from HC header (%d)"
1103                      , timeBins, fTBins));
1104       }
1105
1106     }
1107
1108   }
1109
1110 }  
1111
1112 //____________________________________________________________________________
1113 void AliTRDRawStream::DecodeMCMheader()
1114 {
1115   //
1116   //
1117   //
1118
1119   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1120     DecodeMCMheaderVx();
1121     return;
1122   }
1123
1124   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1125   return;
1126
1127 }
1128
1129 //____________________________________________________________________________
1130 void AliTRDRawStream::DecodeMCMheaderVx()
1131 {
1132
1133   //
1134   // Decode the MCM header
1135   //
1136
1137   fMCM  = (fDataWord & 0xff000000) >> 24;
1138   fEv   = (fDataWord & 0x00fffff0) >> 4;
1139
1140   fROB  = fMCM / 16;
1141   fMCM  = fMCM % 16;
1142
1143   fROW  = fGeo->GetPadRowFromMCM(fROB, fMCM);
1144
1145   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
1146                   , fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
1147
1148   if ( fROB % 2 == 0 && fSIDE == 1 ) {
1149     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1150                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1151   }
1152   if ( fROB % 2 != 0 && fSIDE == 0 ) {
1153     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1154                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1155   }
1156   if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
1157        (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 ) {
1158     AliError(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
1159                  , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
1160   }
1161   
1162   fMCMHctr1++;
1163   fMCMHctr2++;
1164
1165   // AdcMask for Zero supressed data
1166   if ( fRawVersion == 3 ) {
1167     // read one more word
1168     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1169       AliError("Could not read data");
1170       return;
1171     }
1172     fWordCtr++;
1173     if ( (fDataWord & 0x000007ff) == 0xC ) {     // at the moment bits 4-10 are empty
1174     //if ( (fDataWord & 0x0000000f) == 0xC ) {
1175       
1176       for ( Int_t ctr = 0; ctr < fGeo->ADCmax(); ctr++ ) {
1177         if ( (fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
1178         else                                  fADCmask[ctr] = kFALSE;
1179       }
1180
1181       AliDebug(4, Form("0x%08x: ADC mask", fDataWord));
1182
1183     }
1184     else {
1185       AliError("Expected ADC mask but did not find one!");
1186     }
1187
1188   }
1189
1190 }
1191
1192 //____________________________________________________________________________
1193 void AliTRDRawStream::DecodeTracklet()
1194 {
1195   //
1196   //
1197   //
1198
1199   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1200     DecodeTrackletVx();
1201     return;
1202   }
1203
1204   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1205   return;
1206
1207 }
1208
1209 //____________________________________________________________________________
1210 void AliTRDRawStream::DecodeTrackletVx()
1211 {
1212
1213   //
1214   // Decode the Tracklet
1215   //
1216   // this function is not tested yet on real tracklets
1217   //
1218
1219   fTracklPID    = (fDataWord >> 24) & 0xff;
1220   fTracklPadRow = (fDataWord >> 20) & 0xf;    // 0:15
1221   fTracklDefL   = (fDataWord >> 13) & 0x7f;
1222   fTracklPadPos = (fDataWord)       & 0x1fff;
1223
1224   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
1225   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
1226   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
1227
1228   AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
1229                   , fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
1230                   , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
1231
1232   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
1233       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
1234     AliError(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
1235   }
1236
1237 }
1238
1239 //____________________________________________________________________________
1240 void AliTRDRawStream::DecodeGTUlinkMask()
1241 {
1242   //
1243   //
1244   //
1245
1246   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1247     DecodeGTUlinkMaskVx();
1248     return;
1249   }
1250
1251   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1252   return;
1253
1254 }
1255
1256 //____________________________________________________________________________
1257 void AliTRDRawStream::DecodeGTUlinkMaskVx()
1258 {
1259
1260   //
1261   // Decode the link masks sent by the GTU. These marke the active optical links
1262   // between GTU and Super Module. Up to now only fully active links are found
1263   // (0xfff = 12 active links).
1264   //
1265
1266   if ( fGTUctr1 == -1 ) fGTUctr2++;
1267   fGTUctr1++;
1268
1269   //printf("fGTUctr=%d",fGTUctr);
1270   //printf("fGTUctr1=%d, fGTUctr2=%d",fGTUctr1, fGTUctr2);
1271
1272   if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) {
1273     fGTUlinkMask[fGTUctr2][fGTUctr1] = (fDataWord & 0xfff);
1274   }
1275
1276   for ( Int_t ctr = 0; ctr < 12; ctr++ ) {
1277     if ( IsGTULinkActive(fGTUctr2, ctr/2, fGTUctr1, ctr%2) ) {
1278       AliDebug(3, Form("SM %2d Stack %d: GTU Link %2d is active!", fGTUctr2, fGTUctr1, ctr)); 
1279     }
1280   }
1281
1282 }
1283
1284 //____________________________________________________________________________
1285 Int_t  AliTRDRawStream::DecodeDataWord()
1286 {
1287
1288   //
1289   // Decode the Data
1290   //
1291
1292   if      ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1293     return DecodeDataWordV1V2();
1294   }
1295   else if ( fRawVersion >= 3 && fRawVersion <= 3 ) {
1296     return DecodeDataWordV3();
1297   }
1298
1299   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1300   return -1;
1301
1302 }
1303
1304 //____________________________________________________________________________
1305 Int_t  AliTRDRawStream::DecodeDataWordV1V2()
1306 {
1307
1308   //
1309   // Decode the Data (full raw data. No zero suppression. 21 adc channels)
1310   //
1311   // return  0 means continue to next data word
1312   // return -1 means break data loop
1313   //
1314
1315   if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
1316     AliError(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)fDataWord));
1317     return -1;
1318   }
1319
1320   if ( (fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
1321     //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
1322     fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
1323     fTbSwitchCtr = 0;
1324     fADC++;
1325     fTB=0;
1326   }
1327
1328   fTbSwitchCtr++; // Just read one word
1329
1330   // We have only timeTotal time bins
1331   if ( fTbSwitchCtr > fTimeWords ) {
1332     AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
1333     return 0;
1334   }
1335
1336   // We have only 21 ADC channels.
1337   if ( fADC > (Int_t)fGeo->ADCmax()-1 ) {
1338     AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord, (Int_t)fADC));
1339     return 0;
1340   }
1341
1342   // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
1343   // MCMs and are good for online tracking in the MCM.
1344   if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
1345
1346     // Get Pad column
1347     fCOL = fGeo->GetPadColFromADC(fROB, fMCM, fADC);
1348
1349     // We have only 144 Pad Columns
1350     if ( fCOL > fColMax-1 || fCOL < 0 ) {
1351       AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
1352                     fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
1353     }
1354
1355     // Decode 32 bit data words with information from 3 time bins and copy the data
1356     fSig[0] = (fDataWord & 0x00000ffc) >> 2;
1357     fSig[1] = (fDataWord & 0x003ff000) >> 12;
1358     fSig[2] = (fDataWord & 0xffc00000) >> 22;
1359
1360     // Print data to screen:
1361     AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
1362                      fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
1363     
1364   }
1365   else {
1366     
1367     fCOL = -1;
1368     
1369   }
1370
1371   return 1;
1372
1373 }
1374
1375 //____________________________________________________________________________
1376 Int_t  AliTRDRawStream::DecodeDataWordV3()
1377 {
1378
1379   //
1380   // Decode the data (Zero suppresses data. 21 adc channels)
1381   //
1382   // return  0 means continue to next data word
1383   // return -1 means break data loop
1384   //
1385   // NOT TESTED YET!!!!!!!!
1386   //
1387
1388   if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
1389     AliError(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)fDataWord));
1390     return -1;
1391   }
1392
1393   if ( (fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
1394     //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
1395     fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
1396     fTbSwitchCtr = 0;
1397     //
1398     // Jump to next ADC channel that is not masked
1399     do {
1400       fADC++;
1401     } while ( ((fADC < fGeo->ADCmax()) && (fADCmask[fADC] == kFALSE)) || (fADC >= fGeo->ADCmax()) );
1402     fTB=0;
1403   }
1404
1405   fTbSwitchCtr++; // Just read one word
1406
1407   // We have only timeTotal time bins
1408   if ( fTbSwitchCtr > fTimeWords ) {
1409     AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
1410     return 0;
1411   }
1412
1413   // We have only 21 ADC channels.
1414   if ( fADC > (Int_t)fGeo->ADCmax()-1 ) {
1415     AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord, (Int_t)fADC));
1416     return 0;
1417   }
1418
1419   // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
1420   // MCMs and are good for online tracking in the MCM.
1421   if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
1422
1423     // Get Pad column
1424     fCOL = fGeo->GetPadColFromADC(fROB, fMCM, fADC);
1425
1426     // We have only 144 Pad Columns
1427     if ( fCOL > fColMax-1 || fCOL < 0 ) {
1428       AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
1429                     fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
1430     }
1431
1432     // Decode 32 bit data words with information from 3 time bins and copy the data
1433     fSig[0] = (fDataWord & 0x00000ffc) >> 2;
1434     fSig[1] = (fDataWord & 0x003ff000) >> 12;
1435     fSig[2] = (fDataWord & 0xffc00000) >> 22;
1436
1437     // Print data to screen:
1438     AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
1439                      fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
1440     
1441   }
1442   else {
1443     
1444     fCOL = -1;
1445     
1446   }
1447
1448   return 1;
1449
1450 }