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