]>
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 | ||
16 | #include "AliMUONVRawStreamTracker.h" | |
17 | #include "AliMUONTrackerDDLDecoder.h" | |
18 | ||
19 | class AliMUONRawStreamTrackerHP : public AliMUONVRawStreamTracker | |
20 | { | |
21 | public: | |
8a0dae7c | 22 | class AliDspHeader; |
23 | class AliBusPatch; | |
e3a2b9c9 | 24 | |
25 | /// Default constructor. | |
26 | AliMUONRawStreamTrackerHP(); | |
27 | ||
28 | /// Constructor for setting the raw reader. | |
29 | AliMUONRawStreamTrackerHP(AliRawReader* rawReader); | |
30 | ||
31 | /// Default destructor. | |
32 | virtual ~AliMUONRawStreamTrackerHP(); | |
33 | ||
34 | // The following public methods are all inherited from AliMUONVRawStreamTracker: | |
35 | ||
36 | /// Initialize iterator | |
37 | virtual void First(); | |
38 | ||
39 | /// DDL iterator | |
40 | virtual Bool_t NextDDL(); | |
41 | ||
42 | /// Whether the iteration is finished or not | |
43 | virtual Bool_t IsDone() const; | |
44 | ||
45 | /// Nothing is actually done in the AddErrorMessage method because we log | |
46 | /// the error messages as we find them in AliDecoderEventHandler::OnError(). | |
8a0dae7c | 47 | virtual void AddErrorMessage() { }; |
e3a2b9c9 | 48 | |
49 | /// Advance one step in the iteration. Returns false if finished. | |
50 | virtual Bool_t Next(Int_t& busPatchId, | |
51 | UShort_t& manuId, UChar_t& manuChannel, | |
52 | UShort_t& adc); | |
53 | ||
54 | /// Returns the next batch of decoded channel data. | |
8a0dae7c | 55 | const AliBusPatch* Next() |
56 | { | |
57 | do { | |
58 | if (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) return fCurrentBusPatch++; | |
59 | } while (NextDDL()); | |
60 | return NULL; | |
61 | } | |
e3a2b9c9 | 62 | |
63 | /// Return maximum number of blocks per DDL allowed. | |
64 | virtual Int_t GetMaxBlock() const { return (Int_t) fDecoder.MaxBlocks(); } | |
65 | /// Return maximum number of Dsp per block allowed. | |
66 | virtual Int_t GetMaxDsp() const { return (Int_t) fDecoder.MaxDSPs(); } | |
67 | /// Return maximum number of Buspatch per Dsp allowed. | |
68 | virtual Int_t GetMaxBus() const { return (Int_t) fDecoder.MaxBusPatches(); } | |
69 | ||
70 | /// Set maximum number of blocks per DDL allowed. | |
8a0dae7c | 71 | virtual void SetMaxBlock(Int_t blk); |
e3a2b9c9 | 72 | /// Set maximum number of Dsp per block allowed. |
8a0dae7c | 73 | virtual void SetMaxDsp(Int_t dsp); |
e3a2b9c9 | 74 | /// Set maximum number of Buspatch per Dsp allowed. |
8a0dae7c | 75 | virtual void SetMaxBus(Int_t bus); |
e3a2b9c9 | 76 | |
77 | /// Return number of the current DDL. | |
78 | virtual Int_t GetDDL() const { return fDDL - 1; } | |
79 | ||
80 | /// check error/Warning presence | |
81 | virtual Bool_t IsErrorMessage() const { return fHadError; } | |
8a0dae7c | 82 | |
83 | /// Get number of parity errors | |
84 | Int_t GetParityErrors() const | |
85 | { | |
86 | return (Int_t) fDecoder.GetHandler().ParityErrorCount(); | |
87 | } | |
88 | ||
89 | /// Get number of glitch errors | |
90 | Int_t GetGlitchErrors() const | |
91 | { | |
92 | return (Int_t) fDecoder.GetHandler().GlitchErrorCount(); | |
93 | } | |
94 | ||
95 | /// Get number of padding word errors | |
96 | Int_t GetPaddingErrors() const | |
97 | { | |
98 | return (Int_t) fDecoder.GetHandler().PaddingErrorCount(); | |
99 | } | |
100 | ||
101 | /// Set warnings flag to disable warnings on data errors. | |
102 | void DisableWarnings() { fDecoder.GetHandler().Warnings(kFALSE); } | |
103 | /// Set warnings flag to enable warnings on data errors. | |
104 | void EnableWarnings() { fDecoder.GetHandler().Warnings(kTRUE); } | |
105 | ||
106 | /// Returns the "try to recover from errors" flag. | |
107 | Bool_t TryRecover() const { return Bool_t(fDecoder.TryRecover()); } | |
108 | ||
109 | /// Sets the "try to recover from errors" flag. | |
110 | /// i.e. should the decoder try to recover from errors found in the | |
111 | /// payload headers. | |
112 | void TryRecover(Bool_t value) { fDecoder.TryRecover(bool(value)); } | |
113 | ||
114 | /// Light weight interface class to the block header data. | |
115 | class AliBlockHeader | |
116 | { | |
117 | public: | |
118 | /// Default constructor. | |
119 | AliBlockHeader( | |
120 | AliDspHeader* dspArray = NULL, | |
121 | const AliMUONBlockHeaderStruct* header = NULL | |
122 | ) | |
123 | : fNext(NULL), fDspCount(0), fFirstDsp(dspArray), fHeader(header) | |
124 | { | |
125 | } | |
126 | ||
127 | /// Implement shallow copying in the copy constructor. | |
128 | AliBlockHeader(const AliBlockHeader& o) : | |
129 | fNext(o.fNext), fDspCount(o.fDspCount), fFirstDsp(o.fFirstDsp), fHeader(o.fHeader) | |
130 | { | |
131 | } | |
132 | ||
133 | /// Implement shallow copying in the assignment operator. | |
134 | AliBlockHeader& operator = (const AliBlockHeader& object) | |
135 | { | |
136 | memcpy(this, &object, sizeof(AliBlockHeader)); | |
137 | return *this; | |
138 | } | |
139 | ||
140 | /// Default destructor. | |
141 | ~AliBlockHeader() {}; | |
142 | ||
143 | /// Return data key word for CRT header | |
144 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
145 | /// Return total length of block structure (w/o padding word) | |
146 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
147 | /// Return length of raw data | |
148 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
149 | /// Return Dsp id | |
150 | Int_t GetDspId() const {assert(fHeader != NULL); return fHeader->fDSPId;} | |
151 | /// Return L0 trigger word | |
152 | Int_t GetL0Trigger() const {assert(fHeader != NULL); return fHeader->fL0Trigger;} | |
153 | /// Return Bunch Crossing for mini-event id (see TDR chapter 8) | |
154 | Int_t GetMiniEventId() const {assert(fHeader != NULL); return fHeader->fMiniEventId;} | |
155 | /// Return Event Id in bunch crossing | |
156 | Int_t GetEventId1() const {assert(fHeader != NULL); return fHeader->fEventId1;} | |
157 | /// Return Event Id in orbit number | |
158 | Int_t GetEventId2() const {assert(fHeader != NULL); return fHeader->fEventId2;} | |
159 | ||
160 | /// Return the header's raw data. | |
161 | const AliMUONBlockHeaderStruct* GetHeader() {return fHeader;} | |
162 | ||
163 | /// Return the next block header. | |
164 | const AliBlockHeader* Next() const { return fNext; } | |
165 | ||
166 | /// Returns the first AliDspHeader class in this block. | |
167 | const AliDspHeader* GetFirstDspHeader() const { return fFirstDsp; } | |
168 | ||
169 | /// Returns the number of DSPs within this block. | |
170 | UInt_t GetDspCount() const { return fDspCount; } | |
171 | ||
172 | /// Return the i'th DSP in this block. | |
173 | const AliDspHeader* GetDspHeader(UInt_t i) const | |
174 | { | |
175 | return i < fDspCount ? GetFirstDspHeader() + i : NULL; | |
176 | } | |
177 | ||
178 | /// Sets the next block header. | |
179 | void SetNext(const AliBlockHeader* next) { fNext = next; } | |
180 | ||
181 | /// Increments the DSP count. | |
182 | void IncDspCount() { fDspCount++; }; | |
183 | ||
184 | /// Print the contents of the header to screen. | |
185 | void Print() const; | |
186 | ||
187 | private: | |
188 | ||
189 | const AliBlockHeader* fNext; ///< Pointer to next block. | |
190 | UInt_t fDspCount; ///< The number of AliDspHeader objects found in the array pointed to by fFirstDsp. | |
191 | const AliDspHeader* fFirstDsp; ///< The first DSP associated with this block. | |
192 | const AliMUONBlockHeaderStruct* fHeader; ///< Pointer to header in DDL payload. | |
193 | }; | |
194 | ||
195 | /// Light weight interface class to the DSP header data. | |
196 | class AliDspHeader | |
197 | { | |
198 | public: | |
199 | /// Default constructor. | |
200 | AliDspHeader( | |
201 | const AliBlockHeader* block = NULL, | |
202 | const AliBusPatch* busPatchArray = NULL, | |
203 | const AliMUONDSPHeaderStruct* header = NULL | |
204 | ) : | |
205 | fBlock(block), fNext(NULL), fBusPatchCount(0), | |
206 | fFirstBusPatch(busPatchArray), fHeader(header) | |
207 | { | |
208 | } | |
209 | ||
210 | /// Implement shallow copying in the copy constructor. | |
211 | AliDspHeader(const AliDspHeader& o) : | |
212 | fBlock(o.fBlock), fNext(o.fNext), fBusPatchCount(o.fBusPatchCount), | |
213 | fFirstBusPatch(o.fFirstBusPatch), fHeader(o.fHeader) | |
214 | { | |
215 | } | |
216 | ||
217 | /// Implement shallow copying in the assignment operator. | |
218 | AliDspHeader& operator = (const AliDspHeader& object) | |
219 | { | |
220 | memcpy(this, &object, sizeof(AliDspHeader)); | |
221 | return *this; | |
222 | } | |
223 | ||
224 | /// Default destructor. | |
225 | ~AliDspHeader() {}; | |
226 | ||
227 | /// Return Data key word for FRT header | |
228 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
229 | /// Return total length of block structure | |
230 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
231 | /// Return length of raw data | |
232 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
233 | /// Return Dsp id | |
234 | Int_t GetDspId() const {assert(fHeader != NULL); return fHeader->fDSPId;} | |
235 | /// Return L1 accept in Block Structure (CRT) | |
236 | Int_t GetBlkL1ATrigger() const {assert(fHeader != NULL); return fHeader->fBlkL1ATrigger;} | |
237 | /// Return Mini Event Id in bunch crossing | |
238 | Int_t GetMiniEventId() const {assert(fHeader != NULL); return fHeader->fMiniEventId;} | |
239 | /// Return Number of L1 accept in DSP Structure (FRT) | |
240 | Int_t GetL1ATrigger() const {assert(fHeader != NULL); return fHeader->fL1ATrigger;} | |
241 | /// Return Number of L1 reject in DSP Structure (FRT) | |
242 | Int_t GetL1RTrigger() const {assert(fHeader != NULL); return fHeader->fL1RTrigger;} | |
243 | /// Return padding dummy word for 64 bits transfer | |
244 | UInt_t GetPaddingWord() const {assert(fHeader != NULL); return fHeader->fPaddingWord;} | |
245 | /// Return Error word | |
246 | Int_t GetErrorWord() const {assert(fHeader != NULL); return fHeader->fErrorWord;} | |
247 | ||
248 | /// Return raw data of header | |
249 | const AliMUONDSPHeaderStruct* GetHeader() {return fHeader;} | |
250 | ||
251 | /// Return the parent block header. | |
252 | const AliBlockHeader* GetBlockHeader() const { return fBlock; } | |
253 | ||
254 | /// Return the next DSP header. | |
255 | const AliDspHeader* Next() const { return fNext; } | |
256 | ||
257 | /// Returns the first AliBusPatch class in this DSP. | |
258 | const AliBusPatch* GetFirstBusPatch() const { return fFirstBusPatch; } | |
259 | ||
260 | /// Returns the number of bus patches within this DSP. | |
261 | UInt_t GetBusPatchCount() const { return fBusPatchCount; } | |
262 | ||
263 | /// Return the i'th bus patch in this DSP. | |
264 | const AliBusPatch* GetBusPatch(UInt_t i) const | |
265 | { | |
266 | return i < fBusPatchCount ? GetFirstBusPatch() + i : NULL; | |
267 | } | |
268 | ||
269 | /// Sets the next DSP header. | |
270 | void SetNext(const AliDspHeader* next) { fNext = next; } | |
271 | ||
272 | /// Increments the bus patch count. | |
273 | void IncBusPatchCount() { fBusPatchCount++; }; | |
274 | ||
275 | /// Print the contents of the header to screen. | |
276 | void Print() const; | |
277 | ||
278 | private: | |
279 | ||
280 | const AliBlockHeader* fBlock; ///< Pointer to parent block structure. | |
281 | const AliDspHeader* fNext; ///< Pointer to next DSP. | |
282 | UInt_t fBusPatchCount; ///< The number of AliDspHeader objects found in the array pointed to by fFirstBusPatch | |
283 | const AliBusPatch* fFirstBusPatch; ///< The first bus patch of this DSP. | |
284 | const AliMUONDSPHeaderStruct* fHeader; ///< Pointer to header in DDL payload. | |
285 | }; | |
286 | ||
287 | /// Light weight interface class to the bus patch data. | |
288 | class AliBusPatch | |
289 | { | |
290 | public: | |
291 | /// Default constructor. | |
292 | AliBusPatch( | |
293 | const AliDspHeader* dsp = NULL, | |
294 | const AliMUONBusPatchHeaderStruct* header = NULL, | |
295 | const UInt_t* data = NULL, | |
296 | const Bool_t* parityOk = NULL | |
297 | ) : | |
298 | fDSP(dsp), | |
299 | fNext(NULL), | |
300 | fHeader(header), | |
301 | fData(data), | |
302 | fParityOk(parityOk) | |
303 | { | |
304 | } | |
305 | ||
306 | /// Implement shallow copying in the copy constructor. | |
307 | AliBusPatch(const AliBusPatch& o) : | |
308 | fDSP(o.fDSP), | |
309 | fNext(o.fNext), | |
310 | fHeader(o.fHeader), | |
311 | fData(o.fData), | |
312 | fParityOk(o.fParityOk) | |
313 | { | |
314 | } | |
315 | ||
316 | /// Implement shallow copying in the assignment operator. | |
317 | AliBusPatch& operator = (const AliBusPatch& object) | |
318 | { | |
319 | memcpy(this, &object, sizeof(AliBusPatch)); | |
320 | return *this; | |
321 | } | |
322 | ||
323 | /// Default destructor. | |
324 | ~AliBusPatch() {}; | |
325 | ||
326 | /// Return Data key word for bus patch header. | |
327 | Int_t GetDataKey() const {assert(fHeader != NULL); return fHeader->fDataKey;} | |
328 | /// Return total length of buspatch structure | |
329 | Int_t GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;} | |
330 | /// Return length of raw data | |
331 | Int_t GetLength() const {assert(fHeader != NULL); return fHeader->fLength;} | |
332 | /// Return bus patch id | |
333 | Int_t GetBusPatchId() const {assert(fHeader != NULL); return fHeader->fBusPatchId;} | |
334 | ||
335 | /// Return raw data of header | |
336 | const AliMUONBusPatchHeaderStruct* GetHeader() {return fHeader;} | |
337 | /// Return raw digit data | |
338 | const UInt_t* GetData() const {return fData;} | |
339 | /// Returns the number of raw data words within this bus patch. | |
340 | UInt_t GetDataCount() const { return (UInt_t)GetLength(); } | |
341 | ||
342 | /// Returns the parity bit of the n'th raw data word. | |
343 | Char_t GetParity(UInt_t n) const | |
344 | { | |
345 | assert( fHeader != NULL and n < fHeader->fLength ); | |
346 | return (Char_t)(fData[n] >> 31) & 0x1; | |
347 | } | |
348 | ||
349 | /// Returns the MANU ID of the n'th raw data word. | |
350 | UShort_t GetManuId(UInt_t n) const | |
351 | { | |
352 | assert( fHeader != NULL and n < fHeader->fLength ); | |
353 | return (UShort_t)(fData[n] >> 18) & 0x7FF; | |
354 | } | |
355 | ||
356 | /// Returns the channel ID of the n'th raw data word. | |
357 | UChar_t GetChannelId(UInt_t n) const | |
358 | { | |
359 | assert( fHeader != NULL and n < fHeader->fLength ); | |
360 | return (Char_t)(fData[n] >> 12) & 0x3F; | |
361 | } | |
362 | ||
363 | /// Returns the charge/signal of the n'th raw data word. | |
364 | UShort_t GetCharge(UInt_t n) const | |
365 | { | |
366 | assert( fHeader != NULL and n < fHeader->fLength ); | |
367 | return (UShort_t)(fData[n] & 0xFFF); | |
368 | } | |
369 | ||
370 | /// Returns the n'th raw data word. | |
371 | UInt_t GetData(UInt_t n) const | |
372 | { | |
373 | assert( fHeader != NULL and n < fHeader->fLength ); | |
374 | return fData[n]; | |
375 | } | |
376 | ||
377 | /// Returns kTRUE if the parity of the n'th raw data word is OK | |
378 | /// and kFALSE otherwise. | |
379 | Bool_t IsParityOk(UInt_t n) const | |
380 | { | |
381 | assert( fHeader != NULL and n < fHeader->fLength ); | |
382 | return fParityOk[n]; | |
383 | } | |
384 | ||
385 | /// Unpacks and returns the fields of the n'th raw data word. kTRUE | |
386 | /// is returned if the data word's parity was OK and kFALSE otherwise. | |
387 | Bool_t GetData(UInt_t n, UShort_t& manuId, UChar_t& channelId, UShort_t& adc) const | |
388 | { | |
389 | assert( fHeader != NULL and n < fHeader->fLength ); | |
390 | AliMUONTrackerDDLDecoderEventHandler::UnpackADC(fData[n], manuId, channelId, adc); | |
391 | return fParityOk[n]; | |
392 | } | |
393 | ||
394 | /// Return the parent block header. | |
395 | const AliDspHeader* GetDspHeader() const { return fDSP; } | |
396 | ||
397 | /// Return the next bus patch header. | |
398 | const AliBusPatch* Next() const { return fNext; } | |
399 | ||
400 | /// Sets the next bus patch. | |
401 | void SetNext(const AliBusPatch* next) { fNext = next; } | |
402 | ||
403 | /// Print the contents of the bus patch to screen. | |
404 | void Print(const Option_t* opt = "") const; | |
405 | ||
406 | private: | |
407 | ||
408 | const AliDspHeader* fDSP; ///< The DSP this bus patch belongs to. | |
409 | const AliBusPatch* fNext; ///< Next bus patch object in the DSP. | |
410 | const AliMUONBusPatchHeaderStruct* fHeader; ///< Pointer to bus patch in DDL payload. | |
411 | const UInt_t* fData; ///< Pointer to the bus patch data. | |
412 | const Bool_t* fParityOk; ///< Array of flags indicating if the parity of the given data word in fData is good or not. | |
413 | }; | |
414 | ||
415 | /// Return the number of blocks in the DDL payload. | |
416 | UInt_t GetBlockCount() const | |
417 | { | |
418 | return fDecoder.GetHandler().BlockCount(); | |
419 | } | |
420 | ||
421 | /// Return the first block header. | |
422 | const AliBlockHeader* GetFirstBlockHeader() const | |
423 | { | |
424 | return fDecoder.GetHandler().BlockHeader(0); | |
425 | } | |
426 | ||
427 | /// Return the i'th block header or NULL if not found. | |
428 | const AliBlockHeader* GetBlockHeader(UInt_t i) const | |
429 | { | |
430 | return fDecoder.GetHandler().BlockHeader(i); | |
431 | } | |
432 | ||
433 | /// Returns the number of DSPs for the given block number. | |
434 | UInt_t GetDspCount(UInt_t block) const | |
435 | { | |
436 | const AliBlockHeader* b = GetBlockHeader(block); | |
437 | return b != NULL ? b->GetDspCount() : 0; | |
438 | } | |
439 | ||
440 | /// Returns the i'th DSP header for the given block number or NULL if not found. | |
441 | const AliDspHeader* GetDspHeader(UInt_t block, UInt_t i) const | |
442 | { | |
443 | const AliBlockHeader* b = GetBlockHeader(block); | |
444 | return b != NULL ? b->GetDspHeader(i) : NULL; | |
445 | } | |
446 | ||
447 | /// Returns the number of bus patches for the given block and dsp number. | |
448 | UInt_t GetBusPatchCount(UInt_t block, UInt_t dsp) const | |
449 | { | |
450 | const AliDspHeader* d = GetDspHeader(block, dsp); | |
451 | return d != NULL ? d->GetBusPatchCount() : 0; | |
452 | } | |
453 | ||
454 | /// Returns the i'th bus patch for the given block and dsp. | |
455 | const AliBusPatch* GetBusPatch(UInt_t block, UInt_t dsp, UInt_t i) const | |
456 | { | |
457 | const AliDspHeader* d = GetDspHeader(block, dsp); | |
458 | return d != NULL ? d->GetBusPatch(i) : NULL; | |
459 | } | |
460 | ||
461 | /// Returns the current bus patch being decoded or NULL if none found. | |
462 | const AliBusPatch* CurrentBusPatch() const | |
463 | { | |
464 | return (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ? | |
465 | fCurrentBusPatch : NULL; | |
466 | } | |
467 | ||
468 | /// Returns the current DSP being decoded or NULL if none found. | |
469 | const AliDspHeader* CurrentDspHeader() const | |
470 | { | |
471 | const AliBusPatch* busPatch = CurrentBusPatch(); | |
472 | return (busPatch != NULL) ? busPatch->GetDspHeader() : NULL; | |
473 | } | |
474 | ||
475 | /// Returns the current block header being decoded or NULL if none found. | |
476 | const AliBlockHeader* CurrentBlockHeader() const | |
477 | { | |
478 | const AliDspHeader* dsp = CurrentDspHeader(); | |
479 | return (dsp != NULL) ? dsp->GetBlockHeader() : NULL; | |
480 | } | |
e3a2b9c9 | 481 | |
482 | private: | |
483 | ||
484 | // Do not allow copying of this class. | |
485 | /// Not implemented | |
486 | AliMUONRawStreamTrackerHP(const AliMUONRawStreamTrackerHP& stream); | |
487 | /// Not implemented | |
488 | AliMUONRawStreamTrackerHP& operator = (const AliMUONRawStreamTrackerHP& stream); | |
489 | ||
490 | /// This is the custom event handler (callback interface) class which | |
491 | /// unpacks raw data words and fills an internal buffer with decoded digits | |
492 | /// as they are decoded by the high performance decoder. | |
493 | /// Any errors are logged to the parent AliMUONVRawStreamTracker, so one | |
494 | /// must set this pointer appropriately before decoding and DDL payload. | |
495 | class AliDecoderEventHandler : public AliMUONTrackerDDLDecoderEventHandler | |
496 | { | |
497 | public: | |
498 | ||
499 | /// Default constructor. | |
500 | AliDecoderEventHandler(); | |
501 | /// Default destructor. | |
502 | virtual ~AliDecoderEventHandler(); | |
503 | ||
8a0dae7c | 504 | /// Sets the internal arrays based on the maximum number of structures allowed. |
505 | void SetMaxStructs(UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches); | |
506 | ||
e3a2b9c9 | 507 | /// Sets the raw stream object which should be the parent of this class. |
508 | void SetRawStream(AliMUONVRawStreamTracker* rawStream) { fRawStream = rawStream; } | |
509 | ||
8a0dae7c | 510 | /// Return the number of blocks found in the payload. |
511 | UInt_t BlockCount() const { return fBlockCount; }; | |
e3a2b9c9 | 512 | |
8a0dae7c | 513 | /// Return the i'th block structure. |
514 | const AliBlockHeader* BlockHeader(UInt_t i) const | |
515 | { | |
516 | return i < fBlockCount ? &fBlocks[i] : NULL; | |
517 | } | |
518 | ||
519 | /// Return the first bus patch decoded. | |
520 | const AliBusPatch* FirstBusPatch() const { return fBusPatches; } | |
521 | ||
522 | /// Returns the marker to the end of bus patches. i.e. one position past the last bus patch. | |
523 | const AliBusPatch* EndOfBusPatch() const { return fEndOfBusPatches; } | |
524 | ||
525 | /// Returns the number of parity errors found in the DDL. | |
526 | UInt_t ParityErrorCount() const { return fParityErrors; } | |
527 | /// Returns the number of glitch errors found in the DDL. | |
528 | UInt_t GlitchErrorCount() const { return fGlitchErrors; } | |
529 | /// Returns the number of padding errors found in the DDL. | |
530 | UInt_t PaddingErrorCount() const { return fPaddingErrors; } | |
531 | ||
532 | /// Returns the warnings flag. | |
533 | Bool_t Warnings() const { return fWarnings; } | |
534 | /// Sets the warnings flag. | |
535 | void Warnings(Bool_t value) { fWarnings = value; } | |
e3a2b9c9 | 536 | |
537 | // The following methods are inherited from AliMUONTrackerDDLDecoderEventHandler: | |
538 | ||
539 | /// New buffer handler. | |
540 | void OnNewBuffer(const void* buffer, UInt_t bufferSize); | |
8a0dae7c | 541 | |
542 | /// End of buffer handler marks the end of bus patches. | |
543 | void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/) | |
544 | { | |
545 | fEndOfBusPatches = fCurrentBusPatch+1; | |
546 | } | |
547 | ||
548 | /// New block handler is called by the decoder whenever a new block | |
549 | /// structure is found. We just mark the new block and increment the | |
550 | /// internal counter. | |
551 | void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/) | |
552 | { | |
553 | assert( fBlockCount < (UInt_t)fRawStream->GetMaxBlock() and header != NULL ); | |
554 | if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1); // Link the block unless it is the first one. | |
555 | *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header); | |
556 | fBlockCount++; | |
557 | } | |
558 | ||
559 | /// New DSP handler is called by the decoder whenever a new DSP | |
560 | /// structure is found. We just mark the DSP and increment the | |
561 | /// appropriate counters. | |
562 | void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/) | |
563 | { | |
564 | assert( fCurrentBlock->GetDspCount() < (UInt_t)fRawStream->GetMaxDsp() and header != NULL ); | |
565 | if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1); // Link the DSP unless it is the first one. | |
566 | *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header); | |
567 | fCurrentBlock->IncDspCount(); | |
568 | } | |
e3a2b9c9 | 569 | |
570 | /// New bus patch handler. | |
8a0dae7c | 571 | /// This is called by the high performance decoder when a new bus patch |
572 | /// is found within the DDL payload. | |
573 | void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data) | |
574 | { | |
575 | assert( fCurrentDSP->GetBusPatchCount() < (UInt_t)fRawStream->GetMaxBus() and header != NULL and data != NULL ); | |
576 | if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1); // Link the bus patch unless it is the first one. | |
577 | *(++fCurrentBusPatch) = AliBusPatch(fCurrentDSP, header, reinterpret_cast<const UInt_t*>(data), fCurrentParityOkFlag+1); | |
578 | fCurrentDSP->IncBusPatchCount(); | |
579 | } | |
e3a2b9c9 | 580 | |
581 | /// Raw data word handler. | |
8a0dae7c | 582 | void OnData(UInt_t /*data*/, bool parityError) |
583 | { | |
584 | assert( fCurrentParityOkFlag < fParityOk + fMaxChannels ); | |
585 | *(++fCurrentParityOkFlag) = Bool_t(not parityError); | |
586 | } | |
e3a2b9c9 | 587 | |
588 | /// Error handler. | |
589 | void OnError(ErrorCode error, const void* location); | |
590 | ||
591 | private: | |
592 | ||
593 | // Do not allow copying of this class. | |
594 | /// Not implemented | |
595 | AliDecoderEventHandler(const AliDecoderEventHandler& /*obj*/); | |
596 | /// Not implemented | |
597 | AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/); | |
598 | ||
e3a2b9c9 | 599 | AliMUONVRawStreamTracker* fRawStream; //!< Pointer to the parent raw stream object. |
600 | const void* fBufferStart; //!< Pointer to the start of the current DDL payload buffer. | |
8a0dae7c | 601 | UInt_t fBlockCount; //!< Number of blocks filled in fBlocks. |
602 | AliBlockHeader* fBlocks; //!< Array of blocks. [0..fMaxBlocks-1] | |
603 | AliDspHeader* fDSPs; //!< Array of DSPs. [0..fMaxDsps*fMaxBlocks-1] | |
604 | AliBusPatch* fBusPatches; //!< Array of bus patches. [0..fMaxBusPatches*fMaxDsps*fMaxBlocks-1] | |
605 | AliBusPatch* fEndOfBusPatches; //!< Marks the last bus patch. | |
606 | UInt_t fMaxChannels; //!< Maximum number of elements that can be stored in fParityOk. | |
607 | Bool_t* fParityOk; //!< Array of flags for indicating if the parity is good for a raw data word. | |
608 | AliBlockHeader* fCurrentBlock; //!< Current block in fBlocks. | |
609 | AliDspHeader* fCurrentDSP; //!< Current DSP in fDSPs. | |
610 | AliBusPatch* fCurrentBusPatch; //!< Current bus patch in fBusPatches. | |
611 | Bool_t* fCurrentParityOkFlag; //!< Current parity flag to be set in fParityOk. | |
612 | UInt_t fParityErrors; //!< Number of parity errors found in DDL. | |
613 | UInt_t fGlitchErrors; //!< Number of glitch errors found in DDL. | |
614 | UInt_t fPaddingErrors; //!< Number of padding errors found in DDL. | |
615 | Bool_t fWarnings; //!< Flag indicating if we should generate a warning for errors. | |
e3a2b9c9 | 616 | }; |
617 | ||
618 | AliMUONTrackerDDLDecoder<AliDecoderEventHandler> fDecoder; //!< The decoder for the DDL payload. | |
619 | Int_t fDDL; //!< The current DDL number being handled. | |
e3a2b9c9 | 620 | Int_t fBufferSize; //!< This is the buffer size in bytes of fBuffer. |
621 | UChar_t* fBuffer; //!< This is the buffer in which we store the DDL payload read from AliRawReader. | |
8a0dae7c | 622 | const AliBusPatch* fCurrentBusPatch; //!< The current data word to return by Next(). |
623 | const UInt_t* fCurrentData; //!< The current data word to return by Next(). | |
624 | const UInt_t* fEndOfData; //!< The last data word in the current bus patch. | |
e3a2b9c9 | 625 | Bool_t fHadError; //!< Flag indicating if there was a decoding error or not. |
8a0dae7c | 626 | Bool_t fDone; //!< Flag indicating if the iteration is done or not. |
e3a2b9c9 | 627 | |
628 | ClassDef(AliMUONRawStreamTrackerHP, 0) // High performance decoder for reading MUON raw digits from tracking chamber DDL data. | |
629 | }; | |
630 | ||
631 | #endif // ALIMUONRAWSTREAMTRACKERHP_H | |
8a0dae7c | 632 |