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