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