]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDrawStream.cxx
Remove old tracking code
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStream.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 ////////////////////////////////////////////////////////////////////////////
17 //                                                                        //
18 //  Decoding data from the TRD raw stream                                 //
19 //  and translation into ADC values                                       //
20 //                                                                        //
21 //  Author: J. Klein (jochen.klein@cern.ch)                               //
22 //                                                                        //
23 ////////////////////////////////////////////////////////////////////////////
24
25 #include <cstdio>
26 #include <cstdarg>
27
28 #include "TClonesArray.h"
29 #include "TTree.h"
30
31 #include "AliLog.h"
32 #include "AliRawReader.h"
33 #include "AliTRDdigitsManager.h"
34 #include "AliTRDdigitsParam.h"
35 #include "AliTRDtrapConfig.h"
36 #include "AliTRDarrayADC.h"
37 #include "AliTRDarrayDictionary.h"
38 #include "AliTRDSignalIndex.h"
39 #include "AliTRDtrackletWord.h"
40 #include "AliESDTrdTrack.h"
41 #include "AliTreeLoader.h"
42
43 #include "AliTRDrawStream.h"
44
45 // temporary
46 #include "AliRunLoader.h"
47
48 ClassImp(AliTRDrawStream)
49
50 // some static information 
51 const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15, 
52                                               8, 9, 10, 11, 
53                                               4, 5, 6, 7, 
54                                               0, 1, 2, 3};
55 const Int_t  AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
56 const Int_t  AliTRDrawStream::fgkNlinks = 12;
57 const Int_t  AliTRDrawStream::fgkNstacks = 5;
58 const UInt_t AliTRDrawStream::fgkDataEndmarker     = 0x00000000;
59 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
60
61 const char* AliTRDrawStream::fgErrorMessages[] = {
62   "Unknown error",
63   "Link monitor active",
64   "Pretrigger counter mismatch",
65   "not a TRD equipment (1024-1041)",
66   "Invalid Stack header",
67   "Invalid detector number",
68   "No digits could be retrieved from the digitsmanager",
69   "HC header mismatch", 
70   "HC check bits wrong",
71   "Unexpected position in readout stream",
72   "Invalid testpattern mode",
73   "Testpattern mismatch",
74   "Number of timebins changed",
75   "ADC mask inconsistent", 
76   "ADC check bits invalid", 
77   "Missing ADC data",
78   "Missing expected ADC channels",
79   "Missing MCM headers"
80 };
81
82 const Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
83   0,
84   0,
85   2, 
86   1, 
87   0, 
88   1, 
89   1, 
90   1,
91   1, 
92   2,
93   1,
94   1,
95   1,
96   1, 
97   2, 
98   1, 
99   1, 
100   1
101 };
102
103 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
104   AliTRDrawStream::kTolerate,
105   AliTRDrawStream::kDiscardHC,
106   AliTRDrawStream::kTolerate,
107   AliTRDrawStream::kAbort,
108   AliTRDrawStream::kAbort,
109   AliTRDrawStream::kAbort,
110   AliTRDrawStream::kAbort,
111   AliTRDrawStream::kDiscardHC,
112   AliTRDrawStream::kDiscardHC,
113   AliTRDrawStream::kTolerate,
114   AliTRDrawStream::kTolerate,
115   AliTRDrawStream::kTolerate,
116   AliTRDrawStream::kTolerate,
117   AliTRDrawStream::kTolerate,
118   AliTRDrawStream::kTolerate,
119   AliTRDrawStream::kTolerate,
120   AliTRDrawStream::kTolerate,
121   AliTRDrawStream::kTolerate
122 };
123
124 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
125   fStats(), 
126   fStoreError(&AliTRDrawStream::StoreErrorTree),
127   fRawReader(rawReader),
128   fDigitsManager(0x0),
129   fDigitsParam(0x0),
130   fErrors(0x0),
131   fLastError(),
132   fErrorFlags(0),
133   fPayloadStart(0x0),
134   fPayloadCurr(0x0),
135   fPayloadSize(0),
136   fNtimebins(-1),
137   fLastEvId(-1),
138   fCurrSlot(-1),
139   fCurrLink(-1),
140   fCurrRobPos(-1),
141   fCurrMcmPos(-1),
142   fCurrEquipmentId(0),
143   fCurrSmuIndexHeaderSize(0),
144   fCurrSmuIndexHeaderVersion(0),
145   fCurrTrackEnable(0),
146   fCurrTrackletEnable(0),
147   fCurrStackMask(0),
148   fCurrStackIndexWord(0x0),
149   fCurrStackHeaderSize(0x0),
150   fCurrStackHeaderVersion(0x0),
151   fCurrLinkMask(0x0),
152   fCurrCleanCheckout(0x0),
153   fCurrBoardId(0x0),
154   fCurrHwRev(0x0),
155   fCurrLinkMonitorFlags(0x0),
156   fCurrLinkDataTypeFlags(0x0),
157   fCurrLinkDebugFlags(0x0),
158   fCurrSpecial(-1),
159   fCurrMajor(-1),
160   fCurrMinor(-1),
161   fCurrAddHcWords(-1),
162   fCurrSm(-1),
163   fCurrStack(-1),
164   fCurrLayer(-1),
165   fCurrSide(-1),
166   fCurrHC(-1),
167   fCurrCheck(-1),
168   fCurrNtimebins(-1),
169   fCurrBC(-1),
170   fCurrPtrgCnt(-1),
171   fCurrPtrgPhase(-1),
172   fNDumpMCMs(0),
173   fTrackletArray(0x0),
174   fAdcArray(0x0),
175   fSignalIndex(0x0),
176   fTrackletTree(0x0),
177   fTracklets(0x0),
178   fTracks(0x0),
179   fMarkers(0x0)
180 {
181   // default constructor
182
183   fCurrStackIndexWord     = new UInt_t[fgkNstacks];      
184   fCurrStackHeaderSize    = new UInt_t[fgkNstacks];      
185   fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
186   fCurrLinkMask           = new UInt_t[fgkNstacks];              
187   fCurrCleanCheckout      = new UInt_t[fgkNstacks];      
188   fCurrBoardId            = new UInt_t[fgkNstacks];              
189   fCurrHwRev              = new UInt_t[fgkNstacks];             
190   fCurrLinkMonitorFlags   = new UInt_t[fgkNstacks * fgkNlinks];
191   fCurrLinkDataTypeFlags  = new UInt_t[fgkNstacks * fgkNlinks];
192   fCurrLinkDebugFlags     = new UInt_t[fgkNstacks * fgkNlinks];
193   for (Int_t i = 0; i < 100; i++)
194     fDumpMCM[i] = 0;
195
196   // preparing TClonesArray
197   fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
198
199   // setting up the error tree
200   fErrors = new TTree("errorStats", "Error statistics");
201   fErrors->SetDirectory(0x0);
202   fErrors->Branch("error", &fLastError);
203   fErrors->SetCircular(1000);
204   for (Int_t i = 0; i < 100; i++) {
205     fErrorBuffer[i] = 0;
206   }
207
208 }
209
210 AliTRDrawStream::~AliTRDrawStream()
211 {
212   // destructor
213
214   delete fErrors;
215
216   delete [] fCurrStackIndexWord;
217   delete [] fCurrStackHeaderSize;
218   delete [] fCurrStackHeaderVersion;
219   delete [] fCurrLinkMask;
220   delete [] fCurrCleanCheckout;
221   delete [] fCurrBoardId;
222   delete [] fCurrHwRev;
223   delete [] fCurrLinkMonitorFlags;
224   delete [] fCurrLinkDataTypeFlags;
225   delete [] fCurrLinkDebugFlags;
226 }
227
228 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
229 {
230   // read the current event from the raw reader and fill it to the digits manager
231
232   if (!fRawReader) {
233     AliError("No raw reader available");
234     return kFALSE;
235   }
236
237   // tracklet output
238   ConnectTracklets(trackletTree);
239
240   // some preparations
241   fDigitsParam = 0x0;
242
243   // loop over all DDLs
244   // data starts with GTU payload, i.e. SMU index word
245   UChar_t *buffer = 0x0;
246
247   while (fRawReader->ReadNextData(buffer)) {
248
249     fCurrEquipmentId = fRawReader->GetEquipmentId();
250     AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
251
252     if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
253       EquipmentError(kNonTrdEq, "Skipping");
254       continue;
255     }
256
257     // setting the pointer to data and current reading position
258     fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
259     fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
260     fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
261     AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
262
263     // read SMU index header
264     if (ReadSmHeader() < 0) {
265       AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
266       continue;
267     }
268
269     // read stack index header
270     for (Int_t iStack = 0; iStack < 5; iStack++) {
271       if ((fCurrStackMask & (1 << iStack)) != 0) 
272         ReadStackIndexHeader(iStack);
273     }
274
275     for (Int_t iStack = 0; iStack < 5; iStack++) {
276       fCurrSlot = iStack;
277       if ((fCurrStackMask & (1 << fCurrSlot)) == 0) 
278         continue;
279
280       AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
281       for (Int_t iLink = 0; iLink < 12; iLink++) {
282         fCurrLink = iLink;
283         fCurrHC   = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + iLink;
284         if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
285           continue;
286         
287         fErrorFlags = 0;
288         // check for link monitor error flag
289         if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
290           LinkError(kLinkMonitor);
291
292         // read the data from one HC
293         ReadLinkData();
294
295         // read all data endmarkers
296         SeekNextLink();
297       }
298     }
299   }
300   return kTRUE;
301 }
302
303
304 Bool_t AliTRDrawStream::NextDDL()
305 {
306   // continue reading with the next equipment
307
308   if (!fRawReader)
309     return kFALSE;
310
311   fCurrEquipmentId = 0;
312   fCurrSlot = 0;
313   fCurrLink = 0;
314
315   UChar_t *buffer = 0x0;
316
317   while (fRawReader->ReadNextData(buffer)) {
318
319     fCurrEquipmentId = fRawReader->GetEquipmentId();
320     AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
321     
322     if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
323       EquipmentError(kNonTrdEq, "Skipping");
324       continue;
325     }
326
327     // setting the pointer to data and current reading position
328     fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
329     fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
330     AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
331
332     // read SMU index header
333     if (ReadSmHeader() < 0) {
334       AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
335       continue;
336     }
337     
338     // read stack index header
339     for (Int_t iStack = 0; iStack < 5; iStack++) {
340       if ((fCurrStackMask & (1 << iStack)) != 0) {
341         ReadStackIndexHeader(iStack);
342       }
343     }
344     return kTRUE;
345   }
346
347   return kFALSE;
348 }
349
350
351 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
352 {
353   // read the data for the next chamber
354   // in case you only want to read the data of a single chamber
355   // to read all data ReadEvent(...) is recommended
356
357   fDigitsManager = digMgr; 
358   fDigitsParam   = 0x0;
359
360   fErrorFlags = 0;
361
362   // tracklet output preparation
363   TTree *trklTree = 0x0;
364   AliRunLoader *rl = AliRunLoader::Instance();
365   AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
366   AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
367   if (trklLoader) {
368     AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
369     if (trklTreeLoader) 
370       trklTree = trklTreeLoader->Tree();
371     else 
372       trklTree = trklLoader->Tree();
373   }
374
375   if (fTrackletTree != trklTree)
376     ConnectTracklets(trklTree);
377
378   if (!fRawReader) {
379     AliError("No raw reader available");
380     return -1;
381   }
382
383   while (fCurrSlot < 0 || fCurrSlot >= 5) {
384     if (!NextDDL()) {
385       fCurrSlot = -1;
386       return -1;
387     }
388     while ((fCurrSlot < 5) &&
389            (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
390             ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
391       fCurrLink++;
392       if (fCurrLink > 11) {
393         fCurrLink = 0;
394         fCurrSlot++;
395       }
396     }
397   }
398
399   AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
400   fCurrHC   = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
401
402   if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
403     LinkError(kLinkMonitor);
404
405   // read the data from one HC
406   ReadLinkData();
407   
408   // read all data endmarkers
409   SeekNextLink();
410
411   if (fCurrLink % 2 == 0) {
412     // if we just read the A-side HC then also check the B-side
413     fCurrLink++;
414     fCurrHC++;
415     if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
416       ReadLinkData();
417       SeekNextLink();
418     }
419   }
420
421   //??? to check 
422   do {
423     fCurrLink++; 
424     if (fCurrLink > 11) {
425       fCurrLink = 0;
426       fCurrSlot++;
427     }
428   } while ((fCurrSlot < 5) && 
429            (((fCurrStackMask & (1 << fCurrSlot)) == 0) || 
430             ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
431
432   // return chamber information from HC if it is valid
433   // otherwise return information from link position
434   if (fCurrSm < 0 || fCurrSm > 17 || fCurrStack < 0 || fCurrStack > 4 || fCurrLayer < 0 || fCurrLayer > 5)
435     return ((fCurrEquipmentId-1024) + fCurrSlot * 6 + fCurrLink/2);
436   else
437     return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
438 }
439
440
441 Int_t AliTRDrawStream::ReadSmHeader()
442 {
443   // read the SMU index header at the current reading position 
444   // and store the information in the corresponding variables
445
446   if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
447     EquipmentError(kUnknown, "SM Header incomplete");
448     return -1;
449   }
450
451   fCurrSmuIndexHeaderSize     = ((*fPayloadCurr) >> 16) & 0xffff;
452   fCurrSmuIndexHeaderVersion  = ((*fPayloadCurr) >> 12) &    0xf;
453   //  fCurrSmuIndexHeaderTrgAvail = ((*fPayloadCurr) >>  9) &    0x1;
454   //  fCurrSmuIndexHeaderEvType   = ((*fPayloadCurr) >>  7) &    0x3;
455   fCurrTrackEnable            = ((*fPayloadCurr) >>  6) &    0x1;
456   fCurrTrackletEnable         = ((*fPayloadCurr) >>  5) &    0x1;
457   fCurrStackMask              = ((*fPayloadCurr)      ) &   0x1f;
458
459   AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
460                    fCurrSmuIndexHeaderSize, 
461                    fCurrSmuIndexHeaderVersion, 
462                    fCurrTrackEnable, 
463                    fCurrTrackletEnable,
464                    fCurrStackMask));
465
466   // decode GTU track words
467   UInt_t trackWord[2] = { 0, 0 };
468   Int_t stack = 0;
469   Int_t idx = 0;
470   for (UInt_t iWord = 4; iWord < fCurrSmuIndexHeaderSize; iWord++) {
471     if (fPayloadCurr[iWord] == 0x10000000) {
472       stack++;
473       idx = 0;
474     }
475     else {
476       if ((idx == 0) &&
477           ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
478         AliDebug(1,Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
479         continue;
480       }
481       else if ((idx & 0x1)==0x1) {
482         trackWord[idx&0x1] = fPayloadCurr[iWord];
483         AliDebug(1,Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
484 //      if (fTracks)
485 //        new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-1024);
486       }
487       else {
488         trackWord[idx&0x1] = fPayloadCurr[iWord];
489       }
490       idx++;
491     }
492   }
493
494   fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
495
496   return fCurrSmuIndexHeaderSize + 1;
497 }
498
499 Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
500 {
501   // read the stack index header 
502   // and store the information in the corresponding variables
503
504   fCurrStackIndexWord[stack]     = *fPayloadCurr;
505   fCurrStackHeaderSize[stack]    = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
506   fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
507   fCurrLinkMask[stack]           = (*fPayloadCurr) & 0xfff;
508
509   if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
510     StackError(kStackHeaderInvalid, "Stack index header aborted");
511     return -1;
512   }
513
514   switch (fCurrStackHeaderVersion[stack]) {
515   case 0xa: 
516     if (fCurrStackHeaderSize[stack] < 8) {
517       StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
518       return -1;
519     }
520     
521     fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
522     fCurrBoardId[stack]       = (fPayloadCurr[1] >> 8) & 0xff;
523     fCurrHwRev[stack]         = (fPayloadCurr[1] >> 16) & 0xffff;
524     
525     for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
526       // A side
527       fCurrLinkMonitorFlags  [stack*fgkNlinks + iLayer*2]      = fPayloadCurr[iLayer+2] & 0xf;
528       fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2]      = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
529       fCurrLinkDebugFlags    [stack*fgkNlinks + iLayer*2]      = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
530       // B side
531       fCurrLinkMonitorFlags  [stack*fgkNlinks + iLayer*2 + 1]  = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
532       fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1]  = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
533       fCurrLinkDebugFlags    [stack*fgkNlinks + iLayer*2 + 1]  = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
534     }
535     break;
536     
537   default:
538     StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
539   }
540   
541   fPayloadCurr += fCurrStackHeaderSize[stack];
542
543   return fCurrStackHeaderSize[stack];
544 }
545
546 Int_t AliTRDrawStream::ReadLinkData()
547 {
548   // read the data in one link (one HC) until the data endmarker is reached
549   // returns the number of words read!
550
551   Int_t count = 0;
552   UInt_t* startPosLink = fPayloadCurr;
553
554 //  printf("----- HC: %i -----\n", fCurrHC);
555 //  for (Int_t i = 0; i < 3; i++) {
556 //    printf("0x%08x 0x%08x 0x%08x 0x%08x\n", 
557 //         fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
558 //  }
559
560   if (fMarkers)
561     new ((*fMarkers)[fMarkers->GetEntriesFast()])
562       AliTRDrawStreamError(-kHCactive, fCurrSm, fCurrStack, fCurrLink);
563
564   if (fErrorFlags & kDiscardHC)
565     return count;
566
567   count += ReadTracklets();
568   if (fErrorFlags & kDiscardHC)
569     return count;
570
571   count += ReadHcHeader();
572   if (fErrorFlags & kDiscardHC)
573     return count;
574
575   Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
576
577   if (det > -1 && det < 540) {
578     
579     if ((fAdcArray = fDigitsManager->GetDigits(det))) {
580       //fAdcArray->Expand();
581       if (fAdcArray->GetNtime() != fCurrNtimebins)
582         fAdcArray->Allocate(16, 144, fCurrNtimebins);
583     }
584     else {
585       LinkError(kNoDigits);
586     }
587     
588     if (!fDigitsParam) {
589       fDigitsParam = fDigitsManager->GetDigitsParam();
590     }
591     if (fDigitsParam) {
592       fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
593       fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
594       fDigitsParam->SetADCbaseline(det, 10);
595     }
596     
597     if (fDigitsManager->UsesDictionaries()) {
598       fDigitsManager->GetDictionary(det, 0)->Reset();
599       fDigitsManager->GetDictionary(det, 1)->Reset();
600       fDigitsManager->GetDictionary(det, 2)->Reset();
601     }
602
603     if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
604       fSignalIndex->SetSM(fCurrSm);
605       fSignalIndex->SetStack(fCurrStack);
606       fSignalIndex->SetLayer(fCurrLayer);
607       fSignalIndex->SetDetNumber(det);
608       if (!fSignalIndex->IsAllocated())
609         fSignalIndex->Allocate(16, 144, fCurrNtimebins);
610     }
611     
612     // ----- check which kind of data -----
613     if (fCurrMajor & 0x40) {
614       if ((fCurrMajor & 0x7) == 0x7) {
615         AliDebug(1, "This is a config event");
616         UInt_t *startPos = fPayloadCurr;
617         while (fPayloadCurr - fPayloadStart < fPayloadSize &&
618                *fPayloadCurr != fgkDataEndmarker)
619           fPayloadCurr++;
620         count += fPayloadCurr - startPos;
621         
622         // feeding TRAP config
623         AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
624         trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
625       }
626       else {
627         Int_t tpmode = fCurrMajor & 0x7;
628         AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
629         ReadTPData(tpmode);
630       }
631     }
632     else if (fCurrMajor & 0x20) {
633       AliDebug(1, "This is a zs event");
634       count += ReadZSData();
635     }
636     else {
637       AliDebug(1, "This is a nozs event");
638       count += ReadNonZSData();
639     }
640   }
641   else {
642     LinkError(kInvalidDetector, "%i", det);
643     while (fPayloadCurr - fPayloadStart < fPayloadSize &&
644            *fPayloadCurr != fgkDataEndmarker)
645       fPayloadCurr++;
646   }
647
648   if (fCurrSm > -1 && fCurrSm < 18) {
649     fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes     += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
650     fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
651     fStats.fStatsSector[fCurrSm].fBytesRead                      += count * sizeof(UInt_t);
652     fStats.fBytesRead                                            += count * sizeof(UInt_t);
653   }
654
655   return count;
656 }
657
658 Int_t AliTRDrawStream::ReadTracklets()
659 {
660   // read the tracklets from one HC
661
662   fTrackletArray->Clear();
663
664   UInt_t *start = fPayloadCurr;
665   while (*(fPayloadCurr) != fgkTrackletEndmarker && 
666          fPayloadCurr - fPayloadStart < fPayloadSize) {
667
668     new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
669
670     fPayloadCurr++;
671   }
672
673   if (fTrackletArray->GetEntriesFast() > 0) {
674     AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(), 
675                      (fCurrEquipmentId-1024), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
676     if (fCurrSm > -1 && fCurrSm < 18) {
677       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
678       fStats.fStatsSector[fCurrSm].fNTracklets                      += fTrackletArray->GetEntriesFast();
679     }
680     if (fTrackletTree)
681       fTrackletTree->Fill();
682     if (fTracklets)
683       for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
684         new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
685       }
686   }
687
688   // loop over remaining tracklet endmarkers
689   while ((*(fPayloadCurr) == fgkTrackletEndmarker && 
690           fPayloadCurr - fPayloadStart < fPayloadSize)) 
691     fPayloadCurr++;
692   
693   return fPayloadCurr - start;
694 }
695
696 Int_t AliTRDrawStream::ReadHcHeader()
697 {
698   // read and parse the HC header of one HC
699   // and store the information in the corresponding variables
700
701   UInt_t *start = fPayloadCurr;
702   // check not to be at the data endmarker
703   if (*fPayloadCurr == fgkDataEndmarker)
704     return 0;
705
706   fCurrSpecial    = (*fPayloadCurr >> 31) & 0x1;
707   fCurrMajor      = (*fPayloadCurr >> 24) & 0x7f;
708   fCurrMinor      = (*fPayloadCurr >> 17) & 0x7f;
709   fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
710   fCurrSm         = (*fPayloadCurr >> 9) & 0x1f;
711   fCurrLayer      = (*fPayloadCurr >> 6) & 0x7;
712   fCurrStack      = (*fPayloadCurr >> 3) & 0x7;
713   fCurrSide       = (*fPayloadCurr >> 2) & 0x1;
714   fCurrCheck      = (*fPayloadCurr) & 0x3;
715
716   if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) || 
717       fCurrStack != fCurrSlot || 
718       fCurrLayer != fCurrLink / 2 || 
719       fCurrSide != fCurrLink % 2) {
720     LinkError(kHCmismatch,
721               "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x", 
722               fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
723               fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);;
724   }
725   if (fCurrCheck != 0x1) {
726     LinkError(kHCcheckFailed);
727   }
728   
729   if (fCurrAddHcWords > 0) {
730     fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
731     fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
732     fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
733     fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
734   }
735   
736   fPayloadCurr += 1 + fCurrAddHcWords;
737   
738   return (fPayloadCurr - start);
739 }
740
741 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
742 {
743   // testing of testpattern 1 to 3 (hardcoded), 0 missing
744   // evcnt checking missing
745   Int_t cpu = 0;
746   Int_t cpufromchannel[] = {0, 0, 0, 0, 0,  1, 1, 1, 1, 1,  2, 2, 2, 2, 2,  3, 3, 3, 3, 3, 3};
747   Int_t evcnt = 0;
748   Int_t count = 0;
749   Int_t mcmcount = -1;
750   Int_t wordcount = 0;
751   Int_t channelcount = 0;
752   UInt_t expword = 0;
753   UInt_t expadcval = 0;
754   UInt_t diff = 0;
755   Int_t lastmcmpos = -1;
756   Int_t lastrobpos = -1;
757
758   UInt_t* start = fPayloadCurr;
759
760   while (*(fPayloadCurr) != fgkDataEndmarker && 
761          fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
762
763     // ----- Checking MCM Header -----
764     AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
765     mcmcount++;
766     
767     // ----- checking for proper readout order - ROB -----
768     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
769       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
770     }
771     else {
772       ROBError(kPosUnexp);
773     }
774     fCurrRobPos = ROB(*fPayloadCurr);
775     
776     // ----- checking for proper readout order - MCM -----
777     if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
778       lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
779     }
780     else {
781       MCMError(kPosUnexp);
782     }
783     fCurrMcmPos = MCM(*fPayloadCurr);
784     
785
786     fPayloadCurr++;
787     
788     evcnt = 0x3f & *fPayloadCurr >> 26;
789     cpu = -1;
790     channelcount = 0;
791     while (channelcount < 21) {
792       count = 0;
793       if (cpu != cpufromchannel[channelcount]) {
794         cpu = cpufromchannel[channelcount];
795         expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
796         wordcount = 0;
797       }
798       
799       while (count < 10) {
800         if (channelcount % 2 == 0)
801           expword = 0x3;
802         else 
803           expword = 0x2;
804         
805         if (mode == 1) {
806           // ----- TP 1 -----
807           expword |= expadcval << 2;
808           expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
809           expword |= expadcval << 12;
810           expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
811           expword |= expadcval << 22;
812           expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
813         }
814         else if (mode == 2) {
815           // ----- TP 2 ------
816           expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) | 
817             ((fCurrStack + 1) << 15) | 
818             (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1); 
819         }
820         else if (mode == 3) {
821           // ----- TP 3 -----
822           expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) | 
823             (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0); 
824         }
825         else {
826           expword = 0;
827           LinkError(kTPmodeInvalid, "Just reading");
828         }
829
830         diff = *fPayloadCurr ^ expword;
831         if (diff != 0) {
832           MCMError(kTPmismatch,
833                    "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)", 
834                    *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
835         }
836         fPayloadCurr++;
837         count++;
838         wordcount++;
839       }
840       channelcount++;
841     }
842     // continue with next MCM
843   }
844   return fPayloadCurr - start; 
845 }
846
847
848 Int_t AliTRDrawStream::ReadZSData()
849 {
850   // read the zs data from one link from the current reading position
851   
852   UInt_t *start = fPayloadCurr;
853   
854   Int_t mcmcount = 0;
855   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
856   Int_t channelcount = 0;
857   Int_t channelcountExp = 0;
858   Int_t channelcountMax = 0;
859   Int_t timebins;
860   Int_t currentTimebin = 0;
861   Int_t adcwc = 0;
862   Int_t evno = -1;
863   Int_t lastmcmpos = -1;
864   Int_t lastrobpos = -1;
865
866   if (fCurrNtimebins != fNtimebins) {
867     if (fNtimebins > 0) 
868       LinkError(kNtimebinsChanged,
869                 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
870     fNtimebins = fCurrNtimebins;
871   }
872   
873   timebins = fNtimebins;
874   
875   while (*(fPayloadCurr) != fgkDataEndmarker && 
876          fPayloadCurr - fPayloadStart < fPayloadSize) {
877     
878     // ----- Checking MCM Header -----
879     AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
880     UInt_t *startPosMCM = fPayloadCurr;
881     
882     // ----- checking for proper readout order - ROB -----
883     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
884       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
885     }
886     else {
887       ROBError(kPosUnexp);
888     }
889     fCurrRobPos = ROB(*fPayloadCurr);
890     
891     // ----- checking for proper readout order - MCM -----
892     if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
893       lastmcmpos = GetMCMReadoutPos(lastmcmpos);
894     }
895     else {
896       MCMError(kPosUnexp);
897     }
898     fCurrMcmPos = MCM(*fPayloadCurr);
899     
900     if (EvNo(*fPayloadCurr) != evno) {
901       if (evno == -1)
902         evno = EvNo(*fPayloadCurr);
903       else {
904         MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
905       }
906     }
907     Int_t adccoloff = AdcColOffset(*fPayloadCurr);
908     Int_t padcoloff = PadColOffset(*fPayloadCurr);
909     Int_t row = Row(*fPayloadCurr);
910     fPayloadCurr++;
911     
912     // ----- Reading ADC channels -----
913     AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
914     
915     // ----- analysing the ADC mask -----
916     channelcount = 0;
917     channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
918     channelcountMax = GetNActiveChannels(*fPayloadCurr);
919     Int_t channelmask = GetActiveChannels(*fPayloadCurr);
920     Int_t channelno = -1;
921     fPayloadCurr++; 
922
923     if (channelcountExp != channelcountMax) {
924       if (channelcountExp > channelcountMax) {
925         Int_t temp = channelcountExp;
926         channelcountExp = channelcountMax;
927         channelcountMax = temp;
928       }
929       while (channelcountExp < channelcountMax && channelcountExp < 21 && 
930              fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
931         MCMError(kAdcMaskInconsistent,
932                  "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x", 
933                  *(fPayloadCurr + 10 * channelcountExp), 
934                  *(fPayloadCurr + 10 * channelcountExp + 1) );
935         if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1))) 
936           channelcountExp++;
937         else {
938           break;
939         }
940       }
941       MCMError(kAdcMaskInconsistent,
942                "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!", 
943                GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
944     }
945     AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
946     
947     // ----- reading marked ADC channels -----
948     while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
949       if (channelno < 20)
950         channelno++;
951       while (channelno < 20 && (channelmask & 1 << channelno) == 0)
952         channelno++;
953       
954       if (fCurrNtimebins > 30) {
955         currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
956         timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
957       } 
958       else {
959         currentTimebin = 0;
960       }
961       
962       adcwc = 0;
963       AliDebug(2, Form("Now looking %i words", timebins / 3));
964       Int_t adccol = adccoloff - channelno;
965       Int_t padcol = padcoloff - channelno;
966 //      if (adccol < 3 || adccol > 165) 
967 //      AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i", 
968 //                   channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
969
970       while (adcwc < timebins / 3 && 
971              *(fPayloadCurr) != fgkDataEndmarker && 
972              fPayloadCurr - fPayloadStart < fPayloadSize) {
973         int check = 0x3 & *fPayloadCurr;
974         if (channelno % 2 != 0) { // odd channel
975           if (check != 0x2 && channelno < 21) {
976             MCMError(kAdcCheckInvalid,
977                      "%i for %2i. ADC word in odd channel %i", 
978                      check, adcwc+1, channelno);
979           }
980         }
981         else {                  // even channel
982           if (check != 0x3 && channelno < 21) {
983             MCMError(kAdcCheckInvalid,
984                      "%i for %2i. ADC word in even channel %i", 
985                      check, adcwc+1, channelno);
986           }
987         }
988         
989         // filling the actual timebin data
990         int tb2 = 0x3ff & *fPayloadCurr >> 22;
991         int tb1 = 0x3ff & *fPayloadCurr >> 12;
992         int tb0 = 0x3ff & *fPayloadCurr >> 2;
993         if (adcwc != 0 || fCurrNtimebins <= 30) 
994           fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
995         else
996           tb0 = -1;
997         fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
998         fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
999         
1000         adcwc++;
1001         fPayloadCurr++;
1002       }
1003       
1004       if (adcwc != timebins / 3) 
1005         MCMError(kAdcDataAbort);
1006       
1007       // adding index 
1008       if (padcol > 0 && padcol < 144) {
1009         fSignalIndex->AddIndexRC(row, padcol);
1010       }
1011       
1012       channelcount++;
1013     }
1014
1015     if (fCurrSm > -1 && fCurrSm < 18) {
1016       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1017       fStats.fStatsSector[fCurrSm].fNChannels                      += channelcount;
1018     }
1019     if (channelcount != channelcountExp)
1020       MCMError(kAdcChannelsMiss);
1021     
1022     mcmcount++;
1023     if (fCurrSm > -1 && fCurrSm < 18) {
1024       fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1025       fStats.fStatsSector[fCurrSm].fNMCMs++;
1026     }
1027
1028     if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1029       DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1030               startPosMCM, fPayloadCurr - startPosMCM);
1031     }
1032
1033     // continue with next MCM
1034   }
1035
1036   // check for missing MCMs (if header suppression is inactive)
1037   if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1038     LinkError(kMissMcmHeaders,
1039               "No. of MCM headers %i not as expected: %i", 
1040               mcmcount, mcmcountExp);
1041   }
1042
1043   return (fPayloadCurr - start);
1044 }
1045
1046 Int_t AliTRDrawStream::ReadNonZSData()
1047 {
1048   // read the non-zs data from one link from the current reading position
1049   
1050   UInt_t *start = fPayloadCurr;
1051   
1052   Int_t mcmcount = 0;
1053   Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1054   Int_t channelcount = 0;
1055   Int_t channelcountExp = 0;
1056   Int_t timebins;
1057   Int_t currentTimebin = 0;
1058   Int_t adcwc = 0;
1059   Int_t evno = -1;
1060   Int_t lastmcmpos = -1;
1061   Int_t lastrobpos = -1;
1062
1063   if (fCurrNtimebins != fNtimebins) {
1064     if (fNtimebins > 0) 
1065       LinkError(kNtimebinsChanged,
1066                 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1067     fNtimebins = fCurrNtimebins;
1068   }
1069   
1070   timebins = fNtimebins;
1071   
1072   while (*(fPayloadCurr) != fgkDataEndmarker && 
1073          fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1074     
1075     // ----- Checking MCM Header -----
1076     AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1077     
1078     // ----- checking for proper readout order - ROB -----
1079     if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1080       lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1081     }
1082     else {
1083       ROBError(kPosUnexp);
1084     }
1085     fCurrRobPos = ROB(*fPayloadCurr);
1086     
1087     // ----- checking for proper readout order - MCM -----
1088     if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1089       lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
1090     }
1091     else {
1092       MCMError(kPosUnexp);
1093     }
1094     fCurrMcmPos = MCM(*fPayloadCurr);
1095     
1096     if (EvNo(*fPayloadCurr) != evno) {
1097       if (evno == -1)
1098         evno = EvNo(*fPayloadCurr);
1099       else {
1100         MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1101       }
1102     }
1103     
1104     channelcount = 0;
1105     channelcountExp = 21;
1106     int channelno = -1;
1107
1108     Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1109     Int_t padcoloff = PadColOffset(*fPayloadCurr);
1110     Int_t row = Row(*fPayloadCurr);
1111
1112     fPayloadCurr++;
1113
1114     // ----- reading marked ADC channels -----
1115     while (channelcount < channelcountExp && 
1116            *(fPayloadCurr) != fgkDataEndmarker) {
1117       if (channelno < 20)
1118         channelno++;
1119       
1120       currentTimebin = 0;
1121       
1122       adcwc = 0;
1123       AliDebug(2, Form("Now looking %i words", timebins / 3));
1124       Int_t adccol = adccoloff - channelno;
1125       Int_t padcol = padcoloff - channelno;
1126       while (adcwc < timebins / 3 && 
1127              *(fPayloadCurr) != fgkDataEndmarker && 
1128              fPayloadCurr - fPayloadStart < fPayloadSize) {
1129         int check = 0x3 & *fPayloadCurr;
1130         if (channelno % 2 != 0) { // odd channel
1131           if (check != 0x2 && channelno < 21) {
1132             MCMError(kAdcCheckInvalid,
1133                      "%i for %2i. ADC word in odd channel %i", 
1134                      check, adcwc+1, channelno);
1135           }
1136         }
1137         else {                  // even channel
1138           if (check != 0x3 && channelno < 21) {
1139             MCMError(kAdcCheckInvalid,
1140                      "%i for %2i. ADC word in even channel %i", 
1141                      check, adcwc+1, channelno);
1142           }
1143         }
1144         
1145         // filling the actual timebin data
1146         int tb2 = 0x3ff & *fPayloadCurr >> 22;
1147         int tb1 = 0x3ff & *fPayloadCurr >> 12;
1148         int tb0 = 0x3ff & *fPayloadCurr >> 2;
1149         if (adcwc != 0 || fCurrNtimebins <= 30) 
1150           fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1151         else
1152           tb0 = -1;
1153         fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1154         fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1155
1156         adcwc++;
1157         fPayloadCurr++;
1158       }
1159
1160       if (adcwc != timebins / 3) 
1161         MCMError(kAdcDataAbort);
1162       
1163       // adding index 
1164       if (padcol > 0 && padcol < 144) {
1165         fSignalIndex->AddIndexRC(row, padcol);
1166       }
1167
1168       channelcount++;
1169     }
1170
1171     if (channelcount != channelcountExp)
1172       MCMError(kAdcChannelsMiss);
1173     mcmcount++;
1174     // continue with next MCM
1175   }
1176
1177   // check for missing MCMs (if header suppression is inactive)
1178   if (mcmcount != mcmcountExp) {
1179     LinkError(kMissMcmHeaders,
1180               "%i not as expected: %i", mcmcount, mcmcountExp);
1181   }
1182
1183   return (fPayloadCurr - start);
1184 }
1185
1186 Int_t AliTRDrawStream::SeekNextLink()
1187 {
1188   UInt_t *start = fPayloadCurr;
1189
1190   // read until data endmarkers
1191   while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1192          *fPayloadCurr != fgkDataEndmarker)
1193     fPayloadCurr++;
1194
1195   // read all data endmarkers
1196   while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1197          *fPayloadCurr == fgkDataEndmarker)
1198     fPayloadCurr++;
1199
1200   return (fPayloadCurr - start);
1201 }
1202
1203 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree) 
1204 {
1205   fTrackletTree = trklTree;
1206   if (!fTrackletTree) 
1207     return kTRUE;
1208
1209   if (!fTrackletTree->GetBranch("hc")) 
1210     fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1211   else 
1212     fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1213
1214   if (!fTrackletTree->GetBranch("trkl")) 
1215     fTrackletTree->Branch("trkl", &fTrackletArray);
1216   else 
1217     fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1218
1219   return kTRUE;
1220 }
1221
1222
1223 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1224
1225   // register error according to error code on equipment level 
1226   // and return the corresponding error message
1227
1228   fLastError.fSector = fCurrEquipmentId - 1024;
1229   fLastError.fStack  = -1;
1230   fLastError.fLink   = -1;
1231   fLastError.fRob    = -1;
1232   fLastError.fMcm    = -1;
1233   fLastError.fError  = err;
1234   (this->*fStoreError)();
1235
1236   va_list ap;
1237   if (fgErrorDebugLevel[err] > 10) 
1238     AliDebug(fgErrorDebugLevel[err],
1239              Form("Event %6i: Eq. %2d - %s : %s", 
1240                   fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1241                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1242   else 
1243     AliError(Form("Event %6i: Eq. %2d - %s : %s", 
1244                   fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1245                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1246   fErrorFlags |= fgErrorBehav[err];
1247 }                                                                               
1248
1249
1250 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1251
1252   // register error according to error code on stack level 
1253   // and return the corresponding error message
1254
1255   fLastError.fSector = fCurrEquipmentId - 1024;
1256   fLastError.fStack  = fCurrSlot;
1257   fLastError.fLink   = -1;
1258   fLastError.fRob    = -1;
1259   fLastError.fMcm    = -1;
1260   fLastError.fError  = err;
1261   (this->*fStoreError)();
1262
1263   va_list ap;
1264   if (fgErrorDebugLevel[err] > 0) 
1265     AliDebug(fgErrorDebugLevel[err], 
1266              Form("Event %6i: Eq. %2d S %i - %s : %s", 
1267                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1268                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1269   else 
1270     AliError(Form("Event %6i: Eq. %2d S %i - %s : %s", 
1271                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1272                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1273   fErrorFlags |= fgErrorBehav[err];
1274
1275
1276
1277 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
1278
1279   // register error according to error code on link level 
1280   // and return the corresponding error message
1281
1282   fLastError.fSector = fCurrEquipmentId - 1024;
1283   fLastError.fStack  = fCurrSlot;
1284   fLastError.fLink   = fCurrLink;
1285   fLastError.fRob    = -1;
1286   fLastError.fMcm    = -1;
1287   fLastError.fError  = err;
1288   (this->*fStoreError)();
1289
1290   va_list ap;
1291   if (fgErrorDebugLevel[err] > 0)
1292     AliDebug(fgErrorDebugLevel[err], 
1293              Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", 
1294                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1295                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1296   else 
1297     AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", 
1298                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1299                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1300   fErrorFlags |= fgErrorBehav[err];
1301
1302
1303
1304 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
1305
1306   // register error according to error code on ROB level 
1307   // and return the corresponding error message
1308
1309   fLastError.fSector = fCurrEquipmentId - 1024;
1310   fLastError.fStack  = fCurrSlot;
1311   fLastError.fLink   = fCurrLink;
1312   fLastError.fRob    = fCurrRobPos;
1313   fLastError.fMcm    = -1;
1314   fLastError.fError  = err;
1315   (this->*fStoreError)();
1316
1317   va_list ap;
1318   if (fgErrorDebugLevel[err] > 0) 
1319     AliDebug(fgErrorDebugLevel[err], 
1320              Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", 
1321                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
1322                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1323   else 
1324     AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", 
1325                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err], 
1326                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1327   fErrorFlags |= fgErrorBehav[err];
1328
1329
1330
1331 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
1332
1333   // register error according to error code on MCM level 
1334   // and return the corresponding error message
1335
1336   fLastError.fSector = fCurrEquipmentId - 1024;
1337   fLastError.fStack  = fCurrSlot;
1338   fLastError.fLink   = fCurrLink;
1339   fLastError.fRob    = fCurrRobPos;
1340   fLastError.fMcm    = fCurrMcmPos;
1341   fLastError.fError  = err;
1342   (this->*fStoreError)();
1343
1344   va_list ap;
1345   if (fgErrorDebugLevel[err] > 0) 
1346     AliDebug(fgErrorDebugLevel[err], 
1347              Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1348                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err], 
1349                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1350   else 
1351     AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1352                   fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err], 
1353                   (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1354   fErrorFlags |= fgErrorBehav[err];
1355 }
1356
1357 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1358
1359   // return the error message for the given error code
1360
1361   if (errCode > 0 && errCode < kLastErrorCode) 
1362     return fgErrorMessages[errCode];
1363   else 
1364     return ""; 
1365
1366
1367 void AliTRDrawStream::AliTRDrawStats::ClearStats()
1368 {
1369   // clear statistics (includes clearing sector-wise statistics)
1370
1371   fBytesRead = 0;
1372   for (Int_t iSector = 0; iSector < 18; iSector++) {
1373     fStatsSector[iSector].ClearStats();
1374   }
1375
1376 }
1377
1378 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1379 {
1380   // clear statistics (includes clearing HC-wise statistics)
1381
1382   fBytes = 0;
1383   fBytesRead = 0;
1384   fNTracklets = 0;
1385   fNMCMs = 0;
1386   fNChannels = 0;
1387
1388   for (Int_t iHC = 0; iHC < 60; iHC++) {
1389     fStatsHC[iHC].ClearStats();
1390   }
1391 }
1392
1393 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1394 {
1395   // clear statistics
1396
1397   fBytes = 0;
1398   fBytesRead = 0;
1399   fNTracklets = 0;
1400   fNMCMs = 0;
1401   fNChannels = 0;
1402 }
1403
1404 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1405
1406   // mark MCM for dumping of raw data
1407
1408   if (dump) {
1409     fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm; 
1410   }
1411   else {
1412     Int_t iMCM;
1413     for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1414       if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1415         fNDumpMCMs--;
1416         break;
1417       }
1418     }
1419     for ( ; iMCM < fNDumpMCMs; iMCM++) {
1420       fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1421     }
1422   }
1423 }
1424
1425 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) 
1426 {
1427   // check if MCM data should be dumped
1428
1429   for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1430     if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1431       return kTRUE;
1432     }
1433   }
1434   return kFALSE;
1435 }
1436
1437 void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
1438 {
1439   // dump raw data
1440
1441   title += "\n";
1442   Int_t pos = 0;
1443   for ( ; pos+3 < length; pos += 4) {
1444     title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n", 
1445                   start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1446   }
1447   for ( ; pos < length; pos++) {
1448     title += Form("0x%08x ", start[pos]);
1449   }
1450   AliInfo(title);
1451 }
1452
1453 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) : 
1454   fError(error),
1455   fSector(sector),
1456   fStack(stack),
1457   fLink(link), 
1458   fRob(rob),
1459   fMcm(mcm)
1460 {
1461   // ctor
1462
1463 }