]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDRawStream.cxx
Revised version of raw data v1 (bug fix and coding vios)
[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 }
365
366 //_____________________________________________________________________________
367 Bool_t AliTRDRawStream::SetRawVersion(Int_t rv)
368 {
369   //
370   // Set the raw data version
371   //
372
373   if ( rv >= 0 && rv <= 2 ) {
374     fRawVersion = rv;
375     return kTRUE;
376   }
377
378   return kFALSE;
379
380 }
381
382 //_____________________________________________________________________________
383 Bool_t AliTRDRawStream::Next()
384 {
385   //
386   // This is Bogdans code for reading raw data (offline use only).
387   // It is used for fRawVersion == 0. This funcyion read the next raw digit.
388   // Returns kFALSE if there is no digit left
389   //
390
391   fPrevDetector = fDetector;
392   fPrevRow      = fRow;
393   fPrevColumn   = fColumn;
394   UChar_t data;
395
396   AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
397   if (!calibration) return kFALSE;
398   
399   Int_t timeBins = calibration->GetNumberOfTimeBins();
400   
401   while (fCount >= 0) {
402
403     while (fCount == 0) {  // next detector
404
405       // read the flag
406       if (!fRawReader->ReadNextChar(data)) {
407         return kFALSE;
408       }
409       if (data != 0xBB) {
410         AliError(Form("wrong flag: %x", data));
411         fCount = -1;
412         return kFALSE;
413       }
414
415       // read the detector number
416       if (!fRawReader->ReadNextChar(data)) {
417         AliError("Could not read detector number");
418         fCount = -1;
419         return kFALSE;
420       }
421       fDetector = data;
422       if (!fRawReader->ReadNextChar(data)) {
423         AliError("Could not read detector number");
424         fCount = -1;
425         return kFALSE;
426       }
427       fDetector += (UInt_t(data) << 8);
428
429       // read the number of byts
430       if (!fRawReader->ReadNextChar(data)) {
431         AliError("Could not read number of bytes");
432         fCount = -1;
433         return kFALSE;
434       }
435       fCount = data;
436       if (!fRawReader->ReadNextChar(data)) {
437         AliError("Could not read number of bytes");
438         fCount = -1;
439         return kFALSE;
440       }
441       fCount += (UInt_t(data) << 8);
442       if (!fRawReader->ReadNextChar(data)) {
443         AliError("Could not read number of bytes");
444         fCount = -1;
445         return kFALSE;
446       }
447       fCount += (UInt_t(data) << 16);
448
449       // read the number of active pads
450       if (!fRawReader->ReadNextChar(data)) {
451         AliError("Could not read number of active pads");
452         fCount = -1;
453         return kFALSE;
454       }
455       fNPads = data;
456       if (!fRawReader->ReadNextChar(data)) {
457         AliError("Could not read number of active pads");
458         fCount = -1;
459         return kFALSE;
460       }
461       fNPads += (UInt_t(data) << 8);
462
463       fTime = timeBins;
464
465     }
466
467     // read the pad row and column number
468     if ((fTime >= timeBins) && (fCount > 2)) {
469       if (!fRawReader->ReadNextChar(data)) {
470         AliError("Could not read row number");
471         fCount = -1;
472         return kFALSE;
473       }
474       fCount--;
475       fRow = data - 1;
476       if (!fRawReader->ReadNextChar(data)) {
477         AliError("Could not read column number");
478         fCount = -1;
479         return kFALSE;
480       }
481       fCount--;
482       fColumn = data - 1;
483       fTime = 0;
484     }
485
486     // read the next data byte
487     if (!fRawReader->ReadNextChar(data)) {
488       AliError("Could not read data");
489       fCount = -1;
490       return kFALSE;
491     }
492     fCount--;
493
494     if (data == 0) {  // zeros
495       if (!fRawReader->ReadNextChar(data)) {
496         AliError("Could not read time value");
497         fCount = -1;
498         return kFALSE;
499       }
500       fCount--;
501       fTime += data + 1;
502
503     } 
504     else {          // signal
505       fSignal = (UInt_t(data & 0x7F) << 8);
506       if (!fRawReader->ReadNextChar(data)) {
507         AliError("Could not read ADC value");
508         fCount = -1;
509         return kFALSE;
510       }
511       fCount--;
512       fSignal += data;
513       fTime++;
514       return kTRUE;
515     }
516   }
517
518   return kFALSE;
519
520 }
521
522 //____________________________________________________________________________
523 Bool_t AliTRDRawStream::ReadAll()
524 {
525
526   //
527   // Read all TRD raw data word (32 bits). This is for all fRawVersion > 0.
528   // Return kFALSE if something is not cool
529   //
530   // by C. Lippmann
531   //
532  
533   AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
534   if (!commonParam) {
535     AliError("Could not get common parameters");
536     return kFALSE;
537   }
538
539   AliTRDcalibDB     *calibration = AliTRDcalibDB::Instance();
540   if (!calibration) {
541     AliError("Could not get calibration object");
542     return kFALSE;
543   }
544   
545   UInt_t timeTotal = calibration->GetNumberOfTimeBins();
546
547   // The number of data words needed for this number of time bins (there
548   // are 3 time bins in one word)
549   UInt_t timeWords = ( timeTotal%3 == 0 ) ? timeTotal/3 :  timeTotal/3 + 1;
550
551   AliDebug(2, Form("Number of Timebins read from CDB: %d", timeTotal));
552
553   UInt_t tBswitch    = 3;
554   UInt_t tBswitchCtr = 0;
555   Int_t  wordCtr     = 0;
556   Int_t  EqID        = 0;
557   Int_t  datasize    = 0;
558   Int_t  iDET        = 0;
559
560   fHCHctr1 = fHCHctr2 =  0;
561   fGTUctr1 = fGTUctr2 = -1;
562
563   AliInfo("Converting TRD raw data to digits ...");
564
565   while ( 1 ) { // loop over all supermodules
566
567     wordCtr   = 0;
568     fHCHctr1  = 0;
569     fMCMHctr1 = 0;
570
571     //
572     // 0) Find first GTU Link Mask and test if we can read data
573     //
574     do {
575
576       if ( !fRawReader->ReadNextInt( fDataWord ) ) {  // This is the standard exit point
577         // Compress also the digits from the last detector
578         if ( fChamberDone[iDET] == 2 ) {
579           //printf("Compressing data for det %d\n", iDET);
580           fDigits->Compress(1,0);
581           fTrack0->Compress(1,0);
582           fTrack1->Compress(1,0);
583           fTrack2->Compress(1,0);
584         }
585         AliInfo(Form("Finished processing TRD raw data: Found %d Half-Chambers", fHCHctr2));
586         //
587         /*
588         fDigits = fDigitsManager->GetDigits(iDET+1);
589         fTrack0 = fDigitsManager->GetDictionary(iDET+1,0);
590         fTrack1 = fDigitsManager->GetDictionary(iDET+1,1);
591         fTrack2 = fDigitsManager->GetDictionary(iDET+1,2);
592         fDigits->Allocate(fRowMax,fColMax,timeTotal);
593         fTrack0->Allocate(fRowMax,fColMax,timeTotal);
594         fTrack1->Allocate(fRowMax,fColMax,timeTotal);
595         fTrack2->Allocate(fRowMax,fColMax,timeTotal);
596         fDigits->SetDataUnchecked(0, 0, 0, 50);
597         fTrack0->SetDataUnchecked(0, 0, 0, 0);
598         fTrack1->SetDataUnchecked(0, 0, 0, 0);
599         fTrack2->SetDataUnchecked(0, 0, 0, 0);  
600         fDigits->Compress(1,0);
601         fTrack0->Compress(1,0);
602         fTrack1->Compress(1,0);
603         fTrack2->Compress(1,0);
604         */
605         //
606         return kTRUE;
607       }
608       wordCtr++;
609
610       // After reading the first word check for size of this data and get Eq. ID
611       if ( wordCtr == 1 ) {
612         datasize = fRawReader->GetDataSize()/4;  // Size of this payload is in 32bit words
613         EqID     = fRawReader->GetEquipmentId(); // Get Equipment ID
614       }
615
616       // GTU Link Mask?
617       if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
618         fStatus = 1;      // GTU link mask found
619         DecodeGTUlinkMask();
620         break;
621       } 
622       else {
623         AliError(Form("Equipment %d: First data word is not GTU Link Mask!", EqID));
624         return kFALSE;
625       }
626
627     } 
628     while ( wordCtr < datasize );
629
630     //
631     // loop over all half chambers in one supermodule
632     //
633     while ( wordCtr < datasize ) {
634
635       //
636       // 1) Find end_of_tracklet_marker
637       //
638       while ( wordCtr < datasize ) {
639
640         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
641           AliError("Could not read data");
642           return kFALSE;
643         }
644         wordCtr++;
645
646         // GTU Link Mask?
647         if ( (fDataWord & 0xfffff000) ==  0xe0000000 ) {
648           DecodeGTUlinkMask();
649           continue;
650         }
651
652         // endoftrackletmarker?
653         if ( fDataWord == endoftrackletmarker ) {
654           AliDebug(3, "end-of-tracklet-marker found");
655           fStatus = 1;
656           break;
657         } 
658         else {
659           // Tracklets found
660           AliDebug(3, "Tracklet found");
661           DecodeTracklet();
662         }
663
664       }
665
666       if ( fStatus == 0 ) break;
667     
668       //
669       // 2) Look for non-end_of_tracklet_marker
670       //
671       fStatus = 0;
672       while ( wordCtr < datasize ) { 
673
674         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
675           AliError("Could not read data");
676           return kFALSE;
677         }
678         wordCtr++;
679         //printf("Word %d: 0x%08x\n", wordCtr, fDataWord); 
680
681         if ( fDataWord != endoftrackletmarker ) {
682           fStatus = 1;
683           break;
684         }
685
686       }
687
688       if ( fStatus == 0 ) break;
689     
690       //
691       // 3) This Word must be Half Chamber Header
692       //
693       fStatus = 0;
694       if ( (fDataWord & 0x00000003) == 1 ) { // HC header
695
696         // If both half chambers of chamber corresponding to previous header
697         // were already processed, we can compress these digits
698         iDET = fGeo->GetDetector(fLAYER, fSTACK, fSM); // !!this is still the previous HC!!!
699         if ( fChamberDone[iDET] == 2 ) {
700           //printf("Compressing data for det %d\n", iDET);
701           fDigits->Compress(1,0);
702           fTrack0->Compress(1,0);
703           fTrack1->Compress(1,0);
704           fTrack2->Compress(1,0);
705         }
706
707         // Read from new HC header the chamber position (fLAYER, fSTACK, fSM)
708         DecodeHCheader(timeTotal); // This is the new header!
709         wordCtr += fHCHWords;
710         iDET    = fGeo->GetDetector(fLAYER, fSTACK, fSM);
711         fRowMax = commonParam->GetRowMax(fLAYER,fSTACK,fSM);
712         fColMax = commonParam->GetColMax(fROC);
713
714         // The container for the digits of this detector
715         fDigits = fDigitsManager->GetDigits(iDET);
716         fTrack0 = fDigitsManager->GetDictionary(iDET,0);
717         fTrack1 = fDigitsManager->GetDictionary(iDET,1);
718         fTrack2 = fDigitsManager->GetDictionary(iDET,2);
719         
720         // Allocate memory if it was not already done
721         if (fDigits->GetNtime() == 0) {
722           //printf("Allocating digits memory for det %d\n", iDET);
723           fDigits->Allocate(fRowMax,fColMax,timeTotal);
724           fTrack0->Allocate(fRowMax,fColMax,timeTotal);
725           fTrack1->Allocate(fRowMax,fColMax,timeTotal);
726           fTrack2->Allocate(fRowMax,fColMax,timeTotal);
727         }
728
729         fMCMHctr2 = 0;
730
731         fChamberDone[iDET]++;
732
733       }
734     
735       //
736       // 4) Scan MCM data
737       //
738       fStatus = 0;
739       while ( wordCtr < datasize ) {
740
741         if ( !fRawReader->ReadNextInt( fDataWord ) ) {
742           AliError("Could not read data");
743           return kFALSE;
744         }
745         wordCtr++;
746         //printf("Word %d: 0x%08x\n", wordCtr, fDataWord); 
747       
748         if( (fDataWord & 0x0000000f) == 0xC ) { // MCM Header
749           DecodeMCMheader();
750           if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 ) {
751             AliError("Wrong fMCM or fROB. Skip this data");
752             break;
753           }
754           tBswitch    = 3;  // For first adc channel we expect: (fDataWord & 3) = 3
755           tBswitchCtr = 0;  // 
756           fADC = fTB  = 0;  // Reset Counter
757           fStatus     = 1;  // Now 1 means MCM header is found
758           continue;
759         }
760     
761         // End of half-chamber data, finished:
762         if ( fDataWord == endofeventmarker ) {
763           fGTUctr1 = -1;
764           break;
765         }
766
767         if ( fStatus == 1 ) {       // MCM header is set, ADC data is valid.
768     
769           //
770           // Found some data. Decode it now:
771           //
772           if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
773             AliError(Form("Data %08x : Data Word ends neither with 11 nor 10", (Int_t)fDataWord));
774             break;
775           }
776
777           if ( (fDataWord & 0x00000003) != tBswitch ) {    // Next ADC channel found
778             //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
779             tBswitch = (tBswitch & 2) | !(tBswitch & 1);   // 0x3 <--> 0x2
780             tBswitchCtr = 0;
781             fADC++;
782             fTB=0;
783           }
784
785           tBswitchCtr++; // Just read one word
786         
787           // We have only timeTotal time bins
788           if ( tBswitchCtr > timeWords ) {
789             AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)tBswitchCtr));
790             continue;
791           }
792
793           // We have only 21 ADC channels.
794           if ( fADC > (Int_t)fGeo->ADCmax()-1 ) {
795             AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord, (Int_t)fADC));
796             continue;
797           }
798
799           // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
800           // MCMs and are good for online tracking in the MCM.
801           if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
802
803             // Get Pad column
804             fCOL = fGeo->GetPadCol(fROB, fMCM, fADC);
805
806             // We have only 144 Pad Columns
807             if ( fCOL > fColMax-1 || fCOL < 0 ) {
808               AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
809                             fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
810             }
811
812             // Decode 32 bit data words with information from 3 time bins and copy the data
813             fSig[0] = (fDataWord & 0x00000ffc) >> 2;
814             fSig[1] = (fDataWord & 0x003ff000) >> 12;
815             fSig[2] = (fDataWord & 0xffc00000) >> 22;
816
817             // Print data to screen:
818             AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
819                              fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
820
821             // Write Digits
822             if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax ) {  // A real pad
823               for ( Int_t ctr = 0; ctr < 3; ctr++ ) {
824                 if ( fTB+ctr < (Int_t)timeTotal ) {
825                   /*
826                   fDigits->SetDataUnchecked(fROW, fCOL, fTB+ctr, fSig[ctr]);
827                   fTrack0->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
828                   fTrack1->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
829                   fTrack2->SetDataUnchecked(fROW, fCOL, fTB+ctr, 0);
830                   */
831                   fDigits->SetData(fROW, fCOL, fTB+ctr, fSig[ctr]);
832                   fTrack0->SetData(fROW, fCOL, fTB+ctr, 0);
833                   fTrack1->SetData(fROW, fCOL, fTB+ctr, 0);
834                   fTrack2->SetData(fROW, fCOL, fTB+ctr, 0);
835                 }
836               }
837             }
838
839             fTB += 3;
840
841           } 
842           else {
843
844             fCOL = -1;
845
846           }
847
848         }
849         
850       }
851
852       AliDebug(2, Form("SM%d L%dS%d side %x: Processed %d MCMs.", fSM, fLAYER, fSTACK, fSIDE+10, fMCMHctr2));
853
854     } // End Half-Chamber loop
855
856     AliDebug(1, Form("SM%d (Eq %d): Processed %d HC (%d MCMs)", fSM, EqID, fHCHctr1, fMCMHctr1));
857
858   } // End Super Module loop
859
860   // Compress also the digits from the last detector
861   if ( fChamberDone[iDET] == 2 ) {
862     //printf("Compressing data for det %d\n", iDET);
863     fDigits->Compress(1,0);
864     fTrack0->Compress(1,0);
865     fTrack1->Compress(1,0);
866     fTrack2->Compress(1,0);
867   }
868
869   return kTRUE;
870
871 }
872
873 //============================================================================
874 // Decoding functions
875 //============================================================================
876
877 //____________________________________________________________________________
878 void AliTRDRawStream::DecodeHCheader(Int_t timeBins)
879 {
880   //
881   // Decode a half chamber header
882   //
883
884   if ( (fDataWord >> 31) != 1 )  {
885
886     if ( fRawVersion == 1 ) {
887       DecodeHCheaderV1();
888     }
889     else {
890       AliError(Form("Mismatch between fRawVersion (%d) and HC header signature", fRawVersion));
891     }
892     return;
893
894   } 
895   else {
896
897     fRVmajor = (fDataWord >> 24) & 0x7f;
898     fRVminor = (fDataWord >> 17) & 0x7f;
899     if ( fRawVersion != fRVmajor ) {
900       AliError(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header(%d)"
901                    ,fRawVersion,fRVmajor));
902     }
903     if (fRawVersion == 2 ) {
904       DecodeHCheaderV2(timeBins);
905     }
906     return;
907
908   }
909
910   AliError(Form(" Unsupported raw version: %d", fRawVersion));
911   return;
912
913 }
914
915 //____________________________________________________________________________
916 void AliTRDRawStream::DecodeHCheaderV1()
917 {
918
919   //
920   // Decode the HC header (fRawVersion == 1, SM I Commissioning 06)
921   //
922
923   if ( (fDataWord & 0x3) == 1 ) {
924
925     fDCS   = (fDataWord >> 20);
926     fSM    = (fDataWord >> 15) & 0x1f;
927     fLAYER = (fDataWord >> 12) & 0x7;
928     fSTACK = (fDataWord >>  9) & 0x7;
929     fSIDE  = (fDataWord >>  8) & 0x1;
930
931     fROC   = fGeo->GetDetectorSec(fLAYER, fSTACK);
932
933     //AliDebug(3, Form("0x%08x: HC header: dcs=%d; sm=%d; roc=%d; side=%x", fDataWord, fDCS, fSM, fROC, fSIDE+10));
934     if ((fSM    <  0) || 
935         (fSM    > 17) || 
936         (fLAYER <  0) || 
937         (fLAYER >  5) || 
938         (fSTACK <  0) || 
939         (fSTACK >  4) || 
940         (fSIDE  <  0) || 
941         (fSIDE  >  1)) {
942       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
943                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
944     } 
945     else {
946       fStatus = 1;
947       fHCHctr1++;
948       fHCHctr2++;
949     }
950     fHCHWords = 0;
951
952   } 
953   else { 
954
955     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
956
957   }
958
959 }
960
961
962 //____________________________________________________________________________
963 void AliTRDRawStream::DecodeHCheaderV2(Int_t timeBins)
964 {
965   //
966   // Decode the HC header (fRawVersion == 2, Full raw production)
967   //
968
969   // 1st word
970   if ( (fDataWord & 0x3) == 1 ) {
971
972     fHCHWords = (fDataWord >> 14) & 0x7;
973     fSM       = (fDataWord >>  9) & 0x1f;
974     fLAYER    = (fDataWord >>  6) & 0x7;
975     fSTACK    = (fDataWord >>  3) & 0x7;
976     fSIDE     = (fDataWord >>  2) & 0x1;
977
978     fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
979
980     AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", fDataWord, fSM, fROC, fSIDE+10));
981
982     if ((fSM    <  0) || 
983         (fSM    > 17) || 
984         (fLAYER <  0) || 
985         (fLAYER >  5) || 
986         (fSTACK <  0) || 
987         (fSTACK >  4) || 
988         (fSIDE  <  0) || 
989         (fSIDE  >  1)) {
990       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
991                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
992     } 
993     else {
994       fStatus = 1;
995       fHCHctr1++;
996       fHCHctr2++;
997     }
998   } 
999   else { 
1000     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
1001   }
1002
1003   // 2nd word
1004   if ( fHCHWords >= 1 ) {
1005     // read one more word
1006     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1007       AliError("Could not read data");
1008       return;
1009     }
1010     if ( (fDataWord & 0x3) == 1 ) {
1011       
1012       fBCctr   =  (fDataWord >> 16);
1013       fPTctr   =  (fDataWord >> 12) & 0xf;
1014       fPTphase =  (fDataWord >>  8) & 0xf;
1015       fTBins   = ((fDataWord >>  2) & 0x3f) + 1;
1016
1017       AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
1018                       , fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
1019
1020       if( fTBins != timeBins ) {
1021         AliError(Form("Mismatch between Number of Time Bins from CDB (%d) and from HC header (%d)"
1022                      , timeBins, fTBins));
1023       }
1024
1025     }
1026
1027   }
1028
1029   // 3rd word
1030   if ( fHCHWords >= 2 ) {
1031     // read one more word
1032     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1033       AliError("Could not read data");
1034       return;
1035     }
1036     if ( (fDataWord & 0x3) == 1 ) {
1037       /*
1038       Not finished. Next to come:
1039       fTCon 
1040       fPEDon
1041       fGAINon
1042       fFiltered
1043       .....
1044     */
1045     }
1046
1047   }
1048
1049 }  
1050
1051 //____________________________________________________________________________
1052 void AliTRDRawStream::DecodeMCMheader()
1053 {
1054   //
1055   //
1056   //
1057
1058   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1059     DecodeMCMheaderV1();
1060     return;
1061   }
1062
1063   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1064   return;
1065
1066 }
1067
1068 //____________________________________________________________________________
1069 void AliTRDRawStream::DecodeMCMheaderV1()
1070 {
1071
1072   //
1073   // Decode the MCM header
1074   //
1075
1076   fMCM  = (fDataWord & 0xff000000) >> 24;
1077   fEv   = (fDataWord & 0x00fffff0) >> 4;
1078
1079   fROB  = fMCM / 16;
1080   fMCM  = fMCM % 16;
1081
1082   fROW  = fGeo->GetPadRow(fROB, fMCM);
1083
1084   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
1085                   , fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
1086
1087   if ( fROB % 2 == 0 && fSIDE == 1 ) {
1088     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1089                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1090   }
1091   if ( fROB % 2 != 0 && fSIDE == 0 ) {
1092     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1093                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1094   }
1095   if ( (fSTACK == 2 && fROW > 11) || (fSTACK != 2 && fROW > 15) || fROW < 0 ) {
1096     AliError(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
1097                  , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
1098   }
1099   
1100   fMCMHctr1++;
1101   fMCMHctr2++;
1102
1103 }
1104
1105 //____________________________________________________________________________
1106 void AliTRDRawStream::DecodeTracklet()
1107 {
1108   //
1109   //
1110   //
1111
1112   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1113     DecodeTrackletV1();
1114     return;
1115   }
1116
1117   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1118   return;
1119
1120 }
1121
1122 //____________________________________________________________________________
1123 void AliTRDRawStream::DecodeTrackletV1()
1124 {
1125
1126   //
1127   // Decode the Tracklet
1128   //
1129   // this function is not tested yet on real tracklets
1130   //
1131
1132   fTracklPID    = (fDataWord >> 24) & 0xff;
1133   fTracklPadRow = (fDataWord >> 20) & 0xf;    // 0:15
1134   fTracklDefL   = (fDataWord >> 13) & 0x7f;
1135   fTracklPadPos = (fDataWord)       & 0x1fff;
1136
1137   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
1138   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
1139   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
1140
1141   AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
1142                   , fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
1143                   , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
1144
1145   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
1146       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
1147     AliError(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
1148   }
1149
1150 }
1151
1152 //____________________________________________________________________________
1153 void AliTRDRawStream::DecodeGTUlinkMask()
1154 {
1155   //
1156   //
1157   //
1158
1159   if ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1160     DecodeGTUlinkMaskV1();
1161     return;
1162   }
1163
1164   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1165   return;
1166
1167 }
1168
1169 //____________________________________________________________________________
1170 void AliTRDRawStream::DecodeGTUlinkMaskV1()
1171 {
1172
1173   //
1174   // Decode the link masks sent by the GTU. These marke the active optical links
1175   // between GTU and Super Module. Up to now only fully active links are found
1176   // (0xfff = 12 active links).
1177   //
1178
1179   if ( fGTUctr1 == -1 ) fGTUctr2++;
1180   fGTUctr1++;
1181
1182   //printf("fGTUctr=%d",fGTUctr);
1183   //printf("fGTUctr1=%d, fGTUctr2=%d",fGTUctr1, fGTUctr2);
1184
1185   if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) {
1186     fGTUlinkMask[fGTUctr2][fGTUctr1] = (fDataWord & 0xfff);
1187   }
1188
1189   for ( Int_t ctr = 0; ctr < 12; ctr++ ) {
1190     if ( IsGTULinkActive(fGTUctr2, ctr/2, fGTUctr1, ctr%2) ) {
1191       AliDebug(3, Form("SM %2d Stack %d: GTU Link %2d is active!", fGTUctr2, fGTUctr1, ctr)); 
1192     }
1193   }
1194
1195 }
1196