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