]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawStreamTrackerHP.h
Changes in tracker raw data decoding and mchview :
[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   Int_t GetMaxDDL() const { return fgkMaxDDL; }
548   
549         /// This is the custom event handler (callback interface) class which
550         /// unpacks raw data words and fills an internal buffer with decoded digits
551         /// as they are decoded by the high performance decoder.
552         class AliDecoderEventHandler : public AliMUONTrackerDDLDecoderEventHandler
553         {
554         public:
555         
556                 /// Default constructor.
557                 AliDecoderEventHandler();
558                 /// Default destructor.
559                 virtual ~AliDecoderEventHandler();
560                 
561                 /// Sets the internal arrays based on the maximum number of structures allowed.
562                 void SetMaxStructs(UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches);
563                 
564                 /// Return the number of blocks found in the payload.
565                 UInt_t BlockCount() const { return fBlockCount; };
566                 
567                 /// Return the i'th block structure.
568                 const AliBlockHeader* BlockHeader(UInt_t i) const
569                 {
570                         return i < fBlockCount ? &fBlocks[i] : NULL;
571                 }
572
573                 /// Return the first bus patch decoded.
574                 const AliBusPatch* FirstBusPatch() const { return fBusPatches; }
575
576                 /// Returns the marker to the end of bus patches. i.e. one position past the last bus patch.
577                 const AliBusPatch* EndOfBusPatch() const { return fEndOfBusPatches; }
578
579                 /// Returns the number of parity errors found in the DDL.
580                 UInt_t ParityErrorCount() const { return fParityErrors; }
581                 /// Returns the number of glitch errors found in the DDL.
582                 UInt_t GlitchErrorCount() const { return fGlitchErrors; }
583                 /// Returns the number of padding errors found in the DDL.
584                 UInt_t PaddingErrorCount() const { return fPaddingErrors; }
585
586                 /// Returns the warnings flag.
587                 Bool_t Warnings() const { return fWarnings; }
588                 /// Sets the warnings flag.
589                 void Warnings(Bool_t value) { fWarnings = value; }
590                 
591                 // The following methods are inherited from AliMUONTrackerDDLDecoderEventHandler:
592                 
593                 /// New buffer handler.
594                 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
595
596                 /// End of buffer handler marks the end of bus patches.
597                 void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/)
598                 {
599                         fEndOfBusPatches = fCurrentBusPatch+1;
600                 }
601                 
602                 /// New block handler is called by the decoder whenever a new block
603                 /// structure is found. We just mark the new block and increment the
604                 /// internal counter.
605                 void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/);
606                 
607                 /// New DSP handler is called by the decoder whenever a new DSP
608                 /// structure is found. We just mark the DSP and increment the
609                 /// appropriate counters.
610                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
611                 
612                 /// New bus patch handler.
613                 /// This is called by the high performance decoder when a new bus patch
614                 /// is found within the DDL payload.
615                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data);
616                 
617                 /// Raw data word handler.
618                 void OnData(UInt_t /*data*/, bool parityError)
619                 {
620                         assert( fCurrentParityOkFlag < fParityOk + fMaxChannels );
621                         *(++fCurrentParityOkFlag) = Bool_t(not parityError);
622                 }
623                 
624                 /// Error handler.
625                 void OnError(ErrorCode error, const void* location);
626         
627     /// Set reader
628     void SetReader(AliRawReader* reader) { fRawReader = reader; }
629     
630     /// Get reader
631     AliRawReader* GetReader() const { return fRawReader; }
632     
633         private:
634         
635                 // Do not allow copying of this class.
636                 /// Not implemented
637                 AliDecoderEventHandler(const AliDecoderEventHandler& /*obj*/);
638                 /// Not implemented
639                 AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/);
640
641     AliRawReader* fRawReader; //!< Pointer to the raw reader
642                 const void* fBufferStart;   //!< Pointer to the start of the current DDL payload buffer.
643                 UInt_t fBlockCount;  //!< Number of blocks filled in fBlocks.
644                 AliBlockHeader* fBlocks;  //!< Array of blocks. [0..fMaxBlocks-1]
645                 AliDspHeader* fDSPs;      //!< Array of DSPs. [0..fMaxDsps*fMaxBlocks-1]
646                 AliBusPatch* fBusPatches; //!< Array of bus patches. [0..fMaxBusPatches*fMaxDsps*fMaxBlocks-1]
647                 AliBusPatch* fEndOfBusPatches;  //!< Marks the last bus patch.
648                 UInt_t fMaxChannels;   //!< Maximum number of elements that can be stored in fParityOk.
649                 Bool_t* fParityOk;     //!< Array of flags for indicating if the parity is good for a raw data word.
650                 AliBlockHeader* fCurrentBlock;  //!< Current block in fBlocks.
651                 AliDspHeader* fCurrentDSP;      //!< Current DSP in fDSPs.
652                 AliBusPatch* fCurrentBusPatch;  //!< Current bus patch in fBusPatches.
653                 Bool_t* fCurrentParityOkFlag;  //!< Current parity flag to be set in fParityOk.
654                 UInt_t fParityErrors;   //!< Number of parity errors found in DDL.
655                 UInt_t fGlitchErrors;   //!< Number of glitch errors found in DDL.
656                 UInt_t fPaddingErrors;  //!< Number of padding errors found in DDL.
657                 Bool_t fWarnings;       //!< Flag indicating if we should generate a warning for errors.
658     UInt_t fMaxBlocks; //!< max number of blocks
659     UInt_t fMaxDsps; //!< max number of dsps per block
660     UInt_t fMaxBusPatches; //!< max number of buspatches per dsp
661
662         };
663
664   Bool_t fEnableErrorLogger; //!< whether or not we log errors
665         AliMUONTrackerDDLDecoder<AliDecoderEventHandler> fDecoder;  //!< The decoder for the DDL payload.
666         Int_t fDDL;         //!< The current DDL number being handled.
667         Int_t fBufferSize;  //!< This is the buffer size in bytes of fBuffer.
668         UChar_t* fBuffer;   //!< This is the buffer in which we store the DDL payload read from AliRawReader.
669         const AliBusPatch* fkCurrentBusPatch;  //!< The current bus patch being handled by Next().
670         const UInt_t* fkCurrentData;  //!< The current data word to return by Next().
671         const UInt_t* fkEndOfData;  //!< The last data word in the current bus patch.
672         Bool_t fHadError;   //!< Flag indicating if there was a decoding error or not.
673         Bool_t fDone;       //!< Flag indicating if the iteration is done or not.
674         mutable AliMUONDDLTracker* fDDLObject; //!< Temporary DDL object used by GetDDLTracker() for caching.
675   Int_t fTotalNumberOfGlitchErrors; //!< number of glitch errors since First() was called
676   Int_t fTotalNumberOfParityErrors; //!< number of glitch errors since First() was called
677   Int_t fTotalNumberOfPaddingErrors; //!< number of glitch errors since First() was called
678   
679   static const Int_t fgkMaxDDL; //!< max number of tracker DDLs
680
681         ClassDef(AliMUONRawStreamTrackerHP, 0) // High performance decoder for reading MUON raw digits from tracking chamber DDL data.
682 };
683
684 ////////////////////////////////////////////////////////////////////////////////
685
686 inline const AliMUONRawStreamTrackerHP::AliBusPatch* AliMUONRawStreamTrackerHP::Next()
687 {
688         /// Returns the next batch of decoded channel data.
689         if (fkCurrentBusPatch == NULL) return NULL;
690         do {
691                 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
692                         return fkCurrentBusPatch++;
693         } while (NextDDL());
694         return NULL;
695 }
696
697 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBlock(
698                 const AliMUONBlockHeaderStruct* header, const void* /*data*/
699         )
700 {
701         /// New block handler is called by the decoder whenever a new block
702         /// structure is found. We just mark the new block and increment the
703         /// internal counter.
704
705         assert( header != NULL );
706         assert( fBlockCount < fMaxBlocks );
707         // Link the block unless it is the first one.
708         if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1);
709         *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header);
710         fBlockCount++;
711 }
712
713 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewDSP(
714                 const AliMUONDSPHeaderStruct* header, const void* /*data*/
715         )
716 {
717         /// New DSP handler is called by the decoder whenever a new DSP
718         /// structure is found. We just mark the DSP and increment the
719         /// appropriate counters.
720         
721         assert( header != NULL );
722         assert( fCurrentBlock->GetDspCount() < fMaxDsps );
723         // Link the DSP unless it is the first one.
724         if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1);
725         *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header);
726         fCurrentBlock->IncDspCount();
727 }
728
729 inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBusPatch(
730                 const AliMUONBusPatchHeaderStruct* header, const void* data
731         )
732 {
733         /// New bus patch handler.
734         /// This is called by the high performance decoder when a new bus patch
735         /// is found within the DDL payload.
736
737         assert( header != NULL );
738         assert( data != NULL );
739         assert( fCurrentDSP->GetBusPatchCount() < fMaxBusPatches );
740         // Link the bus patch unless it is the first one. 
741         if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1);
742         *(++fCurrentBusPatch) = AliBusPatch(
743                         fCurrentDSP,
744                         header,
745                         reinterpret_cast<const UInt_t*>(data),
746                         fCurrentParityOkFlag+1
747                 );
748         fCurrentDSP->IncBusPatchCount();
749 }
750
751 #endif  // ALIMUONRAWSTREAMTRACKERHP_H
752