]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawStreamTrackerHP.h
Fixes in reconstruction:
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTrackerHP.h
1 #ifndef ALIMUONRAWSTREAMTRACKERHP_H
2 #define ALIMUONRAWSTREAMTRACKERHP_H
3 /* This file is property of and copyright by the ALICE HLT Project        *
4  * ALICE Experiment at CERN, All rights reserved.                         *
5  * See cxx source for full Copyright notice                               */
6
7 /* $Id$*/
8
9 ///
10 /// \file   AliMUONRawStreamTrackerHP.h
11 /// \author Artur Szostak <artursz@iafrica.com>
12 /// \date   29-11-2007
13 /// \brief  Declaration of the high performance decoder for muon trigger chamber raw streams.
14 ///
15
16 #ifndef ROOT_TObject
17 #  include "TObject.h"
18 #endif
19 #include "AliMUONTrackerDDLDecoder.h"
20
21 #include <cstring>
22
23 class AliMUONDDLTracker;
24 class AliRawReader;
25
26 class AliMUONRawStreamTrackerHP : public TObject
27 {
28 public:
29         class AliDspHeader;
30         class AliBusPatch;
31
32         /// Default constructor.
33         AliMUONRawStreamTrackerHP();
34         
35         /// Constructor for setting the raw reader.
36         AliMUONRawStreamTrackerHP(AliRawReader* rawReader);
37         
38         /// Default destructor.
39         virtual ~AliMUONRawStreamTrackerHP();
40         
41   /// Get object for reading the raw data
42   virtual AliRawReader* GetReader();
43
44         /// Initialize iterator
45         virtual void First();
46         
47         /// DDL iterator 
48         virtual Bool_t NextDDL();
49         
50         /// Whether the iteration is finished or not
51         virtual Bool_t IsDone() const;
52         
53         /// Nothing is actually done in the AddErrorMessage method because we log
54         /// the error messages as we find them in AliDecoderEventHandler::OnError().
55         virtual void AddErrorMessage() { };
56
57         /// Advance one step in the iteration. Returns false if finished.
58         virtual Bool_t Next(Int_t& busPatchId,
59                             UShort_t& manuId, UChar_t& manuChannel,
60                             UShort_t& adc) { return Next(busPatchId,manuId,manuChannel,adc,kTRUE); }
61         
62         /// Advance one step in the iteration. Returns false if finished.
63         virtual Bool_t Next(Int_t& busPatchId,
64                       UShort_t& manuId,
65                       UChar_t& manuChannel,
66                       UShort_t& adc,
67                       Bool_t skipParityErrors);
68
69         /// Construct and return a pointer to the DDL payload object.
70         virtual AliMUONDDLTracker* GetDDLTracker() const;
71         
72         /// Returns the next batch of decoded channel data.
73         const AliBusPatch* Next();
74         
75         /// Return maximum number of blocks per DDL allowed.
76         virtual Int_t GetMaxBlock() const { return (Int_t) fDecoder.MaxBlocks(); }
77         /// Return maximum number of Dsp per block allowed.
78         virtual Int_t GetMaxDsp() const { return (Int_t) fDecoder.MaxDSPs(); }
79         /// Return maximum number of Buspatch per Dsp allowed.
80         virtual Int_t GetMaxBus() const { return (Int_t) fDecoder.MaxBusPatches(); }
81         
82         /// Set maximum number of blocks per DDL allowed.
83         virtual void SetMaxBlock(Int_t blk);
84         /// Set maximum number of Dsp per block allowed.
85         virtual void SetMaxDsp(Int_t dsp);
86         /// Set maximum number of Buspatch per Dsp allowed.
87         virtual void SetMaxBus(Int_t bus);
88         
89         /// Return number of the current DDL.
90         virtual Int_t GetDDL() const { return fDDL - 1; }
91         
92         /// check error/Warning presence
93         virtual Bool_t IsErrorMessage() const { return fHadError; }
94         
95         /// Get number of parity errors
96         Int_t   GetParityErrors() const
97         {
98                 return (Int_t) fDecoder.GetHandler().ParityErrorCount();
99         }
100
101         /// Get number of glitch errors
102         Int_t   GetGlitchErrors() const
103         {
104                 return (Int_t) fDecoder.GetHandler().GlitchErrorCount();
105         }
106
107         /// Get number of padding word errors
108         Int_t   GetPaddingErrors() const
109         {
110                 return (Int_t) fDecoder.GetHandler().PaddingErrorCount();
111         }
112
113         /// Set warnings flag to disable warnings on data errors.
114         void DisableWarnings() { fDecoder.GetHandler().Warnings(kFALSE); }
115         /// Set warnings flag to enable warnings on data errors.
116         void EnableWarnings() { fDecoder.GetHandler().Warnings(kTRUE); }
117
118         /// Returns the "try to recover from errors" flag.
119         Bool_t TryRecover() const { return Bool_t(fDecoder.TryRecover()); }
120         
121         /// Sets the "try to recover from errors" flag.
122         /// i.e. should the decoder try to recover from errors found in the
123         /// payload headers.
124         void TryRecover(Bool_t value) { fDecoder.TryRecover(bool(value)); }
125         
126         /// Returns the auto-detect trailer words flag.
127         Bool_t AutoDetectTrailer() const { return Bool_t(fDecoder.AutoDetectTrailer()); }
128         
129         /// Sets the auto-detect trailer words flag.
130         /// When set to true the decoder will try to detect if the end of DDL
131         /// keys are in the trailer words or not. These are generated by the
132         /// detector but not the older versions of AliRoot simulations.
133         void AutoDetectTrailer(Bool_t value) { fDecoder.AutoDetectTrailer(bool(value)); }
134
135         /// Returns the flag indicating if the data is expected to have the
136         /// end of DDL keys in the trailer. This flag is ignored if AutoDetectTrailer()
137         /// was set to true.
138         Bool_t CheckForTrailer() const { return Bool_t(fDecoder.CheckForTrailer()); }
139         
140         /// Sets the flag indicating if the trailer words should contain the
141         /// end of DDL key.
142         void CheckForTrailer(Bool_t value) { fDecoder.CheckForTrailer(bool(value)); }
143         
144         /// Light weight interface class to the block header data.
145         class AliBlockHeader
146         {
147         public:
148                 /// Default constructor.
149                 AliBlockHeader(
150                                 AliDspHeader* dspArray = NULL,
151                                 const AliMUONBlockHeaderStruct* header = NULL
152                         )
153                         : fNext(NULL), fDspCount(0), fFirstDsp(dspArray), fHeader(header)
154                 {
155                 }
156                 
157                 /// Implement shallow copying in the copy constructor.
158                 AliBlockHeader(const AliBlockHeader& o) :
159                         fNext(o.fNext), fDspCount(o.fDspCount), fFirstDsp(o.fFirstDsp), fHeader(o.fHeader)
160                 {
161                 }
162                 
163                 /// Implement shallow copying in the assignment operator.
164                 AliBlockHeader& operator = (const AliBlockHeader& object)
165                 {
166                         memcpy(this, &object, sizeof(AliBlockHeader));
167                         return *this;
168                 }
169         
170                 /// Default destructor.
171                 ~AliBlockHeader() {};
172         
173                 /// Return data key word for CRT header
174                 Int_t   GetDataKey()        const {assert(fHeader != NULL); return fHeader->fDataKey;}
175                 /// Return total length of block structure (w/o padding word)
176                 Int_t   GetTotalLength()    const {assert(fHeader != NULL); return fHeader->fTotalLength;}
177                 /// Return length of raw data
178                 Int_t   GetLength()         const {assert(fHeader != NULL); return fHeader->fLength;}
179                 /// Return Dsp id
180                 Int_t   GetDspId()          const {assert(fHeader != NULL); return fHeader->fDSPId;}
181                 /// Return L0 trigger word
182                 Int_t   GetL0Trigger()      const {assert(fHeader != NULL); return fHeader->fL0Trigger;}
183                 /// Return Bunch Crossing for mini-event id (see TDR chapter 8)
184                 Int_t   GetMiniEventId()    const {assert(fHeader != NULL); return fHeader->fMiniEventId;}
185                 /// Return Event Id in bunch crossing
186                 Int_t   GetEventId1()       const {assert(fHeader != NULL); return fHeader->fEventId1;}
187                 /// Return Event Id in orbit number
188                 Int_t   GetEventId2()       const {assert(fHeader != NULL); return fHeader->fEventId2;}
189         
190                 /// Return the header's raw data.
191                 const AliMUONBlockHeaderStruct* GetHeader() const {return fHeader;}
192                 
193                 /// Return the next block header.
194                 const AliBlockHeader* Next() const { return fNext; }
195                 
196                 /// Returns the first AliDspHeader class in this block.
197                 const AliDspHeader* GetFirstDspHeader() const { return fFirstDsp; }
198                 
199                 /// Returns the number of DSPs within this block.
200                 UInt_t GetDspCount() const { return fDspCount; }
201         
202                 /// Return the i'th DSP in this block.
203                 const AliDspHeader* GetDspHeader(UInt_t i) const
204                 {
205                         return i < fDspCount ? GetFirstDspHeader() + i : NULL;
206                 }
207                 
208                 /// Sets the next block header.
209                 void SetNext(const AliBlockHeader* next) { fNext = next; }
210
211                 /// Increments the DSP count.
212                 void IncDspCount() { fDspCount++; };
213                 
214                 /// Print the contents of the header to screen.
215                 void Print() const;
216         
217         private:
218         
219                 const AliBlockHeader* fNext;  ///< Pointer to next block.
220                 UInt_t fDspCount;    ///< The number of AliDspHeader objects found in the array pointed to by fFirstDsp.
221                 const AliDspHeader* fFirstDsp;  ///< The first DSP associated with this block.
222                 const AliMUONBlockHeaderStruct*  fHeader;  ///< Pointer to header in DDL payload.
223         };
224         
225         /// Light weight interface class to the DSP header data.
226         class AliDspHeader
227         {
228         public:
229                 /// Default constructor.
230                 AliDspHeader(
231                                 const AliBlockHeader* block = NULL,
232                                 const AliBusPatch* busPatchArray = NULL,
233                                 const AliMUONDSPHeaderStruct* header = NULL
234                         ) :
235                         fBlock(block), fNext(NULL), fBusPatchCount(0),
236                         fFirstBusPatch(busPatchArray), fHeader(header)
237                 {
238                 }
239                 
240                 /// Implement shallow copying in the copy constructor.
241                 AliDspHeader(const AliDspHeader& o) :
242                         fBlock(o.fBlock), fNext(o.fNext), fBusPatchCount(o.fBusPatchCount),
243                         fFirstBusPatch(o.fFirstBusPatch), fHeader(o.fHeader)
244                 {
245                 }
246                 
247                 /// Implement shallow copying in the assignment operator.
248                 AliDspHeader& operator = (const AliDspHeader& object)
249                 {
250                         memcpy(this, &object, sizeof(AliDspHeader));
251                         return *this;
252                 }
253         
254                 /// Default destructor.
255                 ~AliDspHeader() {};
256         
257                 /// Return Data key word for FRT header
258                 Int_t   GetDataKey()        const {assert(fHeader != NULL); return fHeader->fDataKey;}
259                 /// Return total length of block structure
260                 Int_t   GetTotalLength()    const {assert(fHeader != NULL); return fHeader->fTotalLength;}
261                 /// Return length of raw data
262                 Int_t   GetLength()         const {assert(fHeader != NULL); return fHeader->fLength;}
263                 /// Return Dsp id
264                 Int_t   GetDspId()          const {assert(fHeader != NULL); return fHeader->fDSPId;}
265                 /// Return L1 accept in Block Structure (CRT)
266                 Int_t   GetBlkL1ATrigger()  const {assert(fHeader != NULL); return fHeader->fBlkL1ATrigger;}
267                 /// Return Mini Event Id in bunch crossing
268                 Int_t   GetMiniEventId()    const {assert(fHeader != NULL); return fHeader->fMiniEventId;}
269                 /// Return Number of L1 accept in DSP Structure (FRT)
270                 Int_t   GetL1ATrigger()     const {assert(fHeader != NULL); return fHeader->fL1ATrigger;}
271                 /// Return Number of L1 reject in DSP Structure (FRT)
272                 Int_t   GetL1RTrigger()     const {assert(fHeader != NULL); return fHeader->fL1RTrigger;}
273                 /// Return padding dummy word for 64 bits transfer
274                 UInt_t  GetPaddingWord()    const {assert(fHeader != NULL); return fHeader->fPaddingWord;}
275                 /// Return Error word
276                 Int_t   GetErrorWord()      const {assert(fHeader != NULL); return fHeader->fErrorWord;}
277         
278                 /// Return raw data of header
279                 const AliMUONDSPHeaderStruct* GetHeader() const { return fHeader; }
280                 
281                 /// Return the parent block header.
282                 const AliBlockHeader* GetBlockHeader() const { return fBlock; }
283                 
284                 /// Return the next DSP header.
285                 const AliDspHeader* Next() const { return fNext; }
286                 
287                 /// Returns the first AliBusPatch class in this DSP.
288                 const AliBusPatch* GetFirstBusPatch() const { return fFirstBusPatch; }
289                 
290                 /// Returns the number of bus patches within this DSP.
291                 UInt_t GetBusPatchCount() const { return fBusPatchCount; }
292         
293                 /// Return the i'th bus patch in this DSP.
294                 const AliBusPatch* GetBusPatch(UInt_t i) const
295                 {
296                         return i < fBusPatchCount ? GetFirstBusPatch() + i : NULL;
297                 }
298         
299                 /// Sets the next DSP header.
300                 void SetNext(const AliDspHeader* next) { fNext = next; }
301
302                 /// Increments the bus patch count.
303                 void IncBusPatchCount() { fBusPatchCount++; };
304                 
305                 /// Print the contents of the header to screen.
306                 void Print() const;
307         
308         private:
309         
310                 const AliBlockHeader* fBlock;  ///< Pointer to parent block structure.
311                 const AliDspHeader* fNext;  ///< Pointer to next DSP.
312                 UInt_t fBusPatchCount;    ///< The number of AliDspHeader objects found in the array pointed to by fFirstBusPatch
313                 const AliBusPatch* fFirstBusPatch;  ///< The first bus patch of this DSP.
314                 const AliMUONDSPHeaderStruct*  fHeader;  ///< Pointer to header in DDL payload.
315         };
316         
317         /// Light weight interface class to the bus patch data.
318         class AliBusPatch
319         {
320         public:
321                 /// Default constructor.
322                 AliBusPatch(
323                                 const AliDspHeader* dsp = NULL,
324                                 const AliMUONBusPatchHeaderStruct* header = NULL,
325                                 const UInt_t* data = NULL,
326                                 const Bool_t* parityOk = NULL
327                         ) :
328                         fDSP(dsp),
329                         fNext(NULL),
330                         fHeader(header),
331                         fData(data),
332                         fParityOk(parityOk)
333                 {
334                 }
335                 
336                 /// Implement shallow copying in the copy constructor.
337                 AliBusPatch(const AliBusPatch& o) :
338                         fDSP(o.fDSP),
339                         fNext(o.fNext),
340                         fHeader(o.fHeader),
341                         fData(o.fData),
342                         fParityOk(o.fParityOk)
343                 {
344                 }
345                 
346                 /// Implement shallow copying in the assignment operator.
347                 AliBusPatch& operator = (const AliBusPatch& object)
348                 {
349                         memcpy(this, &object, sizeof(AliBusPatch));
350                         return *this;
351                 }
352         
353                 /// Default destructor.
354                 ~AliBusPatch() {};
355                 
356                 /// Return Data key word for bus patch header.
357                 Int_t   GetDataKey()     const {assert(fHeader != NULL); return fHeader->fDataKey;}
358                 /// Return total length of buspatch structure
359                 Int_t   GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;}
360                 /// Return length of raw data
361                 Int_t   GetLength()      const {assert(fHeader != NULL); return fHeader->fLength;}
362                 /// Return bus patch id
363                 Int_t   GetBusPatchId()  const {assert(fHeader != NULL); return fHeader->fBusPatchId;}
364
365                 /// Return raw data of header
366                 const AliMUONBusPatchHeaderStruct* GetHeader() const {return fHeader;}
367                 /// Return raw digit data
368                 const UInt_t* GetData()  const {return fData;}
369                 /// Returns the number of raw data words within this bus patch.
370                 UInt_t GetDataCount() const { return (UInt_t)GetLength(); }
371
372                 /// Returns the parity bit of the n'th raw data word.
373                 Char_t GetParity(UInt_t n) const
374                 {
375                         assert( fHeader != NULL && n < fHeader->fLength );
376                         return (Char_t)(fData[n] >> 31) &  0x1;
377                 }
378                 
379                 /// Returns the MANU ID of the n'th raw data word.
380                 UShort_t GetManuId(UInt_t n) const
381                 {
382                         assert( fHeader != NULL && n < fHeader->fLength );
383                         return (UShort_t)(fData[n] >> 18) &  0x7FF;
384                 }
385                 
386                 /// Returns the channel ID of the n'th raw data word.
387                 UChar_t GetChannelId(UInt_t n) const
388                 {
389                         assert( fHeader != NULL && n < fHeader->fLength );
390                         return (Char_t)(fData[n] >> 12) & 0x3F;
391                 }
392                 
393                 /// Returns the charge/signal of the n'th raw data word.
394                 UShort_t GetCharge(UInt_t n) const
395                 {
396                         assert( fHeader != NULL && n < fHeader->fLength );
397                         return (UShort_t)(fData[n] & 0xFFF);
398                 }
399                 
400                 /// Returns the n'th raw data word.
401                 UInt_t GetData(UInt_t n) const
402                 {
403                         assert( fHeader != NULL && n < fHeader->fLength );
404                         return fData[n];
405                 }
406                 
407                 /// Returns kTRUE if the parity of the n'th raw data word is OK
408                 /// and kFALSE otherwise.
409                 Bool_t IsParityOk(UInt_t n) const
410                 {
411                         assert( fHeader != NULL && n < fHeader->fLength );
412                         return fParityOk[n];
413                 }
414                 
415                 /// Unpacks and returns the fields of the n'th raw data word. kTRUE
416                 /// is returned if the data word's parity was OK and kFALSE otherwise.
417                 Bool_t GetData(UInt_t n, UShort_t& manuId, UChar_t& channelId, UShort_t& adc) const
418                 {
419                         assert( fHeader != NULL && n < fHeader->fLength );
420                         AliMUONTrackerDDLDecoderEventHandler::UnpackADC(fData[n], manuId, channelId, adc);
421                         return fParityOk[n];
422                 }
423                 
424                 /// Return the parent block header.
425                 const AliDspHeader* GetDspHeader() const { return fDSP; }
426                 
427                 /// Return the next bus patch header.
428                 const AliBusPatch* Next() const { return fNext; }
429                 
430                 /// Sets the next bus patch.
431                 void SetNext(const AliBusPatch* next) { fNext = next; }
432                 
433                 /// Print the contents of the bus patch to screen.
434                 void Print(const Option_t* opt = "") const;
435         
436         private:
437         
438                 const AliDspHeader* fDSP;   ///< The DSP this bus patch belongs to.
439                 const AliBusPatch* fNext;  ///< Next bus patch object in the DSP.
440                 const AliMUONBusPatchHeaderStruct*  fHeader;  ///< Pointer to bus patch in DDL payload.
441                 const UInt_t* fData;  ///< Pointer to the bus patch data.
442                 const Bool_t* fParityOk;  ///< Array of flags indicating if the parity of the given data word in fData is good or not.          
443         };
444         
445         /// Return the number of blocks in the DDL payload.
446         UInt_t GetBlockCount() const
447         {
448                 return fDecoder.GetHandler().BlockCount();
449         }
450         
451         /// Return the first block header.
452         const AliBlockHeader* GetFirstBlockHeader() const
453         {
454                 return fDecoder.GetHandler().BlockHeader(0);
455         }
456         
457         /// Return the i'th block header or NULL if not found.
458         const AliBlockHeader* GetBlockHeader(UInt_t i) const
459         {
460                 return fDecoder.GetHandler().BlockHeader(i);
461         }
462         
463         /// Returns the number of DSPs for the given block number.
464         UInt_t GetDspCount(UInt_t block) const
465         {
466                 const AliBlockHeader* b = GetBlockHeader(block);
467                 return b != NULL ? b->GetDspCount() : 0;
468         }
469         
470         /// Returns the i'th DSP header for the given block number or NULL if not found.
471         const AliDspHeader* GetDspHeader(UInt_t block, UInt_t i) const
472         {
473                 const AliBlockHeader* b = GetBlockHeader(block);
474                 return b != NULL ? b->GetDspHeader(i) : NULL;
475         }
476         
477         /// Returns the number of bus patches for the given block and dsp number.
478         UInt_t GetBusPatchCount(UInt_t block, UInt_t dsp) const
479         {
480                 const AliDspHeader* d = GetDspHeader(block, dsp);
481                 return d != NULL ? d->GetBusPatchCount() : 0;
482         }
483         
484         /// Returns the i'th bus patch for the given block and dsp.
485         const AliBusPatch* GetBusPatch(UInt_t block, UInt_t dsp, UInt_t i) const
486         {
487                 const AliDspHeader* d = GetDspHeader(block, dsp);
488                 return d != NULL ? d->GetBusPatch(i) : NULL;
489         }
490
491         /// Returns the current bus patch being decoded or NULL if none found.
492         const AliBusPatch* CurrentBusPatch() const
493         {
494                 return (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ?
495                         fkCurrentBusPatch : NULL;
496         }
497
498         /// Returns the current DSP being decoded or NULL if none found.
499         const AliDspHeader* CurrentDspHeader() const
500         {
501                 const AliBusPatch* busPatch = CurrentBusPatch();
502                 return (busPatch != NULL) ? busPatch->GetDspHeader() : NULL;
503         }
504
505         /// Returns the current block header being decoded or NULL if none found.
506         const AliBlockHeader* CurrentBlockHeader() const
507         {
508                 const AliDspHeader* dsp = CurrentDspHeader();
509                 return (dsp != NULL) ? dsp->GetBlockHeader() : NULL;
510         }
511
512   /// Set the raw reader
513   void SetReader(AliRawReader* reader);
514   
515   /// Enable error info logger
516   virtual void EnabbleErrorLogger() { fEnableErrorLogger = kTRUE; }
517   
518   /// Check if error info logger enable
519   virtual Bool_t IsErrorLogger() const {return fEnableErrorLogger; }
520     
521   /// Number of glitch errors since First() was called
522   Int_t NumberOfGlitchErrors() const { return fTotalNumberOfGlitchErrors; }
523
524   /// Number of padding errors since First() was called
525   Int_t NumberOfPaddingErrors() const { return fTotalNumberOfPaddingErrors; }
526
527   /// Number of parity errors since First() was called
528   Int_t NumberOfParityErrors() const { return fTotalNumberOfParityErrors; }
529
530   /// Whether we got glitch errors or not
531   Bool_t HasGlitchError() const { return NumberOfGlitchErrors() > 0; }
532
533   /// Whether we got padding errors or not
534   Bool_t HasPaddingError() const { return NumberOfPaddingErrors() > 0; }
535
536   /// Whether we got parity errors or not
537   Bool_t HasParityError() const { return NumberOfParityErrors() > 0; }
538
539 private:
540
541         // Do not allow copying of this class.
542         /// Not implemented
543         AliMUONRawStreamTrackerHP(const AliMUONRawStreamTrackerHP& stream);
544         /// Not implemented
545         AliMUONRawStreamTrackerHP& operator = (const AliMUONRawStreamTrackerHP& stream);
546         
547         /// Return max number of tracker DDLs
548         Int_t GetMaxDDL() const { return fgkMaxDDL; }
549   
550         /// This is the custom event handler (callback interface) class which
551         /// unpacks raw data words and fills an internal buffer with decoded digits
552         /// as they are decoded by the high performance decoder.
553         class AliDecoderEventHandler : public AliMUONTrackerDDLDecoderEventHandler
554         {
555         public:
556         
557                 /// Default constructor.
558                 AliDecoderEventHandler();
559                 /// Default destructor.
560                 virtual ~AliDecoderEventHandler();
561                 
562                 /// Sets the internal arrays based on the maximum number of structures allowed.
563                 void SetMaxStructs(UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches);
564                 
565                 /// Return the number of blocks found in the payload.
566                 UInt_t BlockCount() const { return fBlockCount; };
567                 
568                 /// Return the i'th block structure.
569                 const AliBlockHeader* BlockHeader(UInt_t i) const
570                 {
571                         return i < fBlockCount ? &fBlocks[i] : NULL;
572                 }
573
574                 /// Return the first bus patch decoded.
575                 const AliBusPatch* FirstBusPatch() const { return fBusPatches; }
576
577                 /// Returns the marker to the end of bus patches. i.e. one position past the last bus patch.
578                 const AliBusPatch* EndOfBusPatch() const { return fEndOfBusPatches; }
579
580                 /// Returns the number of parity errors found in the DDL.
581                 UInt_t ParityErrorCount() const { return fParityErrors; }
582                 /// Returns the number of glitch errors found in the DDL.
583                 UInt_t GlitchErrorCount() const { return fGlitchErrors; }
584                 /// Returns the number of padding errors found in the DDL.
585                 UInt_t PaddingErrorCount() const { return fPaddingErrors; }
586
587                 /// Returns the warnings flag.
588                 Bool_t Warnings() const { return fWarnings; }
589                 /// Sets the warnings flag.
590                 void Warnings(Bool_t value) { fWarnings = value; }
591                 
592                 // The following methods are inherited from AliMUONTrackerDDLDecoderEventHandler:
593                 
594                 /// New buffer handler.
595                 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
596
597                 /// End of buffer handler marks the end of bus patches.
598                 void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/)
599                 {
600                         fEndOfBusPatches = fCurrentBusPatch+1;
601                 }
602                 
603                 /// New block handler is called by the decoder whenever a new block
604                 /// structure is found. We just mark the new block and increment the
605                 /// internal counter.
606                 void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/);
607                 
608                 /// New DSP handler is called by the decoder whenever a new DSP
609                 /// structure is found. We just mark the DSP and increment the
610                 /// appropriate counters.
611                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
612                 
613                 /// New bus patch handler.
614                 /// This is called by the high performance decoder when a new bus patch
615                 /// is found within the DDL payload.
616                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data);
617                 
618                 /// Raw data word handler.
619                 void OnData(UInt_t /*data*/, bool parityError)
620                 {
621                         assert( fCurrentParityOkFlag < fParityOk + fMaxChannels );
622                         *(++fCurrentParityOkFlag) = Bool_t(not parityError);
623                 }
624                 
625                 /// Error handler.
626                 void OnError(ErrorCode error, const void* location);
627         
628     /// Set reader
629     void SetReader(AliRawReader* reader) { fRawReader = reader; }
630     
631     /// Get reader
632     AliRawReader* GetReader() const { return fRawReader; }
633     
634         private:
635         
636                 // Do not allow copying of this class.
637                 /// Not implemented
638                 AliDecoderEventHandler(const AliDecoderEventHandler& /*obj*/);
639                 /// Not implemented
640                 AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/);
641
642     AliRawReader* fRawReader; //!< Pointer to the raw reader
643                 const void* fBufferStart;   //!< Pointer to the start of the current DDL payload buffer.
644                 UInt_t fBlockCount;  //!< Number of blocks filled in fBlocks.
645                 AliBlockHeader* fBlocks;  //!< Array of blocks. [0..fMaxBlocks-1]
646                 AliDspHeader* fDSPs;      //!< Array of DSPs. [0..fMaxDsps*fMaxBlocks-1]
647                 AliBusPatch* fBusPatches; //!< Array of bus patches. [0..fMaxBusPatches*fMaxDsps*fMaxBlocks-1]
648                 AliBusPatch* fEndOfBusPatches;  //!< Marks the last bus patch.
649                 UInt_t fMaxChannels;   //!< Maximum number of elements that can be stored in fParityOk.
650                 Bool_t* fParityOk;     //!< Array of flags for indicating if the parity is good for a raw data word.
651                 AliBlockHeader* fCurrentBlock;  //!< Current block in fBlocks.
652                 AliDspHeader* fCurrentDSP;      //!< Current DSP in fDSPs.
653                 AliBusPatch* fCurrentBusPatch;  //!< Current bus patch in fBusPatches.
654                 Bool_t* fCurrentParityOkFlag;  //!< Current parity flag to be set in fParityOk.
655                 UInt_t fParityErrors;   //!< Number of parity errors found in DDL.
656                 UInt_t fGlitchErrors;   //!< Number of glitch errors found in DDL.
657                 UInt_t fPaddingErrors;  //!< Number of padding errors found in DDL.
658                 Bool_t fWarnings;       //!< Flag indicating if we should generate a warning for errors.
659     UInt_t fMaxBlocks; //!< max number of blocks
660     UInt_t fMaxDsps; //!< max number of dsps per block
661     UInt_t fMaxBusPatches; //!< max number of buspatches per dsp
662
663         };
664
665   Bool_t fEnableErrorLogger; //!< whether or not we log errors
666         AliMUONTrackerDDLDecoder<AliDecoderEventHandler> fDecoder;  //!< The decoder for the DDL payload.
667         Int_t fDDL;         //!< The current DDL number being handled.
668         Int_t fBufferSize;  //!< This is the buffer size in bytes of fBuffer.
669         UChar_t* fBuffer;   //!< This is the buffer in which we store the DDL payload read from AliRawReader.
670         const AliBusPatch* fkCurrentBusPatch;  //!< The current bus patch being handled by Next().
671         const UInt_t* fkCurrentData;  //!< The current data word to return by Next().
672         const UInt_t* fkEndOfData;  //!< The last data word in the current bus patch.
673         Bool_t fHadError;   //!< Flag indicating if there was a decoding error or not.
674         Bool_t fDone;       //!< Flag indicating if the iteration is done or not.
675         mutable AliMUONDDLTracker* fDDLObject; //!< Temporary DDL object used by GetDDLTracker() for caching.
676   Int_t fTotalNumberOfGlitchErrors; //!< number of glitch errors since First() was called
677   Int_t fTotalNumberOfParityErrors; //!< number of glitch errors since First() was called
678   Int_t fTotalNumberOfPaddingErrors; //!< number of glitch errors since First() was called
679   
680   static const Int_t fgkMaxDDL; //!< max number of tracker DDLs
681
682         ClassDef(AliMUONRawStreamTrackerHP, 0) // High performance decoder for reading MUON raw digits from tracking chamber DDL data.
683 };
684
685 ////////////////////////////////////////////////////////////////////////////////
686
687 inline const AliMUONRawStreamTrackerHP::AliBusPatch* AliMUONRawStreamTrackerHP::Next()
688 {
689         /// Returns the next batch of decoded channel data.
690         if (fkCurrentBusPatch == NULL) return NULL;
691         do {
692                 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
693                         return fkCurrentBusPatch++;
694         } while (NextDDL());
695         return NULL;
696 }
697
698 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBlock(
699                 const AliMUONBlockHeaderStruct* header, const void* /*data*/
700         )
701 {
702         /// New block handler is called by the decoder whenever a new block
703         /// structure is found. We just mark the new block and increment the
704         /// internal counter.
705
706         assert( header != NULL );
707         assert( fBlockCount < fMaxBlocks );
708         // Link the block unless it is the first one.
709         if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1);
710         *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header);
711         fBlockCount++;
712 }
713
714 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewDSP(
715                 const AliMUONDSPHeaderStruct* header, const void* /*data*/
716         )
717 {
718         /// New DSP handler is called by the decoder whenever a new DSP
719         /// structure is found. We just mark the DSP and increment the
720         /// appropriate counters.
721         
722         assert( header != NULL );
723         assert( fCurrentBlock->GetDspCount() < fMaxDsps );
724         // Link the DSP unless it is the first one.
725         if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1);
726         *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header);
727         fCurrentBlock->IncDspCount();
728 }
729
730 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBusPatch(
731                 const AliMUONBusPatchHeaderStruct* header, const void* data
732         )
733 {
734         /// New bus patch handler.
735         /// This is called by the high performance decoder when a new bus patch
736         /// is found within the DDL payload.
737
738         assert( header != NULL );
739         assert( data != NULL );
740         assert( fCurrentDSP->GetBusPatchCount() < fMaxBusPatches );
741         // Link the bus patch unless it is the first one. 
742         if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1);
743         *(++fCurrentBusPatch) = AliBusPatch(
744                         fCurrentDSP,
745                         header,
746                         reinterpret_cast<const UInt_t*>(data),
747                         fCurrentParityOkFlag+1
748                 );
749         fCurrentDSP->IncBusPatchCount();
750 }
751
752 #endif  // ALIMUONRAWSTREAMTRACKERHP_H
753