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