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