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