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