Line data Source code
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 24 : 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 16 : 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 0 : 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 0 : 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 0 : }
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 0 : }
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 128 : }
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 0 : }
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 128 : }
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 128 : }
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 1936 : }
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 0 : }
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 16 : 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 16 : 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 0 : 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 0 : 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 0 : 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 16 : 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 0 : 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 0 : 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 0 : 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 0 : assert( header != NULL );
393 0 : return (header->fL0CountAndMask >> 16) & 0xFFFF;
394 : }
395 :
396 : /// Return mask
397 : static UShort_t GetRegionalMask(const AliMUONRegionalHeaderStruct* header)
398 : {
399 0 : assert( header != NULL );
400 0 : return header->fL0CountAndMask & 0xFFFF;
401 : }
402 :
403 : /// Return RegPhysFlag
404 : static bool GetRegionalPhysFlag(const AliMUONRegionalHeaderStruct* header)
405 : {
406 0 : assert( header != NULL );
407 0 : return (header->fWord & 0x80000000) != 0;
408 : }
409 :
410 : /// Return ResetNb
411 : static UChar_t GetRegionalResetNb(const AliMUONRegionalHeaderStruct* header)
412 : {
413 0 : assert( header != NULL );
414 0 : return (UChar_t)(header->fWord >> 25) & 0x3F;
415 : }
416 :
417 : /// Return SerialNb
418 : static UChar_t GetRegionalSerialNb(const AliMUONRegionalHeaderStruct* header)
419 : {
420 0 : assert( header != NULL );
421 0 : return (UChar_t)(header->fWord >> 20) & 0x1F;
422 : }
423 :
424 : /// Return Id
425 : static UChar_t GetRegionalId(const AliMUONRegionalHeaderStruct* header)
426 : {
427 0 : assert( header != NULL );
428 0 : return (UChar_t)(header->fWord >> 16) & 0x0F;
429 : }
430 :
431 : /// Return Version
432 : static UChar_t GetRegionalVersion(const AliMUONRegionalHeaderStruct* header)
433 : {
434 0 : assert( header != NULL );
435 0 : return (UChar_t)(header->fWord >> 8) & 0xFF;
436 : }
437 :
438 : /// Return Output
439 : static UChar_t GetRegionalOutput(const AliMUONRegionalHeaderStruct* header)
440 : {
441 0 : assert( header != NULL );
442 0 : return (UChar_t)(header->fWord & 0xFF);
443 : }
444 :
445 : /// Return ErrorBits
446 : static UShort_t GetRegionalErrorBits(const AliMUONRegionalHeaderStruct* header)
447 : {
448 0 : assert( header != NULL );
449 0 : return (UShort_t)(header->fDarcWord >> 22) & 0x3FF;
450 : }
451 :
452 : /// Return FPGANumber
453 : static UChar_t GetRegionalFPGANumber(const AliMUONRegionalHeaderStruct* header)
454 : {
455 0 : assert( header != NULL );
456 0 : return (UChar_t) (header->fDarcWord >> 19) & 0x7;
457 : }
458 :
459 : /// Return DarcPhysFlag
460 : static bool GetRegionalDarcPhysFlag(const AliMUONRegionalHeaderStruct* header)
461 : {
462 0 : assert( header != NULL );
463 0 : return (header->fDarcWord & 0x8000) != 0;
464 : }
465 :
466 : /// Return PresentFlag
467 : static bool GetRegionalPresentFlag(const AliMUONRegionalHeaderStruct* header)
468 : {
469 0 : assert( header != NULL );
470 0 : return (header->fDarcWord & 0x4000) != 0;
471 : }
472 :
473 : /// Return RamNotFullFlag
474 : static bool GetRegionalRamNotFullFlag(const AliMUONRegionalHeaderStruct* header)
475 : {
476 0 : assert( header != NULL );
477 0 : return (header->fDarcWord & 0x2000) != 0;
478 : }
479 :
480 : /// Return RamNotEmptyFlag
481 : static bool GetRegionalRamNotEmptyFlag(const AliMUONRegionalHeaderStruct* header)
482 : {
483 0 : assert( header != NULL );
484 0 : return (header->fDarcWord & 0x1000) != 0;
485 : }
486 :
487 : /// Return L2RejStatus
488 : static bool GetRegionalL2RejStatus(const AliMUONRegionalHeaderStruct* header)
489 : {
490 0 : assert( header != NULL );
491 0 : return (header->fDarcWord & 0x800) != 0;
492 : }
493 :
494 : /// Return L2AccStatus
495 : static bool GetRegionalL2AccStatus(const AliMUONRegionalHeaderStruct* header)
496 : {
497 0 : assert( header != NULL );
498 0 : return (header->fDarcWord & 0x400) != 0;
499 : }
500 :
501 : /// Return L1Status
502 : static bool GetRegionalL1Status(const AliMUONRegionalHeaderStruct* header)
503 : {
504 0 : assert( header != NULL );
505 0 : return (header->fDarcWord & 0x200) != 0;
506 : }
507 :
508 : /// Return L0Status
509 : static bool GetRegionalL0Status(const AliMUONRegionalHeaderStruct* header)
510 : {
511 0 : assert( header != NULL );
512 0 : return (header->fDarcWord & 0x100) != 0;
513 : }
514 :
515 : /// Return EventInRam
516 : static UChar_t GetRegionalEventInRam(const AliMUONRegionalHeaderStruct* header)
517 : {
518 0 : assert( header != NULL );
519 0 : return (UChar_t) (header->fDarcWord >> 4) & 0x4;
520 : }
521 :
522 : /// Return Busy
523 : static UChar_t GetRegionalBusy(const AliMUONRegionalHeaderStruct* header)
524 : {
525 0 : assert( header != NULL );
526 0 : 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 8 : assert(header != NULL);
537 4 : 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 0 : assert(header != NULL);
545 0 : 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 3872 : assert(local != NULL);
555 1936 : return (local->fX2X1 >> 16) & 0xFFFF;
556 : }
557 :
558 : /// Return X1
559 : static UShort_t GetLocalX1(const AliMUONLocalInfoStruct* local)
560 : {
561 3872 : assert(local != NULL);
562 1936 : return (local->fX2X1) & 0xFFFF;
563 : }
564 :
565 : /// Return X4
566 : static UShort_t GetLocalX4(const AliMUONLocalInfoStruct* local)
567 : {
568 3872 : assert(local != NULL);
569 1936 : return (local->fX4X3 >> 16) & 0xFFFF;
570 : }
571 :
572 : /// Return X3
573 : static UShort_t GetLocalX3(const AliMUONLocalInfoStruct* local)
574 : {
575 3872 : assert(local != NULL);
576 1936 : return (local->fX4X3) & 0xFFFF;
577 : }
578 :
579 : /// Return Y2
580 : static UShort_t GetLocalY2(const AliMUONLocalInfoStruct* local)
581 : {
582 3872 : assert(local != NULL);
583 1936 : return (local->fY2Y1 >> 16) & 0xFFFF;
584 : }
585 :
586 : /// Return Y1
587 : static UShort_t GetLocalY1(const AliMUONLocalInfoStruct* local)
588 : {
589 3872 : assert(local != NULL);
590 1936 : return (local->fY2Y1) & 0xFFFF;
591 : }
592 :
593 : /// Return Y4
594 : static UShort_t GetLocalY4(const AliMUONLocalInfoStruct* local)
595 : {
596 3872 : assert(local != NULL);
597 1936 : return (local->fY4Y3 >> 16) & 0xFFFF;
598 : }
599 :
600 : /// Return Y3
601 : static UShort_t GetLocalY3(const AliMUONLocalInfoStruct* local)
602 : {
603 3872 : assert(local != NULL);
604 1936 : return (local->fY4Y3) & 0xFFFF;
605 : }
606 :
607 : /// Return Id
608 : static UChar_t GetLocalId(const AliMUONLocalInfoStruct* local)
609 : {
610 0 : assert(local != NULL);
611 0 : return local->fTriggerBits >> 19 & 0xF;
612 : }
613 :
614 : /// Return Dec
615 : static UChar_t GetLocalDec(const AliMUONLocalInfoStruct* local)
616 : {
617 3872 : assert(local != NULL);
618 1936 : return local->fTriggerBits >> 15 & 0xF;
619 : }
620 :
621 : /// Return TrigY
622 : static bool GetLocalTrigY(const AliMUONLocalInfoStruct* local)
623 : {
624 1936 : assert(local != NULL);
625 968 : return (local->fTriggerBits >> 14 & 0x1);
626 : }
627 :
628 : /// Return TriggerY
629 : static bool GetLocalTriggerY(const AliMUONLocalInfoStruct* local)
630 : {
631 0 : return not (GetLocalTrigY(local) and GetLocalYPos(local) == 15);
632 : }
633 :
634 : /// Return Upos
635 : static UChar_t GetLocalYPos(const AliMUONLocalInfoStruct* local)
636 : {
637 1936 : assert(local != NULL);
638 968 : return local->fTriggerBits >> 10 & 0xF;
639 : }
640 :
641 : /// Get Sign of X deviation
642 : static bool GetLocalSXDev(const AliMUONLocalInfoStruct* local)
643 : {
644 1936 : assert(local != NULL);
645 968 : return (local->fTriggerBits >> 9 & 0x1);
646 : }
647 :
648 : /// Get X deviation
649 : static UChar_t GetLocalXDev(const AliMUONLocalInfoStruct* local)
650 : {
651 1936 : assert(local != NULL);
652 968 : return local->fTriggerBits >> 5 & 0xF;
653 : }
654 :
655 : /// Return TriggerX
656 : static bool GetLocalTriggerX(const AliMUONLocalInfoStruct* local)
657 : {
658 0 : return not (GetLocalSXDev(local) and (GetLocalXDev(local) == 0)
659 0 : and GetLocalXPos(local) == 0);
660 : }
661 :
662 : /// Return Xpos
663 : static UChar_t GetLocalXPos(const AliMUONLocalInfoStruct* local)
664 : {
665 1936 : assert(local != NULL);
666 968 : return local->fTriggerBits & 0x1F;
667 : }
668 :
669 : /// Return LPT
670 1936 : static UChar_t GetLocalLpt(const AliMUONLocalInfoStruct* local) {return (GetLocalDec(local) & 0x3);}
671 :
672 : /// Return HPT
673 1936 : 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 0 : assert(scalars != NULL);
679 0 : return (scalars->fEOS >> 1) & 0x3FF;
680 : }
681 :
682 : /// Return ComptXY
683 : static UChar_t GetLocalComptXY(const AliMUONLocalScalarsStruct* scalars)
684 : {
685 0 : assert(scalars != NULL);
686 0 : return scalars->fEOS & 0x1;
687 : }
688 :
689 : /// Return XY1
690 : static UShort_t GetLocalXY1(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
691 : {
692 0 : assert(scalars != NULL and n < 16);
693 0 : return (n % 2 == 1) ? (scalars->fScaler[(n/2)] & 0xFFFF)
694 0 : : ((scalars->fScaler[(n/2)] >> 16) & 0xFFFF);
695 : }
696 :
697 : /// Return XY2
698 : static UShort_t GetLocalXY2(const AliMUONLocalScalarsStruct* scalars, UInt_t n)
699 : {
700 0 : assert(scalars != NULL and n < 16);
701 0 : return (n % 2 == 1) ? (scalars->fScaler[8 + (n/2)] & 0xFFFF)
702 0 : : ((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 0 : assert(scalars != NULL and n < 16);
709 0 : return (n % 2 == 1) ? (scalars->fScaler[8*2 + (n/2)] & 0xFFFF)
710 0 : : ((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 0 : assert(scalars != NULL and n < 16);
717 0 : return (n % 2 == 1) ? (scalars->fScaler[8*3 + (n/2)] & 0xFFFF)
718 0 : : ((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 0 : switch (code)
793 : {
794 : case kNoError:
795 0 : return "Decoding was successful.";
796 : case kTooManyRegionals:
797 0 : return "Too many regional card structures are expected in the DDL payload.";
798 : case kNoDarcHeader:
799 0 : return "The DARC header is missing. The DDL buffer is too short"
800 : " to hold a DARC header.";
801 : case kNoDarcScalars:
802 0 : return "The DARC scalars are missing or corrupt."
803 : " The DDL buffer is too short to contain them.";
804 : case kWrongEventType:
805 0 : return "Wrong event type obtained from the Darc header.";
806 : case kNoEndOfDarc:
807 0 : return "The DDL buffer is too short to contain an end of DARC"
808 : " header key word.";
809 : case kBadEndOfDarc:
810 0 : return "End of DARC header key word is incorrect or corrupt.";
811 : case kNoGlobalHeader:
812 0 : return "The global header is missing. The DDL buffer is too"
813 : " short to hold a global header.";
814 : case kNoGlobalScalars:
815 0 : return "The global scalars are missing or corrupt. The DDL"
816 : " buffer is too short to contain them.";
817 : case kNoEndOfGlobal:
818 0 : return "The DDL buffer is too short to contain an end of global"
819 : " header key word.";
820 : case kBadEndOfGlobal:
821 0 : return "End of global header key word is incorrect or corrupt.";
822 : case kNoRegionalHeader:
823 0 : return "The regional header is missing. The DDL buffer is too"
824 : " short to hold another regional header.";
825 : case kNoRegionalScalars:
826 0 : return "The regional scalars are missing or corrupt. The DDL"
827 : " buffer is too short to contain them.";
828 : case kNoEndOfRegional:
829 0 : return "The DDL buffer is too short to contain an end of regional"
830 : " header key word.";
831 : case kBadEndOfRegional:
832 0 : return "End of regional header key word is incorrect or corrupt.";
833 : case kNoLocalStruct:
834 0 : return "The local structure is missing. The DDL buffer is too"
835 : " short to hold another local structure.";
836 : case kNoLocalScalars:
837 0 : return "The local scalars are missing or corrupt. The DDL buffer"
838 : " is too short to contain them.";
839 : case kNoEndOfLocal:
840 0 : return "The DDL buffer is too short to contain an end of local"
841 : " structure key word.";
842 : case kBadEndOfLocal:
843 0 : return "End of local structure key word is incorrect or corrupt.";
844 : case kBufferTooBig:
845 0 : return "The DDL raw data is larger than indicated by the headers;"
846 : " extra bytes are probably just garbage.";
847 : default:
848 0 : return "Unknown error code!";
849 : }
850 0 : }
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
|