]>
Commit | Line | Data |
---|---|---|
e3a2b9c9 | 1 | #ifndef ALIMUONRAWSTREAMTRACKERHP_H |
2 | #define ALIMUONRAWSTREAMTRACKERHP_H | |
3 | /* This file is property of and copyright by the ALICE HLT Project * | |
4 | * ALICE Experiment at CERN, All rights reserved. * | |
5 | * See cxx source for full Copyright notice */ | |
6 | ||
7 | /* $Id$*/ | |
8 | ||
9 | /// | |
10 | /// \file AliMUONRawStreamTrackerHP.h | |
11 | /// \author Artur Szostak <artursz@iafrica.com> | |
12 | /// \date 29-11-2007 | |
13 | /// \brief Declaration of the high performance decoder for muon trigger chamber raw streams. | |
14 | /// | |
15 | ||
b6f591ae | 16 | #ifndef ROOT_TObject |
17 | # include "TObject.h" | |
18 | #endif | |
e3a2b9c9 | 19 | #include "AliMUONTrackerDDLDecoder.h" |
20 | ||
586dda01 | 21 | #include <cstring> |
22 | ||
481d8064 | 23 | class AliMUONDDLTracker; |
b6f591ae | 24 | class AliRawReader; |
64c2397e | 25 | class AliMUONLogger; |
481d8064 | 26 | |
b6f591ae | 27 | class AliMUONRawStreamTrackerHP : public TObject |
e3a2b9c9 | 28 | { |
29 | public: | |
8a0dae7c | 30 | class AliDspHeader; |
31 | class AliBusPatch; | |
64c2397e | 32 | |
33 | /// Values indicating the logging detail level to use for error messages. | |
34 | enum EDetailLevel | |
35 | { | |
36 | kLowErrorDetail, /// Logs minimal information in the error messages. | |
37 | kMediumErrorDetail, /// Logs a medium level of detail in the error messages. | |
38 | kHighErrorDetail /// Logs maximum information in the error messages. | |
39 | }; | |
e3a2b9c9 | 40 | |
41 | /// Default constructor. | |
42 | AliMUONRawStreamTrackerHP(); | |
43 | ||
44 | /// Constructor for setting the raw reader. | |
45 | AliMUONRawStreamTrackerHP(AliRawReader* rawReader); | |
46 | ||
47 | /// Default destructor. | |
48 | virtual ~AliMUONRawStreamTrackerHP(); | |
49 | ||
74585128 | 50 | /// Get object for reading the raw data |
64c2397e | 51 | virtual AliRawReader* GetReader() { return fRawReader; } |
52 | ||
53 | /// Set the raw reader | |
54 | void SetReader(AliRawReader* reader) { fRawReader = reader; } | |
74585128 | 55 | |
e3a2b9c9 | 56 | /// Initialize iterator |
57 | virtual void First(); | |
58 | ||
59 | /// DDL iterator | |
60 | virtual Bool_t NextDDL(); | |
61 | ||
62 | /// Whether the iteration is finished or not | |
63 | virtual Bool_t IsDone() const; | |
bc057b0a | 64 | |
65 | /// Advance one step in the iteration. Returns false if finished. | |
66 | virtual Bool_t Next(Int_t& busPatchId, | |
67 | UShort_t& manuId, UChar_t& manuChannel, | |
68 | UShort_t& adc) { return Next(busPatchId,manuId,manuChannel,adc,kTRUE); } | |
e3a2b9c9 | 69 | |
70 | /// Advance one step in the iteration. Returns false if finished. | |
71 | virtual Bool_t Next(Int_t& busPatchId, | |
b6f591ae | 72 | UShort_t& manuId, |
73 | UChar_t& manuChannel, | |
74 | UShort_t& adc, | |
75 | Bool_t skipParityErrors); | |
76 | ||
481d8064 | 77 | /// Construct and return a pointer to the DDL payload object. |
78 | virtual AliMUONDDLTracker* GetDDLTracker() const; | |
79 | ||
e3a2b9c9 | 80 | /// Returns the next batch of decoded channel data. |
29ee96d8 | 81 | const AliBusPatch* Next(); |
e3a2b9c9 | 82 | |
83 | /// Return maximum number of blocks per DDL allowed. | |
84 | virtual Int_t GetMaxBlock() const { return (Int_t) fDecoder.MaxBlocks(); } | |
85 | /// Return maximum number of Dsp per block allowed. | |
86 | virtual Int_t GetMaxDsp() const { return (Int_t) fDecoder.MaxDSPs(); } | |
87 | /// Return maximum number of Buspatch per Dsp allowed. | |
88 | virtual Int_t GetMaxBus() const { return (Int_t) fDecoder.MaxBusPatches(); } | |
89 | ||
90 | /// Set maximum number of blocks per DDL allowed. | |
8a0dae7c | 91 | virtual void SetMaxBlock(Int_t blk); |
e3a2b9c9 | 92 | /// Set maximum number of Dsp per block allowed. |
8a0dae7c | 93 | virtual void SetMaxDsp(Int_t dsp); |
e3a2b9c9 | 94 | /// Set maximum number of Buspatch per Dsp allowed. |
8a0dae7c | 95 | virtual void SetMaxBus(Int_t bus); |
e3a2b9c9 | 96 | |
a5f5f349 | 97 | /// Return number of the current DDL being processed in the range [0..19] or -1 if no DDL set. |
e3a2b9c9 | 98 | virtual Int_t GetDDL() const { return fDDL - 1; } |
99 | ||
100 | /// check error/Warning presence | |
101 | virtual Bool_t IsErrorMessage() const { return fHadError; } | |
8a0dae7c | 102 | |
74585128 | 103 | /// Get number of parity errors in the DDL last decoded. |
8a0dae7c | 104 | Int_t GetParityErrors() const |
105 | { | |
106 | return (Int_t) fDecoder.GetHandler().ParityErrorCount(); | |
107 | } | |
108 | ||
74585128 | 109 | /// Get number of glitch errors in the DDL last decoded. |
8a0dae7c | 110 | Int_t GetGlitchErrors() const |
111 | { | |
112 | return (Int_t) fDecoder.GetHandler().GlitchErrorCount(); | |
113 | } | |
114 | ||
74585128 | 115 | /// Get number of padding word errors in the DDL last decoded. |
8a0dae7c | 116 | Int_t GetPaddingErrors() const |
117 | { | |
118 | return (Int_t) fDecoder.GetHandler().PaddingErrorCount(); | |
119 | } | |
120 | ||
74585128 | 121 | /// Get number of token lost errors in the DDL last decoded. |
122 | Int_t GetTokenLostErrors() const | |
123 | { | |
124 | return (Int_t) fDecoder.GetHandler().TokenLostCount(); | |
125 | } | |
126 | ||
8a0dae7c | 127 | /// Set warnings flag to disable warnings on data errors. |
64c2397e | 128 | void DisableWarnings() { fWarnings = kFALSE; } |
8a0dae7c | 129 | /// Set warnings flag to enable warnings on data errors. |
64c2397e | 130 | void EnableWarnings() { fWarnings = kTRUE; } |
131 | ||
52ce8802 | 132 | /// Returns the flag indicating if we should generate a warning for errors. |
64c2397e | 133 | Bool_t IsWarningsEnabled() const { return fWarnings; } |
8a0dae7c | 134 | |
135 | /// Returns the "try to recover from errors" flag. | |
136 | Bool_t TryRecover() const { return Bool_t(fDecoder.TryRecover()); } | |
137 | ||
138 | /// Sets the "try to recover from errors" flag. | |
139 | /// i.e. should the decoder try to recover from errors found in the | |
140 | /// payload headers. | |
141 | void TryRecover(Bool_t value) { fDecoder.TryRecover(bool(value)); } | |
142 | ||
29b6be6a | 143 | /// Returns the auto-detect trailer words flag. |
144 | Bool_t AutoDetectTrailer() const { return Bool_t(fDecoder.AutoDetectTrailer()); } | |
145 | ||
146 | /// Sets the auto-detect trailer words flag. | |
147 | /// When set to true the decoder will try to detect if the end of DDL | |
148 | /// keys are in the trailer words or not. These are generated by the | |
149 | /// detector but not the older versions of AliRoot simulations. | |
150 | void AutoDetectTrailer(Bool_t value) { fDecoder.AutoDetectTrailer(bool(value)); } | |
151 | ||
152 | /// Returns the flag indicating if the data is expected to have the | |
153 | /// end of DDL keys in the trailer. This flag is ignored if AutoDetectTrailer() | |
154 | /// was set to true. | |
155 | Bool_t CheckForTrailer() const { return Bool_t(fDecoder.CheckForTrailer()); } | |
156 | ||
157 | /// Sets the flag indicating if the trailer words should contain the | |
158 | /// end of DDL key. | |
159 | void CheckForTrailer(Bool_t value) { fDecoder.CheckForTrailer(bool(value)); } | |
160 | ||
8a0dae7c | 161 | /// Light weight interface class to the block header data. |
162 | class AliBlockHeader | |
163 | { | |
164 | public: | |
165 | /// Default constructor. | |
166 | AliBlockHeader( | |
167 | AliDspHeader* dspArray = NULL, | |
168 | const AliMUONBlockHeaderStruct* header = NULL | |
169 | ) | |
170 | : fNext(NULL), fDspCount(0), fFirstDsp(dspArray), fHeader(header) | |
171 | { | |
172 | } | |
173 | ||
174 | /// Implement shallow copying in the copy constructor. | |
175 | AliBlockHeader(const AliBlockHeader& o) : | |
176 | fNext(o.fNext), fDspCount(o.fDspCount), fFirstDsp(o.fFirstDsp), fHeader(o.fHeader) | |
177 | { | |
178 | } | |
179 | ||
180 | /// Implement shallow copying in the assignment operator. | |
181 | AliBlockHeader& operator = (const AliBlockHeader& object) | |
182 | { | |
183 | memcpy(this, &object, sizeof(AliBlockHeader)); | |
184 | return *this; | |
185 | } | |
186 | ||
187 | /// Default destructor. | |
188 | ~AliBlockHeader() {}; | |
189 | ||
190 | /// Return data key word for CRT header | |
191 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
192 | /// Return total length of block structure (w/o padding word) | |
193 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
194 | /// Return length of raw data | |
195 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
196 | /// Return Dsp id | |
197 | Int_t GetDspId() const {assert(fHeader != NULL); return fHeader->fDSPId;} | |
198 | /// Return L0 trigger word | |
199 | Int_t GetL0Trigger() const {assert(fHeader != NULL); return fHeader->fL0Trigger;} | |
200 | /// Return Bunch Crossing for mini-event id (see TDR chapter 8) | |
201 | Int_t GetMiniEventId() const {assert(fHeader != NULL); return fHeader->fMiniEventId;} | |
202 | /// Return Event Id in bunch crossing | |
203 | Int_t GetEventId1() const {assert(fHeader != NULL); return fHeader->fEventId1;} | |
204 | /// Return Event Id in orbit number | |
205 | Int_t GetEventId2() const {assert(fHeader != NULL); return fHeader->fEventId2;} | |
206 | ||
207 | /// Return the header's raw data. | |
29ee96d8 | 208 | const AliMUONBlockHeaderStruct* GetHeader() const {return fHeader;} |
8a0dae7c | 209 | |
210 | /// Return the next block header. | |
211 | const AliBlockHeader* Next() const { return fNext; } | |
212 | ||
213 | /// Returns the first AliDspHeader class in this block. | |
214 | const AliDspHeader* GetFirstDspHeader() const { return fFirstDsp; } | |
215 | ||
216 | /// Returns the number of DSPs within this block. | |
217 | UInt_t GetDspCount() const { return fDspCount; } | |
218 | ||
219 | /// Return the i'th DSP in this block. | |
220 | const AliDspHeader* GetDspHeader(UInt_t i) const | |
221 | { | |
222 | return i < fDspCount ? GetFirstDspHeader() + i : NULL; | |
223 | } | |
224 | ||
225 | /// Sets the next block header. | |
226 | void SetNext(const AliBlockHeader* next) { fNext = next; } | |
227 | ||
228 | /// Increments the DSP count. | |
229 | void IncDspCount() { fDspCount++; }; | |
230 | ||
231 | /// Print the contents of the header to screen. | |
232 | void Print() const; | |
233 | ||
234 | private: | |
235 | ||
236 | const AliBlockHeader* fNext; ///< Pointer to next block. | |
237 | UInt_t fDspCount; ///< The number of AliDspHeader objects found in the array pointed to by fFirstDsp. | |
238 | const AliDspHeader* fFirstDsp; ///< The first DSP associated with this block. | |
239 | const AliMUONBlockHeaderStruct* fHeader; ///< Pointer to header in DDL payload. | |
240 | }; | |
241 | ||
242 | /// Light weight interface class to the DSP header data. | |
243 | class AliDspHeader | |
244 | { | |
245 | public: | |
246 | /// Default constructor. | |
247 | AliDspHeader( | |
248 | const AliBlockHeader* block = NULL, | |
249 | const AliBusPatch* busPatchArray = NULL, | |
250 | const AliMUONDSPHeaderStruct* header = NULL | |
251 | ) : | |
252 | fBlock(block), fNext(NULL), fBusPatchCount(0), | |
253 | fFirstBusPatch(busPatchArray), fHeader(header) | |
254 | { | |
255 | } | |
256 | ||
257 | /// Implement shallow copying in the copy constructor. | |
258 | AliDspHeader(const AliDspHeader& o) : | |
259 | fBlock(o.fBlock), fNext(o.fNext), fBusPatchCount(o.fBusPatchCount), | |
260 | fFirstBusPatch(o.fFirstBusPatch), fHeader(o.fHeader) | |
261 | { | |
262 | } | |
263 | ||
264 | /// Implement shallow copying in the assignment operator. | |
265 | AliDspHeader& operator = (const AliDspHeader& object) | |
266 | { | |
267 | memcpy(this, &object, sizeof(AliDspHeader)); | |
268 | return *this; | |
269 | } | |
270 | ||
271 | /// Default destructor. | |
272 | ~AliDspHeader() {}; | |
273 | ||
274 | /// Return Data key word for FRT header | |
275 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
276 | /// Return total length of block structure | |
277 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
278 | /// Return length of raw data | |
279 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
280 | /// Return Dsp id | |
281 | Int_t GetDspId() const {assert(fHeader != NULL); return fHeader->fDSPId;} | |
282 | /// Return L1 accept in Block Structure (CRT) | |
283 | Int_t GetBlkL1ATrigger() const {assert(fHeader != NULL); return fHeader->fBlkL1ATrigger;} | |
284 | /// Return Mini Event Id in bunch crossing | |
285 | Int_t GetMiniEventId() const {assert(fHeader != NULL); return fHeader->fMiniEventId;} | |
286 | /// Return Number of L1 accept in DSP Structure (FRT) | |
287 | Int_t GetL1ATrigger() const {assert(fHeader != NULL); return fHeader->fL1ATrigger;} | |
288 | /// Return Number of L1 reject in DSP Structure (FRT) | |
289 | Int_t GetL1RTrigger() const {assert(fHeader != NULL); return fHeader->fL1RTrigger;} | |
290 | /// Return padding dummy word for 64 bits transfer | |
291 | UInt_t GetPaddingWord() const {assert(fHeader != NULL); return fHeader->fPaddingWord;} | |
292 | /// Return Error word | |
293 | Int_t GetErrorWord() const {assert(fHeader != NULL); return fHeader->fErrorWord;} | |
294 | ||
295 | /// Return raw data of header | |
29ee96d8 | 296 | const AliMUONDSPHeaderStruct* GetHeader() const { return fHeader; } |
8a0dae7c | 297 | |
298 | /// Return the parent block header. | |
299 | const AliBlockHeader* GetBlockHeader() const { return fBlock; } | |
300 | ||
301 | /// Return the next DSP header. | |
302 | const AliDspHeader* Next() const { return fNext; } | |
303 | ||
304 | /// Returns the first AliBusPatch class in this DSP. | |
305 | const AliBusPatch* GetFirstBusPatch() const { return fFirstBusPatch; } | |
306 | ||
307 | /// Returns the number of bus patches within this DSP. | |
308 | UInt_t GetBusPatchCount() const { return fBusPatchCount; } | |
309 | ||
310 | /// Return the i'th bus patch in this DSP. | |
311 | const AliBusPatch* GetBusPatch(UInt_t i) const | |
312 | { | |
313 | return i < fBusPatchCount ? GetFirstBusPatch() + i : NULL; | |
314 | } | |
315 | ||
316 | /// Sets the next DSP header. | |
317 | void SetNext(const AliDspHeader* next) { fNext = next; } | |
318 | ||
319 | /// Increments the bus patch count. | |
320 | void IncBusPatchCount() { fBusPatchCount++; }; | |
321 | ||
322 | /// Print the contents of the header to screen. | |
323 | void Print() const; | |
324 | ||
325 | private: | |
326 | ||
327 | const AliBlockHeader* fBlock; ///< Pointer to parent block structure. | |
328 | const AliDspHeader* fNext; ///< Pointer to next DSP. | |
329 | UInt_t fBusPatchCount; ///< The number of AliDspHeader objects found in the array pointed to by fFirstBusPatch | |
330 | const AliBusPatch* fFirstBusPatch; ///< The first bus patch of this DSP. | |
331 | const AliMUONDSPHeaderStruct* fHeader; ///< Pointer to header in DDL payload. | |
332 | }; | |
333 | ||
334 | /// Light weight interface class to the bus patch data. | |
335 | class AliBusPatch | |
336 | { | |
337 | public: | |
338 | /// Default constructor. | |
339 | AliBusPatch( | |
340 | const AliDspHeader* dsp = NULL, | |
341 | const AliMUONBusPatchHeaderStruct* header = NULL, | |
342 | const UInt_t* data = NULL, | |
343 | const Bool_t* parityOk = NULL | |
344 | ) : | |
345 | fDSP(dsp), | |
346 | fNext(NULL), | |
347 | fHeader(header), | |
348 | fData(data), | |
349 | fParityOk(parityOk) | |
350 | { | |
351 | } | |
352 | ||
353 | /// Implement shallow copying in the copy constructor. | |
354 | AliBusPatch(const AliBusPatch& o) : | |
355 | fDSP(o.fDSP), | |
356 | fNext(o.fNext), | |
357 | fHeader(o.fHeader), | |
358 | fData(o.fData), | |
359 | fParityOk(o.fParityOk) | |
360 | { | |
361 | } | |
362 | ||
363 | /// Implement shallow copying in the assignment operator. | |
364 | AliBusPatch& operator = (const AliBusPatch& object) | |
365 | { | |
366 | memcpy(this, &object, sizeof(AliBusPatch)); | |
367 | return *this; | |
368 | } | |
369 | ||
370 | /// Default destructor. | |
371 | ~AliBusPatch() {}; | |
372 | ||
373 | /// Return Data key word for bus patch header. | |
374 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
375 | /// Return total length of buspatch structure | |
376 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
377 | /// Return length of raw data | |
378 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
379 | /// Return bus patch id | |
380 | Int_t GetBusPatchId() const {assert(fHeader != NULL); return fHeader->fBusPatchId;} | |
381 | ||
382 | /// Return raw data of header | |
29ee96d8 | 383 | const AliMUONBusPatchHeaderStruct* GetHeader() const {return fHeader;} |
8a0dae7c | 384 | /// Return raw digit data |
385 | const UInt_t* GetData() const {return fData;} | |
386 | /// Returns the number of raw data words within this bus patch. | |
387 | UInt_t GetDataCount() const { return (UInt_t)GetLength(); } | |
388 | ||
389 | /// Returns the parity bit of the n'th raw data word. | |
390 | Char_t GetParity(UInt_t n) const | |
391 | { | |
29ee96d8 | 392 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 393 | return (Char_t)(fData[n] >> 31) & 0x1; |
394 | } | |
395 | ||
396 | /// Returns the MANU ID of the n'th raw data word. | |
397 | UShort_t GetManuId(UInt_t n) const | |
398 | { | |
29ee96d8 | 399 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 400 | return (UShort_t)(fData[n] >> 18) & 0x7FF; |
401 | } | |
402 | ||
403 | /// Returns the channel ID of the n'th raw data word. | |
404 | UChar_t GetChannelId(UInt_t n) const | |
405 | { | |
29ee96d8 | 406 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 407 | return (Char_t)(fData[n] >> 12) & 0x3F; |
408 | } | |
409 | ||
410 | /// Returns the charge/signal of the n'th raw data word. | |
411 | UShort_t GetCharge(UInt_t n) const | |
412 | { | |
29ee96d8 | 413 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 414 | return (UShort_t)(fData[n] & 0xFFF); |
415 | } | |
416 | ||
417 | /// Returns the n'th raw data word. | |
418 | UInt_t GetData(UInt_t n) const | |
419 | { | |
29ee96d8 | 420 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 421 | return fData[n]; |
422 | } | |
423 | ||
424 | /// Returns kTRUE if the parity of the n'th raw data word is OK | |
425 | /// and kFALSE otherwise. | |
426 | Bool_t IsParityOk(UInt_t n) const | |
427 | { | |
29ee96d8 | 428 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 429 | return fParityOk[n]; |
430 | } | |
431 | ||
432 | /// Unpacks and returns the fields of the n'th raw data word. kTRUE | |
433 | /// is returned if the data word's parity was OK and kFALSE otherwise. | |
434 | Bool_t GetData(UInt_t n, UShort_t& manuId, UChar_t& channelId, UShort_t& adc) const | |
435 | { | |
29ee96d8 | 436 | assert( fHeader != NULL && n < fHeader->fLength ); |
8a0dae7c | 437 | AliMUONTrackerDDLDecoderEventHandler::UnpackADC(fData[n], manuId, channelId, adc); |
438 | return fParityOk[n]; | |
439 | } | |
440 | ||
441 | /// Return the parent block header. | |
442 | const AliDspHeader* GetDspHeader() const { return fDSP; } | |
443 | ||
444 | /// Return the next bus patch header. | |
445 | const AliBusPatch* Next() const { return fNext; } | |
446 | ||
447 | /// Sets the next bus patch. | |
448 | void SetNext(const AliBusPatch* next) { fNext = next; } | |
449 | ||
450 | /// Print the contents of the bus patch to screen. | |
451 | void Print(const Option_t* opt = "") const; | |
452 | ||
453 | private: | |
454 | ||
455 | const AliDspHeader* fDSP; ///< The DSP this bus patch belongs to. | |
456 | const AliBusPatch* fNext; ///< Next bus patch object in the DSP. | |
457 | const AliMUONBusPatchHeaderStruct* fHeader; ///< Pointer to bus patch in DDL payload. | |
458 | const UInt_t* fData; ///< Pointer to the bus patch data. | |
459 | const Bool_t* fParityOk; ///< Array of flags indicating if the parity of the given data word in fData is good or not. | |
460 | }; | |
461 | ||
462 | /// Return the number of blocks in the DDL payload. | |
463 | UInt_t GetBlockCount() const | |
464 | { | |
465 | return fDecoder.GetHandler().BlockCount(); | |
466 | } | |
467 | ||
468 | /// Return the first block header. | |
469 | const AliBlockHeader* GetFirstBlockHeader() const | |
470 | { | |
471 | return fDecoder.GetHandler().BlockHeader(0); | |
472 | } | |
473 | ||
474 | /// Return the i'th block header or NULL if not found. | |
475 | const AliBlockHeader* GetBlockHeader(UInt_t i) const | |
476 | { | |
477 | return fDecoder.GetHandler().BlockHeader(i); | |
478 | } | |
479 | ||
480 | /// Returns the number of DSPs for the given block number. | |
481 | UInt_t GetDspCount(UInt_t block) const | |
482 | { | |
483 | const AliBlockHeader* b = GetBlockHeader(block); | |
484 | return b != NULL ? b->GetDspCount() : 0; | |
485 | } | |
486 | ||
487 | /// Returns the i'th DSP header for the given block number or NULL if not found. | |
488 | const AliDspHeader* GetDspHeader(UInt_t block, UInt_t i) const | |
489 | { | |
490 | const AliBlockHeader* b = GetBlockHeader(block); | |
491 | return b != NULL ? b->GetDspHeader(i) : NULL; | |
492 | } | |
493 | ||
494 | /// Returns the number of bus patches for the given block and dsp number. | |
495 | UInt_t GetBusPatchCount(UInt_t block, UInt_t dsp) const | |
496 | { | |
497 | const AliDspHeader* d = GetDspHeader(block, dsp); | |
498 | return d != NULL ? d->GetBusPatchCount() : 0; | |
499 | } | |
500 | ||
501 | /// Returns the i'th bus patch for the given block and dsp. | |
502 | const AliBusPatch* GetBusPatch(UInt_t block, UInt_t dsp, UInt_t i) const | |
503 | { | |
504 | const AliDspHeader* d = GetDspHeader(block, dsp); | |
505 | return d != NULL ? d->GetBusPatch(i) : NULL; | |
506 | } | |
507 | ||
508 | /// Returns the current bus patch being decoded or NULL if none found. | |
509 | const AliBusPatch* CurrentBusPatch() const | |
510 | { | |
586dda01 | 511 | return (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ? |
512 | fkCurrentBusPatch : NULL; | |
8a0dae7c | 513 | } |
514 | ||
515 | /// Returns the current DSP being decoded or NULL if none found. | |
516 | const AliDspHeader* CurrentDspHeader() const | |
517 | { | |
518 | const AliBusPatch* busPatch = CurrentBusPatch(); | |
519 | return (busPatch != NULL) ? busPatch->GetDspHeader() : NULL; | |
520 | } | |
521 | ||
522 | /// Returns the current block header being decoded or NULL if none found. | |
523 | const AliBlockHeader* CurrentBlockHeader() const | |
524 | { | |
525 | const AliDspHeader* dsp = CurrentDspHeader(); | |
526 | return (dsp != NULL) ? dsp->GetBlockHeader() : NULL; | |
527 | } | |
74585128 | 528 | |
64c2397e | 529 | /// Enable error logging to the raw reader. \note Kept for backward compatibility. |
530 | virtual void EnabbleErrorLogger() { EnableRawReaderErrorLogger(); } | |
531 | ||
532 | /// Enable error info logging to AliMUONLogger. | |
533 | void EnableMUONErrorLogger() { fEnableMUONErrorLogger = kTRUE; } | |
534 | ||
535 | /// Disable logging to AliMUONLogger. | |
536 | void DisableMUONErrorLogger() { fEnableMUONErrorLogger = kFALSE; } | |
537 | ||
538 | /// Enable error info logging to raw reader. | |
539 | void EnableRawReaderErrorLogger() { fEnableRawReaderErrorLogger = kTRUE; } | |
540 | ||
541 | /// Disable logging to the raw reader. | |
542 | void DisableRawReaderErrorLogger() { fEnableRawReaderErrorLogger = kFALSE; } | |
74585128 | 543 | |
64c2397e | 544 | /// Check if the AliMUONLogger is enabled for error logging. |
545 | Bool_t IsMUONErrorLoggerEnabled() const { return fEnableMUONErrorLogger; } | |
74585128 | 546 | |
64c2397e | 547 | /// Check if the AliMUONLogger is enabled for error logging. |
548 | Bool_t IsRawReaderErrorLoggerEnabled() const { return fEnableRawReaderErrorLogger; } | |
549 | ||
550 | /// Returns the logger object. (constant version) | |
551 | const AliMUONLogger* GetMUONErrorLogger() const { return fLogger; } | |
552 | ||
553 | /// Returns the logger object. | |
554 | AliMUONLogger* GetMUONErrorLogger() { return fLogger; } | |
555 | ||
556 | /// Sets the logger object to use. Ownership of the logger object remains with the caller. | |
557 | void SetMUONErrorLogger(AliMUONLogger* logger) { fLogger = logger; } | |
558 | ||
559 | /// Returns the level of detail used in the error messages. | |
560 | EDetailLevel GetLoggingDetailLevel() const { return fDetailLevel; } | |
561 | ||
562 | /// Sets the level of detail used in the error messages. | |
563 | void SetLoggingDetailLevel(EDetailLevel level) { fDetailLevel = level; } | |
74585128 | 564 | |
565 | /// Number of glitch errors since First() was called | |
566 | UInt_t NumberOfGlitchErrors() const { return fTotalNumberOfGlitchErrors; } | |
567 | ||
568 | /// Number of padding errors since First() was called | |
569 | UInt_t NumberOfPaddingErrors() const { return fTotalNumberOfPaddingErrors; } | |
570 | ||
571 | /// Number of parity errors since First() was called | |
572 | UInt_t NumberOfParityErrors() const { return fTotalNumberOfParityErrors; } | |
573 | ||
574 | /// Number of token lost errors since First() was called | |
575 | UInt_t NumberOfTokenLostErrors() const { return fTotalNumberOfTokenLostErrors; } | |
576 | ||
577 | /// Whether we got glitch errors or not | |
578 | Bool_t HasGlitchError() const { return NumberOfGlitchErrors() > 0; } | |
579 | ||
580 | /// Whether we got padding errors or not | |
581 | Bool_t HasPaddingError() const { return NumberOfPaddingErrors() > 0; } | |
582 | ||
583 | /// Whether we got parity errors or not | |
584 | Bool_t HasParityError() const { return NumberOfParityErrors() > 0; } | |
585 | ||
586 | /// Whether we got token lost errors or not | |
587 | Bool_t HasTokenLostError() const { return NumberOfTokenLostErrors() > 0; } | |
b6f591ae | 588 | |
e3a2b9c9 | 589 | private: |
590 | ||
591 | // Do not allow copying of this class. | |
592 | /// Not implemented | |
593 | AliMUONRawStreamTrackerHP(const AliMUONRawStreamTrackerHP& stream); | |
594 | /// Not implemented | |
595 | AliMUONRawStreamTrackerHP& operator = (const AliMUONRawStreamTrackerHP& stream); | |
596 | ||
cddcc1f3 | 597 | /// Return max number of tracker DDLs |
598 | Int_t GetMaxDDL() const { return fgkMaxDDL; } | |
64c2397e | 599 | |
600 | /// swap method for Power PC | |
601 | virtual void Swap(UInt_t* buffer, Int_t size) const; | |
602 | ||
e3a2b9c9 | 603 | /// This is the custom event handler (callback interface) class which |
604 | /// unpacks raw data words and fills an internal buffer with decoded digits | |
605 | /// as they are decoded by the high performance decoder. | |
e3a2b9c9 | 606 | class AliDecoderEventHandler : public AliMUONTrackerDDLDecoderEventHandler |
607 | { | |
608 | public: | |
609 | ||
610 | /// Default constructor. | |
611 | AliDecoderEventHandler(); | |
612 | /// Default destructor. | |
613 | virtual ~AliDecoderEventHandler(); | |
614 | ||
8a0dae7c | 615 | /// Sets the internal arrays based on the maximum number of structures allowed. |
616 | void SetMaxStructs(UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches); | |
617 | ||
64c2397e | 618 | /// Sets the raw stream object which should be the parent of this class. |
619 | void SetRawStream(AliMUONRawStreamTrackerHP* rawStream) { fRawStream = rawStream; } | |
620 | ||
8a0dae7c | 621 | /// Return the number of blocks found in the payload. |
622 | UInt_t BlockCount() const { return fBlockCount; }; | |
e3a2b9c9 | 623 | |
8a0dae7c | 624 | /// Return the i'th block structure. |
625 | const AliBlockHeader* BlockHeader(UInt_t i) const | |
626 | { | |
627 | return i < fBlockCount ? &fBlocks[i] : NULL; | |
628 | } | |
629 | ||
630 | /// Return the first bus patch decoded. | |
631 | const AliBusPatch* FirstBusPatch() const { return fBusPatches; } | |
632 | ||
633 | /// Returns the marker to the end of bus patches. i.e. one position past the last bus patch. | |
634 | const AliBusPatch* EndOfBusPatch() const { return fEndOfBusPatches; } | |
635 | ||
636 | /// Returns the number of parity errors found in the DDL. | |
637 | UInt_t ParityErrorCount() const { return fParityErrors; } | |
638 | /// Returns the number of glitch errors found in the DDL. | |
639 | UInt_t GlitchErrorCount() const { return fGlitchErrors; } | |
640 | /// Returns the number of padding errors found in the DDL. | |
641 | UInt_t PaddingErrorCount() const { return fPaddingErrors; } | |
74585128 | 642 | /// Returns the number of token lost errors found in the DDL. |
643 | UInt_t TokenLostCount() const { return fTokenLostErrors; } | |
e3a2b9c9 | 644 | |
645 | // The following methods are inherited from AliMUONTrackerDDLDecoderEventHandler: | |
646 | ||
647 | /// New buffer handler. | |
648 | void OnNewBuffer(const void* buffer, UInt_t bufferSize); | |
8a0dae7c | 649 | |
650 | /// End of buffer handler marks the end of bus patches. | |
651 | void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/) | |
652 | { | |
653 | fEndOfBusPatches = fCurrentBusPatch+1; | |
654 | } | |
655 | ||
656 | /// New block handler is called by the decoder whenever a new block | |
657 | /// structure is found. We just mark the new block and increment the | |
658 | /// internal counter. | |
29ee96d8 | 659 | void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/); |
8a0dae7c | 660 | |
661 | /// New DSP handler is called by the decoder whenever a new DSP | |
662 | /// structure is found. We just mark the DSP and increment the | |
663 | /// appropriate counters. | |
29ee96d8 | 664 | void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/); |
e3a2b9c9 | 665 | |
666 | /// New bus patch handler. | |
8a0dae7c | 667 | /// This is called by the high performance decoder when a new bus patch |
668 | /// is found within the DDL payload. | |
29ee96d8 | 669 | void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data); |
e3a2b9c9 | 670 | |
671 | /// Raw data word handler. | |
8a0dae7c | 672 | void OnData(UInt_t /*data*/, bool parityError) |
673 | { | |
674 | assert( fCurrentParityOkFlag < fParityOk + fMaxChannels ); | |
675 | *(++fCurrentParityOkFlag) = Bool_t(not parityError); | |
676 | } | |
e3a2b9c9 | 677 | |
678 | /// Error handler. | |
679 | void OnError(ErrorCode error, const void* location); | |
680 | ||
681 | private: | |
682 | ||
683 | // Do not allow copying of this class. | |
684 | /// Not implemented | |
685 | AliDecoderEventHandler(const AliDecoderEventHandler& /*obj*/); | |
686 | /// Not implemented | |
687 | AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/); | |
688 | ||
64c2397e | 689 | AliMUONRawStreamTrackerHP* fRawStream; //!< Pointer to the parent raw stream object. |
e3a2b9c9 | 690 | const void* fBufferStart; //!< Pointer to the start of the current DDL payload buffer. |
8a0dae7c | 691 | UInt_t fBlockCount; //!< Number of blocks filled in fBlocks. |
692 | AliBlockHeader* fBlocks; //!< Array of blocks. [0..fMaxBlocks-1] | |
693 | AliDspHeader* fDSPs; //!< Array of DSPs. [0..fMaxDsps*fMaxBlocks-1] | |
694 | AliBusPatch* fBusPatches; //!< Array of bus patches. [0..fMaxBusPatches*fMaxDsps*fMaxBlocks-1] | |
695 | AliBusPatch* fEndOfBusPatches; //!< Marks the last bus patch. | |
696 | UInt_t fMaxChannels; //!< Maximum number of elements that can be stored in fParityOk. | |
697 | Bool_t* fParityOk; //!< Array of flags for indicating if the parity is good for a raw data word. | |
698 | AliBlockHeader* fCurrentBlock; //!< Current block in fBlocks. | |
699 | AliDspHeader* fCurrentDSP; //!< Current DSP in fDSPs. | |
700 | AliBusPatch* fCurrentBusPatch; //!< Current bus patch in fBusPatches. | |
701 | Bool_t* fCurrentParityOkFlag; //!< Current parity flag to be set in fParityOk. | |
702 | UInt_t fParityErrors; //!< Number of parity errors found in DDL. | |
703 | UInt_t fGlitchErrors; //!< Number of glitch errors found in DDL. | |
704 | UInt_t fPaddingErrors; //!< Number of padding errors found in DDL. | |
74585128 | 705 | UInt_t fTokenLostErrors; //!< Number of token lost errors found in DDL. |
74585128 | 706 | UInt_t fMaxBlocks; //!< max number of blocks |
707 | UInt_t fMaxDsps; //!< max number of dsps per block | |
708 | UInt_t fMaxBusPatches; //!< max number of buspatches per dsp | |
e3a2b9c9 | 709 | }; |
b6f591ae | 710 | |
64c2397e | 711 | AliRawReader* fRawReader; //!< Pointer to the raw reader |
712 | AliMUONLogger* fLogger; //!< Logger object to store error messages. | |
713 | EDetailLevel fDetailLevel; //!< The logging detail level used in the error messages generated in OnError. | |
714 | Bool_t fEnableMUONErrorLogger; //!< whether or not we log errors to AliMUONLogger | |
715 | Bool_t fEnableRawReaderErrorLogger; //!< whether or not we log errors to the raw reader. | |
716 | Bool_t fWarnings; //!< Flag indicating if we should generate a warning for errors. | |
e3a2b9c9 | 717 | AliMUONTrackerDDLDecoder<AliDecoderEventHandler> fDecoder; //!< The decoder for the DDL payload. |
718 | Int_t fDDL; //!< The current DDL number being handled. | |
e3a2b9c9 | 719 | Int_t fBufferSize; //!< This is the buffer size in bytes of fBuffer. |
720 | UChar_t* fBuffer; //!< This is the buffer in which we store the DDL payload read from AliRawReader. | |
586dda01 | 721 | const AliBusPatch* fkCurrentBusPatch; //!< The current bus patch being handled by Next(). |
722 | const UInt_t* fkCurrentData; //!< The current data word to return by Next(). | |
723 | const UInt_t* fkEndOfData; //!< The last data word in the current bus patch. | |
e3a2b9c9 | 724 | Bool_t fHadError; //!< Flag indicating if there was a decoding error or not. |
8a0dae7c | 725 | Bool_t fDone; //!< Flag indicating if the iteration is done or not. |
481d8064 | 726 | mutable AliMUONDDLTracker* fDDLObject; //!< Temporary DDL object used by GetDDLTracker() for caching. |
74585128 | 727 | UInt_t fTotalNumberOfGlitchErrors; //!< number of glitch errors since First() was called |
728 | UInt_t fTotalNumberOfParityErrors; //!< number of parity errors since First() was called | |
729 | UInt_t fTotalNumberOfPaddingErrors; //!< number of padding errors since First() was called | |
730 | UInt_t fTotalNumberOfTokenLostErrors; //!< number of token lost errors since First() was called | |
731 | ||
732 | static const Int_t fgkMaxDDL; //!< max number of tracker DDLs | |
e3a2b9c9 | 733 | |
734 | ClassDef(AliMUONRawStreamTrackerHP, 0) // High performance decoder for reading MUON raw digits from tracking chamber DDL data. | |
735 | }; | |
736 | ||
29ee96d8 | 737 | //////////////////////////////////////////////////////////////////////////////// |
738 | ||
739 | inline const AliMUONRawStreamTrackerHP::AliBusPatch* AliMUONRawStreamTrackerHP::Next() | |
740 | { | |
741 | /// Returns the next batch of decoded channel data. | |
586dda01 | 742 | if (fkCurrentBusPatch == NULL) return NULL; |
29ee96d8 | 743 | do { |
586dda01 | 744 | if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) |
745 | return fkCurrentBusPatch++; | |
29ee96d8 | 746 | } while (NextDDL()); |
747 | return NULL; | |
748 | } | |
749 | ||
750 | inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBlock( | |
751 | const AliMUONBlockHeaderStruct* header, const void* /*data*/ | |
752 | ) | |
753 | { | |
754 | /// New block handler is called by the decoder whenever a new block | |
755 | /// structure is found. We just mark the new block and increment the | |
756 | /// internal counter. | |
757 | ||
758 | assert( header != NULL ); | |
b6f591ae | 759 | assert( fBlockCount < fMaxBlocks ); |
29ee96d8 | 760 | // Link the block unless it is the first one. |
761 | if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1); | |
762 | *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header); | |
763 | fBlockCount++; | |
764 | } | |
765 | ||
766 | inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewDSP( | |
767 | const AliMUONDSPHeaderStruct* header, const void* /*data*/ | |
768 | ) | |
769 | { | |
770 | /// New DSP handler is called by the decoder whenever a new DSP | |
771 | /// structure is found. We just mark the DSP and increment the | |
772 | /// appropriate counters. | |
773 | ||
774 | assert( header != NULL ); | |
b6f591ae | 775 | assert( fCurrentBlock->GetDspCount() < fMaxDsps ); |
29ee96d8 | 776 | // Link the DSP unless it is the first one. |
777 | if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1); | |
778 | *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header); | |
779 | fCurrentBlock->IncDspCount(); | |
780 | } | |
781 | ||
782 | inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBusPatch( | |
783 | const AliMUONBusPatchHeaderStruct* header, const void* data | |
784 | ) | |
785 | { | |
786 | /// New bus patch handler. | |
787 | /// This is called by the high performance decoder when a new bus patch | |
788 | /// is found within the DDL payload. | |
789 | ||
790 | assert( header != NULL ); | |
791 | assert( data != NULL ); | |
b6f591ae | 792 | assert( fCurrentDSP->GetBusPatchCount() < fMaxBusPatches ); |
29ee96d8 | 793 | // Link the bus patch unless it is the first one. |
794 | if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1); | |
795 | *(++fCurrentBusPatch) = AliBusPatch( | |
796 | fCurrentDSP, | |
797 | header, | |
798 | reinterpret_cast<const UInt_t*>(data), | |
799 | fCurrentParityOkFlag+1 | |
800 | ); | |
801 | fCurrentDSP->IncBusPatchCount(); | |
802 | } | |
803 | ||
e3a2b9c9 | 804 | #endif // ALIMUONRAWSTREAMTRACKERHP_H |
8a0dae7c | 805 |