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