fixed compiler problem
[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   ,fFiltered(0)
71   ,fHCHctr1(0)
72   ,fHCHctr2(0)
73   ,fMCMHctr1(0)
74   ,fMCMHctr2(0)
75   ,fGTUctr1(0)
76   ,fGTUctr2(0)
77   ,fTracklPID(0)
78   ,fTracklDefL(0)
79   ,fTracklPadPos(0)
80   ,fTracklPadRow(0)
81   ,fGTUlinkMask()
82   ,fRawReader(NULL)
83   ,fCount(0)
84   ,fDetector(-1)
85   ,fPrevDetector(-1)
86   ,fNPads(-1)
87   ,fRow(-1)
88   ,fPrevRow(-1)
89   ,fColumn(-1)
90   ,fPrevColumn(-1)
91   ,fTime(-1)
92   ,fSignal(-1)
93   ,fRawVersion(1)
94   ,fDataWord(0)
95   ,fStatus(0)
96   ,fRowMax(0)
97   ,fColMax(0)
98   ,fChamberDone()
99   ,fGeo(NULL)
100   ,fDigitsManager(NULL) 
101   ,fDigits(NULL) 
102   ,fTrack0(NULL) 
103   ,fTrack1(NULL) 
104   ,fTrack2(NULL) 
105 {
106   //
107   // Default constructor
108   //
109
110   for (Int_t i = 0; i < 540; i++) {
111     fChamberDone[i] = 0;
112   }
113
114 }
115
116 //_____________________________________________________________________________
117 AliTRDRawStream::AliTRDRawStream(AliRawReader *rawReader
118                                , AliTRDdigitsManager *man
119                                , AliTRDdataArrayI *dig) 
120   :TObject()
121   ,fSig()
122   ,fADC(0)
123   ,fTB(0)
124   ,fEv(0)
125   ,fROB(0)
126   ,fMCM(0)
127   ,fSM(0)
128   ,fLAYER(0)
129   ,fSTACK(0)
130   ,fROC(0)
131   ,fSIDE(0)
132   ,fDCS(0)
133   ,fROW(0)
134   ,fCOL(0)
135   ,fBCctr(0)
136   ,fPTctr(0)
137   ,fPTphase(0)
138   ,fRVmajor(0)
139   ,fRVminor(0)
140   ,fHCHWords(0)
141   ,fTBins(0)
142   ,fTCon(0)
143   ,fPEDon(0)
144   ,fGAINon(0)
145   ,fFiltered(0)
146   ,fHCHctr1(0)
147   ,fHCHctr2(0)
148   ,fMCMHctr1(0)
149   ,fMCMHctr2(0)
150   ,fGTUctr1(0)
151   ,fGTUctr2(0)
152   ,fTracklPID(0)
153   ,fTracklDefL(0)
154   ,fTracklPadPos(0)
155   ,fTracklPadRow(0)
156   ,fGTUlinkMask()
157   ,fRawReader(rawReader)
158   ,fCount(0)
159   ,fDetector(-1)
160   ,fPrevDetector(-1)
161   ,fNPads(-1)
162   ,fRow(-1)
163   ,fPrevRow(-1)
164   ,fColumn(-1)
165   ,fPrevColumn(-1)
166   ,fTime(-1)
167   ,fSignal(-1)
168   ,fRawVersion(1)
169   ,fDataWord(0)
170   ,fStatus(0)
171   ,fRowMax(0)
172   ,fColMax(0)
173   ,fChamberDone()
174   ,fGeo(NULL) 
175   ,fDigitsManager(man) 
176   ,fDigits(dig) 
177   ,fTrack0(NULL) 
178   ,fTrack1(NULL) 
179   ,fTrack2(NULL) 
180
181 {
182   //
183   // Create an object to read TRD raw digits
184   //
185
186   fGeo = new AliTRDgeometry();
187
188   fRawReader->Select("TRD");
189
190   for (Int_t i = 0; i < 540; i++) {
191     fChamberDone[i] = 0;
192   }
193
194 }
195
196 //_____________________________________________________________________________
197 AliTRDRawStream::AliTRDRawStream(AliRawReader *rawReader) 
198   :TObject()
199   ,fSig()
200   ,fADC(0)
201   ,fTB(0)
202   ,fEv(0)
203   ,fROB(0)
204   ,fMCM(0)
205   ,fSM(0)
206   ,fLAYER(0)
207   ,fSTACK(0)
208   ,fROC(0)
209   ,fSIDE(0)
210   ,fDCS(0)
211   ,fROW(0)
212   ,fCOL(0)
213   ,fBCctr(0)
214   ,fPTctr(0)
215   ,fPTphase(0)
216   ,fRVmajor(0)
217   ,fRVminor(0)
218   ,fHCHWords(0)
219   ,fTBins(0)
220   ,fTCon(0)
221   ,fPEDon(0)
222   ,fGAINon(0)
223   ,fFiltered(0)
224   ,fHCHctr1(0)
225   ,fHCHctr2(0)
226   ,fMCMHctr1(0)
227   ,fMCMHctr2(0)
228   ,fGTUctr1(0)
229   ,fGTUctr2(0)
230   ,fTracklPID(0)
231   ,fTracklDefL(0)
232   ,fTracklPadPos(0)
233   ,fTracklPadRow(0)
234   ,fGTUlinkMask()
235   ,fRawReader(rawReader)
236   ,fCount(0)
237   ,fDetector(-1)
238   ,fPrevDetector(-1)
239   ,fNPads(-1)
240   ,fRow(-1)
241   ,fPrevRow(-1)
242   ,fColumn(-1)
243   ,fPrevColumn(-1)
244   ,fTime(-1)
245   ,fSignal(-1)
246   ,fRawVersion(1)
247   ,fDataWord(0)
248   ,fStatus(0)
249   ,fRowMax(0)
250   ,fColMax(0)
251   ,fChamberDone()
252   ,fGeo(NULL) 
253   ,fDigitsManager(NULL) 
254   ,fDigits(NULL) 
255   ,fTrack0(NULL) 
256   ,fTrack1(NULL) 
257   ,fTrack2(NULL) 
258
259 {
260   //
261   // Create an object to read TRD raw digits
262   //
263
264   fRawReader->Select("TRD");
265
266   for (Int_t i = 0; i < 540; i++) {
267     fChamberDone[i] = 0;
268   }
269
270 }
271
272 //_____________________________________________________________________________
273 AliTRDRawStream::AliTRDRawStream(const AliTRDRawStream& stream)
274   :TObject(stream)
275   ,fSig()
276   ,fADC(0)
277   ,fTB(0)
278   ,fEv(0)
279   ,fROB(0)
280   ,fMCM(0)
281   ,fSM(0)
282   ,fLAYER(0)
283   ,fSTACK(0)
284   ,fROC(0)
285   ,fSIDE(0)
286   ,fDCS(0)
287   ,fROW(0)
288   ,fCOL(0)
289   ,fBCctr(0)
290   ,fPTctr(0)
291   ,fPTphase(0)
292   ,fRVmajor(0)
293   ,fRVminor(0)
294   ,fHCHWords(0)
295   ,fTBins(0)
296   ,fTCon(0)
297   ,fPEDon(0)
298   ,fGAINon(0)
299   ,fFiltered(0)
300   ,fHCHctr1(0)
301   ,fHCHctr2(0)
302   ,fMCMHctr1(0)
303   ,fMCMHctr2(0)
304   ,fGTUctr1(0)
305   ,fGTUctr2(0)
306   ,fTracklPID(0)
307   ,fTracklDefL(0)
308   ,fTracklPadPos(0)
309   ,fTracklPadRow(0)
310   ,fGTUlinkMask()
311   ,fRawReader(NULL)
312   ,fCount(0)
313   ,fDetector(-1)
314   ,fPrevDetector(-1)
315   ,fNPads(-1)
316   ,fRow(-1)
317   ,fPrevRow(-1)
318   ,fColumn(-1)
319   ,fPrevColumn(-1)
320   ,fTime(-1)
321   ,fSignal(-1)
322   ,fRawVersion(1)
323   ,fDataWord(0)
324   ,fStatus(0)
325   ,fRowMax(0)
326   ,fColMax(0)
327   ,fChamberDone()
328   ,fGeo(NULL) 
329   ,fDigitsManager(NULL) 
330   ,fDigits(NULL) 
331   ,fTrack0(NULL) 
332   ,fTrack1(NULL) 
333   ,fTrack2(NULL) 
334
335 {
336   //
337   // Copy constructor
338   //
339
340   AliFatal("Copy constructor not implemented");
341
342 }
343
344 //_____________________________________________________________________________
345 AliTRDRawStream& AliTRDRawStream::operator = (const AliTRDRawStream& 
346                                               /* stream */)
347 {
348   //
349   // Assigment operator
350   //
351
352   Fatal("operator =", "assignment operator not implemented");
353   return *this;
354
355 }
356
357 //_____________________________________________________________________________
358 AliTRDRawStream::~AliTRDRawStream()
359 {
360   //
361   // Destructor
362   //
363
364   delete fGeo;
365   delete fRawReader;
366   //delete fDigitsManager;
367   delete fDigits;
368   delete fTrack0;
369   delete fTrack1;
370   delete fTrack2;
371
372 }
373
374 //_____________________________________________________________________________
375 Bool_t AliTRDRawStream::SetRawVersion(Int_t rv)
376 {
377   //
378   // Set the raw data version
379   //
380
381   if ( rv >= 0 && rv <= 2 ) {
382     fRawVersion = rv;
383     return kTRUE;
384   }
385
386   return kFALSE;
387
388 }
389
390 //_____________________________________________________________________________
391 Bool_t AliTRDRawStream::Next()
392 {
393   //
394   // This is Bogdans code for reading raw data (offline use only).
395   // It is used for fRawVersion == 0. This funcyion read the next raw digit.
396   // Returns kFALSE if there is no digit left
397   //
398
399   fPrevDetector = fDetector;
400   fPrevRow      = fRow;
401   fPrevColumn   = fColumn;
402   UChar_t data;
403
404   AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
405   if (!calibration) return kFALSE;
406   
407   Int_t timeBins = calibration->GetNumberOfTimeBins();
408   
409   while (fCount >= 0) {
410
411     while (fCount == 0) {  // next detector
412
413       // read the flag
414       if (!fRawReader->ReadNextChar(data)) {
415         return kFALSE;
416       }
417       if (data != 0xBB) {
418         AliError(Form("wrong flag: %x", data));
419         fCount = -1;
420         return kFALSE;
421       }
422
423       // read the detector number
424       if (!fRawReader->ReadNextChar(data)) {
425         AliError("Could not read detector number");
426         fCount = -1;
427         return kFALSE;
428       }
429       fDetector = data;
430       if (!fRawReader->ReadNextChar(data)) {
431         AliError("Could not read detector number");
432         fCount = -1;
433         return kFALSE;
434       }
435       fDetector += (UInt_t(data) << 8);
436
437       // read the number of byts
438       if (!fRawReader->ReadNextChar(data)) {
439         AliError("Could not read number of bytes");
440         fCount = -1;
441         return kFALSE;
442       }
443       fCount = data;
444       if (!fRawReader->ReadNextChar(data)) {
445         AliError("Could not read number of bytes");
446         fCount = -1;
447         return kFALSE;
448       }
449       fCount += (UInt_t(data) << 8);
450       if (!fRawReader->ReadNextChar(data)) {
451         AliError("Could not read number of bytes");
452         fCount = -1;
453         return kFALSE;
454       }
455       fCount += (UInt_t(data) << 16);
456
457       // read the number of active pads
458       if (!fRawReader->ReadNextChar(data)) {
459         AliError("Could not read number of active pads");
460         fCount = -1;
461         return kFALSE;
462       }
463       fNPads = data;
464       if (!fRawReader->ReadNextChar(data)) {
465         AliError("Could not read number of active pads");
466         fCount = -1;
467         return kFALSE;
468       }
469       fNPads += (UInt_t(data) << 8);
470
471       fTime = timeBins;
472
473     }
474
475     // read the pad row and column number
476     if ((fTime >= timeBins) && (fCount > 2)) {
477       if (!fRawReader->ReadNextChar(data)) {
478         AliError("Could not read row number");
479         fCount = -1;
480         return kFALSE;
481       }
482       fCount--;
483       fRow = data - 1;
484       if (!fRawReader->ReadNextChar(data)) {
485         AliError("Could not read column number");
486         fCount = -1;
487         return kFALSE;
488       }
489       fCount--;
490       fColumn = data - 1;
491       fTime = 0;
492     }
493
494     // read the next data byte
495     if (!fRawReader->ReadNextChar(data)) {
496       AliError("Could not read data");
497       fCount = -1;
498       return kFALSE;
499     }
500     fCount--;
501
502     if (data == 0) {  // zeros
503       if (!fRawReader->ReadNextChar(data)) {
504         AliError("Could not read time value");
505         fCount = -1;
506         return kFALSE;
507       }
508       fCount--;
509       fTime += data + 1;
510
511     } 
512     else {          // signal
513       fSignal = (UInt_t(data & 0x7F) << 8);
514       if (!fRawReader->ReadNextChar(data)) {
515         AliError("Could not read ADC value");
516         fCount = -1;
517         return kFALSE;
518       }
519       fCount--;
520       fSignal += data;
521       fTime++;
522       return kTRUE;
523     }
524   }
525
526   return kFALSE;
527
528 }
529
530 //____________________________________________________________________________
531 Bool_t AliTRDRawStream::ReadAll()
532 {
533
534   //
535   // Read all TRD raw data word (32 bits). This is for all FrawVersion > 0.
536   // Return kFALSE if something is not cool
537   //
538   // by C. Lippmann
539   //
540  
541   AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
542   if (!commonParam) {
543     AliError("Could not get common parameters");
544     return kFALSE;
545   }
546
547   AliTRDcalibDB     *calibration = AliTRDcalibDB::Instance();
548   if (!calibration) {
549     AliError("Could not get calibration object");
550     return kFALSE;
551   }
552   
553   UInt_t timeTotal = calibration->GetNumberOfTimeBins();
554
555   // The number of data words needed for this number of time bins (there
556   // are 3 time bins in one word)
557   UInt_t timeWords = ( timeTotal%3 == 0 ) ? timeTotal/3 :  timeTotal/3 + 1;
558
559   AliDebug(2, Form("Number of Timebins read from CDB: %d", timeTotal));
560
561   UInt_t TBswitch    = 3;
562   UInt_t TBswitchCtr = 0;
563   Int_t  WordCtr     = 0;
564   Int_t  EqID        = 0;
565   Int_t  datasize    = 0;
566   Int_t  iDET        = 0;
567
568   fHCHctr1 = fHCHctr2 =  0;
569   fGTUctr1 = fGTUctr2 = -1;
570
571   AliInfo("Converting TRD raw data to digits ...");
572
573   while ( 1 ) { // loop over all supermodules
574
575     WordCtr   = 0;
576     fHCHctr1  = 0;
577     fMCMHctr1 = 0;
578
579     //
580     // 0) Find first GTU Link Mask and test if we can read data
581     //
582     do {
583
584       if ( !fRawReader->ReadNextInt( fDataWord ) ) {
585         AliInfo(Form("Finished processing TRD raw data: Found %d Half-Chambers", fHCHctr2));
586         return kTRUE;
587       }
588       WordCtr++;
589
590       // After reading the first word check for size of this data and get Eq. ID
591       if ( WordCtr == 1 ) {
592         datasize = fRawReader->GetDataSize()/4;  // Size of this payload is in 32bit words
593         EqID     = fRawReader->GetEquipmentId(); // Get Equipment ID
594       }
595
596       // GTU Link Mask?
597       if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
598         fStatus = 1;      // GTU link mask found
599         DecodeGTUlinkMask();
600         break;
601       } 
602       else {
603         AliError(Form("Equipment %d: First data word is not GTU Link Mask!", EqID));
604         return kFALSE;
605       }
606
607     } 
608     while ( WordCtr < datasize );
609
610     //
611     // loop over all half chambers in one supermodule
612     //
613     while ( WordCtr < datasize ) {
614
615       //
616       // 1) Find end_of_tracklet_marker
617       //
618       while ( WordCtr < datasize ) {
619
620         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
621           AliError("Could not read data");
622           return kFALSE;
623         }
624         WordCtr++;
625
626         // GTU Link Mask?
627         if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
628           DecodeGTUlinkMask();
629           continue;
630         }
631
632         // end_of_tracklet_marker?
633         if ( fDataWord == end_of_tracklet_marker ) {
634           AliDebug(3, "end_of_tracklet_marker found");
635           fStatus = 1;
636           break;
637         } 
638         else {
639           // Tracklets found
640           AliDebug(3, "Tracklet found");
641           DecodeTracklet();
642         }
643
644       }
645
646       if ( fStatus == 0 ) break;
647     
648       //
649       // 2) Look for non-end_of_tracklet_marker
650       //
651       fStatus = 0;
652       while ( WordCtr < datasize ) { 
653
654         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
655           AliError("Could not read data");
656           return kFALSE;
657         }
658         WordCtr++;
659         //printf("Word %d: 0x%08x\n", WordCtr, fDataWord); 
660
661         if ( fDataWord != end_of_tracklet_marker ) {
662           fStatus = 1;
663           break;
664         }
665
666       }
667
668       if ( fStatus == 0 ) break;
669     
670       //
671       // 3) This Word must be Half Chamber Header
672       //
673       fStatus = 0;
674       if ( (fDataWord & 0x00000003) == 1 ) { // HC header
675
676         // If both half chambers of chamber corresponding to previous header
677         // were already processed, we can compress these digits
678         iDET = fGeo->GetDetector(fLAYER, fSTACK, fSM);
679         if ( fChamberDone[iDET] == 2 ) {
680           fDigits->Compress(1,0);
681           fTrack0->Compress(1,0);
682           fTrack1->Compress(1,0);
683           fTrack2->Compress(1,0);
684         }
685
686         // Read from new HC header the chamber position (fLAYER, fSTACK, fSM)
687         DecodeHCheader(timeTotal);
688         WordCtr += fHCHWords;
689         iDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
690         fRowMax = commonParam->GetRowMax(fLAYER,fSTACK,fSM);
691         fColMax = commonParam->GetColMax(fROC);
692
693         // Add a container for the digits of this detector
694         fDigits = fDigitsManager->GetDigits(iDET);
695         fTrack0 = fDigitsManager->GetDictionary(iDET,0);
696         fTrack1 = fDigitsManager->GetDictionary(iDET,1);
697         fTrack2 = fDigitsManager->GetDictionary(iDET,2);
698         
699         fChamberDone[iDET]++;
700         
701         // Allocate memory if it was not already done
702         if (fDigits->GetNtime() == 0) {
703           fDigits->Allocate(fRowMax,fColMax,timeTotal);
704           fTrack0->Allocate(fRowMax,fColMax,timeTotal);
705           fTrack1->Allocate(fRowMax,fColMax,timeTotal);
706           fTrack2->Allocate(fRowMax,fColMax,timeTotal);
707         }
708
709         fMCMHctr2 = 0;
710
711       }
712     
713       //
714       // 4) Scan MCM data
715       //
716       fStatus = 0;
717       while ( WordCtr < datasize ) {
718
719         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
720           AliError("Could not read data");
721           return kFALSE;
722         }
723         WordCtr++;
724         //printf("Word %d: 0x%08x\n", WordCtr, fDataWord); 
725       
726         //if ( WordCtr == 4*datasize ) AliInfo(Form("Achtung! WordCtr=%d (%d)", WordCtr, 4*datasize));
727
728         if( (fDataWord & 0x0000000f) == 0xC ) { // MCM Header
729           DecodeMCMheader();
730           if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 ) {
731             AliError("Wrong fMCM or fROB. Skip this data");
732             break;
733           }
734           TBswitch    = 3;  // For first adc channel we expect: (fDataWord & 3) = 3
735           TBswitchCtr = 0;  // 
736           fADC = fTB  = 0;  // Reset Counter
737           fStatus     = 1;  // Now 1 means MCM header is found
738           continue;
739         }
740     
741         // End of half-chamber data, finished:
742         if ( fDataWord == end_of_event_marker ) {
743           fGTUctr1 = -1;
744           break;
745         }
746
747         if ( fStatus == 1 ) {       // MCM header is set, ADC data is valid.
748     
749           //
750           // Found some data. Decode it now:
751           //
752           if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
753             AliError(Form("Data %08x : Data Word ends neither with 11 nor 10", (Int_t)fDataWord));
754             break;
755           }
756
757           if ( (fDataWord & 0x00000003) != TBswitch ) {    // Next ADC channel found
758             //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
759             TBswitch = (TBswitch & 2) | !(TBswitch & 1);   // 0x3 <--> 0x2
760             TBswitchCtr = 0;
761             fADC++;
762             fTB=0;
763           }
764
765           TBswitchCtr++; // Just read one word
766         
767           // We have only timeTotal time bins
768           if ( TBswitchCtr > timeWords ) {
769             AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)TBswitchCtr));
770             continue;
771           }
772
773           // We have only 21 ADC channels.
774           if ( fADC > 20 ) {
775             AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord,
776                           (Int_t)fADC));
777             continue;
778           }
779
780           // There are 18 pads connected to each MCM ADC channels 2...19. The
781           // other channels cross to other MCMs and are good for online tracking
782           // in the MCM.
783           if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
784
785             fCOL = fGeo->GetPadCol(fROB, fMCM, fADC);
786
787             // We have only 144 Pad Columns
788             if ( fCOL > fColMax-1 || fCOL < 0 ) {
789               AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
790                             fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
791             }
792
793             // Decode 32 bit data words with information from 3 time bins and copy the data
794             fSig[0] = (fDataWord & 0x00000ffc) >> 2;
795             fSig[1] = (fDataWord & 0x003ff000) >> 12;
796             fSig[2] = (fDataWord & 0xffc00000) >> 22;
797
798             // Print data to screen:
799             AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
800                              fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
801
802             // Write Digits
803             if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax ) {  // A real pad
804               for ( Int_t ctr = 0; ctr <3; ctr++ ) {
805                 if ( fTB+ctr < (Int_t)timeTotal ) {
806                   fDigits->SetDataUnchecked(fROW, fCOL, fTB+ctr, fSig[ctr]);
807                   fTrack0->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
808                   fTrack1->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
809                   fTrack2->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
810                 }
811               }
812             }
813
814             fTB += 3;
815
816           } 
817           else {
818
819             fCOL = -1;
820
821           }
822
823         }
824         
825       }
826
827       AliDebug(2, Form("SM%d L%dS%d side %x: Processed %d MCMs.", fSM, fLAYER, fSTACK, fSIDE+10, fMCMHctr2));
828
829     } // End Half-Chamber loop
830
831     AliDebug(1, Form("SM%d (Eq %d): Processed %d HC (%d MCMs)", fSM, EqID, fHCHctr1, fMCMHctr1));
832
833   } // End Super Module loop
834
835   return kTRUE;
836
837 }
838
839 //============================================================================
840 // Decoding functions
841 //============================================================================
842
843 //____________________________________________________________________________
844 void AliTRDRawStream::DecodeHCheader(Int_t timeBins)
845 {
846   //
847   // Decode a half chamber header
848   //
849
850   if ( (fDataWord >> 31) != 1 )  {
851
852     if ( fRawVersion == 1 ) {
853       DecodeHCheaderV1();
854     }
855     else {
856       AliError(Form("Mismatch between fRawVersion (%d) and HC header signature", fRawVersion));
857     }
858     return;
859
860   } 
861   else {
862
863     fRVmajor = (fDataWord >> 24) & 0x7f;
864     fRVminor = (fDataWord >> 17) & 0x7f;
865     if ( fRawVersion != fRVmajor ) {
866       AliError(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header(%d)"
867                    ,fRawVersion,fRVmajor));
868     }
869     if (fRawVersion == 2 ) {
870       DecodeHCheaderV2(timeBins);
871     }
872     return;
873
874   }
875
876   AliError(Form(" Unsupported raw version: %d", fRawVersion));
877   return;
878
879 }
880
881 //____________________________________________________________________________
882 void AliTRDRawStream::DecodeHCheaderV1()
883 {
884
885   //
886   // Decode the HC header (fRawVersion == 1, SM I Commissioning 06)
887   //
888
889   if ( (fDataWord & 0x3) == 1 ) {
890
891     fDCS   = (fDataWord >> 20);
892     fSM    = (fDataWord >> 15) & 0x1f;
893     fLAYER = (fDataWord >> 12) & 0x7;
894     fSTACK = (fDataWord >>  9) & 0x7;
895     fSIDE  = (fDataWord >>  8) & 0x1;
896
897     fROC   = fGeo->GetDetectorSec(fLAYER, fSTACK);
898
899     //AliDebug(3, Form("0x%08x: HC header: dcs=%d; sm=%d; roc=%d; side=%x", fDataWord, fDCS, fSM, fROC, fSIDE+10));
900     if ((fSM    <  0) || 
901         (fSM    > 17) || 
902         (fLAYER <  0) || 
903         (fLAYER >  5) || 
904         (fSTACK <  0) || 
905         (fSTACK >  4) || 
906         (fSIDE  <  0) || 
907         (fSIDE  >  1)) {
908       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
909                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
910     } 
911     else {
912       fStatus = 1;
913       fHCHctr1++;
914       fHCHctr2++;
915     }
916     fHCHWords = 0;
917
918   } 
919   else { 
920
921     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
922
923   }
924
925 }
926
927
928 //____________________________________________________________________________
929 void AliTRDRawStream::DecodeHCheaderV2(Int_t timeBins)
930 {
931   //
932   // Decode the HC header (fRawVersion == 2, Full raw production)
933   //
934
935   // 1st word
936   if ( (fDataWord & 0x3) == 1 ) {
937
938     fHCHWords = (fDataWord >> 14) & 0x7;
939     fSM       = (fDataWord >>  9) & 0x1f;
940     fLAYER    = (fDataWord >>  6) & 0x7;
941     fSTACK    = (fDataWord >>  3) & 0x7;
942     fSIDE     = (fDataWord >>  2) & 0x1;
943
944     fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
945
946     AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", fDataWord, fSM, fROC, fSIDE+10));
947
948     if ((fSM    <  0) || 
949         (fSM    > 17) || 
950         (fLAYER <  0) || 
951         (fLAYER >  5) || 
952         (fSTACK <  0) || 
953         (fSTACK >  4) || 
954         (fSIDE  <  0) || 
955         (fSIDE  >  1)) {
956       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
957                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
958     } 
959     else {
960       fStatus = 1;
961       fHCHctr1++;
962       fHCHctr2++;
963     }
964   } 
965   else { 
966     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
967   }
968
969   // 2nd word
970   if ( fHCHWords >= 1 ) {
971     // read one more word
972     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
973       AliError("Could not read data");
974       return;
975     }
976     if ( (fDataWord & 0x3) == 1 ) {
977       
978       fBCctr   =  (fDataWord >> 16);
979       fPTctr   =  (fDataWord >> 12) & 0xf;
980       fPTphase =  (fDataWord >>  8) & 0xf;
981       fTBins   = ((fDataWord >>  2) & 0x3f) + 1;
982
983       AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
984                       , fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
985
986       if( fTBins != timeBins ) {
987         AliError(Form("Mismatch between Number of Time Bins from CDB (%d) and from HC header (%d)"
988                      , timeBins, fTBins));
989       }
990
991     }
992
993   }
994
995   // 3rd word
996   if ( fHCHWords >= 2 ) {
997     // read one more word
998     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
999       AliError("Could not read data");
1000       return;
1001     }
1002     if ( (fDataWord & 0x3) == 1 ) {
1003       /*
1004       Not finished. Next to come:
1005       fTCon 
1006       fPEDon
1007       fGAINon
1008       fFiltered
1009       .....
1010     */
1011     }
1012
1013   }
1014
1015 }  
1016
1017 //____________________________________________________________________________
1018 void AliTRDRawStream::DecodeMCMheader()
1019 {
1020   //
1021   //
1022   //
1023
1024   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1025     DecodeMCMheaderV1();
1026     return;
1027   }
1028
1029   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1030   return;
1031
1032 }
1033
1034 //____________________________________________________________________________
1035 void AliTRDRawStream::DecodeMCMheaderV1()
1036 {
1037
1038   //
1039   // Decode the MCM header
1040   //
1041
1042   fMCM  = (fDataWord & 0xff000000) >> 24;
1043   fEv   = (fDataWord & 0x00fffff0) >> 4;
1044
1045   fROB  = fMCM / 16;
1046   fMCM  = fMCM % 16;
1047
1048   fROW  = fGeo->GetPadRow(fROB, fMCM);
1049
1050   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
1051                   , fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
1052
1053   if ( fROB % 2 == 0 && fSIDE == 1 ) {
1054     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1055                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1056   }
1057   if ( fROB % 2 != 0 && fSIDE == 0 ) {
1058     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1059                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1060   }
1061   if ( (fSTACK == 2 && fROW > 11) || (fSTACK != 2 && fROW > 15) || fROW < 0 ) {
1062     AliError(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
1063                  , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
1064   }
1065   
1066   fMCMHctr1++;
1067   fMCMHctr2++;
1068
1069 }
1070
1071 //____________________________________________________________________________
1072 void AliTRDRawStream::DecodeTracklet()
1073 {
1074   //
1075   //
1076   //
1077
1078   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1079     DecodeTrackletV1();
1080     return;
1081   }
1082
1083   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1084   return;
1085
1086 }
1087
1088 //____________________________________________________________________________
1089 void AliTRDRawStream::DecodeTrackletV1()
1090 {
1091
1092   //
1093   // Decode the Tracklet
1094   //
1095   // this function is not tested yet on real tracklets
1096   //
1097
1098   fTracklPID    = (fDataWord >> 24) & 0xff;
1099   fTracklPadRow = (fDataWord >> 20) & 0xf;    // 0:15
1100   fTracklDefL   = (fDataWord >> 13) & 0x7f;
1101   fTracklPadPos = (fDataWord)       & 0x1fff;
1102
1103   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
1104   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
1105   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
1106
1107   AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
1108                   , fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
1109                   , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
1110
1111   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
1112       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
1113     AliError(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
1114   }
1115
1116 }
1117
1118 //____________________________________________________________________________
1119 void AliTRDRawStream::DecodeGTUlinkMask()
1120 {
1121   //
1122   //
1123   //
1124
1125   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1126     DecodeGTUlinkMaskV1();
1127     return;
1128   }
1129
1130   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1131   return;
1132
1133 }
1134
1135 //____________________________________________________________________________
1136 void AliTRDRawStream::DecodeGTUlinkMaskV1()
1137 {
1138
1139   //
1140   // Decode the link masks sent by the GTU. These marke the active optical links
1141   // between GTU and Super Module. Up to now only fully active links are found
1142   // (0xfff = 12 active links).
1143   //
1144
1145   if ( fGTUctr1 == -1 ) fGTUctr2++;
1146   fGTUctr1++;
1147
1148   //printf("fGTUctr=%d",fGTUctr);
1149   //printf("fGTUctr1=%d, fGTUctr2=%d",fGTUctr1, fGTUctr2);
1150
1151   if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) {
1152     fGTUlinkMask[fGTUctr2][fGTUctr1] = (fDataWord & 0xfff);
1153   }
1154
1155   for ( Int_t ctr = 0; ctr < 12; ctr++ ) {
1156     if ( IsGTULinkActive(fGTUctr2, ctr/2, fGTUctr1, ctr%2) ) {
1157       AliDebug(3, Form("SM %2d Stack %d: GTU Link %2d is active!", fGTUctr2, fGTUctr1, ctr)); 
1158     }
1159   }
1160
1161 }
1162