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