]>
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 | ||
2235e482 | 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 | ||
1788245f | 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 | ||
2235e482 | 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 | ||
1788245f | 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 | ||
2235e482 | 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 | ||
1788245f | 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 ); | |
2235e482 | 414 | return (UChar_t)(header->fWord >> 25) & 0x3F; |
1788245f | 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 ); | |
2235e482 | 449 | return (UShort_t)(header->fDarcWord >> 22) & 0x3FF; |
1788245f | 450 | } |
451 | ||
452 | /// Return FPGANumber | |
453 | static UChar_t GetRegionalFPGANumber(const AliMUONRegionalHeaderStruct* header) | |
454 | { | |
455 | assert( header != NULL ); | |
2235e482 | 456 | return (UChar_t) (header->fDarcWord >> 19) & 0x7; |
1788245f | 457 | } |
458 | ||
459 | /// Return DarcPhysFlag | |
460 | static bool GetRegionalDarcPhysFlag(const AliMUONRegionalHeaderStruct* header) | |
461 | { | |
462 | assert( header != NULL ); | |
2235e482 | 463 | return (header->fDarcWord & 0x8000) != 0; |
1788245f | 464 | } |
465 | ||
466 | /// Return PresentFlag | |
467 | static bool GetRegionalPresentFlag(const AliMUONRegionalHeaderStruct* header) | |
468 | { | |
469 | assert( header != NULL ); | |
2235e482 | 470 | return (header->fDarcWord & 0x4000) != 0; |
1788245f | 471 | } |
472 | ||
473 | /// Return RamNotFullFlag | |
474 | static bool GetRegionalRamNotFullFlag(const AliMUONRegionalHeaderStruct* header) | |
475 | { | |
476 | assert( header != NULL ); | |
2235e482 | 477 | return (header->fDarcWord & 0x2000) != 0; |
1788245f | 478 | } |
479 | ||
480 | /// Return RamNotEmptyFlag | |
481 | static bool GetRegionalRamNotEmptyFlag(const AliMUONRegionalHeaderStruct* header) | |
482 | { | |
483 | assert( header != NULL ); | |
2235e482 | 484 | return (header->fDarcWord & 0x1000) != 0; |
1788245f | 485 | } |
486 | ||
487 | /// Return L2RejStatus | |
488 | static bool GetRegionalL2RejStatus(const AliMUONRegionalHeaderStruct* header) | |
489 | { | |
490 | assert( header != NULL ); | |
2235e482 | 491 | return (header->fDarcWord & 0x800) != 0; |
1788245f | 492 | } |
493 | ||
494 | /// Return L2AccStatus | |
495 | static bool GetRegionalL2AccStatus(const AliMUONRegionalHeaderStruct* header) | |
496 | { | |
497 | assert( header != NULL ); | |
2235e482 | 498 | return (header->fDarcWord & 0x400) != 0; |
1788245f | 499 | } |
500 | ||
501 | /// Return L1Status | |
502 | static bool GetRegionalL1Status(const AliMUONRegionalHeaderStruct* header) | |
503 | { | |
504 | assert( header != NULL ); | |
2235e482 | 505 | return (header->fDarcWord & 0x200) != 0; |
1788245f | 506 | } |
507 | ||
508 | /// Return L0Status | |
509 | static bool GetRegionalL0Status(const AliMUONRegionalHeaderStruct* header) | |
510 | { | |
511 | assert( header != NULL ); | |
2235e482 | 512 | return (header->fDarcWord & 0x100) != 0; |
1788245f | 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); | |
616d91d8 | 693 | return (n % 2 == 1) ? (scalars->fScaler[(n/2)] & 0xFFFF) |
1788245f | 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); | |
616d91d8 | 701 | return (n % 2 == 1) ? (scalars->fScaler[8 + (n/2)] & 0xFFFF) |
1788245f | 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); | |
616d91d8 | 709 | return (n % 2 == 1) ? (scalars->fScaler[8*2 + (n/2)] & 0xFFFF) |
1788245f | 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); | |
616d91d8 | 717 | return (n % 2 == 1) ? (scalars->fScaler[8*3 + (n/2)] & 0xFFFF) |
1788245f | 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 |