]>
Commit | Line | Data |
---|---|---|
1788245f | 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 |