Adding more bins in QA (Alis)
[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 OnNewRegionalStructV2 method will be called for each regional header
246         /// found in the DDL payload.
247         /// The default behaviour of this method is to do nothing.
248         /// This method is an alternate version to OnNewRegionalStruct and an
249         /// inheriting class needs only implement one or the other version.
250         /// - param UInt_t  The structure index number of the regional structure.
251         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the regional
252         ///       structure header.
253         /// - param const AliMUONRegionalScalarsStruct*  The regional scalars found
254         ///       in the raw data. If there are no scalars in the data then this
255         ///       pointer is set to NULL.
256         /// - param const void*  A pointer to the start of the local trigger
257         ///       structures data for this regional block.
258         void OnNewRegionalStructV2(
259                         UInt_t /*num*/,
260                         const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
261                         const AliMUONRegionalScalarsStruct* /*scalars*/,
262                         const void* /*data*/
263                 )
264         {
265         }
266         
267         /// The OnEndOfRegionalStruct method will be called whenever a regional
268         /// structure has been processed. For each OnNewRegionalStruct method
269         /// call a symmetric call to OnEndOfRegionalStruct is made after processing
270         /// of the regional structure is done (after the last call to OnLocalStruct
271         /// for that regional structure).
272         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the regional
273         ///       structure header.
274         /// - param const AliMUONRegionalScalarsStruct*  The regional scalars found
275         ///       in the raw data. If there are no scalars in the data then this
276         ///       pointer is set to NULL.
277         /// - param const void*  A pointer to the start of the local trigger
278         ///       structures data for this regional block.
279         void OnEndOfRegionalStruct(
280                         const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
281                         const AliMUONRegionalScalarsStruct* /*scalars*/,
282                         const void* /*data*/
283                 )
284         {
285         }
286         
287         /// The OnEndOfRegionalStructV2 method will be called whenever a regional
288         /// structure has been processed. For each OnNewRegionalStruct method
289         /// call a symmetric call to OnEndOfRegionalStruct is made after processing
290         /// of the regional structure is done (after the last call to OnLocalStruct
291         /// for that regional structure).
292         /// This method is an alternate version to OnEndOfRegionalStruct and an
293         /// inheriting class needs only implement one or the other version.
294         /// - param UInt_t  The structure index number of the regional structure.
295         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the regional
296         ///       structure header.
297         /// - param const AliMUONRegionalScalarsStruct*  The regional scalars found
298         ///       in the raw data. If there are no scalars in the data then this
299         ///       pointer is set to NULL.
300         /// - param const void*  A pointer to the start of the local trigger
301         ///       structures data for this regional block.
302         void OnEndOfRegionalStructV2(
303                         UInt_t /*num*/,
304                         const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
305                         const AliMUONRegionalScalarsStruct* /*scalars*/,
306                         const void* /*data*/
307                 )
308         {
309         }
310         
311         /// The OnLocalStruct method will be called for each local trigger
312         /// structure found in the DDL payload. The user must overload this
313         /// method to process the local structures as needed.
314         /// The default behaviour of this method is to do nothing.
315         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the local
316         ///       trigger structure found.
317         /// - param const AliMUONRegionalScalarsStruct*  The local scalars found
318         ///       in the raw data. If there are no scalars in the data then this
319         ///       pointer is set to NULL.
320         void OnLocalStruct(
321                         const AliMUONLocalInfoStruct* /*localStruct*/,
322                         const AliMUONLocalScalarsStruct* /*scalars*/
323                 )
324         {
325         }
326         
327         /// The OnLocalStructV2 method will be called for each local trigger
328         /// structure found in the DDL payload. The user must overload this
329         /// method to process the local structures as needed.
330         /// The default behaviour of this method is to do nothing.
331         /// This method is an alternate version to OnLocalStruct and an
332         /// inheriting class needs only implement one or the other version.
333         /// - param UInt_t  The structure index number of the local structure.
334         /// - param const AliMUONRegionalHeaderStruct*  A pointer to the local
335         ///       trigger structure found.
336         /// - param const AliMUONRegionalScalarsStruct*  The local scalars found
337         ///       in the raw data. If there are no scalars in the data then this
338         ///       pointer is set to NULL.
339         void OnLocalStructV2(
340                         UInt_t /*num*/,
341                         const AliMUONLocalInfoStruct* /*localStruct*/,
342                         const AliMUONLocalScalarsStruct* /*scalars*/
343                 )
344         {
345         }
346         
347         // The following static methods are helper routines for decoding the
348         // DARC header bits.
349         
350         /// Return event type
351         /// \param header  Should be the header as given by the OnDarkHeader() method.
352         static UChar_t GetDarcEventType(UInt_t header) { return (UChar_t)(header >> 30) & 0x3; };
353         
354         /// Return Darc type
355         /// \param header  Should be the header as given by the OnDarkHeader() method.
356         static UChar_t GetDarcType(UInt_t header) { return (UChar_t)(header >> 24) & 0x7; }
357         
358         /// Return serial number
359         /// \param header  Should be the header as given by the OnDarkHeader() method.
360         static UChar_t GetDarcSerialNb(UInt_t header) { return (UChar_t)(header >> 20) & 0xF; }
361         
362         /// Return version
363         /// \param header  Should be the header as given by the OnDarkHeader() method.
364         static UChar_t GetDarcVersion(UInt_t header) { return (UChar_t)(header >> 12) & 0xFF; }
365         
366         /// Return VME trig
367         /// \param header  Should be the header as given by the OnDarkHeader() method.
368         static bool GetDarcVMETrig(UInt_t header) { return (header & 0x800); }
369         
370         /// Return global flag
371         /// \param header  Should be the header as given by the OnDarkHeader() method.
372         static bool GetDarcGlobalFlag(UInt_t header) { return (header & 0x400); }
373         
374         /// Return CPT trigger
375         /// \param header  Should be the header as given by the OnDarkHeader() method.
376         static bool GetDarcCTPTrig(UInt_t header) { return (header & 0x200); }
377         
378         /// Return DAQ flag
379         /// \param header  Should be the header as given by the OnDarkHeader() method.
380         static bool GetDarcDAQFlag(UInt_t header) { return (header & 0x100); }
381         
382         /// Return reg pattern
383         /// \param header  Should be the header as given by the OnDarkHeader() method.
384         static UChar_t GetDarcRegPattern(UInt_t header) { return (UChar_t)(header & 0xFF); }
385         
386         // The following static methods are helper routines for decoding the
387         // regional structure header bits.
388         
389         /// Return L0
390         static UShort_t GetRegionalL0(const AliMUONRegionalHeaderStruct* header)
391         {
392                 assert( header != NULL );
393                 return (header->fL0CountAndMask >> 16) & 0xFFFF;
394         }
395         
396         /// Return mask
397         static UShort_t GetRegionalMask(const AliMUONRegionalHeaderStruct* header)
398         {
399                 assert( header != NULL );
400                 return header->fL0CountAndMask & 0xFFFF;
401         }
402         
403         /// Return RegPhysFlag
404         static bool GetRegionalPhysFlag(const AliMUONRegionalHeaderStruct* header)
405         {
406                 assert( header != NULL );
407                 return (header->fWord & 0x80000000) != 0;
408         }
409         
410         /// Return ResetNb
411         static UChar_t GetRegionalResetNb(const AliMUONRegionalHeaderStruct* header)
412         {
413                 assert( header != NULL );
414                 return (UChar_t)(header->fWord >> 25) &  0x3F;
415         }
416         
417         /// Return SerialNb
418         static UChar_t GetRegionalSerialNb(const AliMUONRegionalHeaderStruct* header)
419         {
420                 assert( header != NULL );
421                 return (UChar_t)(header->fWord >> 20) &  0x1F;
422         }
423         
424         /// Return Id
425         static UChar_t GetRegionalId(const AliMUONRegionalHeaderStruct* header)
426         {
427                 assert( header != NULL );
428                 return (UChar_t)(header->fWord >> 16) &  0x0F;
429         }
430         
431         /// Return Version
432         static UChar_t GetRegionalVersion(const AliMUONRegionalHeaderStruct* header)
433         {
434                 assert( header != NULL );
435                 return (UChar_t)(header->fWord >> 8)  &  0xFF;
436         }
437         
438         /// Return Output
439         static UChar_t GetRegionalOutput(const AliMUONRegionalHeaderStruct* header)
440         {
441                 assert( header != NULL );
442                 return (UChar_t)(header->fWord       &  0xFF);
443         }
444         
445         /// Return ErrorBits
446         static UShort_t GetRegionalErrorBits(const AliMUONRegionalHeaderStruct* header)
447         {
448                 assert( header != NULL );
449                 return (UShort_t)(header->fDarcWord >> 22) &  0x3FF;
450         }
451         
452         /// Return FPGANumber
453         static UChar_t GetRegionalFPGANumber(const AliMUONRegionalHeaderStruct* header)
454         {
455                 assert( header != NULL );
456                 return (UChar_t)  (header->fDarcWord >> 19) &  0x7;
457         }
458         
459         /// Return DarcPhysFlag
460         static bool GetRegionalDarcPhysFlag(const AliMUONRegionalHeaderStruct* header)
461         {
462                 assert( header != NULL );
463                 return (header->fDarcWord  &  0x8000) != 0;
464         }
465         
466         /// Return PresentFlag
467         static bool GetRegionalPresentFlag(const AliMUONRegionalHeaderStruct* header)
468         {
469                 assert( header != NULL );
470                 return (header->fDarcWord  &  0x4000) != 0;
471         }
472         
473         /// Return RamNotFullFlag
474         static bool GetRegionalRamNotFullFlag(const AliMUONRegionalHeaderStruct* header)
475         {
476                 assert( header != NULL );
477                 return (header->fDarcWord  &  0x2000) != 0;
478         }
479         
480         /// Return RamNotEmptyFlag
481         static bool GetRegionalRamNotEmptyFlag(const AliMUONRegionalHeaderStruct* header)
482         {
483                 assert( header != NULL );
484                 return (header->fDarcWord  &  0x1000) != 0;
485         }
486         
487         /// Return L2RejStatus
488         static bool GetRegionalL2RejStatus(const AliMUONRegionalHeaderStruct* header)
489         {
490                 assert( header != NULL );
491                 return (header->fDarcWord  &  0x800) != 0;
492         }
493         
494         /// Return L2AccStatus
495         static bool GetRegionalL2AccStatus(const AliMUONRegionalHeaderStruct* header)
496         {
497                 assert( header != NULL );
498                 return (header->fDarcWord  &  0x400) != 0;
499         }
500         
501         /// Return L1Status
502         static bool GetRegionalL1Status(const AliMUONRegionalHeaderStruct* header)
503         {
504                 assert( header != NULL );
505                 return (header->fDarcWord  &  0x200) != 0;
506         }
507         
508         /// Return L0Status
509         static bool GetRegionalL0Status(const AliMUONRegionalHeaderStruct* header)
510         {
511                 assert( header != NULL );
512                 return (header->fDarcWord  &  0x100) != 0;
513         }
514         
515         /// Return EventInRam
516         static UChar_t GetRegionalEventInRam(const AliMUONRegionalHeaderStruct* header)
517         {
518                 assert( header != NULL );
519                 return (UChar_t)  (header->fDarcWord >> 4)  &  0x4;
520         }
521         
522         /// Return Busy
523         static UChar_t GetRegionalBusy(const AliMUONRegionalHeaderStruct* header)
524         {
525                 assert( header != NULL );
526                 return (UChar_t)  (header->fDarcWord)       &  0x4;
527         }
528         
529         // The following static methods are helper routines for decoding the
530         // global header bits.
531         
532         /// Return global output
533         /// \param header  Should be the header as given by the OnGlobalHeader() method.
534         static UChar_t GetGlobalOutput(const AliMUONGlobalHeaderStruct* header)
535         {
536                 assert(header != NULL);
537                 return header->fOutput & 0xFF;
538         }
539         
540         /// Return global config
541         /// \param header  Should be the header as given by the OnGlobalHeader() method.
542         static UShort_t GetGlobalConfig(const AliMUONGlobalHeaderStruct* header)
543         {
544                 assert(header != NULL);
545                 return (header->fOutput >> 16) & 0xFFFF;
546         }
547         
548         // The following static methods are helper routines for decoding the
549         // local trigger structure and scalar bits.
550         
551         /// Return X2
552         static UShort_t GetLocalX2(const AliMUONLocalInfoStruct* local)
553         {
554                 assert(local != NULL);
555                 return (local->fX2X1 >> 16) & 0xFFFF;
556         }
557         
558         /// Return X1
559         static UShort_t GetLocalX1(const AliMUONLocalInfoStruct* local)
560         {
561                 assert(local != NULL);
562                 return (local->fX2X1) & 0xFFFF;
563         }
564         
565         /// Return X4
566         static UShort_t GetLocalX4(const AliMUONLocalInfoStruct* local)
567         {
568                 assert(local != NULL);
569                 return (local->fX4X3 >> 16) & 0xFFFF;
570         }
571         
572         /// Return X3
573         static UShort_t GetLocalX3(const AliMUONLocalInfoStruct* local)
574         {
575                 assert(local != NULL);
576                 return (local->fX4X3) & 0xFFFF;
577         }
578
579         /// Return Y2
580         static UShort_t GetLocalY2(const AliMUONLocalInfoStruct* local)
581         {
582                 assert(local != NULL);
583                 return (local->fY2Y1 >> 16) & 0xFFFF;
584         }
585         
586         /// Return Y1
587         static UShort_t GetLocalY1(const AliMUONLocalInfoStruct* local)
588         {
589                 assert(local != NULL);
590                 return (local->fY2Y1) & 0xFFFF;
591         }
592         
593         /// Return Y4
594         static UShort_t GetLocalY4(const AliMUONLocalInfoStruct* local)
595         {
596                 assert(local != NULL);
597                 return (local->fY4Y3 >> 16) & 0xFFFF;
598         }
599         
600         /// Return Y3
601         static UShort_t GetLocalY3(const AliMUONLocalInfoStruct* local)
602         {
603                 assert(local != NULL);
604                 return (local->fY4Y3) & 0xFFFF;
605         }
606         
607         /// Return Id
608         static UChar_t GetLocalId(const AliMUONLocalInfoStruct* local)
609         {
610                 assert(local != NULL);
611                 return local->fTriggerBits >> 19 &  0xF;
612         }
613         
614         /// Return Dec
615         static UChar_t GetLocalDec(const AliMUONLocalInfoStruct* local)
616         {
617                 assert(local != NULL);
618                 return local->fTriggerBits >> 15 &  0xF;
619         }
620         
621         /// Return TrigY
622         static bool GetLocalTrigY(const AliMUONLocalInfoStruct* local)
623         {
624                 assert(local != NULL);
625                 return (local->fTriggerBits >> 14 & 0x1);
626         }
627         
628         /// Return TriggerY
629         static bool GetLocalTriggerY(const AliMUONLocalInfoStruct* local)
630         {
631                 return not (GetLocalTrigY(local) and GetLocalYPos(local) == 15);
632         }
633         
634         /// Return Upos
635         static UChar_t GetLocalYPos(const AliMUONLocalInfoStruct* local)
636         {
637                 assert(local != NULL);
638                 return local->fTriggerBits >> 10 & 0xF;
639         }
640         
641         /// Get Sign of X deviation 
642         static bool GetLocalSXDev(const AliMUONLocalInfoStruct* local)
643         {
644                 assert(local != NULL);
645                 return (local->fTriggerBits >> 9 & 0x1);
646         }
647         
648         /// Get X deviation 
649         static UChar_t GetLocalXDev(const AliMUONLocalInfoStruct* local)
650         {
651                 assert(local != NULL);
652                 return local->fTriggerBits >> 5 & 0xF;
653         }
654         
655         /// Return TriggerX
656         static bool GetLocalTriggerX(const AliMUONLocalInfoStruct* local)
657         {
658                 return not (GetLocalSXDev(local) and (GetLocalXDev(local) == 0)
659                             and GetLocalXPos(local) == 0);
660         }
661         
662         /// Return Xpos
663         static UChar_t GetLocalXPos(const AliMUONLocalInfoStruct* local)
664         {
665                 assert(local != NULL);
666                 return local->fTriggerBits & 0x1F;
667         }
668
669         /// Return LPT
670         static UChar_t GetLocalLpt(const AliMUONLocalInfoStruct* local) {return (GetLocalDec(local) & 0x3);}
671         
672         /// Return HPT
673         static UChar_t GetLocalHpt(const AliMUONLocalInfoStruct* local) {return (GetLocalDec(local) >> 2) & 0x3;}
674         
675         /// Return switch
676         static UShort_t GetLocalSwitch(const AliMUONLocalScalarsStruct* scalars)
677         {
678                 assert(scalars != NULL);
679                 return (scalars->fEOS >> 1) & 0x3FF;
680         }
681         
682         /// Return ComptXY
683         static UChar_t GetLocalComptXY(const AliMUONLocalScalarsStruct* scalars)
684         {
685                 assert(scalars != NULL);
686                 return scalars->fEOS & 0x1;
687         }
688         
689         /// Return XY1
690         static UShort_t GetLocalXY1(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
691         {
692                 assert(scalars != NULL and n < 16);
693                 return  (n % 2 == 1) ? (scalars->fScaler[(n/2)] & 0xFFFF)
694                                      : ((scalars->fScaler[(n/2)] >> 16) &  0xFFFF);
695         }
696         
697         /// Return XY2
698         static UShort_t GetLocalXY2(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
699         {
700                 assert(scalars != NULL and n < 16);
701                 return  (n % 2 == 1) ? (scalars->fScaler[8 + (n/2)] & 0xFFFF)
702                                      : ((scalars->fScaler[8 + (n/2)] >> 16) &  0xFFFF);
703         }
704         
705         /// Return XY3
706         static UShort_t GetLocalXY3(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
707         {
708                 assert(scalars != NULL and n < 16);
709                 return  (n % 2 == 1) ? (scalars->fScaler[8*2 + (n/2)] & 0xFFFF)
710                                      : ((scalars->fScaler[8*2 + (n/2)] >> 16) &  0xFFFF);
711         }
712         
713         /// Return XY4
714         static UShort_t GetLocalXY4(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
715         {
716                 assert(scalars != NULL and n < 16);
717                 return  (n % 2 == 1) ? (scalars->fScaler[8*3 + (n/2)] & 0xFFFF)
718                                      : ((scalars->fScaler[8*3 + (n/2)] >> 16) &  0xFFFF);
719         }
720         
721         /// Whenever a parsing error of the DDL payload is encountered because of
722         /// corruption of the raw data the OnError method is called immediately at
723         /// the point this error is discovered.
724         /// The default behaviour of this method is to do nothing.
725         /// -param error  This is an error code indicating the kind of problem
726         ///               encountered with the DDL payload.
727         /// -param location  This is a pointer into the DDL payload memory buffer
728         ///         indicating the exact location where the parsing error happened
729         ///         or i.e. the location of the corruption.
730         /// Note that a relative offset in bytes from the start of the memory buffer
731         /// can be calculated by: storing the buffer pointer recevied in OnNewBuffer
732         /// earlier in fBufferStart for example, and then the offset is given by:
733         ///   offset = (unsigned long)location - (unsigned long)fBufferStart;
734         void OnError(ErrorCode /*error*/, const void* /*location*/) {}
735         
736         /// This is a utility method which converts an error code to a string
737         /// representation for printing purposes.
738         /// \param code  The error code as received in OnError for example.
739         /// \return  An ANSI string containing the name of the error code symbol.
740         static const char* ErrorCodeToString(ErrorCode code);
741         
742         /// This is a utility method which converts an error code to user friendly
743         /// descriptive message useful for printing to the screen.
744         /// \param code  The error code as received in OnError for example.
745         /// \return  An ANSI string containing a descriptive message of the error.
746         static const char* ErrorCodeToMessage(ErrorCode code);
747 };
748
749 //_____________________________________________________________________________
750
751 inline const char* AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToString(ErrorCode code)
752 {
753         /// This is a utility method which converts an error code to a string
754         /// representation for printing purposes.
755         /// \param code  The error code as received in OnError for example.
756         /// \return  An ANSI string containing the name of the error code symbol.
757         
758         switch (code)
759         {
760         case kNoError: return "kNoError";
761         case kTooManyRegionals: return "kTooManyRegionals";
762         case kNoDarcHeader: return "kNoDarcHeader";
763         case kNoDarcScalars: return "kNoDarcScalars";
764         case kWrongEventType: return "kWrongEventType";
765         case kNoEndOfDarc: return "kNoEndOfDarc";
766         case kBadEndOfDarc: return "kBadEndOfDarc";
767         case kNoGlobalHeader: return "kNoGlobalHeader";
768         case kNoGlobalScalars: return "kNoGlobalScalars";
769         case kNoEndOfGlobal: return "kNoEndOfGlobal";
770         case kBadEndOfGlobal: return "kBadEndOfGlobal";
771         case kNoRegionalHeader: return "kNoRegionalHeader";
772         case kNoRegionalScalars: return "kNoRegionalScalars";
773         case kNoEndOfRegional: return "kNoEndOfRegional";
774         case kBadEndOfRegional: return "kBadEndOfRegional";
775         case kNoLocalStruct: return "kNoLocalStruct";
776         case kNoLocalScalars: return "kNoLocalScalars";
777         case kNoEndOfLocal: return "kNoEndOfLocal";
778         case kBadEndOfLocal: return "kBadEndOfLocal";
779         case kBufferTooBig: return "kBufferTooBig";
780         default: return "INVALID";
781         }
782 }
783
784
785 inline const char* AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToMessage(ErrorCode code)
786 {
787         /// This is a utility method which converts an error code to user friendly
788         /// descriptive message useful for printing to the screen.
789         /// \param code  The error code as received in OnError for example.
790         /// \return  An ANSI string containing a descriptive message of the error.
791         
792         switch (code)
793         {
794         case kNoError:
795                 return "Decoding was successful.";
796         case kTooManyRegionals:
797                 return "Too many regional card structures are expected in the DDL payload.";
798         case kNoDarcHeader:
799                 return "The DARC header is missing. The DDL buffer is too short"
800                         " to hold a DARC header.";
801         case kNoDarcScalars:
802                 return "The DARC scalars are missing or corrupt."
803                         " The DDL buffer is too short to contain them.";
804         case kWrongEventType:
805                 return "Wrong event type obtained from the Darc header.";
806         case kNoEndOfDarc:
807                 return "The DDL buffer is too short to contain an end of DARC"
808                         " header key word.";
809         case kBadEndOfDarc:
810                 return "End of DARC header key word is incorrect or corrupt.";
811         case kNoGlobalHeader:
812                 return "The global header is missing. The DDL buffer is too"
813                         " short to hold a global header.";
814         case kNoGlobalScalars:
815                 return "The global scalars are missing or corrupt. The DDL"
816                         " buffer is too short to contain them.";
817         case kNoEndOfGlobal:
818                 return "The DDL buffer is too short to contain an end of global"
819                         " header key word.";
820         case kBadEndOfGlobal:
821                 return "End of global header key word is incorrect or corrupt.";
822         case kNoRegionalHeader:
823                 return "The regional header is missing. The DDL buffer is too"
824                         " short to hold another regional header.";
825         case kNoRegionalScalars:
826                 return "The regional scalars are missing or corrupt. The DDL"
827                         " buffer is too short to contain them.";
828         case kNoEndOfRegional:
829                 return "The DDL buffer is too short to contain an end of regional"
830                         " header key word.";
831         case kBadEndOfRegional:
832                 return "End of regional header key word is incorrect or corrupt.";
833         case kNoLocalStruct:
834                 return "The local structure is missing. The DDL buffer is too"
835                         " short to hold another local structure.";
836         case kNoLocalScalars:
837                 return "The local scalars are missing or corrupt. The DDL buffer"
838                         " is too short to contain them.";
839         case kNoEndOfLocal:
840                 return "The DDL buffer is too short to contain an end of local"
841                         " structure key word.";
842         case kBadEndOfLocal:
843                 return "End of local structure key word is incorrect or corrupt.";
844         case kBufferTooBig:
845                 return "The DDL raw data is larger than indicated by the headers;"
846                         " extra bytes are probably just garbage.";
847         default:
848                 return "Unknown error code!";
849         }
850 }
851
852
853 inline std::ostream& operator << (std::ostream& os, AliMUONTriggerDDLDecoderEventHandler::ErrorCode code)
854 {
855         /// This is the stream operator for std::ostream classes to be able to
856         /// easily write the error messages associated with the error codes generated
857         /// by the decoder to 'cout' or 'cerr' for example.
858         
859         os << AliMUONTriggerDDLDecoderEventHandler::ErrorCodeToMessage(code);
860         return os;
861 }
862
863 #endif // ALIMUONTRIGGERDDLDECODEREVENTHANDLER_H