]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDRawStream.cxx
Adding statistical function (Marian)
[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                   // The MC labels have been already flushed, no need
855                   // in the following three lines
856                   //              fTrack0->SetData(fROW, fCOL, fTB+ctr, 0);
857                   //              fTrack1->SetData(fROW, fCOL, fTB+ctr, 0);
858                   //              fTrack2->SetData(fROW, fCOL, fTB+ctr, 0);
859                   //
860                 }
861               }
862             }
863
864             fTB += 3;
865
866           }
867           else {
868
869             fCOL = -1;
870
871           }
872
873         }
874
875       }
876
877       AliDebug(2, Form("SM%02d L%dS%d side %x: Processed %dMCMs=%dbyte", fSM, fLAYER, fSTACK, fSIDE+10,
878                        fMCMHctr2, fHCdataCtr));
879
880     } // End Half-Chamber loop
881
882     AliDebug(1, Form("SM%02d (Eq %d): Processed %d HC (%dMCMs=%dbyte)", fSM, EqID, fHCHctr1, fMCMHctr1,
883                      datasize*4));
884     
885   } // End Super Module loop
886
887   // Compress also the digits from the last detector
888   if ( fChamberDone[iDET] == 2 ) {
889     //printf("Compressing data for det %d\n", iDET);
890     fDigits->Compress(1,0);
891     fTrack0->Compress(1,0);
892     fTrack1->Compress(1,0);
893     fTrack2->Compress(1,0);
894   }
895
896   if ( sizeOK ) return 1;
897   else          return 2;
898
899 }
900
901 //============================================================================
902 // Decoding functions
903 //============================================================================
904
905 //____________________________________________________________________________
906 void AliTRDRawStream::DecodeHCheader(Int_t timeBins)
907 {
908   //
909   // Decode a half chamber header
910   //
911
912   if ( (fDataWord >> 31) == 0 )  { // Can only happen for fRawVersion == 1
913
914     if ( fRawVersion != 1 ) {
915
916       AliWarning("===============================================================================");
917       AliWarning(Form("Mismatch between fRawVersion (%d) and HC header signature", fRawVersion));
918       AliWarning("Setting fRawVersion to 1");
919       AliWarning("===============================================================================");
920       fRawVersion = 1;
921
922     }
923
924     DecodeHCheaderV1();
925     return;
926
927   } 
928   else {
929
930     fRVmajor = (fDataWord >> 24) & 0x7f;
931     fRVminor = (fDataWord >> 17) & 0x7f;
932
933     if ( fRawVersion != fRVmajor ) {
934
935       AliWarning("===============================================================================");
936       AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
937                       ,fRawVersion,fRVmajor));
938       AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
939       AliWarning("===============================================================================");
940       fRawVersion = fRVmajor;
941
942     }
943     if ( fRawVersion >= 2 && fRawVersion <= 3 ) {
944       DecodeHCheaderV2V3(timeBins);
945     }
946
947     //
948     // check for zero suppression
949     if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
950     else                                        fZeroSuppressed = kFALSE;
951
952     return;
953
954   }
955
956   AliError(Form(" Unsupported raw version: %d", fRawVersion));
957   return;
958
959 }
960
961 //____________________________________________________________________________
962 void AliTRDRawStream::DecodeHCheaderV1()
963 {
964
965   //
966   // Decode the HC header (fRawVersion == 1, SM I Commissioning 06)
967   //
968
969   if ( (fDataWord & 0x3) == 1 ) {
970
971     fDCS   = (fDataWord >> 20);
972     fSM    = (fDataWord >> 15) & 0x1f;
973     fLAYER = (fDataWord >> 12) & 0x7;
974     fSTACK = (fDataWord >>  9) & 0x7;
975     fSIDE  = (fDataWord >>  8) & 0x1;
976
977     fROC   = fGeo->GetDetectorSec(fLAYER, fSTACK);
978
979     //AliDebug(3, Form("0x%08x: HC header: dcs=%d; sm=%d; roc=%d; side=%x", fDataWord, fDCS, fSM, fROC, fSIDE+10));
980
981     if ((fSM    <  0) || 
982         (fSM    > 17) || 
983         (fLAYER <  0) || 
984         (fLAYER >  5) || 
985         (fSTACK <  0) || 
986         (fSTACK >  4) || 
987         (fSIDE  <  0) || 
988         (fSIDE  >  1)) {
989       AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
990                       fDataWord, fDCS, fSM, fLAYER, fSTACK));
991     } 
992     else {
993       fStatus = 1;
994       fHCHctr1++;
995       fHCHctr2++;
996     }
997     fHCHWords = 0;
998
999   } 
1000   else { 
1001
1002     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
1003
1004   }
1005
1006 }
1007
1008
1009 //____________________________________________________________________________
1010 void AliTRDRawStream::DecodeHCheaderV2V3(Int_t timeBins)
1011 {
1012   //
1013   // Decode the HC header (fRawVersion == 2, 3, 4, ???)
1014   //
1015
1016   // 1st word (h[0])
1017   if ( (fDataWord & 0x3) == 1 ) {
1018
1019     fHCHWords = (fDataWord >> 14) & 0x7;
1020     fSM       = (fDataWord >>  9) & 0x1f;
1021     fLAYER    = (fDataWord >>  6) & 0x7;
1022     fSTACK    = (fDataWord >>  3) & 0x7;
1023     fSIDE     = (fDataWord >>  2) & 0x1;
1024
1025     fROC      = fGeo->GetDetectorSec(fLAYER, fSTACK);
1026
1027     AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", fDataWord, fSM, fROC, fSIDE+10));
1028
1029     if ((fSM    <  0) || 
1030         (fSM    > 17) || 
1031         (fLAYER <  0) || 
1032         (fLAYER >  5) || 
1033         (fSTACK <  0) || 
1034         (fSTACK >  4) || 
1035         (fSIDE  <  0) || 
1036         (fSIDE  >  1)) {
1037       AliError(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
1038                     fDataWord, fDCS, fSM, fLAYER, fSTACK));
1039     } 
1040     else {
1041       fStatus = 1;
1042       fHCHctr1++;
1043       fHCHctr2++;
1044     }
1045   } 
1046   else { 
1047     AliError(Form("0x%08x: No HC header when it was expected.", fDataWord)); 
1048   }
1049
1050   // 2nd word (h[1])
1051   if ( fHCHWords >= 1 ) {
1052     // read one more word
1053     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1054       AliError("Could not read data");
1055       return;
1056     }
1057     fWordCtr++;
1058     if ( (fDataWord & 0x3) == 1 ) {
1059       
1060       fBCctr   =  (fDataWord >> 16);
1061       fPTctr   =  (fDataWord >> 12) & 0xf;
1062       fPTphase =  (fDataWord >>  8) & 0xf;
1063       fTBins   = ((fDataWord >>  2) & 0x3f) + 1;
1064
1065       AliDebug(3, Form("0x%08x: HC header 2: BCctr=%d PTctr=%d PTph=%d TB=%d"
1066                       , fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
1067
1068       if( fTBins != timeBins ) {
1069
1070         AliWarning("===============================================================================");
1071         AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
1072                       , timeBins, fTBins));
1073         AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
1074         AliWarning("===============================================================================");
1075
1076       }
1077
1078     }
1079
1080   }
1081
1082   // 3nd word (h[2])
1083   if ( fHCHWords >= 2 ) {
1084     // read one more word
1085     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1086       AliError("Could not read data");
1087       return;
1088     }
1089     fWordCtr++;
1090     if ( (fDataWord & 0x3) == 1 ) {
1091        
1092       fTCon     = (fDataWord >> 29) & 0x1;
1093       fPEDon    = (fDataWord >> 31) & 0x1;
1094       fGAINon   = (fDataWord >> 30) & 0x1;
1095       fXTon     = (fDataWord >> 28) & 0x1;
1096       fNonLinOn = (fDataWord >> 27) & 0x1;
1097       fBypass   = (fDataWord >> 26) & 0x1;
1098
1099       fCommonAdditive = (fDataWord >> 20) & 0x3f;
1100
1101       AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
1102                       , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
1103
1104       if( fTBins != timeBins ) {
1105         AliError(Form("Mismatch between Number of Time Bins from CDB (%d) and from HC header (%d)"
1106                      , timeBins, fTBins));
1107       }
1108
1109     }
1110
1111   }
1112
1113 }  
1114
1115 //____________________________________________________________________________
1116 void AliTRDRawStream::DecodeMCMheader()
1117 {
1118   //
1119   //
1120   //
1121
1122   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1123     DecodeMCMheaderVx();
1124     return;
1125   }
1126
1127   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1128   return;
1129
1130 }
1131
1132 //____________________________________________________________________________
1133 void AliTRDRawStream::DecodeMCMheaderVx()
1134 {
1135
1136   //
1137   // Decode the MCM header
1138   //
1139
1140   fMCM  = (fDataWord & 0xff000000) >> 24;
1141   fEv   = (fDataWord & 0x00fffff0) >> 4;
1142
1143   fROB  = fMCM / 16;
1144   fMCM  = fMCM % 16;
1145
1146   fROW  = fGeo->GetPadRowFromMCM(fROB, fMCM);
1147
1148   AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
1149                   , fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
1150
1151   if ( fROB % 2 == 0 && fSIDE == 1 ) {
1152     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1153                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1154   }
1155   if ( fROB % 2 != 0 && fSIDE == 0 ) {
1156     AliError(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
1157                  , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
1158   }
1159   if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
1160        (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 ) {
1161     AliError(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
1162                  , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
1163   }
1164   
1165   fMCMHctr1++;
1166   fMCMHctr2++;
1167
1168   // AdcMask for Zero supressed data
1169   if ( fRawVersion == 3 ) {
1170     // read one more word
1171     if ( !fRawReader->ReadNextInt( fDataWord ) ) {
1172       AliError("Could not read data");
1173       return;
1174     }
1175     fWordCtr++;
1176     if ( (fDataWord & 0x000007ff) == 0xC ) {     // at the moment bits 4-10 are empty
1177     //if ( (fDataWord & 0x0000000f) == 0xC ) {
1178       
1179       for ( Int_t ctr = 0; ctr < fGeo->ADCmax(); ctr++ ) {
1180         if ( (fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
1181         else                                  fADCmask[ctr] = kFALSE;
1182       }
1183
1184       AliDebug(4, Form("0x%08x: ADC mask", fDataWord));
1185
1186     }
1187     else {
1188       AliError("Expected ADC mask but did not find one!");
1189     }
1190
1191   }
1192
1193 }
1194
1195 //____________________________________________________________________________
1196 void AliTRDRawStream::DecodeTracklet()
1197 {
1198   //
1199   //
1200   //
1201
1202   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1203     DecodeTrackletVx();
1204     return;
1205   }
1206
1207   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1208   return;
1209
1210 }
1211
1212 //____________________________________________________________________________
1213 void AliTRDRawStream::DecodeTrackletVx()
1214 {
1215
1216   //
1217   // Decode the Tracklet
1218   //
1219   // this function is not tested yet on real tracklets
1220   //
1221
1222   fTracklPID    = (fDataWord >> 24) & 0xff;
1223   fTracklPadRow = (fDataWord >> 20) & 0xf;    // 0:15
1224   fTracklDefL   = (fDataWord >> 13) & 0x7f;
1225   fTracklPadPos = (fDataWord)       & 0x1fff;
1226
1227   fTracklPID    /= (Float_t)((1<<8) - 1);                      // 0:1 (steps of 0.39%)
1228   fTracklDefL    = (fTracklDefL  - ((1<< 7)-1)/2.) * 140.e-4;  // -0.889:0.889cm 
1229   fTracklPadPos  = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
1230
1231   AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
1232                   , fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
1233                   , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
1234
1235   if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
1236       (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
1237     AliError(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
1238   }
1239
1240 }
1241
1242 //____________________________________________________________________________
1243 void AliTRDRawStream::DecodeGTUlinkMask()
1244 {
1245   //
1246   //
1247   //
1248
1249   if ( fRawVersion >= 1 && fRawVersion <= 3 ) {
1250     DecodeGTUlinkMaskVx();
1251     return;
1252   }
1253
1254   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1255   return;
1256
1257 }
1258
1259 //____________________________________________________________________________
1260 void AliTRDRawStream::DecodeGTUlinkMaskVx()
1261 {
1262
1263   //
1264   // Decode the link masks sent by the GTU. These marke the active optical links
1265   // between GTU and Super Module. Up to now only fully active links are found
1266   // (0xfff = 12 active links).
1267   //
1268
1269   if ( fGTUctr1 == -1 ) fGTUctr2++;
1270   fGTUctr1++;
1271
1272   //printf("fGTUctr=%d",fGTUctr);
1273   //printf("fGTUctr1=%d, fGTUctr2=%d",fGTUctr1, fGTUctr2);
1274
1275   if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) ) {
1276     fGTUlinkMask[fGTUctr2][fGTUctr1] = (fDataWord & 0xfff);
1277   }
1278
1279   for ( Int_t ctr = 0; ctr < 12; ctr++ ) {
1280     if ( IsGTULinkActive(fGTUctr2, ctr/2, fGTUctr1, ctr%2) ) {
1281       AliDebug(3, Form("SM %2d Stack %d: GTU Link %2d is active!", fGTUctr2, fGTUctr1, ctr)); 
1282     }
1283   }
1284
1285 }
1286
1287 //____________________________________________________________________________
1288 Int_t  AliTRDRawStream::DecodeDataWord()
1289 {
1290
1291   //
1292   // Decode the Data
1293   //
1294
1295   if      ( fRawVersion >= 1 && fRawVersion <= 2 ) {
1296     return DecodeDataWordV1V2();
1297   }
1298   else if ( fRawVersion >= 3 && fRawVersion <= 3 ) {
1299     return DecodeDataWordV3();
1300   }
1301
1302   AliError(Form(" Unsupported raw version: %d", fRawVersion));
1303   return -1;
1304
1305 }
1306
1307 //____________________________________________________________________________
1308 Int_t  AliTRDRawStream::DecodeDataWordV1V2()
1309 {
1310
1311   //
1312   // Decode the Data (full raw data. No zero suppression. 21 adc channels)
1313   //
1314   // return  0 means continue to next data word
1315   // return -1 means break data loop
1316   //
1317
1318   if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
1319     AliError(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)fDataWord));
1320     return -1;
1321   }
1322
1323   if ( (fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
1324     //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
1325     fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
1326     fTbSwitchCtr = 0;
1327     fADC++;
1328     fTB=0;
1329   }
1330
1331   fTbSwitchCtr++; // Just read one word
1332
1333   // We have only timeTotal time bins
1334   if ( fTbSwitchCtr > fTimeWords ) {
1335     AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
1336     return 0;
1337   }
1338
1339   // We have only 21 ADC channels.
1340   if ( fADC > (Int_t)fGeo->ADCmax()-1 ) {
1341     AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord, (Int_t)fADC));
1342     return 0;
1343   }
1344
1345   // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
1346   // MCMs and are good for online tracking in the MCM.
1347   if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
1348
1349     // Get Pad column
1350     fCOL = fGeo->GetPadColFromADC(fROB, fMCM, fADC);
1351
1352     // We have only 144 Pad Columns
1353     if ( fCOL > fColMax-1 || fCOL < 0 ) {
1354       AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
1355                     fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
1356     }
1357
1358     // Decode 32 bit data words with information from 3 time bins and copy the data
1359     fSig[0] = (fDataWord & 0x00000ffc) >> 2;
1360     fSig[1] = (fDataWord & 0x003ff000) >> 12;
1361     fSig[2] = (fDataWord & 0xffc00000) >> 22;
1362
1363     // Print data to screen:
1364     // Do NOT switch on for default production, it is VERY slow
1365     //    AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
1366     //               fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
1367     
1368   }
1369   else {
1370     
1371     fCOL = -1;
1372     
1373   }
1374
1375   return 1;
1376
1377 }
1378
1379 //____________________________________________________________________________
1380 Int_t  AliTRDRawStream::DecodeDataWordV3()
1381 {
1382
1383   //
1384   // Decode the data (Zero suppresses data. 21 adc channels)
1385   //
1386   // return  0 means continue to next data word
1387   // return -1 means break data loop
1388   //
1389   // NOT TESTED YET!!!!!!!!
1390   //
1391
1392   if ( (fDataWord & 0x00000003) != 0x2 && (fDataWord & 0x00000003) != 0x3) {
1393     AliError(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)fDataWord));
1394     return -1;
1395   }
1396
1397   if ( (fDataWord & 0x00000003) != fTbSwitch ) {    // Next ADC channel found
1398     //if ( fTB+1 != timeBins ) AliError(Form("Time bins in data (%d) != DB (%d)", fTB+1, timeBins));
1399     fTbSwitch = (fTbSwitch & 2) | !(fTbSwitch & 1);   // 0x3 <--> 0x2
1400     fTbSwitchCtr = 0;
1401     //
1402     // Jump to next ADC channel that is not masked
1403     do {
1404       fADC++;
1405     } while ( ((fADC < fGeo->ADCmax()) && (fADCmask[fADC] == kFALSE)) || (fADC >= fGeo->ADCmax()) );
1406     fTB=0;
1407   }
1408
1409   fTbSwitchCtr++; // Just read one word
1410
1411   // We have only timeTotal time bins
1412   if ( fTbSwitchCtr > fTimeWords ) {
1413     AliError(Form("Data is strange. Already found %d words for this ADC channel", (Int_t)fTbSwitchCtr));
1414     return 0;
1415   }
1416
1417   // We have only 21 ADC channels.
1418   if ( fADC > (Int_t)fGeo->ADCmax()-1 ) {
1419     AliError(Form("Data %08x : Data is strange. fADC is already %d", (Int_t)fDataWord, (Int_t)fADC));
1420     return 0;
1421   }
1422
1423   // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
1424   // MCMs and are good for online tracking in the MCM.
1425   if ( fADC > 1 && fADC < (Int_t)fGeo->ADCmax()-1 ) {
1426
1427     // Get Pad column
1428     fCOL = fGeo->GetPadColFromADC(fROB, fMCM, fADC);
1429
1430     // We have only 144 Pad Columns
1431     if ( fCOL > fColMax-1 || fCOL < 0 ) {
1432       AliError(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
1433                     fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
1434     }
1435
1436     // Decode 32 bit data words with information from 3 time bins and copy the data
1437     fSig[0] = (fDataWord & 0x00000ffc) >> 2;
1438     fSig[1] = (fDataWord & 0x003ff000) >> 12;
1439     fSig[2] = (fDataWord & 0xffc00000) >> 22;
1440
1441     // Print data to screen:
1442     AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
1443                      fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
1444     
1445   }
1446   else {
1447     
1448     fCOL = -1;
1449     
1450   }
1451
1452   return 1;
1453
1454 }