]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDrawStreamTB.cxx
Radical performance improvement
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStreamTB.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: M. Ploskon (ploskon@ikf.uni-frankfurt.de)                         //
28 //                                                                           //
29 ///////////////////////////////////////////////////////////////////////////////
30
31 #include "TString.h"
32 #include "TFile.h"
33 #include "TTreeStream.h"
34
35 #include "AliTRDrawStreamTB.h"
36 #include "AliTRDgeometry.h"
37 #include "AliTRDfeeParam.h"
38 #include "AliTRDdigitsManager.h"
39 #include "AliTRDdataArrayI.h"
40 #include "AliTRDSignalIndex.h"
41
42 #include "AliLog.h"
43 #include "AliRawReader.h"
44
45 #define END_OF_TRACKLET_MARKEROLD 0xaaaaaaaa
46 #define END_OF_TRACKLET_MARKERNEW 0x10001000
47 #define ENDOFRAWDATAMARKER 0x00000000
48 #define WORD_SIZE sizeof(UInt_t)           // size of a word in bytes
49 #define EXTRA_LEAD_WORDS 24
50 #define CDH_WORDS 8
51
52 #define IS_BIT_SET(w,b) ( ((w) >> (b)) & 0x1 ) // 1 if bit b is set in word w
53 #define GET_VALUE_AT(w,m,s) (( (w) >> (s)) & (m) )      // get value of word w rshifted by s and mask with m
54
55 // SM index word masks:
56 #define SM_HEADER_SIZE(w) GET_VALUE_AT(w,0xffff,16) 
57 #define TRACKLETS_ENABLED(w) IS_BIT_SET(w,5)
58 #define STACK_MASK(w) ((w) & 0x1f)
59
60 // Stack word masks
61 #define STACK_HEADER_SIZE(w) GET_VALUE_AT(w,0xffff,16)
62 #define STACK_LINK_WORD(w) ((w) & 0xfff)
63
64 // HC word masks
65 //#define HC_HEADER_MASK_ERR(w) ( ((w) & (0x80000003)) == (0x80000001) ? 0 : 1) // 0 if OK!!!
66 #define HC_HEADER_MASK_ERR(w) ( ((w) & (0x3)) == (0x1) ? 0 : 1) // 0 if OK!!!
67
68 // HC word 0
69 #define HC_SPECIAL_RAW_VERSION(w) IS_BIT_SET(w,31)
70 #define HC_MAJOR_RAW_VERSION(w) GET_VALUE_AT(w,0x7f,24)
71 #define HC_MINOR_RAW_VERSION(w) GET_VALUE_AT(w,0x7f,17)
72 #define HC_EXTRA_WORDS(w) GET_VALUE_AT(w,0x7,14)
73 #define HC_DCS_BOARD(w) GET_VALUE_AT(w,0xfff<<20,20)
74 #define HC_SM_NUMBER(w) GET_VALUE_AT(w,0x1f,9)
75 #define HC_LAYER_NUMBER(w) GET_VALUE_AT(w,0x7,6)
76 #define HC_STACK_NUMBER(w) GET_VALUE_AT(w,0x7,3)
77 #define HC_SIDE_NUMBER(w) IS_BIT_SET(w,2)
78
79 // HC word 1
80 #define HC_NTIMEBINS(w) GET_VALUE_AT(w,0x3f,26)
81 #define HC_BUNCH_CROSS_COUNTER(w) GET_VALUE_AT(w,0xffff,10)
82 #define HC_PRETRIGGER_COUNTER(w) GET_VALUE_AT(w,0xf,6)
83 #define HC_PRETRIGGER_PHASE(w) GET_VALUE_AT(w,0xf,6)
84
85 //--------------------------------------------------------
86
87 // MCM word and ADC mask
88 #define MCM_HEADER_MASK_ERR(w) ( ((w) & (0xf)) == (0xc) ? 0 : 1) // 0 if OK!!!
89 #define MCM_ADCMASK_MASK_ERR(w) ( ((w) & (0xf)) == (0xc) ? 0 : 1) // 0 if OK!!!
90 #define MCM_MCM_NUMBER(w) GET_VALUE_AT(w,0x0f,24)
91 #define MCM_ROB_NUMBER(w) GET_VALUE_AT(w,0x7,28)
92 #define MCM_EVENT_COUNTER(w) GET_VALUE_AT(w,0x00fffff,4)
93 #define MCM_ADCMASK_VAL(w) GET_VALUE_AT(w,0x1fffff,4)
94
95 //this should give 0x1fffff as a mask
96 #define MCM_DUMMY_ADCMASK_VAL 0x001fffffc 
97 //--------------------------------------------------------
98
99 #define MAX_TRACKLETS_PERHC 256 // max number of tracklets per HC - large number for now
100
101 //--------------------------------------------------------
102 #define ADC_WORD_MASK(w) ((w) & 0x3)
103 //--------------------------------------------------------
104 ClassImp(AliTRDrawStreamTB)
105
106 Bool_t AliTRDrawStreamTB::fgExtraSkip = kFALSE;
107 Bool_t AliTRDrawStreamTB::fgSkipCDH = kFALSE;
108 Bool_t AliTRDrawStreamTB::fgWarnError = kTRUE;
109 Bool_t AliTRDrawStreamTB::fgCleanDataOnly = kTRUE;
110 Bool_t AliTRDrawStreamTB::fgDebugFlag = kTRUE;
111 Bool_t AliTRDrawStreamTB::fgDebugStreamFlag = kFALSE;
112 TTreeSRedirector *AliTRDrawStreamTB::fgDebugStreamer = 0;
113 UInt_t AliTRDrawStreamTB::fgStreamEventCounter = 0;
114 UInt_t AliTRDrawStreamTB::fgDumpHead = 0;
115 Int_t  AliTRDrawStreamTB::fgCommonAdditive = 0;
116 Int_t AliTRDrawStreamTB::fgEmptySignals[] = 
117   {
118     -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1
119     -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1
120   };
121
122 AliTRDrawStreamTB::AliTRDrawStreamTB()
123   : TObject()
124   , fSM()
125   , fStack(0)
126   , fHC(0)
127   , fMCM(0)
128   , fADC(0)
129   , fpPos(0)
130   , fpBegin(0)
131   , fpEnd(0)
132   , fWordLength(0)
133   , fStackNumber(-1)
134   , fStackLinkNumber(-1)
135   , fhcMCMcounter(0)
136   , fmcmADCcounter(0)
137   , fLinkTrackletCounter(-1)
138   , fEndOfTrackletCount(-1)
139   , fMaskADCword(0)
140   , fTbinADC(0)
141   , fDecodedADCs(-1)
142   , fEventCounter(0)
143   , fLastEventCounter(0)
144   , fSharedPadsOn(kFALSE)
145   , fMaxADCgeom(0)
146   , fGeometry(0)
147   , fRawReader(0)
148   , fTRDfeeParam(0)
149   , fDebugStreamOwned(kFALSE)
150 {
151   //
152   // default constructor
153   //
154
155   if (Init() == kFALSE)
156     {
157       AliWarning("Unable to Init.");      
158     }
159 }
160
161 //--------------------------------------------------------
162 AliTRDrawStreamTB::AliTRDrawStreamTB(AliRawReader *rawReader)
163   : TObject()
164   , fSM()
165   , fStack(0)
166   , fHC(0)
167   , fMCM(0)
168   , fADC(0)
169   , fpPos(0)
170   , fpBegin(0)
171   , fpEnd(0)
172   , fWordLength(0)
173   , fStackNumber(-1)
174   , fStackLinkNumber(-1)
175   , fhcMCMcounter(0)
176   , fmcmADCcounter(0)
177   , fLinkTrackletCounter(-1)
178   , fEndOfTrackletCount(-1)
179   , fMaskADCword(0)
180   , fTbinADC(0)
181   , fDecodedADCs(-1)
182   , fEventCounter(0)
183   , fLastEventCounter(0)
184   , fSharedPadsOn(kFALSE)
185   , fMaxADCgeom(0)
186   , fGeometry(0)
187   , fRawReader(rawReader)
188   , fTRDfeeParam(0)
189   , fDebugStreamOwned(kFALSE)
190 {
191   //
192   // default constructor
193   //
194   if (fRawReader)
195     {     
196       if (Init() == kFALSE)
197         {
198           AliWarning("Unable to Init. Try setting up the reader with SetReader or buffer with Init(void *, UInt_t )");    
199         }
200     }
201   else
202     {
203       AliWarning("Unable to setup reader. Use SetReader(AliRawReader*).");
204     }
205 }
206
207 //------------------------------------------------------------
208
209 AliTRDrawStreamTB::AliTRDrawStreamTB(const AliTRDrawStreamTB& /*st*/)
210   : TObject()
211   , fSM()
212   , fStack(0)
213   , fHC(0)
214   , fMCM(0)
215   , fADC(0)
216   , fpPos(0)
217   , fpBegin(0)
218   , fpEnd(0)
219   , fWordLength(0)
220   , fStackNumber(-1)
221   , fStackLinkNumber(-1)
222   , fhcMCMcounter(0)
223   , fmcmADCcounter(0)
224   , fLinkTrackletCounter(-1)
225   , fEndOfTrackletCount(-1)
226   , fMaskADCword(0)
227   , fTbinADC(0)
228   , fDecodedADCs(-1)
229   , fEventCounter(0)
230   , fLastEventCounter(0)
231   , fSharedPadsOn(kFALSE)
232   , fMaxADCgeom(0)
233   , fGeometry(0)
234   , fRawReader(0)
235   , fTRDfeeParam(0)
236   , fDebugStreamOwned(kFALSE)
237 {
238   //
239   // Copy constructor
240   // 
241   AliError("Not implemeneted.");
242 }
243
244 //------------------------------------------------------------
245 void AliTRDrawStreamTB::SetRawVersion(Int_t fraw)
246 {
247   //
248   // function provided for backward compatibility
249   //
250   AliWarning("Raw data version is read from raw data stream! No point of setting it in here.");
251   fraw = 0; // avoid warnings
252 }
253
254 //------------------------------------------------------------
255 AliTRDrawStreamTB::~AliTRDrawStreamTB()
256 {
257   //
258   // destructor
259   //
260   delete fGeometry;
261
262   if (fDebugStreamOwned == kTRUE)
263     {
264       if (fgDebugStreamer)
265         {
266           delete fgDebugStreamer;
267           fgDebugStreamer = 0;
268         }
269     }
270 }
271
272 //------------------------------------------------------------
273
274 AliTRDrawStreamTB &
275 AliTRDrawStreamTB::operator=(const AliTRDrawStreamTB &)
276 {
277   //
278   // we are not using this functionality
279   //
280   AliFatal("May not use.");
281   return *this;
282 }
283
284 //------------------------------------------------------------
285
286 void    
287 AliTRDrawStreamTB::EnableDebug(TTreeSRedirector *debugStream)
288 {
289   //
290   // replace the current debug streamer or create a new one if owned
291   //
292
293   if (debugStream == 0)
294     {
295       if (fDebugStreamOwned == kTRUE)
296         {
297           if (fgDebugStreamer)
298             delete fgDebugStreamer;
299         }
300
301       fDebugStreamOwned = kTRUE;
302       fgDebugStreamer    = new TTreeSRedirector("TRDrawDataDebug.root");
303       fgStreamEventCounter = 0;
304
305     }
306   else
307     {
308       if (fDebugStreamOwned == kTRUE)
309         {
310           if (fgDebugStreamer)
311             delete fgDebugStreamer;
312         }
313
314       fgDebugStreamer = debugStream;
315       fDebugStreamOwned = kFALSE;
316     }
317 }
318
319 //___________________________________________________________
320 void 
321 AliTRDrawStreamTB::SwapOnEndian()
322 {
323   //
324   // Check the endian and swap if needed
325   //
326
327   int itemp = 1;
328   char* ptemp = (char*) &itemp;
329   if (ptemp[0] != 1)
330     {
331       // need to swap...
332       if (fgDebugFlag) AliDebug(8, "Swapping.");
333
334       fpPos = fpBegin;
335       UInt_t iutmp = 0;
336       while (fpPos < fpEnd)
337         {
338           fpPos += 1;
339           iutmp = (((*fpPos & 0x000000ffU) << 24) | ((*fpPos & 0x0000ff00U) <<  8) |
340                    ((*fpPos & 0x00ff0000U) >>  8) | ((*fpPos & 0xff000000U) >> 24));
341           // here we override the value in the buffer!
342           *fpPos = iutmp;         
343         }
344       fpPos = fpBegin;
345     }
346 }
347
348 //------------------------------------------------------------
349 void 
350 AliTRDrawStreamTB::DumpErrorCount()
351 {
352   //
353   // print the error statistics into the stdout
354   //
355
356   ;
357   //   AliInfo(Form("Error counts: HC0 %d HC1 %d MCM %d ADCmask %d ADC %d", 
358   //           fHC->fH0ErrorCounter,  fHC->fH1ErrorCounter, fMCM->fErrorCounter, fMCM->fMaskErrorCounter, adc.fErrorCounter));
359 }
360
361 //------------------------------------------------------------
362 Bool_t 
363 AliTRDrawStreamTB::DumpWords(UInt_t *px, UInt_t iw, UInt_t marker)
364 {
365   //
366   // skip few words
367   // note: can be made faster
368   //
369     
370   TString tsreturn = Form("\n[ Dump Sequence at 0x%08x ] : ", px);
371   for (UInt_t i = 0; i < iw; i++)
372     {
373       if (px + iw >= fpEnd)
374         return kFALSE;
375
376       if (i % 8 == 0)
377         tsreturn += "\n                              ";
378       if (marker != 0 && marker == px[i])
379         tsreturn += Form(" *>0x%08x<* ", px[i]);
380       else
381         tsreturn += Form("0x%08x ", px[i]);
382     }
383   tsreturn += "\n";
384
385   AliInfo(tsreturn.Data());
386
387   return kTRUE;
388 }
389
390 //------------------------------------------------------------
391 Bool_t 
392 AliTRDrawStreamTB::SkipWords(UInt_t iw)
393 {
394   //
395   // skip few words
396   // note: can be made faster
397   //
398   
399   if ( fpPos + iw < fpEnd )
400     {
401       fpPos += iw;
402       return kTRUE;
403     }
404   else
405     {
406       if (fgWarnError) AliWarning(Form("Skip %d words failed. %d available", iw, fpEnd - fpPos - 1));
407       if (fgDebugStreamer)
408         {
409           TTreeSRedirector &cstream = *fgDebugStreamer;
410           cstream << "SkipWords"
411                   << "Event=" << fgStreamEventCounter
412                   << ".nwords=" << iw
413 //                << ".read=" << (Char_t*)(fpPos - fpBegin)
414 //                << ".togo=" << (Char_t*)(fpEnd - fpPos)
415 //                << ".length=" << (Char_t*)(fpEnd - fpBegin)
416                   << "\n";
417         }
418       return kFALSE;
419     }
420
421   return kTRUE;
422 }
423
424 //------------------------------------------------------------
425 Bool_t 
426 AliTRDrawStreamTB::SetReader(AliRawReader *reader)
427 {
428   //
429   //
430   //
431
432   if (reader != 0)
433     {
434       fRawReader = reader;
435       if (fRawReader)
436         {         
437           return Init();
438         }
439       else
440         {
441           AliWarning("Unable to setup reader.");
442           return kFALSE;
443         }
444     }
445   else
446     {
447       AliWarning("AliRawReader argument is 0.");
448       fRawReader = 0;
449     }
450
451   return kFALSE;
452 }
453
454 //------------------------------------------------------------
455 Int_t 
456 AliTRDrawStreamTB::NextBuffer()
457 {
458   //
459   // return -1 if no more buffers available
460   // return 0 DecodeSM failed (clean data required for example) but still maybe more data to come
461   // return 1 DecodeSM OK
462   // 
463
464   if (fRawReader != 0)
465     {
466       UChar_t *buffer = 0;
467       UInt_t length = 0;
468       Bool_t kBufferSet = fRawReader->ReadNextData(buffer);
469       if (kBufferSet == kTRUE)
470         {
471           if (fgDebugFlag)  AliDebug(9, "Buffer is set.");
472           length = fRawReader->GetDataSize();
473           if (fgExtraSkip == kTRUE)
474             {
475               buffer += EXTRA_LEAD_WORDS * WORD_SIZE;
476               length -= EXTRA_LEAD_WORDS * WORD_SIZE;
477             }
478
479           if (fgSkipCDH == kTRUE)
480             {
481               buffer += CDH_WORDS * WORD_SIZE;
482               length -= CDH_WORDS * WORD_SIZE;        
483             }
484
485           if (length > 0)
486             {
487               if (fgDebugFlag)  AliDebug(9, Form("Buffer length : %d", length));
488               //return InitBuffer((void*)buffer, length);
489               if (DecodeSM((void*)buffer, length) == kTRUE)
490                 return 1;
491               else
492                 return 0;
493             }
494         }
495       else
496         {
497           return -1;
498         }
499     }
500
501   return -1;
502 }
503
504 //------------------------------------------------------------
505 void 
506 AliTRDrawStreamTB::ResetCounters()
507 {
508   //
509   // reset some global counters
510   //
511
512   fStackNumber = 0;
513   fStackLinkNumber = 0;
514
515   fDecodedADCs = 0;
516
517   fSM.fActiveStacks = 0;
518   fSM.fNexpectedHalfChambers = 0;
519
520   fLinkTrackletCounter = 0;
521
522   fLastEventCounter = 0;
523   fEventCounter = 0;
524 }
525
526 //------------------------------------------------------------
527 void 
528 AliTRDrawStreamTB::ResetIterators()
529 {
530   //
531   // reset the data iterators used in the Next()
532   //
533   fStackNumber = 0;
534   fStackLinkNumber = 0;
535   fhcMCMcounter = 0;  
536   fmcmADCcounter = 0;
537 }
538
539 //------------------------------------------------------------
540
541 Bool_t 
542 AliTRDrawStreamTB::Next()
543 {
544   //
545   // returns with true on next adc read
546   // returns false on errors and end of buffer
547   // 
548
549   while (fStackNumber < 5 && fSM.fActiveStacks > 0)
550     {
551       if(fSM.fStackActive[fStackNumber] == kTRUE)
552         {
553           fStack = &fSM.fStacks[fStackNumber];
554           while (fStackLinkNumber < 12)
555             {
556               if (fStack->fLinksActive[fStackLinkNumber] == kTRUE)
557                 {
558                   fHC = &fStack->fHalfChambers[fStackLinkNumber];
559                   if (!fHC)
560                     {
561                       AliError(Form("Super Strange. HC missing at stack %d link %d", fStackNumber, fStackLinkNumber));
562                       return kFALSE;
563                     }
564                   //if (fgDebugFlag)  AliDebug(2, DumpHCinfoH0(fHC));             
565                   if (fHC->fCorrupted == 0)
566                     {
567                       while (fhcMCMcounter < fHC->fMCMmax)
568                         {
569                           fMCM = &fHC->fMCMs[fhcMCMcounter];
570                           //if (fgDebugFlag)  AliDebug(2, DumpMCMinfo(fMCM));                                     
571                           if (!fMCM)
572                             {
573                               AliError(Form("Super Strange. HC missing at stack %d link %d atMCMslot %d", 
574                                             fStackNumber, fStackLinkNumber, fhcMCMcounter));
575                               return kFALSE;
576                             }
577                           while(fmcmADCcounter < fMCM->fADCmax)
578                             {
579                               //printf("%d %d %d %d\n", fStackNumber, fStackLinkNumber, fhcMCMcounter, fmcmADCcounter);
580                               fADC = &fMCM->fADCs[fmcmADCcounter];
581                               if (!fADC)
582                                 {
583                                   AliError(Form("Super Strange. ADC missing at stack %d link %d MCMslot %d ADCslot %d", 
584                                                 fStackNumber, fStackLinkNumber, fhcMCMcounter, fmcmADCcounter));
585                                   return kFALSE;
586                                 }
587                               fmcmADCcounter++;
588                               //printf("ADC count %d \n",  fmcmADCcounter);
589                               if (fSharedPadsOn)
590                                 {
591                                   return kTRUE;
592                                 }
593                               else
594                                 {
595                                   if (fADC->fIsShared == kFALSE)
596                                     return kTRUE;
597                                 }
598                             } //while adc in MCM
599                           //printf("MCM count %d \n", fhcMCMcounter);
600                           fhcMCMcounter++;
601                           // next MCM should go through all active ADCs
602                           fmcmADCcounter = 0;
603                         } // while mcm
604                     } // if HC OK
605                 }// if link active
606               fStackLinkNumber++;
607               // next stack link (HC) should go through all active MCMs
608               fhcMCMcounter = 0;
609             }// while links
610         }// if stack active
611       fStackNumber++;
612       // next stack should go through all links - start from 0
613       fStackLinkNumber = 0;
614     }
615
616   // in case rawreader manages the mem buffers
617   // lets go for the next buffer
618   if (fRawReader)
619     {
620       Int_t nextBuff = NextBuffer();
621       while (nextBuff != -1)
622         {
623           if (nextBuff > 0)
624             return Next();                
625           nextBuff = NextBuffer();
626         }
627     }
628
629   return kFALSE;
630 }
631
632 //------------------------------------------------------------
633
634 Int_t 
635 AliTRDrawStreamTB::NextChamber(AliTRDdigitsManager *digitsManager)
636 {
637   //
638   // Fills single chamber digit array 
639   // Return value is the detector number
640   //
641
642   AliTRDdataArrayI *digits = 0;
643   AliTRDdataArrayI *track0 = 0;
644   AliTRDdataArrayI *track1 = 0;
645   AliTRDdataArrayI *track2 = 0; 
646   AliTRDSignalIndex *indexes = 0;
647
648   // Loop through the digits
649   Int_t lastdet = -1;
650   Int_t det    = -1;
651   //   Int_t returnDet = -1;
652   Int_t it = 0;
653   while (Next()) 
654     {      
655       det    = GetDet();
656     
657       if (det != lastdet) 
658         { 
659           // If new detector found
660           if (lastdet == -1)
661             {
662               lastdet = det;
663             }
664           else
665             {
666               return lastdet;
667             }
668
669           if (det < 0 || det >= AliTRDgeometry::kNdet)
670             {
671               if (fSM.fClean == kTRUE)
672                 {
673                   AliError(Form("Strange Det Number %d BUT event buffer seems to be clean.", det));
674                 }
675               else
676                 {
677                   AliError(Form("Strange Det Number %d. Event buffer marked NOT clean!", det));
678                 }
679               continue;
680             }
681
682           // Add a container for the digits of this detector
683           digits = digitsManager->GetDigits(det);
684           track0 = digitsManager->GetDictionary(det,0);
685           track1 = digitsManager->GetDictionary(det,1);
686           track2 = digitsManager->GetDictionary(det,2);
687
688           if (!digits)
689             {
690               if (fSM.fClean == kTRUE)
691                 {
692                   AliError(Form("Unable to get digits for det %d BUT event buffer seems to be clean.", det));
693                 }
694               else
695                 {
696                   AliError(Form("Unable to get digits for det %d. Event buffer is NOT clean!", det));
697                 }
698               return -1;
699               //continue;
700             }
701
702           Int_t rowMax = GetRowMax();
703           Int_t colMax = GetColMax();
704           Int_t ntbins = GetNumberOfTimeBins();
705
706           // Allocate memory space for the digits buffer
707           if (digits->GetNtime() == 0) 
708             {
709               digits->Allocate(rowMax, colMax, ntbins);
710               track0->Allocate(rowMax, colMax, ntbins);
711               track1->Allocate(rowMax, colMax, ntbins);
712               track2->Allocate(rowMax, colMax, ntbins);
713             }
714
715           indexes = digitsManager->GetIndexes(det);
716           indexes->SetSM(GetSM());
717           indexes->SetStack(GetStack());
718           indexes->SetLayer(GetLayer());
719           indexes->SetDetNumber(det);
720           if (indexes->IsAllocated() == kFALSE)
721             indexes->Allocate(rowMax, colMax, ntbins);
722         }
723     
724       // ntimebins data are ready to read
725       for (it = 0; it < GetNumberOfTimeBins(); it++)
726         {
727           if (GetSignals()[it] > 0)
728             {
729               digits->SetDataUnchecked(GetRow(), GetCol(), it, GetSignals()[it]);
730               
731               indexes->AddIndexTBin(GetRow(), GetCol(), it);
732               track0->SetDataUnchecked(GetRow(), GetCol(), it, 0);
733               track1->SetDataUnchecked(GetRow(), GetCol(), it, 0);
734               track2->SetDataUnchecked(GetRow(), GetCol(), it, 0);
735             }
736         } // tbins
737     }// while Next()
738
739   // what happens if the last HC is turned off?
740   return det;
741   //return -1;
742 }
743
744 //------------------------------------------------------------
745 Bool_t
746 AliTRDrawStreamTB::Init()
747 {
748   //
749   // general init
750   //
751
752   TDirectory *saveDir = gDirectory; 
753   
754   if (!fGeometry) 
755     {
756       fGeometry = new AliTRDgeometry();
757     }
758   
759   if (!fGeometry) 
760     {
761       AliError("Geometry FAILED!");
762       return kFALSE;
763     }
764
765   fTRDfeeParam = AliTRDfeeParam::Instance();
766   if (!fTRDfeeParam)
767     {
768       AliError("AliTRDfeeParam FAILED!");
769       return kFALSE;
770     }
771
772   fMaxADCgeom = (Int_t)fGeometry->ADCmax();
773
774   // common additive is moved to be static for temp solution
775   // common additive should be delivered in the HC word 2 (3rd word)
776   //fCommonAdditive = 10;
777
778   ResetCounters();
779
780   // in case rawreader manages the mem buffers
781   // lets go for the next buffer
782   if (fRawReader)
783     {
784       Int_t nextBuff = NextBuffer();
785       while (nextBuff != -1)
786         {
787           if (nextBuff > 0)
788             return kTRUE;                 
789           nextBuff = NextBuffer();
790         }
791     }
792
793   if (fgDebugStreamFlag == kTRUE)
794     {
795       if (!fgDebugStreamer)
796         {
797           fgDebugStreamer    = new TTreeSRedirector("TRDrawDataDebug.root");
798           fgStreamEventCounter = 0;
799       
800           if (fgDebugStreamer)
801             {
802               AliInfo(Form("Debug Streamer Initialized! Remember to delete! %s::DeleteDebugStream()", this->IsA()->GetName()));
803               //fDebugStreamOwned = kTRUE;
804             }
805           else
806             {
807               AliError("Unable to init debug stream");
808             }
809         }
810     }
811
812   saveDir->cd();
813
814   return kTRUE;
815 }
816
817 void AliTRDrawStreamTB::DeleteDebugStream()
818 {
819   // 
820   // static helper function
821   //
822
823   if (fgDebugStreamer)
824     {
825       delete fgDebugStreamer;
826       fgDebugStreamer = 0;
827     }
828   
829 }
830
831 //------------------------------------------------------------
832 Bool_t 
833 AliTRDrawStreamTB::InitBuffer(void *buffer, UInt_t length)
834 {
835   // 
836   // init the class before reading from the buffer
837   // and read SM heading info:
838   // -- super module header
839   // -- stack headers + link status words
840   //
841
842   // not in the pre scan mode
843   fgStreamEventCounter++;
844   
845   ResetCounters();
846
847   fpBegin = (UInt_t *)buffer;
848
849   if (WORD_SIZE == 0)
850     {
851       AliFatal("Strange! Size of UInt_t == 0");
852       return kFALSE;
853     }
854
855   fWordLength = length/WORD_SIZE;
856   fpEnd = fpBegin + fWordLength;
857   fpPos = fpBegin;
858
859   if (fpBegin == 0 || length <= 0)
860     {
861       AliError(Form("This will not work! Pointer to the buffer is 0x%08x of size %d", fpBegin, length));
862       return kFALSE;
863     }
864
865   SwapOnEndian();
866
867   if (fgDumpHead > 0)
868     {
869       AliInfo("------------------------------------------------");
870       if (DumpWords(fpBegin, fgDumpHead) == kFALSE)
871         {
872           AliError("Dump failed. Not enough data.");      
873         }
874       AliInfo("------------------------------------------------");
875     }
876
877   //decode SM
878   DecodeSMInfo(fpPos, &fSM);
879
880   if (fgDebugFlag)  AliDebug(5, DumpSMInfo(&fSM));
881
882   fpPos++;
883   if (fpPos < fpEnd)
884     {   
885       if (SkipWords(fSM.fHeaderSize) == kTRUE)
886         {
887           //decode stacks info
888           //for (Int_t istack = 0; istack < fSM.fActiveStacks; istack++)
889           for (Int_t istack = 0; istack < 5; istack++)
890             {
891               if (fSM.fStackActive[istack] == kFALSE)
892                 continue;
893
894               fStack = &fSM.fStacks[istack];
895               DecodeStackInfo(fpPos, fStack);
896               fpPos++;
897
898               fSM.fNexpectedHalfChambers += fStack->fActiveLinks;
899               
900               if (fgDebugFlag)  AliDebug(5, DumpStackInfo(fStack));
901               
902               if (SkipWords(fStack->fHeaderSize) == kFALSE)
903                 {
904                   if (fRawReader) fRawReader->AddMajorErrorLog(kDecodeStackInfo, "Stack head words missing");
905                   return kFALSE;
906                 }
907             }
908         }
909       else
910         {
911           return kFALSE;
912         }
913     }
914   else
915     {
916       if (fgWarnError) AliWarning("No Stack info present. Strange.");
917       if (fRawReader) fRawReader->AddMajorErrorLog(kDecodeStackInfo, "Stack info missing");
918       return kFALSE;
919     }
920
921   if (fgDebugFlag)  AliDebug(5, Form("Expected half chambers : %d", fSM.fNexpectedHalfChambers));
922   
923   //fpPos++;
924   if (fpPos < fpEnd)
925     {
926       if (fgDebugFlag)  AliDebug(5, "Init OK.");
927     }
928   else
929     {
930       if (fgWarnError) AliWarning("No data just after init. Strange.");
931       if (fRawReader) fRawReader->AddMajorErrorLog(kMissingData, "Missing data");
932       return kFALSE;
933     }
934
935   return kTRUE;
936 }
937
938 //------------------------------------------------------------
939 Bool_t 
940 AliTRDrawStreamTB::DecodeSM(void *buffer, UInt_t length)
941 {
942   //
943   // decode all sm at once
944   // still here for devel and debug
945   //
946   
947   //memset(&fSM, 0, sizeof(fSM));
948
949   ResetIterators();
950
951   fSM.fClean = kTRUE;
952   if (InitBuffer(buffer, length) == kTRUE)
953     {
954       // no we are already set!
955       // fpPos++;      
956     }
957   else
958     {
959       if (fgWarnError) AliError("--- INIT failed. ---------------");      
960       fSM.fClean = kFALSE;
961       return kFALSE;
962     }
963
964   //decode data here
965   //fSM.fActiveStacks
966   for (Int_t istack = 0; istack < 5; istack++)
967     {
968       fStackNumber = istack;
969       if (fSM.fStackActive[istack] == kFALSE)
970         continue;
971       
972       fStack = &fSM.fStacks[istack];
973
974       //fStack[istack].fActiveLinks // max is 12
975       for (Int_t ilink = 0; ilink < 12; ilink++)
976         {
977           fStackLinkNumber = ilink;
978           if (fStack->fLinksActive[ilink] == kFALSE)
979             continue;
980
981           if (fpPos >= fpEnd)
982             {
983               if (fRawReader) fRawReader->AddMajorErrorLog(kLinkDataMissing, "Link data missing");            
984               fSM.fClean = kFALSE;
985               break;
986             }
987
988           fHC = &fStack->fHalfChambers[ilink];
989
990           if (fSM.fTrackletEnable == kTRUE)
991             {
992               if (DecodeTracklets() == kFALSE)
993                 {
994                   //          if (fgWarnError) AliError(Form("--- Decode Tracklets failed. --------------- Link %d of %d", 
995                   //                                        ilink + 1, fStack->fActiveLinks));
996                   if (fgDebugStreamer)
997                     {
998                       TTreeSRedirector &cstream = *fgDebugStreamer;
999                       cstream << "TrackletDecodeError"
1000                               << "Event=" << fgStreamEventCounter
1001                               << ".Stack=" << fStackNumber
1002                               << ".Link=" << fStackLinkNumber
1003                               << ".EndOfTrackletCount=" << fEndOfTrackletCount
1004                               << "\n";
1005                     }
1006                   
1007                   fSM.fClean = kFALSE;
1008                   SeekEndOfData();
1009
1010                   if (fgWarnError) 
1011                     {
1012                       AliError(Form("Failed stack %d link %d", fStackNumber, fStackLinkNumber));
1013                       AliError(Form("Debug Event Counter : %d", fgStreamEventCounter)); 
1014                     }
1015                   continue;
1016                   //return kFALSE;
1017                 }
1018             }
1019
1020           if (fpPos >= fpEnd)
1021             {
1022               if (fRawReader) fRawReader->AddMajorErrorLog(kHCdataMissing, "HC data missing");        
1023               fSM.fClean = kFALSE;
1024               break;
1025             }
1026           
1027           if (DecodeHC() == kFALSE)
1028             {
1029 //            if (fgWarnError) AliError(Form("--- Decode HC failed. --------------- Link %d of %d", 
1030 //                                          ilink + 1, fStack->fActiveLinks));
1031               fSM.fClean = kFALSE;
1032               fHC->fCorrupted += 100;
1033               SeekEndOfData();  
1034
1035               if (fgWarnError) 
1036                 {
1037                   AliError(Form("Failed HC : %s", DumpHCinfoH0(fHC)));
1038                   AliError(Form("Failed HC : %s", DumpHCinfoH1(fHC)));
1039                   AliError(Form("Debug Event Counter : %d", fgStreamEventCounter)); 
1040                 }
1041               // let us assume that we have the HC data although link mask says different
1042               // recovery
1043               if (fStackLinkNumber == -1)
1044                 {
1045                   if (fgWarnError) AliWarning("Trying to recover to the right Link Mask.");
1046                   ilink -= 1;
1047                 }
1048                       
1049               continue;
1050               //return kFALSE;
1051             }
1052           else
1053             {
1054               // just finish off with the end of data markers
1055               SeekEndOfData();
1056             }
1057
1058           //if (fgDebugFlag)  AliDebug(5, Form("++++ Done with link %d of %d", ilink + 1, fStack->fActiveLinks));
1059
1060         } // ilink
1061     } // istack
1062
1063   // for next()
1064   ResetIterators();
1065
1066   if (fSM.fClean == kTRUE)
1067     return kTRUE;
1068   
1069   if (fgCleanDataOnly && (fSM.fClean == kFALSE))
1070     {
1071       if (fgWarnError) 
1072         {
1073           AliWarning("Buffer with errors. Returning FALSE.");
1074           AliWarning(Form("--- Failed SM : %s ---", DumpSMInfo(&fSM)));
1075         }
1076       fSM.fActiveStacks = 0; // Next will not give data
1077       return kFALSE;
1078     }
1079
1080   return kTRUE;
1081 }
1082
1083 //------------------------------------------------------------
1084 Int_t 
1085 AliTRDrawStreamTB::DecodeSM()
1086 {
1087   //
1088   // decode SM data in case AliRawReader is in use
1089
1090   if (fRawReader)
1091     {      
1092       Int_t nextBuff = NextBuffer();
1093       while (nextBuff != -1)
1094         {
1095           if (nextBuff > 0)
1096             return nextBuff;              
1097           nextBuff = NextBuffer();
1098         }
1099       return -1;
1100     }
1101   else
1102     {
1103       AliWarning("AliRawReader not set.");
1104     }
1105   return kFALSE;
1106 }
1107
1108 //------------------------------------------------------------
1109 Int_t 
1110 AliTRDrawStreamTB::DecodeSM(AliRawReader *reader)
1111 {
1112   //
1113   // decode SM with the AliRawReader
1114   //
1115   if (reader != 0)
1116     {
1117       fRawReader = reader;
1118       return DecodeSM();
1119     }
1120   else
1121     {
1122       AliWarning("Argument AliRawReader is 0.");
1123     }
1124   return kFALSE;
1125 }
1126
1127 //------------------------------------------------------------
1128 Bool_t 
1129 AliTRDrawStreamTB::SeekEndOfData()
1130 {
1131   //
1132   // go to end of data marker
1133   //
1134   Int_t fEndOfDataCount = 0;
1135
1136   while ( *fpPos != ENDOFRAWDATAMARKER && fpPos < fpEnd )
1137     {
1138       fpPos++;
1139     }
1140   
1141   while (*fpPos == ENDOFRAWDATAMARKER && fpPos < fpEnd )
1142     {
1143       fEndOfDataCount++;
1144       fpPos++;      
1145     }
1146   
1147 //   if (fEndOfDataCount == 0)
1148 //     {
1149 //       if (fgWarnError) AliWarning("End of buffer reached first. No end of data marker?");
1150 //       return kFALSE;
1151 //     }
1152
1153   return kTRUE;
1154 }
1155
1156 //------------------------------------------------------------
1157 Bool_t 
1158 AliTRDrawStreamTB::SeekNextMCMheader()
1159 {
1160   //
1161   // go to mcm marker
1162   //
1163
1164   // move back to the mcm pos
1165   fpPos = fMCM->fPos + 1;
1166
1167   while ( *fpPos != ENDOFRAWDATAMARKER && fpPos < fpEnd )
1168     {
1169       //if (CheckMCMMask(fpPos) == 0)
1170       if (MCM_HEADER_MASK_ERR(*fpPos) == 0)      
1171         {
1172           if (fgWarnError) AliWarning(Form("^^^ Found : Pos 0x%08x : Val 0x%08x", fpPos, *fpPos));
1173           return kTRUE;
1174         }
1175       fpPos++;
1176     }
1177
1178   SeekEndOfData();
1179   return kFALSE;
1180 }
1181
1182 //------------------------------------------------------------
1183
1184 Bool_t 
1185 AliTRDrawStreamTB::DecodeTracklets()
1186 {
1187   //
1188   // decode tracklets
1189   //
1190
1191   fLinkTrackletCounter = 0;
1192   fEndOfTrackletCount = 0;
1193
1194   if (fgDebugFlag)  AliDebug(10, Form("Decode tracklets at 0x%08x : 0x%08x", fpPos, *fpPos));
1195   //cout << Form("Decode tracklets..") << endl;;
1196   //printf("[I] Tracklet... ? \n");
1197
1198   while ( *fpPos != END_OF_TRACKLET_MARKEROLD && *fpPos != END_OF_TRACKLET_MARKERNEW && fpPos < fpEnd )
1199     {
1200
1201       if (fgDebugFlag)  AliDebug(10, Form("Tracklet found at 0x%08x : 0x%08x", fpPos, *fpPos));
1202
1203       //decode tracklets here...
1204       fLinkTrackletCounter++;
1205
1206       if (fLinkTrackletCounter > MAX_TRACKLETS_PERHC)
1207         {
1208           if (fgWarnError) AliWarning(Form("Max number of tracklets exceeded %d > %d. Something is wrong with the input data!", 
1209                           fLinkTrackletCounter, MAX_TRACKLETS_PERHC));
1210
1211           if (fRawReader) fRawReader->AddMajorErrorLog(kTrackletOverflow,"Too many tracklets"); 
1212           return kFALSE;
1213         }
1214
1215       if (fgDebugStreamer)
1216         {
1217           // jan!
1218           unsigned pid;
1219           unsigned row;
1220           signed defl;
1221           signed ypos;
1222           
1223           double deflm;
1224           double yposm;
1225           
1226           unsigned long val;
1227           
1228           val = *fpPos;
1229
1230           pid = val >> 24;
1231           row = (val >> 20) & 0xF;
1232           defl = (val >> 13) & 0x7F;
1233           defl = defl << 25 >> 25;
1234           ypos = val & 0x1FFF;
1235           ypos = ypos << 19 >> 19;
1236           
1237           deflm = defl * 140.0e-6; /* m */
1238           yposm = ypos * 160.0e-6; /* m */
1239           
1240           TTreeSRedirector &cstream = *fgDebugStreamer;
1241           cstream << "MCMtracklets"
1242                   << "Event=" << fgStreamEventCounter
1243                   << ".stack=" << fStackNumber
1244                   << ".link=" << fStackLinkNumber
1245                   << ".pid=" << pid
1246                   << ".row=" << row
1247                   << ".defl=" << defl
1248                   << ".ypos=" << ypos
1249                   << ".deflm=" << deflm
1250                   << ".yposm=" << yposm
1251                   << "\n";
1252         }
1253       fpPos++;
1254     }
1255
1256   while ( ( *fpPos == END_OF_TRACKLET_MARKEROLD || *fpPos == END_OF_TRACKLET_MARKERNEW ) && fpPos < fpEnd )
1257     {
1258       //seek non end of tracklets
1259       //printf("[I] End of tracklets. \n");
1260       if (fgDebugFlag)  AliDebug(10, Form("EoTracklets found at 0x%08x : 0x%08x", fpPos, *fpPos));
1261
1262       fEndOfTrackletCount++;
1263       fpPos++;
1264     }
1265
1266   if ( fEndOfTrackletCount < 2 )
1267     {
1268       //if (fgWarnError) AliWarning(Form("End of tracklet marker words missing %d", 2 - fEndOfTrackletCount));
1269       if (fRawReader) fRawReader->AddMajorErrorLog(kEOTrackeltsMissing, "End of tracklets word missing"); 
1270       return kFALSE;
1271     }
1272
1273   return kTRUE;
1274 }
1275
1276 //------------------------------------------------------------
1277 Bool_t 
1278 AliTRDrawStreamTB::IsRowValid()
1279 {
1280   //SLOW GEOM
1281   if ( (fHC->fStack == 2 && fMCM->fROW >= fGeometry->RowmaxC0()) ||
1282        (fHC->fStack != 2 && fMCM->fROW >= fGeometry->RowmaxC1()) || fMCM->fROW < 0 ) 
1283     {
1284       if (fgWarnError) AliWarning(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
1285                       , fHC->fSM, fHC->fLayer, fHC->fStack, fMCM->fROW, fMCM->fROB, fHC->fSide, fMCM->fMCM ));
1286       if (fRawReader) fRawReader->AddMajorErrorLog(kWrongPadrow, "Wrong Row");
1287       return kFALSE;
1288     }
1289   return kTRUE;
1290 }
1291
1292 //------------------------------------------------------------
1293 Bool_t 
1294 AliTRDrawStreamTB::IsMCMheaderOK()
1295 {
1296   //
1297   // check the mcm header
1298   //
1299
1300   if ( fMCM->fCorrupted > 10 )
1301     {
1302       if (fRawReader) fRawReader->AddMajorErrorLog(kMCMheaderCorrupted,"ADC mask Corrupted"); 
1303       if (fgWarnError) AliWarning(Form("Wrong ADC Mask word 0x%08x %s. Error : %d", *fMCM->fPos, DumpMCMadcMask(fMCM), fMCM->fCorrupted));
1304       return kFALSE;
1305     }
1306
1307   if ( fMCM->fCorrupted > 0 )
1308     {
1309       if (fRawReader) fRawReader->AddMajorErrorLog(kMCMheaderCorrupted,"Corrupted"); 
1310       if (fgWarnError) AliWarning(Form("Wrong MCM word 0x%08x %s. Error : %d", *fMCM->fPos, DumpMCMinfo(fMCM), fMCM->fCorrupted));
1311       return kFALSE;
1312     }
1313
1314   if ( fMCM->fMCM < 0 || fMCM->fMCM > 15 || fMCM->fROB < 0 || fMCM->fROB > 7 ) 
1315     {
1316       if (fRawReader) fRawReader->AddMajorErrorLog(kWrongMCMorROB,"Wrong ROB or MCM"); 
1317       if (fgWarnError) AliWarning(Form("Wrong fMCM or fROB. %s Skip this data.", DumpMCMinfo(fMCM)));
1318       return kFALSE;
1319     }
1320
1321   if (IsRowValid() == kFALSE)
1322     return kFALSE;
1323
1324   return kTRUE;
1325 }
1326 //------------------------------------------------------------
1327 Bool_t 
1328 AliTRDrawStreamTB::DecodeMCMheader()
1329 {
1330   //
1331   // decode the mcm header
1332   //
1333
1334   DecodeMCMheader(fpPos, fMCM);
1335
1336   fMCM->fROW = fTRDfeeParam->GetPadRowFromMCM(fMCM->fROB, fMCM->fMCM);
1337
1338   if (fHC->fRawVMajor > 2)
1339     {
1340       fpPos++;
1341       if ( fpPos < fpEnd )
1342         {
1343           DecodeMask(fpPos, fMCM);
1344           MCMADCwordsWithTbins(fHC->fTimeBins, fMCM);
1345           fMCM->fAdcDataPos = fpPos + 1;
1346         }
1347       else
1348         {
1349           if (fgWarnError) AliWarning("Expected ADC mask word. Fail due to buffer END.");         
1350           if (fRawReader) fRawReader->AddMajorErrorLog(kMCMADCMaskMissing,"Missing"); 
1351           return kFALSE;
1352         }
1353     }
1354   else
1355     {
1356       UInt_t dummyMask = MCM_DUMMY_ADCMASK_VAL;
1357       DecodeMask(&dummyMask, fMCM);
1358       MCMADCwordsWithTbins(fHC->fTimeBins, fMCM);
1359       fMCM->fAdcDataPos = fpPos + 1;
1360     }
1361
1362   if (fgDebugFlag)  
1363     {
1364       AliDebug(6, DumpMCMinfo(fMCM));
1365       AliDebug(7, DumpMCMadcMask(fMCM));
1366     }
1367
1368   if (IsMCMheaderOK() == kFALSE)
1369     {
1370       return kFALSE;
1371     }
1372
1373   if (fEventCounter == 0)
1374     {
1375       fEventCounter = fMCM->fEvCounter;
1376     }
1377   
1378   if (fEventCounter < fLastEventCounter)
1379     {
1380       if (fgWarnError) AliWarning(Form("Weird. Event from the past? Current %d Last %d %s", fEventCounter, fLastEventCounter, DumpMCMinfo(fMCM)));
1381       if (fRawReader) fRawReader->AddMajorErrorLog(kMCMeventMissmatch, "Wrong MCM event counter ? Past-Future"); 
1382       return kFALSE;
1383     }
1384   
1385   if (fEventCounter != fMCM->fEvCounter)
1386     {
1387       if (fgWarnError) AliWarning(Form("Weird. Event missmatch? %d %s", fEventCounter, DumpMCMinfo(fMCM)));
1388       if (fRawReader) fRawReader->AddMajorErrorLog(kMCMeventMissmatch, "Wrong MCM event counter ?"); 
1389       return kFALSE;
1390     }
1391
1392   //fLastEventCounter = fEventCounter;
1393   //AliInfo(Form("Current MCM %s", DumpMCMinfo(fMCM)));
1394     
1395   return kTRUE;
1396   //return IsMCMheaderOK();
1397 }
1398
1399 //------------------------------------------------------------
1400 Bool_t 
1401 AliTRDrawStreamTB::IsHCheaderOK()
1402 {
1403   //
1404   // check the half chamber header
1405   //
1406
1407   if (fHC->fCorrupted > 0)
1408     {
1409       if (fgWarnError) AliWarning(Form("Wrong HC Header word. Word 0x%08x Error : %d", *fHC->fPos, fHC->fCorrupted));
1410       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderCorrupt, "Corrupted"); 
1411
1412       return kFALSE;
1413     }
1414
1415   if (fHC->fStack < 0 || fHC->fStack > 4)
1416     {
1417       if (fgWarnError) AliWarning(Form("Wrong Stack %d", fHC->fStack));
1418       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongStack, "Wrong Stack");       
1419       return kFALSE;
1420     }
1421
1422   if (fHC->fStack != fStackNumber) 
1423     {
1424       if (fgWarnError) AliWarning(Form("Missmatch: Stack in HC header %d HW-stack %d", 
1425                                        fHC->fStack, fStackNumber));
1426       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongStack, "Stack-HWstack");       
1427       // Try this for recovery in DecodeSM(void*,UInt_t) after DecodeHC failed
1428       // buffer will still will be marked as NOT clean
1429       fStackNumber = -1;
1430       return kFALSE;
1431     }
1432
1433   if (fHC->fLayer < 0 || fHC->fLayer >= AliTRDgeometry::kNplan)
1434     {
1435       if (fgWarnError) AliWarning(Form("Wrong plane(layer) %d", fHC->fLayer));
1436       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongLayer, "Wrong Plane"); 
1437       return kFALSE;
1438     }
1439
1440   if ((fHC->fLayer * 2 != fStackLinkNumber) && (fHC->fLayer * 2 != fStackLinkNumber - 1)) 
1441     {
1442       if (fgWarnError) AliWarning(Form("Missmatch: plane(layer) in HCheader %d HW-Link %d | %s", 
1443                                        fHC->fLayer, fStackLinkNumber, DumpStackInfo(fStack)));
1444       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongLayer, "Plane-Link missmatch"); 
1445       // Try this for recovery in DecodeSM(void*,UInt_t) after DecodeHC failed
1446       // buffer will still will be marked as NOT clean
1447       fStackLinkNumber = -1;
1448       return kFALSE;      
1449     }
1450
1451   if (fHC->fSide < 0 || fHC->fSide > 1)
1452     {
1453       if (fgWarnError) AliWarning(Form("Wrong Side %d", fHC->fSide));
1454       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongSide, "Wrong Side");       
1455       return kFALSE;
1456     }
1457   
1458   // SLOW GEOM
1459   fHC->fDET = fGeometry->GetDetector(fHC->fLayer, fHC->fStack, fHC->fSM);
1460   if (fHC->fDET < 0 || fHC->fDET >= AliTRDgeometry::kNdet)
1461     {
1462       if (fgWarnError) AliWarning(Form("Wrong detector %d", fHC->fDET));      
1463       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongDet, "Wrong Det");       
1464       return kFALSE;
1465     }
1466
1467   // SLOW GEOM
1468   // this check fails - raw data inconsistent with geometry?
1469   if (fHC->fSM != fGeometry->GetSector(fHC->fDET)
1470       || fHC->fSM <0 || fHC->fSM >= AliTRDgeometry::kNsect)
1471     {
1472       if (fgWarnError) AliWarning(Form("Wrong SM(sector) %d (Geometry says: %d) Stack=%d Layer=%d Det=%d", 
1473                                        fHC->fSM, fGeometry->GetSector(fHC->fDET),
1474                                        fHC->fStack, fHC->fLayer, fHC->fDET));      
1475       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongSM, "Wrong SM");       
1476       return kFALSE;
1477     }
1478
1479   // SLOW GEOM
1480   // CPU EXPENSIVE!!!
1481   fHC->fROC    = fGeometry->GetDetectorSec(fHC->fLayer, fHC->fStack);
1482   if (fHC->fROC < 0)
1483     {
1484       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongROC, "Wrong ROC");       
1485       return kFALSE;
1486     }
1487
1488   fHC->fRowMax = fGeometry->GetRowMax(fHC->fLayer, fHC->fStack, fHC->fSM);
1489   if (fHC->fRowMax < 1)
1490     {
1491       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongROC, "Wrong ROC Row Max");       
1492       return kFALSE;
1493     }
1494
1495   fHC->fColMax = fGeometry->GetColMax(fHC->fROC);
1496   if (fHC->fColMax < 1)
1497     {
1498       if (fRawReader) fRawReader->AddMajorErrorLog(kHCHeaderWrongROC, "Wrong ROC Col Max");       
1499       return kFALSE;
1500     }
1501   // extra - not needed
1502   //   if (fHC->fSM <0 || fHC->fSM >= AliTRDgeometry::kNsect)
1503   //     {
1504   //       if (fgWarnError) AliWarning(Form("Wrong SM(sector) %d (Geometry says: %d) Stack=%d Layer=%d", 
1505   //                  fHC->fSM, fGeometry->GetDetectorSec(fHC->fLayer, fHC->fStack),
1506   //                  fHC->fStack, fHC->fLayer));      
1507   //       return kFALSE;
1508   //     }
1509   
1510   return kTRUE;
1511 }
1512
1513 //------------------------------------------------------------
1514 Bool_t 
1515 AliTRDrawStreamTB::DecodeHCheader()
1516 {  
1517   //
1518   // decode the half chamber header
1519   //
1520
1521   DecodeHCwordH0(fpPos, fHC);
1522     
1523   if (fHC->fNExtraWords > 0)
1524     {
1525       fpPos++;
1526       if (fpPos < fpEnd)
1527         {
1528           DecodeHCwordH1(fpPos, fHC);
1529         }
1530       else
1531         {
1532           if (fgWarnError) AliWarning("Expected HC header word 1. Fail due to buffer END.");
1533           if (fRawReader) fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC word 1 (count from 0) missing"); 
1534           return kFALSE;
1535         }
1536     }
1537
1538   if (fgDebugFlag)  AliDebug(5, DumpHCinfoH0(fHC));
1539   if (fgDebugFlag)  AliDebug(5, DumpHCinfoH1(fHC));
1540
1541   fHC->fDET = -1;
1542   if (IsHCheaderOK() == kFALSE)
1543     {
1544       return kFALSE;
1545     }
1546   
1547   return kTRUE;
1548 }
1549
1550 //------------------------------------------------------------
1551 Bool_t 
1552 AliTRDrawStreamTB::DecodeHC()
1553 {
1554   //
1555   // decode the hc data
1556   // function for devel & debug
1557   //
1558
1559   if (DecodeHCheader() == kFALSE)
1560     {
1561       if (fgDebugStreamer)
1562         {
1563           TTreeSRedirector &cstream = *fgDebugStreamer;
1564           cstream << "HCDecodeError"
1565                   << "Event=" << fgStreamEventCounter
1566                   << ".stack=" << fStackNumber
1567                   << ".link=" << fStackLinkNumber
1568                   << ".hcCorrupted" << fHC->fCorrupted
1569                   << ".hcRVmajor=" << fHC->fRawVMajor
1570                   << ".hcDCSboard=" << fHC->fDCSboard
1571                   << ".hcSM=" << fHC->fSM
1572                   << ".hcStack=" << fHC->fStack
1573                   << ".hcLayer=" << fHC->fLayer
1574                   << ".hcSide=" << fHC->fSide
1575                   << ".hcTbins=" << fHC->fTimeBins
1576                   << ".hcBunchCross=" << fHC->fBunchCrossCounter
1577                   << ".hcPreTrig=" << fHC->fPreTriggerCounter
1578                   << ".hcPreTrigPh=" << fHC->fPreTriggerPhase
1579                   << ".hcDet=" << fHC->fDET
1580                   << ".hcROC=" << fHC->fROC
1581                   << ".hc=RowMax" << fHC->fRowMax
1582                   << ".hc=ColMax" << fHC->fColMax
1583                   << "\n";
1584         }
1585       
1586       if (fgWarnError) AliWarning("Header decode failed.");
1587       return kFALSE;
1588     }
1589   else
1590     {
1591       fpPos++;
1592       if (fpPos >= fpEnd)
1593         {
1594           if (fgWarnError) AliWarning("No MCM data? Not enough data in the buffer.");
1595           if (fRawReader) fRawReader->AddMajorErrorLog(kMCMdataMissing, "MCM data missing"); 
1596           return kFALSE;
1597         }
1598     }
1599
1600   fHC->fMCMmax = 0;
1601   while (*fpPos != ENDOFRAWDATAMARKER && fpPos < fpEnd)
1602     {
1603       if (fHC->fMCMmax > TRD_MAX_MCM)
1604         {
1605           if (fgWarnError) AliWarning("More mcm data than expected!");
1606           if (fRawReader) fRawReader->AddMajorErrorLog(kMCMoverflow, "Too many mcms found!"); 
1607           return kFALSE;
1608         }
1609
1610       fMCM = &fHC->fMCMs[fHC->fMCMmax];
1611
1612       if (DecodeMCMheader() == kFALSE)
1613         {
1614           if (fgDebugStreamer)
1615             {
1616               TTreeSRedirector &cstream = *fgDebugStreamer;
1617               cstream << "MCMDecodeError"
1618                       << "Event=" << fgStreamEventCounter
1619                       << ".stack=" << fStackNumber
1620                       << ".link=" << fStackLinkNumber
1621                       << ".hcDCSboard=" << fHC->fDCSboard
1622                       << ".hcSM=" << fHC->fSM
1623                       << ".hcStack=" << fHC->fStack
1624                       << ".hcLayer=" << fHC->fLayer
1625                       << ".hcSide=" << fHC->fSide
1626                       << ".hcBunchCross=" << fHC->fBunchCrossCounter
1627                       << ".hcPreTrig=" << fHC->fPreTriggerCounter
1628                       << ".hcPreTrigPh=" << fHC->fPreTriggerPhase
1629                       << ".hcDet=" << fHC->fDET
1630
1631                       << ".mcmCorrupted=" << fMCM->fCorrupted
1632                       << ".mcmROB=" << fMCM->fROB
1633                       << ".mcmMCM=" << fMCM->fMCM
1634                       << ".mcmADCMaskWord=" << fMCM->fADCMaskWord
1635                       << ".mcmEventCounter=" << fMCM->fEvCounter
1636
1637                       << ".fEventCounter=" << fEventCounter 
1638                       << ".fLastEventCounter=" << fLastEventCounter
1639                       << "\n";
1640             }
1641           
1642           return kFALSE;
1643         }
1644
1645       fHC->fMCMmax++;
1646
1647       if (fMCM->fADCmax > 0)
1648         {
1649           fpPos++;
1650           if (fpPos >= fpEnd)
1651             {
1652               if (fgDebugFlag)  AliDebug(9, Form("Buffer short of data. ADC data expected."));    
1653               if (fRawReader) fRawReader->AddMajorErrorLog(kADCdataMissing, "ADC data missing"); 
1654             }
1655           
1656           //      for (Int_t iadc = 0; iadc < TRD_MAX_ADC; iadc++)
1657           for (Int_t iadc = 0; iadc < fMCM->fADCmax; iadc++)
1658             {
1659               fADC = &fMCM->fADCs[iadc];
1660               fADC->fADCnumber = fMCM->fADCchannel[iadc];
1661
1662               if (fgDebugFlag)  AliDebug(9, Form("This is ADC %d of %d. ADC number is %d.", 
1663                                                 iadc+1, fMCM->fADCmax, fMCM->fADCchannel[iadc]));
1664
1665               if (fpPos + fMCM->fSingleADCwords >= fpEnd)
1666                 {
1667                   if (fgDebugStreamer)
1668                     {
1669                       TTreeSRedirector &cstream = *fgDebugStreamer;
1670                       // means no data read
1671                       Int_t ierr = -99;
1672                       cstream << "ADCDecodeError"
1673                               << "Event=" << fgStreamEventCounter
1674                               << ".hcSM=" << fHC->fSM
1675                               << ".hcStack=" << fHC->fStack
1676                               << ".hcLayer=" << fHC->fLayer
1677                               << ".mcmROB=" << fMCM->fROB
1678                               << ".mcmMCM=" << fMCM->fMCM
1679                               << ".mcmADCMaskWord=" << fMCM->fADCMaskWord
1680                               << ".adcErr=" << ierr
1681                               << ".adcNumber=" << ierr
1682                               << "\n";                  
1683                     }
1684                   
1685                   if (fgWarnError) AliWarning(Form("This is ADC %d of %d. ADC number is %d.", iadc+1, fMCM->fADCmax, fMCM->fADCchannel[iadc]));
1686                   if (fgWarnError) AliWarning("--> ADC (10 words) expected. Not enough data in the buffer.");
1687                   if (fgWarnError) AliWarning(Form("--> ADC mask : %s", DumpMCMadcMask(fMCM)));
1688
1689                   if (fRawReader) fRawReader->AddMajorErrorLog(kADCdataMissing, "ADC data missing - less than expected"); 
1690                   return kFALSE;
1691                 }
1692
1693               //DECODE the data here
1694               if (DecodeADC() == kFALSE)
1695                 {
1696                   // check if we are out of the det when the pad is shared
1697                   if (fADC->fIsShared && fADC->fCorrupted == 111)
1698                     {
1699                       fADC->fCOL = -1;
1700                       fpPos = fADC->fPos + fMCM->fSingleADCwords;
1701                     }
1702                   else
1703                     {
1704                       if (fgWarnError) AliWarning(Form("ADC decode failed."));
1705                       //fpPos = fMCM->fPpos + fMCMADCWords;
1706
1707                       if (fgDebugStreamer)
1708                         {
1709                           TTreeSRedirector &cstream = *fgDebugStreamer;
1710                           cstream << "ADCDecodeError"
1711                                   << "Event=" << fgStreamEventCounter
1712                                   << ".hcSM=" << fHC->fSM
1713                                   << ".hcStack=" << fHC->fStack
1714                                   << ".hcLayer=" << fHC->fLayer
1715                                   << ".mcmROB=" << fMCM->fROB
1716                                   << ".mcmMCM=" << fMCM->fMCM
1717                                   << ".mcmADCMaskWord=" << fMCM->fADCMaskWord
1718                                   << ".adcErr=" << fADC->fCorrupted
1719                                   << ".adcNumber=" << fADC->fADCnumber
1720                                   << "\n";                      
1721                         }
1722
1723                       fpPos = fADC->fPos + fMCM->fSingleADCwords;
1724                       return kFALSE;
1725                     }
1726                 }
1727               //decode the ADC words here
1728             }     
1729         } //mcm data present
1730       else
1731         {
1732           fpPos++;
1733         }
1734     }//while eof data
1735
1736   if (fpPos >= fpEnd)
1737     {
1738       if (fgWarnError) AliWarning("We are at the end of buffer. There should be one more word left.");
1739       //SeekEndOfData();  
1740       return kFALSE;
1741     }
1742
1743   return kTRUE;
1744 }
1745
1746 //------------------------------------------------------------
1747 Bool_t
1748 AliTRDrawStreamTB::DecodeADC()
1749 {
1750   //
1751   // decode single ADC channel
1752   //
1753
1754   fADC->fCorrupted = 0;
1755   fMaskADCword = ADC_WORD_MASK(*fpPos);
1756   fADC->fPos = fpPos;
1757
1758   fTbinADC = 0;
1759
1760   for (Int_t i = 0; i < TRD_MAX_TBINS; i++)
1761     fADC->fSignals[i] = 0;
1762
1763   for (Int_t iw = 0; iw < fMCM->fSingleADCwords; iw++)
1764     {
1765       if (fMaskADCword != ADC_WORD_MASK(*fpPos))
1766         {
1767           //this is corrupted data
1768           fADC->fCorrupted += 1;
1769           if (fgWarnError) AliWarning(Form("Mask Change in ADC data Previous word (%d) : 0x%08x Previous mask : 0x%08x Current word(%d) : 0x%08x Current mask : 0x%08x", 
1770                                            iw - 1, *(fpPos-1), fMaskADCword, iw, *fpPos, ADC_WORD_MASK(*fpPos)));
1771           if (fRawReader) fRawReader->AddMajorErrorLog(kADCmaskMissmatch, "Mask change inside single channel"); 
1772
1773           break;
1774         }
1775
1776       // here we subtract the baseline ( == common additive)
1777       fADC->fSignals[fTbinADC + 0] = ((*fpPos & 0x00000ffc) >>  2) - fgCommonAdditive;
1778       fADC->fSignals[fTbinADC + 1] = ((*fpPos & 0x003ff000) >> 12) - fgCommonAdditive;
1779       fADC->fSignals[fTbinADC + 2] = ((*fpPos & 0xffc00000) >> 22) - fgCommonAdditive;
1780
1781       fTbinADC += 3;
1782       fpPos++;
1783     }
1784
1785   if (fADC->fADCnumber <= 1 || fADC->fADCnumber == fMaxADCgeom - 1)
1786     {
1787       fADC->fIsShared = kTRUE;
1788     }
1789   else
1790     {
1791       fADC->fIsShared = kFALSE;
1792     }
1793
1794   if ( fADC->fADCnumber >= fMaxADCgeom - 1)
1795     {
1796       // let us guess the Column
1797       // take the one before last ADC and shift by one column
1798       // later we check if we are inside the limits of the chamber
1799       fADC->fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fMCM->fROB, fMCM->fMCM, fADC->fADCnumber - 1);
1800       fADC->fCOL--;
1801     }
1802   else
1803     {
1804       fADC->fCOL = fTRDfeeParam->GetPadColFromADC(fMCM->fROB, fMCM->fMCM, fADC->fADCnumber);
1805     }
1806
1807   if (fADC->fCOL >= fHC->fColMax || fADC->fCOL < 0)
1808     {
1809       if (fADC->fIsShared == kFALSE)
1810         {
1811           fADC->fCorrupted += 100;
1812
1813           if (fgWarnError) AliWarning(Form("Wrong column! ADCnumber %d MaxIs %d Col %d MaxIs %d MCM= %s", 
1814                                            fADC->fADCnumber, fMaxADCgeom, fADC->fCOL, fHC->fColMax, DumpMCMinfo(fMCM)));
1815           if (fRawReader) fRawReader->AddMajorErrorLog(kWrongPadcolumn, "Wrong column");          
1816         }
1817       else
1818         {
1819           // flag it - we are out of the det when the pad is shared
1820           if (fgDebugFlag) AliDebug(10, Form("Column out of the detector! ADCnumber %d MaxIs %d Col %d MaxIs %d MCM= %s", 
1821                                              fADC->fADCnumber, fMaxADCgeom, fADC->fCOL, fHC->fColMax, DumpMCMinfo(fMCM)));
1822           fADC->fCorrupted += 111;
1823         }
1824     }
1825
1826   if (fADC->fCorrupted > 0)
1827     {
1828       return kFALSE;
1829     }
1830
1831   fDecodedADCs++;
1832   return kTRUE;
1833 }
1834
1835 //--------------------------------------------------------
1836 void AliTRDrawStreamTB::DecodeSMInfo(const UInt_t *word, struct AliTRDrawSM *sm) const
1837 {
1838   //
1839   // Decode the data *word into SM info structure
1840   //
1841     
1842   sm->fPos = (UInt_t*)word;
1843
1844   // do it once here
1845   UInt_t vword = *word;
1846   sm->fHeaderSize = SM_HEADER_SIZE(vword);
1847     
1848   if (TRACKLETS_ENABLED(vword) > 0)
1849     sm->fTrackletEnable = kTRUE;
1850   else
1851     sm->fTrackletEnable = kFALSE;
1852     
1853   UInt_t stackMask = STACK_MASK(vword);
1854   sm->fActiveStacks = 0;
1855   for (Int_t i = 0; i < 5; i++)
1856     {
1857       //if ((stackMask >> i) & 0x1 > 0)
1858       if (IS_BIT_SET(stackMask,i) > 0)
1859         {
1860           sm->fStackActive[i] = kTRUE;
1861           sm->fActiveStacks++;
1862         }
1863       else
1864         {
1865           sm->fStackActive[i] = kFALSE;
1866         }
1867     }
1868 }
1869
1870 //--------------------------------------------------------
1871 const char *AliTRDrawStreamTB::DumpSMInfo(const struct AliTRDrawSM *sm)
1872 {
1873   //
1874   // Get SM structure into a const char
1875   //
1876     
1877   return Form("[ SM Info 0x%08x] : Hsize %d TrackletEnable %d Stacks %d %d %d %d %d",
1878               *sm->fPos,
1879               sm->fHeaderSize, sm->fTrackletEnable,
1880               sm->fStackActive[0], sm->fStackActive[1], sm->fStackActive[2],
1881               sm->fStackActive[3], sm->fStackActive[4]);      
1882 }
1883
1884 //--------------------------------------------------------
1885 void AliTRDrawStreamTB::DecodeStackInfo(const UInt_t *word, struct AliTRDrawStack *st) const
1886 {
1887   //
1888   // Decode stack info - active links
1889   //
1890
1891   st->fPos = (UInt_t*)word;
1892       
1893   // do it once here
1894   UInt_t vword = *word;
1895   st->fHeaderSize = STACK_HEADER_SIZE(vword);
1896
1897   UInt_t linkMask = STACK_LINK_WORD(vword);
1898   st->fActiveLinks = 0;
1899   for (Int_t i = 0; i < 12; i++)
1900     {
1901       //if (linkMask & (0x1 << i) > 0)
1902       if (IS_BIT_SET(linkMask,i) > 0)
1903         {
1904           st->fLinksActive[i] = kTRUE;
1905           st->fTrackletDecode[i] = kTRUE;
1906           st->fHCDecode[i] = kTRUE;
1907           st->fActiveLinks++;
1908         }
1909       else
1910         {
1911           st->fTrackletDecode[i] = kFALSE;
1912           st->fLinksActive[i] = kFALSE;
1913           st->fHCDecode[i] = kFALSE;
1914         }
1915     }
1916 }
1917   
1918 //--------------------------------------------------------
1919 const char *AliTRDrawStreamTB::DumpStackInfo(const struct AliTRDrawStack *st)
1920 {
1921   //
1922   // format the string with the stack info
1923   //
1924   return Form("[ Stack Info 0x%08x ] : Hsize %d Links Active %d %d %d %d %d %d %d %d %d %d %d %d",
1925               *st->fPos,
1926               st->fHeaderSize,
1927               st->fLinksActive[0], st->fLinksActive[1], st->fLinksActive[2], st->fLinksActive[3],
1928               st->fLinksActive[4], st->fLinksActive[5], st->fLinksActive[6], st->fLinksActive[7],
1929               st->fLinksActive[8], st->fLinksActive[9], st->fLinksActive[10], st->fLinksActive[11]);
1930 }
1931
1932 //--------------------------------------------------------
1933 void AliTRDrawStreamTB::DecodeHCwordH0(const UInt_t *word, struct AliTRDrawHC *hc) const
1934 {
1935   //
1936   // decode the hc header word 0
1937   //
1938
1939   // do it once here
1940   UInt_t vword = *word;
1941
1942   hc->fCorrupted = HC_HEADER_MASK_ERR(vword);
1943   if (hc->fCorrupted > 0)
1944     {
1945       hc->fH0ErrorCounter++;
1946     }
1947
1948   hc->fSpecialRawV =  HC_SPECIAL_RAW_VERSION(vword);
1949   hc->fRawVMajor = HC_MAJOR_RAW_VERSION(vword);
1950   hc->fRawVMinor = HC_MINOR_RAW_VERSION(vword);
1951   hc->fNExtraWords = HC_EXTRA_WORDS(vword);
1952   hc->fDCSboard = HC_DCS_BOARD(vword);
1953   hc->fSM = HC_SM_NUMBER(vword);
1954   hc->fStack = HC_STACK_NUMBER(vword);
1955   hc->fLayer = HC_LAYER_NUMBER(vword);
1956   hc->fSide = HC_SIDE_NUMBER(vword);
1957
1958   hc->fPos[0] = (UInt_t*)word;
1959
1960 }
1961
1962 //--------------------------------------------------------
1963 void AliTRDrawStreamTB::DecodeHCwordH1(const UInt_t *word, struct AliTRDrawHC *hc) const
1964 {
1965   //
1966   // 
1967   //
1968
1969   // do it once here
1970   UInt_t vword = *word;
1971
1972   hc->fCorrupted += 10 * HC_HEADER_MASK_ERR(vword);
1973   if (hc->fCorrupted > 10)
1974     {
1975       hc->fH1ErrorCounter++;
1976     }
1977
1978   hc->fTimeBins = HC_NTIMEBINS(vword);
1979   hc->fBunchCrossCounter = HC_BUNCH_CROSS_COUNTER(vword);
1980   hc->fPreTriggerCounter = HC_PRETRIGGER_COUNTER(vword);
1981   hc->fPreTriggerPhase = HC_PRETRIGGER_PHASE(vword);
1982
1983   hc->fPos[1] = (UInt_t*)word;
1984 }
1985   
1986 //--------------------------------------------------------
1987 const char *AliTRDrawStreamTB::DumpHCinfoH0(const struct AliTRDrawHC *hc)
1988 {
1989   //
1990   // 
1991   //
1992   if (!hc)
1993     return Form("Unable to dump. Null received as parameter!?!");
1994   else
1995     return Form("[ HC[0] at 0x%08x ] : 0x%08x Info is : RawV %d SM %d Stack %d Layer %d Side %d DCSboard %d",
1996                 hc->fPos[0], *(hc->fPos[0]), hc->fRawVMajor, hc->fSM, hc->fStack, hc->fLayer, hc->fSide, hc->fDCSboard);
1997 }
1998
1999 //--------------------------------------------------------
2000 const char *AliTRDrawStreamTB::DumpHCinfoH1(const struct AliTRDrawHC *hc)
2001 {
2002   //
2003   // 
2004   //
2005   if (!hc)
2006     return Form("Unable to dump. Null received as parameter!?!");
2007   else
2008     return Form("[ HC[1] at 0x%08x ] : 0x%08x Info is : TBins %d BCcount %d PreTrigCount %d PreTrigPhase %d",
2009                 hc->fPos[1], *(hc->fPos[1]), hc->fTimeBins, hc->fBunchCrossCounter, hc->fPreTriggerCounter, hc->fPreTriggerPhase);
2010 }
2011
2012 //--------------------------------------------------------
2013 void AliTRDrawStreamTB::DecodeMCMheader(const UInt_t *word, struct AliTRDrawMCM *mcm) const
2014 {
2015   //
2016   // decode the mcm header
2017   //
2018
2019   // do it once here
2020   UInt_t vword = *word;
2021
2022   mcm->fCorrupted = MCM_HEADER_MASK_ERR(vword);
2023   //printf("0x%08x %d\n", word, MCM_HEADER_MASK_ERR(word));
2024   if (mcm->fCorrupted)
2025     mcm->fErrorCounter++;
2026   mcm->fROB = MCM_ROB_NUMBER(vword);
2027   mcm->fMCM = MCM_MCM_NUMBER(vword);
2028   mcm->fEvCounter = MCM_EVENT_COUNTER(vword);
2029
2030   mcm->fPos = (UInt_t*)word;
2031 }
2032
2033 //--------------------------------------------------------
2034 UInt_t AliTRDrawStreamTB::GetMCMadcMask(const UInt_t *word, struct AliTRDrawMCM *mcm) const
2035 {
2036   //
2037   // get the adc mask
2038   //
2039
2040   // do it once here
2041   UInt_t vword = *word;
2042
2043   mcm->fADCindex = 0;
2044   mcm->fADCmax   = 0;
2045   mcm->fADCMask  = 0;
2046   mcm->fADCMaskWord = vword;
2047   //memset(mcm->fADCchannel, 0, sizeof(UInt_t) * 30);
2048   //if ((word & 0x0000000F) == 0x0000000C)
2049   if ( MCM_ADCMASK_MASK_ERR(vword) == 0 )
2050     {
2051       //mcm->fADCMask = (word >> 4) & skADCmaskBits;
2052       mcm->fADCMask = MCM_ADCMASK_VAL(vword);
2053     }
2054   else
2055     {
2056       mcm->fADCMask = 0xffffffff;
2057       mcm->fCorrupted += 10;
2058       mcm->fMaskErrorCounter++;
2059     }
2060
2061   return mcm->fADCMask;
2062 }
2063
2064 //--------------------------------------------------------
2065 void AliTRDrawStreamTB::DecodeMask(const UInt_t *word, struct AliTRDrawMCM *mcm) const
2066 {
2067   //
2068   // decode the adc mask - adcs to be read out
2069   //
2070
2071   mcm->fMCMADCWords = 0;
2072   mcm->fSingleADCwords = 0;
2073   mcm->fADCmax = 0;
2074   mcm->fADCMask = GetMCMadcMask(word, mcm);
2075   if (mcm->fADCMask > 0)
2076     {
2077       for (Int_t i = 0; i < TRD_MAX_ADC; i++)
2078         {
2079           mcm->fADCchannel[mcm->fADCmax] = 0;
2080           if( IS_BIT_SET(mcm->fADCMask,i) )
2081             {
2082               mcm->fADCchannel[mcm->fADCmax] = i;
2083               mcm->fADCmax++;
2084             }
2085         }
2086     }
2087 }
2088
2089 //--------------------------------------------------------
2090 void AliTRDrawStreamTB::MCMADCwordsWithTbins(UInt_t fTbins, struct AliTRDrawMCM *mcm) const
2091 {
2092   //
2093   //  count the expected mcm words for a given tbins
2094   //
2095   mcm->fMCMADCWords = ( mcm->fADCmax ) * ( fTbins / 3 );
2096   mcm->fSingleADCwords = 0;
2097   if (mcm->fADCmax > 0)
2098     {
2099       mcm->fSingleADCwords = mcm->fMCMADCWords/mcm->fADCmax;
2100     }
2101 }
2102   
2103 //--------------------------------------------------------
2104 const char *AliTRDrawStreamTB::DumpMCMinfo(const struct AliTRDrawMCM *mcm)
2105 {
2106   //
2107   // mcm info in a string
2108   //
2109   if (!mcm)
2110     return Form("Unable to dump. Null received as parameter!?!");
2111   else
2112     return Form("[ MCM 0x%08x ] : ROB %d MCM %d EvCounter %d", *(mcm->fPos), mcm->fROB, mcm->fMCM, mcm->fEvCounter);
2113 }
2114   
2115 //--------------------------------------------------------
2116 //TString DumpMCMadcMask(const struct AliTRDrawMCMInfo *mcm)
2117 const char *AliTRDrawStreamTB::DumpMCMadcMask(const struct AliTRDrawMCM *mcm)
2118 {
2119   //
2120   // mcm adc mask in a string
2121   //
2122   if (!mcm)
2123     return Form("Unable to dump. Null received as parameter!?!");
2124
2125   TString tsreturn = Form("[Word] : 0x%08x => [Mask] : 0x%08x : ", mcm->fADCMaskWord, mcm->fADCMask);
2126   for (Int_t i = 0; i < 21; i++)
2127     {
2128       tsreturn += Form("%d ", mcm->fADCchannel[i]);
2129     }
2130   tsreturn += "";
2131   return tsreturn.Data();
2132 }