794220b456f1411f740619ffa173114b4558c0dd
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerDDLDecoderEventHandler.h
1 #ifndef ALIMUONTRIGGERDDLDECODEREVENTHANDLER_H
2 #define ALIMUONTRIGGERDDLDECODEREVENTHANDLER_H
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        *
5  * All rights reserved.                                                   *
6  *                                                                        *
7  * Primary Authors:                                                       *
8  *   Artur Szostak <artursz@iafrica.com>                                  *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /* $Id$ */
20
21 ///
22 /// \file   AliMUONTriggerDDLDecoderEventHandler.h
23 /// \author Artur Szostak <artursz@iafrica.com>
24 /// \date   28-11-2007
25 /// \brief  Implementation of the high performance trigger DDL decoder event handler.
26 ///
27 /// This file implementes the AliMUONTriggerDDLDecoderEventHandler class,
28 /// which is the callback interface for the AliMUONTriggerDDLDecoder decoder class.
29 ///
30
31 #include <cassert>
32 #include <ostream>
33 #include <Rtypes.h>
34
35
36 // We use C binding for the structures because C is more uniform with its application
37 // binary interface (ABI) between compilers.
38 extern "C"
39 {
40
41 // The following structures are the headers found in the DDL payload coming from
42 // the muon hardware trigger. The specification is given in ALICE-INT-2005-012
43 // (https://edms.cern.ch/file/591904/1/ALICE-INT-2005-012.pdf)
44
45 /// The optional DARC board scalars.
46 struct AliMUONDarcScalarsStruct
47 {
48         UInt_t     fL0R;       ///< DARC L0 received and used
49         UInt_t     fL1P;       ///< DARC L1 physics
50         UInt_t     fL1S;       ///< DARC L1 software
51         UInt_t     fL2A;       ///< DARC L2 accept
52         UInt_t     fL2R;       ///< DARC L2 reject
53         UInt_t     fClk;       ///< DARC clock
54         UInt_t     fHold;      ///< DARC hold (dead time)
55         UInt_t     fSpare;     ///< DARC Empty slot (for the moment)
56 };
57
58 /// The global input and output words just after the DARC header.
59 struct AliMUONGlobalHeaderStruct
60 {
61         UInt_t     fInput[4];    ///< Global input. 8-bit words comming from the each of the 16 regional controlers.
62         UInt_t     fOutput;      ///< Global ouput
63 };
64
65 /// The optional global card scalars.
66 struct AliMUONGlobalScalarsStruct
67 {
68         UInt_t     fL0;         ///< Global number of L0 triggers
69         UInt_t     fClk;        ///< Global number of clock cycles
70         UInt_t     fScaler[6];  ///< Global card ouput scalars.
71         UInt_t     fHold;       ///< Global number of hold (dead time)
72         UInt_t     fSpare;      ///< Global spare word
73 };
74
75 /// Regional header
76 struct AliMUONRegionalHeaderStruct
77 {
78         UInt_t    fDarcWord;        ///< darc word
79         UInt_t    fWord;            ///< first reg word
80         UInt_t    fInput[2];        ///< regional input
81         UInt_t    fL0CountAndMask;  ///< L0 counter (16 bits) and local mask ("poids faible" 16 bits)
82 };
83
84 /// Optional regional card scalars.
85 struct AliMUONRegionalScalarsStruct
86 {
87         UInt_t     fClk;        ///< Regional number of clock cycles.
88         UInt_t     fScaler[8];  ///< Regional ouput scalars.
89         UInt_t     fHold;       ///< Regional hold (dead time)
90 };
91
92
93 /// Local card trigger information.
94 struct AliMUONLocalInfoStruct
95 {
96         UInt_t fX2X1;  ///< 16 bits X2 position in 16 most significant bits and 16 bits of X1 in least significant bits.
97         UInt_t fX4X3;  ///< 16 bits X4 position in 16 most significant bits and 16 bits of X3 in least significant bits.
98         UInt_t fY2Y1;  ///< 16 bits Y2 position in 16 most significant bits and 16 bits of Y1 in least significant bits.
99         UInt_t fY4Y3;  ///< 16 bits Y4 position in 16 most significant bits and 16 bits of Y3 in least significant bits.
100         UInt_t fTriggerBits;  ///< Trigger bits and deviation.
101 };
102
103 /// Local card trigger scalars.
104 struct AliMUONLocalScalarsStruct
105 {
106         UInt_t     fL0;        ///< local number of L0 triggers.
107         UInt_t     fHold;      ///< local hold (dead time)
108         UInt_t     fClk;       ///< local number of clock cycles
109         
110         UInt_t     fLPtNTrig;  ///< local low Pt no trigger
111         UInt_t     fHPtNTrig;  ///< local high Pt no trigger
112         
113         UInt_t     fLPtRTrig;  ///< local low Pt right trigger
114         UInt_t     fHPtRTrig;  ///< local high Pt right trigger
115         
116         UInt_t     fLPtLTrig;  ///< local low Pt left trigger
117         UInt_t     fHPtLTrig;  ///< local high Pt left trigger
118         
119         UInt_t     fLPtSTrig;  ///< local low Pt straight trigger
120         UInt_t     fHPtSTrig;  ///< local high Pt straight trigger
121         
122         UInt_t     fScaler[8*4];   ///< local data
123         UInt_t     fEOS;           ///< contains switches conf. & flag for reading X (0) or Y (1) in fScaler
124         UInt_t     fReset;         ///< reset signal
125 };
126
127 } // extern "C"
128
129
130 /// \ingroup raw
131 /// \class AliMUONTriggerDDLDecoderEventHandler
132 /// \brief Callback event handler class for the AliMUONTriggerDDLDecoder.
133 /// This class is the base class defining what methods the event handler for the
134 /// high performance decoder should have. This handler actually does nothing.
135 /// The user of this decoder will have to derive from this class a custom event
136 /// handler that actually does something within the callback methods OnNewRegionalHeader,
137 /// OnLocalStruct, OnError etc...
138 ///
139 class AliMUONTriggerDDLDecoderEventHandler
140 {
141 public:
142
143         /// The only reason for a virtual destructor is to make -Weffc++ shutup.
144         /// This should not really be here since we do not actually want or need
145         /// run-time polymorphism.
146         virtual ~AliMUONTriggerDDLDecoderEventHandler() {}
147
148         /// All the possible error codes from the parsing.
149         enum ErrorCode
150         {
151                 kNoError = 0,              /// Decoding was successful.
152                 kTooManyRegionals = 1,     /// Too many regional card structures are expected in the DDL payload.
153                 kNoDarcHeader = 2,         /// The DARC header is missing. The DDL buffer is too short to hold a DARC header.
154                 kNoDarcScalars = 3,        /// The DARC scalars are missing or corrupt. The DDL buffer is too short to contain them.
155                 kWrongEventType = 4,       /// Wrong event type obtained from the Darc header.
156                 kNoEndOfDarc = 5,          /// The DDL buffer is too short to contain an end of DARC header key word.
157                 kBadEndOfDarc = 6,         /// End of DARC header key word is incorrect or corrupt.
158                 kNoGlobalHeader = 7,       /// The global header is missing. The DDL buffer is too short to hold a global header.
159                 kNoGlobalScalars = 8,      /// The global scalars are missing or corrupt. The DDL buffer is too short to contain them.
160                 kNoEndOfGlobal = 9,        /// The DDL buffer is too short to contain an end of global header key word.
161                 kBadEndOfGlobal = 10,      /// End of global header key word is incorrect or corrupt.
162                 kNoRegionalHeader = 11,    /// The regional header is missing. The DDL buffer is too short to hold another regional header.
163                 kNoRegionalScalars = 12,   /// The regional scalars are missing or corrupt. The DDL buffer is too short to contain them.
164                 kNoEndOfRegional = 13,     /// The DDL buffer is too short to contain an end of regional header key word.
165                 kBadEndOfRegional = 14,    /// End of regional header key word is incorrect or corrupt.
166                 kNoLocalStruct = 15,       /// The local structure is missing. The DDL buffer is too short to hold another local structure.
167                 kNoLocalScalars = 16,      /// The local scalars are missing or corrupt. The DDL buffer is too short to contain them.
168                 kNoEndOfLocal = 17,        /// The DDL buffer is too short to contain an end of local structure key word.
169                 kBadEndOfLocal = 18,       /// End of local structure key word is incorrect or corrupt.
170                 kBufferTooBig = 19         /// The DDL raw data is larger than indicated by the headers; extra bytes are probably just garbage.
171         };
172
173         // The following methods should be overridden for specific processing to
174         // take place in your own event handler.
175
176         /// The OnNewBuffer method will be called whenever a new buffer containing
177         /// a DDL payload is about to be processed.
178         /// The default behaviour of this method is to do nothing.
179         /// - param const void*  The pointer to the start of the memory buffer storing
180         ///                the DDL payload.
181         /// - param UInt_t The size in bytes of the memory buffer.
182         void OnNewBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/) {}
183         
184         /// The OnEndOfBuffer method will be called whenever the buffer containing
185         /// a DDL payload has been processed. For each OnNewBuffer method call a
186         /// symmetric call to OnEndOfBuffer is made at the end of processing (after
187         /// the last call to OnLocalStruct)
188         /// The default behaviour of this method is to do nothing.
189         /// - param const void*  The pointer to the start of the memory buffer storing
190         ///                the DDL payload.
191         /// - param UInt_t The size in bytes of the memory buffer.
192         void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/) {}
193         
194         /// The OnDarcHeader method will be called when the DARC header has been
195         /// found in the DDL payload.
196         /// The default behaviour of this method is to do nothing.
197         /// - param UInt_t  The DARC header word as found in the payload.
198         /// - param const AliMUONDarcScalarsStruct*  The DARC scalars found in the
199         ///       raw data. If there are no scalars in the data then this pointer
200         ///       is set to NULL.
201         /// - param const void*  A pointer to the remainder of the raw data after
202         ///       the DARC header and scalars.
203         void OnDarcHeader(
204                         UInt_t /*header*/,
205                         const AliMUONDarcScalarsStruct* /*scalars*/,
206                         const void* /*data*/
207                 )
208         {
209         }
210         
211         /// The OnGlobalHeader method will be called when the global header has
212         /// been found in the DDL payload.
213         /// The default behaviour of this method is to do nothing.
214         /// - param const AliMUONGlobalHeaderStruct*  A pointer to the global header.
215         /// - param const AliMUONDarcScalarsStruct*  The global scalars found in the
216         ///       raw data. If there are no scalars in the data then this pointer
217         ///       is set to NULL.
218         /// - param const void*  A pointer to the start of the regional data blocks.
219         void OnGlobalHeader(
220                         const AliMUONGlobalHeaderStruct* /*header*/,
221                         const AliMUONGlobalScalarsStruct* /*scalars*/,
222                         const void* /*data*/
223                 )
224         {
225         }
226         
227         /// The OnNewRegionalStruct method will be called for each regional header
228         /// found in the DDL payload.
229         /// The default behaviour of this method is to do nothing.
230         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the regional
231         ///       structure header.
232         /// - param const AliMUONRegionalScalarsStruct*  The regional scalars found
233         ///       in the raw data. If there are no scalars in the data then this
234         ///       pointer is set to NULL.
235         /// - param const void*  A pointer to the start of the local trigger
236         ///       structures data for this regional block.
237         void OnNewRegionalStruct(
238                         const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
239                         const AliMUONRegionalScalarsStruct* /*scalars*/,
240                         const void* /*data*/
241                 )
242         {
243         }
244         
245         /// The OnEndOfRegionalStruct method will be called whenever a regional
246         /// structure has been processed. For each OnNewRegionalStruct method
247         /// call a symmetric call to OnEndOfRegionalStruct is made after processing
248         /// of the regional structure is done (after the last call to OnLocalStruct
249         /// for that regional structure).
250         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the regional
251         ///       structure header.
252         /// - param const AliMUONRegionalScalarsStruct*  The regional scalars found
253         ///       in the raw data. If there are no scalars in the data then this
254         ///       pointer is set to NULL.
255         /// - param const void*  A pointer to the start of the local trigger
256         ///       structures data for this regional block.
257         void OnEndOfRegionalStruct(
258                         const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
259                         const AliMUONRegionalScalarsStruct* /*scalars*/,
260                         const void* /*data*/
261                 )
262         {
263         }
264         
265         /// The OnLocalStruct method will be called for each local trigger
266         /// structure found in the DDL payload. The user must overload this
267         /// method to process the local structures as needed.
268         /// The default behaviour of this method is to do nothing.
269         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the local
270         ///       trigger structure found.
271         /// - param const AliMUONRegionalScalarsStruct*  The local scalars found
272         ///       in the raw data. If there are no scalars in the data then this
273         ///       pointer is set to NULL.
274         void OnLocalStruct(
275                         const AliMUONLocalInfoStruct* /*localStruct*/,
276                         const AliMUONLocalScalarsStruct* /*scalars*/
277                 )
278         {
279         }
280         
281         // The following static methods are helper routines for decoding the
282         // DARC header bits.
283         
284         /// Return event type
285         /// \param header  Should be the header as given by the OnDarkHeader() method.
286         static UChar_t GetDarcEventType(UInt_t header) { return (UChar_t)(header >> 30) & 0x3; };
287         
288         /// Return Darc type
289         /// \param header  Should be the header as given by the OnDarkHeader() method.
290         static UChar_t GetDarcType(UInt_t header) { return (UChar_t)(header >> 24) & 0x7; }
291         
292         /// Return serial number
293         /// \param header  Should be the header as given by the OnDarkHeader() method.
294         static UChar_t GetDarcSerialNb(UInt_t header) { return (UChar_t)(header >> 20) & 0xF; }
295         
296         /// Return version
297         /// \param header  Should be the header as given by the OnDarkHeader() method.
298         static UChar_t GetDarcVersion(UInt_t header) { return (UChar_t)(header >> 12) & 0xFF; }
299         
300         /// Return VME trig
301         /// \param header  Should be the header as given by the OnDarkHeader() method.
302         static bool GetDarcVMETrig(UInt_t header) { return (header & 0x800); }
303         
304         /// Return global flag
305         /// \param header  Should be the header as given by the OnDarkHeader() method.
306         static bool GetDarcGlobalFlag(UInt_t header) { return (header & 0x400); }
307         
308         /// Return CPT trigger
309         /// \param header  Should be the header as given by the OnDarkHeader() method.
310         static bool GetDarcCTPTrig(UInt_t header) { return (header & 0x200); }
311         
312         /// Return DAQ flag
313         /// \param header  Should be the header as given by the OnDarkHeader() method.
314         static bool GetDarcDAQFlag(UInt_t header) { return (header & 0x100); }
315         
316         /// Return reg pattern
317         /// \param header  Should be the header as given by the OnDarkHeader() method.
318         static UChar_t GetDarcRegPattern(UInt_t header) { return (UChar_t)(header & 0xFF); }
319         
320         // The following static methods are helper routines for decoding the
321         // regional structure header bits.
322         
323         /// Return L0
324         static UShort_t GetRegionalL0(const AliMUONRegionalHeaderStruct* header)
325         {
326                 assert( header != NULL );
327                 return (header->fL0CountAndMask >> 16) & 0xFFFF;
328         }
329         
330         /// Return mask
331         static UShort_t GetRegionalMask(const AliMUONRegionalHeaderStruct* header)
332         {
333                 assert( header != NULL );
334                 return header->fL0CountAndMask & 0xFFFF;
335         }
336         
337         /// Return RegPhysFlag
338         static bool GetRegionalPhysFlag(const AliMUONRegionalHeaderStruct* header)
339         {
340                 assert( header != NULL );
341                 return (header->fWord & 0x80000000) != 0;
342         }
343         
344         /// Return ResetNb
345         static UChar_t GetRegionalResetNb(const AliMUONRegionalHeaderStruct* header)
346         {
347                 assert( header != NULL );
348                 return (UChar_t)(header->fWord >> 25) &  0x20;
349         }
350         
351         /// Return SerialNb
352         static UChar_t GetRegionalSerialNb(const AliMUONRegionalHeaderStruct* header)
353         {
354                 assert( header != NULL );
355                 return (UChar_t)(header->fWord >> 20) &  0x1F;
356         }
357         
358         /// Return Id
359         static UChar_t GetRegionalId(const AliMUONRegionalHeaderStruct* header)
360         {
361                 assert( header != NULL );
362                 return (UChar_t)(header->fWord >> 16) &  0x0F;
363         }
364         
365         /// Return Version
366         static UChar_t GetRegionalVersion(const AliMUONRegionalHeaderStruct* header)
367         {
368                 assert( header != NULL );
369                 return (UChar_t)(header->fWord >> 8)  &  0xFF;
370         }
371         
372         /// Return Output
373         static UChar_t GetRegionalOutput(const AliMUONRegionalHeaderStruct* header)
374         {
375                 assert( header != NULL );
376                 return (UChar_t)(header->fWord       &  0xFF);
377         }
378         
379         /// Return ErrorBits
380         static UShort_t GetRegionalErrorBits(const AliMUONRegionalHeaderStruct* header)
381         {
382                 assert( header != NULL );
383                 return (UShort_t)(header->fDarcWord >> 21) &  0x3FF;
384         }
385         
386         /// Return FPGANumber
387         static UChar_t GetRegionalFPGANumber(const AliMUONRegionalHeaderStruct* header)
388         {
389                 assert( header != NULL );
390                 return (UChar_t)  (header->fDarcWord >> 18) &  0x7;
391         }
392         
393         /// Return DarcPhysFlag
394         static bool GetRegionalDarcPhysFlag(const AliMUONRegionalHeaderStruct* header)
395         {
396                 assert( header != NULL );
397                 return (header->fDarcWord  &  0x1000) != 0;
398         }
399         
400         /// Return PresentFlag
401         static bool GetRegionalPresentFlag(const AliMUONRegionalHeaderStruct* header)
402         {
403                 assert( header != NULL );
404                 return (header->fDarcWord  &  0x800) != 0;
405         }
406         
407         /// Return RamNotFullFlag
408         static bool GetRegionalRamNotFullFlag(const AliMUONRegionalHeaderStruct* header)
409         {
410                 assert( header != NULL );
411                 return (header->fDarcWord  &  0x400) != 0;
412         }
413         
414         /// Return RamNotEmptyFlag
415         static bool GetRegionalRamNotEmptyFlag(const AliMUONRegionalHeaderStruct* header)
416         {
417                 assert( header != NULL );
418                 return (header->fDarcWord  &  0x200) != 0;
419         }
420         
421         /// Return L2RejStatus
422         static bool GetRegionalL2RejStatus(const AliMUONRegionalHeaderStruct* header)
423         {
424                 assert( header != NULL );
425                 return (header->fDarcWord  &  0x100) != 0;
426         }
427         
428         /// Return L2AccStatus
429         static bool GetRegionalL2AccStatus(const AliMUONRegionalHeaderStruct* header)
430         {
431                 assert( header != NULL );
432                 return (header->fDarcWord  &  0x80) != 0;
433         }
434         
435         /// Return L1Status
436         static bool GetRegionalL1Status(const AliMUONRegionalHeaderStruct* header)
437         {
438                 assert( header != NULL );
439                 return (header->fDarcWord  &  0x40) != 0;
440         }
441         
442         /// Return L0Status
443         static bool GetRegionalL0Status(const AliMUONRegionalHeaderStruct* header)
444         {
445                 assert( header != NULL );
446                 return (header->fDarcWord  &  0x20) != 0;
447         }
448         
449         /// Return EventInRam
450         static UChar_t GetRegionalEventInRam(const AliMUONRegionalHeaderStruct* header)
451         {
452                 assert( header != NULL );
453                 return (UChar_t)  (header->fDarcWord >> 4)  &  0x4;
454         }
455         
456         /// Return Busy
457         static UChar_t GetRegionalBusy(const AliMUONRegionalHeaderStruct* header)
458         {
459                 assert( header != NULL );
460                 return (UChar_t)  (header->fDarcWord)       &  0x4;
461         }
462         
463         // The following static methods are helper routines for decoding the
464         // global header bits.
465         
466         /// Return global output
467         /// \param header  Should be the header as given by the OnGlobalHeader() method.
468         static UChar_t GetGlobalOutput(const AliMUONGlobalHeaderStruct* header)
469         {
470                 assert(header != NULL);
471                 return header->fOutput & 0xFF;
472         }
473         
474         /// Return global config
475         /// \param header  Should be the header as given by the OnGlobalHeader() method.
476         static UShort_t GetGlobalConfig(const AliMUONGlobalHeaderStruct* header)
477         {
478                 assert(header != NULL);
479                 return (header->fOutput >> 16) & 0xFFFF;
480         }
481         
482         // The following static methods are helper routines for decoding the
483         // local trigger structure and scalar bits.
484         
485         /// Return X2
486         static UShort_t GetLocalX2(const AliMUONLocalInfoStruct* local)
487         {
488                 assert(local != NULL);
489                 return (local->fX2X1 >> 16) & 0xFFFF;
490         }
491         
492         /// Return X1
493         static UShort_t GetLocalX1(const AliMUONLocalInfoStruct* local)
494         {
495                 assert(local != NULL);
496                 return (local->fX2X1) & 0xFFFF;
497         }
498         
499         /// Return X4
500         static UShort_t GetLocalX4(const AliMUONLocalInfoStruct* local)
501         {
502                 assert(local != NULL);
503                 return (local->fX4X3 >> 16) & 0xFFFF;
504         }
505         
506         /// Return X3
507         static UShort_t GetLocalX3(const AliMUONLocalInfoStruct* local)
508         {
509                 assert(local != NULL);
510                 return (local->fX4X3) & 0xFFFF;
511         }
512
513         /// Return Y2
514         static UShort_t GetLocalY2(const AliMUONLocalInfoStruct* local)
515         {
516                 assert(local != NULL);
517                 return (local->fY2Y1 >> 16) & 0xFFFF;
518         }
519         
520         /// Return Y1
521         static UShort_t GetLocalY1(const AliMUONLocalInfoStruct* local)
522         {
523                 assert(local != NULL);
524                 return (local->fY2Y1) & 0xFFFF;
525         }
526         
527         /// Return Y4
528         static UShort_t GetLocalY4(const AliMUONLocalInfoStruct* local)
529         {
530                 assert(local != NULL);
531                 return (local->fY4Y3 >> 16) & 0xFFFF;
532         }
533         
534         /// Return Y3
535         static UShort_t GetLocalY3(const AliMUONLocalInfoStruct* local)
536         {
537                 assert(local != NULL);
538                 return (local->fY4Y3) & 0xFFFF;
539         }
540         
541         /// Return Id
542         static UChar_t GetLocalId(const AliMUONLocalInfoStruct* local)
543         {
544                 assert(local != NULL);
545                 return local->fTriggerBits >> 19 &  0xF;
546         }
547         
548         /// Return Dec
549         static UChar_t GetLocalDec(const AliMUONLocalInfoStruct* local)
550         {
551                 assert(local != NULL);
552                 return local->fTriggerBits >> 15 &  0xF;
553         }
554         
555         /// Return TrigY
556         static bool GetLocalTrigY(const AliMUONLocalInfoStruct* local)
557         {
558                 assert(local != NULL);
559                 return (local->fTriggerBits >> 14 & 0x1);
560         }
561         
562         /// Return TriggerY
563         static bool GetLocalTriggerY(const AliMUONLocalInfoStruct* local)
564         {
565                 return not (GetLocalTrigY(local) and GetLocalYPos(local) == 15);
566         }
567         
568         /// Return Upos
569         static UChar_t GetLocalYPos(const AliMUONLocalInfoStruct* local)
570         {
571                 assert(local != NULL);
572                 return local->fTriggerBits >> 10 & 0xF;
573         }
574         
575         /// Get Sign of X deviation 
576         static bool GetLocalSXDev(const AliMUONLocalInfoStruct* local)
577         {
578                 assert(local != NULL);
579                 return (local->fTriggerBits >> 9 & 0x1);
580         }
581         
582         /// Get X deviation 
583         static UChar_t GetLocalXDev(const AliMUONLocalInfoStruct* local)
584         {
585                 assert(local != NULL);
586                 return local->fTriggerBits >> 5 & 0xF;
587         }
588         
589         /// Return TriggerX
590         static bool GetLocalTriggerX(const AliMUONLocalInfoStruct* local)
591         {
592                 return not (GetLocalSXDev(local) and (GetLocalXDev(local) == 0)
593                             and GetLocalXPos(local) == 0);
594         }
595         
596         /// Return Xpos
597         static UChar_t GetLocalXPos(const AliMUONLocalInfoStruct* local)
598         {
599                 assert(local != NULL);
600                 return local->fTriggerBits & 0x1F;
601         }
602
603         /// Return LPT
604         static UChar_t GetLocalLpt(const AliMUONLocalInfoStruct* local) {return (GetLocalDec(local) & 0x3);}
605         
606         /// Return HPT
607         static UChar_t GetLocalHpt(const AliMUONLocalInfoStruct* local) {return (GetLocalDec(local) >> 2) & 0x3;}
608         
609         /// Return switch
610         static UShort_t GetLocalSwitch(const AliMUONLocalScalarsStruct* scalars)
611         {
612                 assert(scalars != NULL);
613                 return (scalars->fEOS >> 1) & 0x3FF;
614         }
615         
616         /// Return ComptXY
617         static UChar_t GetLocalComptXY(const AliMUONLocalScalarsStruct* scalars)
618         {
619                 assert(scalars != NULL);
620                 return scalars->fEOS & 0x1;
621         }
622         
623         /// Return XY1
624         static UShort_t GetLocalXY1(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
625         {
626                 assert(scalars != NULL and n < 16);
627                 return  (n % 2 == 0) ? (scalars->fScaler[(n/2)] & 0xFFFF)
628                                      : ((scalars->fScaler[(n/2)] >> 16) &  0xFFFF);
629         }
630         
631         /// Return XY2
632         static UShort_t GetLocalXY2(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
633         {
634                 assert(scalars != NULL and n < 16);
635                 return  (n % 2 == 0) ? (scalars->fScaler[8 + (n/2)] & 0xFFFF)
636                                      : ((scalars->fScaler[8 + (n/2)] >> 16) &  0xFFFF);
637         }
638         
639         /// Return XY3
640         static UShort_t GetLocalXY3(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
641         {
642                 assert(scalars != NULL and n < 16);
643                 return  (n % 2 == 0) ? (scalars->fScaler[8*2 + (n/2)] & 0xFFFF)
644                                      : ((scalars->fScaler[8*2 + (n/2)] >> 16) &  0xFFFF);
645         }
646         
647         /// Return XY4
648         static UShort_t GetLocalXY4(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
649         {
650                 assert(scalars != NULL and n < 16);
651                 return  (n % 2 == 0) ? (scalars->fScaler[8*3 + (n/2)] & 0xFFFF)
652                                      : ((scalars->fScaler[8*3 + (n/2)] >> 16) &  0xFFFF);
653         }
654         
655         /// Whenever a parsing error of the DDL payload is encountered because of
656         /// corruption of the raw data the OnError method is called immediately at
657         /// the point this error is discovered.
658         /// The default behaviour of this method is to do nothing.
659         /// -param error  This is an error code indicating the kind of problem
660         ///               encountered with the DDL payload.
661         /// -param location  This is a pointer into the DDL payload memory buffer
662         ///         indicating the exact location where the parsing error happened
663         ///         or i.e. the location of the corruption.
664         /// Note that a relative offset in bytes from the start of the memory buffer
665         /// can be calculated by: storing the buffer pointer recevied in OnNewBuffer
666         /// earlier in fBufferStart for example, and then the offset is given by:
667         ///   offset = (unsigned long)location - (unsigned long)fBufferStart;
668         void OnError(ErrorCode /*error*/, const void* /*location*/) {}
669         
670         /// This is a utility method which converts an error code to a string
671         /// representation for printing purposes.
672         /// \param code  The error code as received in OnError for example.
673         /// \return  An ANSI string containing the name of the error code symbol.
674         static const char* ErrorCodeToString(ErrorCode code);
675         
676         /// This is a utility method which converts an error code to user friendly
677         /// descriptive message useful for printing to the screen.
678         /// \param code  The error code as received in OnError for example.
679         /// \return  An ANSI string containing a descriptive message of the error.
680         static const char* ErrorCodeToMessage(ErrorCode code);
681 };
682
683 //_____________________________________________________________________________
684
685 inline const char* AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToString(ErrorCode code)
686 {
687         /// This is a utility method which converts an error code to a string
688         /// representation for printing purposes.
689         /// \param code  The error code as received in OnError for example.
690         /// \return  An ANSI string containing the name of the error code symbol.
691         
692         switch (code)
693         {
694         case kNoError: return "kNoError";
695         case kTooManyRegionals: return "kTooManyRegionals";
696         case kNoDarcHeader: return "kNoDarcHeader";
697         case kNoDarcScalars: return "kNoDarcScalars";
698         case kWrongEventType: return "kWrongEventType";
699         case kNoEndOfDarc: return "kNoEndOfDarc";
700         case kBadEndOfDarc: return "kBadEndOfDarc";
701         case kNoGlobalHeader: return "kNoGlobalHeader";
702         case kNoGlobalScalars: return "kNoGlobalScalars";
703         case kNoEndOfGlobal: return "kNoEndOfGlobal";
704         case kBadEndOfGlobal: return "kBadEndOfGlobal";
705         case kNoRegionalHeader: return "kNoRegionalHeader";
706         case kNoRegionalScalars: return "kNoRegionalScalars";
707         case kNoEndOfRegional: return "kNoEndOfRegional";
708         case kBadEndOfRegional: return "kBadEndOfRegional";
709         case kNoLocalStruct: return "kNoLocalStruct";
710         case kNoLocalScalars: return "kNoLocalScalars";
711         case kNoEndOfLocal: return "kNoEndOfLocal";
712         case kBadEndOfLocal: return "kBadEndOfLocal";
713         case kBufferTooBig: return "kBufferTooBig";
714         default: return "INVALID";
715         }
716 }
717
718
719 inline const char* AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToMessage(ErrorCode code)
720 {
721         /// This is a utility method which converts an error code to user friendly
722         /// descriptive message useful for printing to the screen.
723         /// \param code  The error code as received in OnError for example.
724         /// \return  An ANSI string containing a descriptive message of the error.
725         
726         switch (code)
727         {
728         case kNoError:
729                 return "Decoding was successful.";
730         case kTooManyRegionals:
731                 return "Too many regional card structures are expected in the DDL payload.";
732         case kNoDarcHeader:
733                 return "The DARC header is missing. The DDL buffer is too short"
734                         " to hold a DARC header.";
735         case kNoDarcScalars:
736                 return "The DARC scalars are missing or corrupt."
737                         " The DDL buffer is too short to contain them.";
738         case kWrongEventType:
739                 return "Wrong event type obtained from the Darc header.";
740         case kNoEndOfDarc:
741                 return "The DDL buffer is too short to contain an end of DARC"
742                         " header key word.";
743         case kBadEndOfDarc:
744                 return "End of DARC header key word is incorrect or corrupt.";
745         case kNoGlobalHeader:
746                 return "The global header is missing. The DDL buffer is too"
747                         " short to hold a global header.";
748         case kNoGlobalScalars:
749                 return "The global scalars are missing or corrupt. The DDL"
750                         " buffer is too short to contain them.";
751         case kNoEndOfGlobal:
752                 return "The DDL buffer is too short to contain an end of global"
753                         " header key word.";
754         case kBadEndOfGlobal:
755                 return "End of global header key word is incorrect or corrupt.";
756         case kNoRegionalHeader:
757                 return "The regional header is missing. The DDL buffer is too"
758                         " short to hold another regional header.";
759         case kNoRegionalScalars:
760                 return "The regional scalars are missing or corrupt. The DDL"
761                         " buffer is too short to contain them.";
762         case kNoEndOfRegional:
763                 return "The DDL buffer is too short to contain an end of regional"
764                         " header key word.";
765         case kBadEndOfRegional:
766                 return "End of regional header key word is incorrect or corrupt.";
767         case kNoLocalStruct:
768                 return "The local structure is missing. The DDL buffer is too"
769                         " short to hold another local structure.";
770         case kNoLocalScalars:
771                 return "The local scalars are missing or corrupt. The DDL buffer"
772                         " is too short to contain them.";
773         case kNoEndOfLocal:
774                 return "The DDL buffer is too short to contain an end of local"
775                         " structure key word.";
776         case kBadEndOfLocal:
777                 return "End of local structure key word is incorrect or corrupt.";
778         case kBufferTooBig:
779                 return "The DDL raw data is larger than indicated by the headers;"
780                         " extra bytes are probably just garbage.";
781         default:
782                 return "Unknown error code!";
783         }
784 }
785
786
787 inline std::ostream& operator << (std::ostream& os, AliMUONTriggerDDLDecoderEventHandler::ErrorCode code)
788 {
789         /// This is the stream operator for std::ostream classes to be able to
790         /// easily write the error messages associated with the error codes generated
791         /// by the decoder to 'cout' or 'cerr' for example.
792         
793         os << AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToMessage(code);
794         return os;
795 }
796
797 #endif // ALIMUONTRIGGERDDLDECODEREVENTHANDLER_H