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