]>
Commit | Line | Data |
---|---|---|
e3a2b9c9 | 1 | /************************************************************************** |
2 | * This file is property of and copyright by the ALICE HLT Project * | |
3 | * All rights reserved. * | |
4 | * * | |
5 | * Primary Authors: * | |
6 | * Artur Szostak <artursz@iafrica.com> * | |
7 | * * | |
8 | * Permission to use, copy, modify and distribute this software and its * | |
9 | * documentation strictly for non-commercial purposes is hereby granted * | |
10 | * without fee, provided that the above copyright notice appears in all * | |
11 | * copies and that both the copyright notice and this permission notice * | |
12 | * appear in the supporting documentation. The authors make no claims * | |
13 | * about the suitability of this software for any purpose. It is * | |
14 | * provided "as is" without express or implied warranty. * | |
15 | **************************************************************************/ | |
16 | ||
17 | /* $Id$*/ | |
18 | ||
19 | /// | |
20 | /// \file AliMUONRawStreamTrackerHP.cxx | |
21 | /// \author Artur Szostak <artursz@iafrica.com> | |
22 | /// \date 29-11-2007 | |
23 | /// \brief Implementation of the the high performance decoder AliMUONRawStreamTrackerHP. | |
24 | /// | |
25 | ||
26 | //----------------------------------------------------------------------------- | |
27 | /// \ingroup raw | |
28 | /// \class AliMUONRawStreamTrackerHP | |
29 | /// \brief A high performance stream decoder for muon tracking DDL streams. | |
30 | /// | |
31 | /// This is the raw stream class which interfaces between the high performance | |
32 | /// core decoder and the AliRawReader class. | |
33 | /// To gain the most out of the decoder, the Next() method which returns batches | |
34 | /// of decoded digit / channel information should be used. That is: | |
35 | /// \code | |
8a0dae7c | 36 | /// const AliBusPatch* Next(); |
e3a2b9c9 | 37 | /// \endcode |
38 | /// | |
8a0dae7c | 39 | /// This decoder tries to implement as similar an interface as possible to |
40 | /// AliMUONRawStreamTracker where possible. However certain constructs which | |
41 | /// would slow us down too much are avoided. | |
42 | /// | |
e3a2b9c9 | 43 | /// \author Artur Szostak <artursz@iafrica.com> |
44 | //----------------------------------------------------------------------------- | |
45 | ||
46 | #include "AliMUONRawStreamTrackerHP.h" | |
47 | #include "AliRawReader.h" | |
48 | #include "AliLog.h" | |
49 | #include <cassert> | |
8a0dae7c | 50 | #include <iostream> |
51 | #include <iomanip> | |
52 | using std::cout; | |
53 | using std::endl; | |
54 | using std::hex; | |
55 | using std::dec; | |
e3a2b9c9 | 56 | |
57 | /// \cond CLASSIMP | |
58 | ClassImp(AliMUONRawStreamTrackerHP) | |
59 | /// \endcond | |
60 | ||
61 | ||
62 | AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() : | |
63 | AliMUONVRawStreamTracker(), | |
64 | fDecoder(), | |
65 | fDDL(0), | |
e3a2b9c9 | 66 | fBufferSize(8192), |
67 | fBuffer(new UChar_t[8192]), | |
8a0dae7c | 68 | fCurrentBusPatch(NULL), |
69 | fCurrentData(NULL), | |
70 | fEndOfData(NULL), | |
71 | fHadError(kFALSE), | |
72 | fDone(kFALSE) | |
e3a2b9c9 | 73 | { |
74 | /// | |
75 | /// Default constructor. | |
76 | /// | |
8a0dae7c | 77 | |
78 | // Must set this flag to get all information about parity errors though | |
79 | // the OnData method. OnError gets them either way. | |
80 | fDecoder.ExitOnError(false); | |
81 | fDecoder.SendDataOnParityError(true); | |
82 | ||
83 | fDecoder.GetHandler().SetMaxStructs( | |
84 | fDecoder.MaxBlocks(), | |
85 | fDecoder.MaxDSPs(), | |
86 | fDecoder.MaxBusPatches() | |
87 | ); | |
88 | ||
89 | fDecoder.GetHandler().SetRawStream(this); | |
e3a2b9c9 | 90 | } |
91 | ||
92 | ||
93 | AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP(AliRawReader* rawReader) : | |
94 | AliMUONVRawStreamTracker(rawReader), | |
95 | fDecoder(), | |
96 | fDDL(0), | |
e3a2b9c9 | 97 | fBufferSize(8192), |
98 | fBuffer(new UChar_t[8192]), | |
8a0dae7c | 99 | fCurrentBusPatch(NULL), |
100 | fCurrentData(NULL), | |
101 | fEndOfData(NULL), | |
102 | fHadError(kFALSE), | |
103 | fDone(kFALSE) | |
e3a2b9c9 | 104 | { |
105 | /// | |
106 | /// Constructor with AliRawReader as argument. | |
107 | /// | |
108 | ||
8a0dae7c | 109 | // Must set this flag to get all information about parity errors though |
110 | // the OnData method. OnError gets them either way. | |
111 | fDecoder.ExitOnError(false); | |
112 | fDecoder.SendDataOnParityError(true); | |
113 | ||
114 | fDecoder.GetHandler().SetMaxStructs( | |
115 | fDecoder.MaxBlocks(), | |
116 | fDecoder.MaxDSPs(), | |
117 | fDecoder.MaxBusPatches() | |
118 | ); | |
119 | ||
e3a2b9c9 | 120 | fDecoder.GetHandler().SetRawStream(this); |
121 | } | |
122 | ||
123 | ||
124 | AliMUONRawStreamTrackerHP::~AliMUONRawStreamTrackerHP() | |
125 | { | |
126 | /// | |
127 | /// Default destructor. | |
128 | /// | |
129 | ||
130 | if (fBuffer != NULL) | |
131 | { | |
132 | delete [] fBuffer; | |
133 | } | |
134 | } | |
135 | ||
136 | ||
137 | void AliMUONRawStreamTrackerHP::First() | |
138 | { | |
139 | /// Initialise or reset the iterator. | |
140 | /// The first DDL will be found and decoded. | |
141 | ||
142 | assert( GetReader() != NULL ); | |
143 | ||
144 | fDDL = 0; | |
8a0dae7c | 145 | fDone = kFALSE; |
e3a2b9c9 | 146 | NextDDL(); |
147 | } | |
148 | ||
149 | ||
150 | Bool_t AliMUONRawStreamTrackerHP::NextDDL() | |
151 | { | |
152 | /// Reading the next tracker DDL and decode the payload with the | |
153 | /// high performance decoder. | |
154 | /// \return kTRUE if the next DDL was successfully read and kFALSE otherwise. | |
155 | ||
156 | assert( GetReader() != NULL ); | |
157 | ||
8a0dae7c | 158 | while (fDDL < GetMaxDDL()) |
e3a2b9c9 | 159 | { |
160 | GetReader()->Reset(); | |
161 | GetReader()->Select("MUONTRK", fDDL, fDDL); // Select the DDL file to be read. | |
162 | if (GetReader()->ReadHeader()) break; | |
163 | AliDebug(3, Form("Skipping DDL %d which does not seem to be there", fDDL+1)); | |
164 | fDDL++; | |
165 | } | |
8a0dae7c | 166 | |
167 | // If we reach the end of the DDL list for this event then reset the | |
168 | // DDL counter, mark the iteration as done and | |
169 | if (fDDL >= GetMaxDDL()) | |
170 | { | |
171 | fDDL = 0; | |
172 | fDone = kTRUE; | |
173 | return kFALSE; | |
174 | } | |
175 | else | |
176 | { | |
177 | fDone = kFALSE; | |
178 | } | |
179 | ||
e3a2b9c9 | 180 | AliDebug(3, Form("DDL Number %d\n", fDDL)); |
181 | ||
182 | Int_t dataSize = GetReader()->GetDataSize(); // in bytes | |
183 | // Check if we have enough buffer space already in fBuffer. If we do then | |
184 | // just continue reading otherwise we need to resize the buffer. | |
185 | if (fBufferSize < dataSize) | |
186 | { | |
187 | if (fBuffer != NULL) | |
188 | { | |
189 | delete [] fBuffer; | |
190 | fBuffer = NULL; | |
191 | fBufferSize = 0; | |
192 | } | |
193 | try | |
194 | { | |
195 | fBuffer = new UChar_t[dataSize]; | |
196 | fBufferSize = dataSize; | |
197 | } | |
198 | catch (const std::bad_alloc&) | |
199 | { | |
200 | AliError("Could not allocate more buffer space. Cannot decode DDL."); | |
201 | return kFALSE; | |
202 | } | |
203 | } | |
204 | ||
205 | if (not GetReader()->ReadNext(fBuffer, dataSize)) | |
206 | { | |
207 | return kFALSE; | |
208 | } | |
209 | ||
210 | #ifndef R__BYTESWAP | |
211 | Swap(fBuffer, dataSize); // Swap needed for mac power pc. | |
212 | #endif | |
213 | ||
214 | bool result = false; | |
215 | try | |
216 | { | |
217 | // Since we might allocate memory inside OnNewBuffer in the event | |
218 | // handler we need to trap any memory allocation exception to be robust. | |
219 | result = fDecoder.Decode(fBuffer, dataSize); | |
8a0dae7c | 220 | fHadError = (result == true ? kFALSE : kTRUE); |
e3a2b9c9 | 221 | } |
222 | catch (const std::bad_alloc&) | |
223 | { | |
224 | AliError("Could not allocate more buffer space. Cannot decode DDL."); | |
225 | return kFALSE; | |
226 | } | |
8a0dae7c | 227 | |
228 | // Update the current bus patch pointers. | |
229 | fCurrentBusPatch = fDecoder.GetHandler().FirstBusPatch(); | |
230 | if (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) | |
231 | { | |
232 | fCurrentData = fCurrentBusPatch->GetData(); | |
233 | fEndOfData = fCurrentData + fCurrentBusPatch->GetDataCount(); | |
234 | } | |
235 | else | |
236 | { | |
237 | // If the DDL did not have any bus patches then mark both fCurrentData | |
238 | // and fEndOfData as NULL so that in Next() we are forced to find the | |
239 | // first non empty DDL. | |
240 | fCurrentData = fEndOfData = NULL; | |
241 | } | |
242 | ||
e3a2b9c9 | 243 | fDDL++; // Remember to increment index to next DDL. |
244 | return result; | |
245 | } | |
246 | ||
247 | ||
248 | Bool_t AliMUONRawStreamTrackerHP::IsDone() const | |
249 | { | |
250 | /// Indicates whether the iteration is finished or not. | |
251 | /// \return kTRUE if we already read all the digits and kFALSE if not. | |
252 | ||
8a0dae7c | 253 | return fDone; |
e3a2b9c9 | 254 | } |
255 | ||
256 | ||
257 | Bool_t AliMUONRawStreamTrackerHP::Next( | |
258 | Int_t& busPatchId, UShort_t& manuId, UChar_t& manuChannel, | |
259 | UShort_t& adc | |
260 | ) | |
261 | { | |
262 | /// Advance one step in the iteration. Returns false if finished. | |
263 | /// [out] \param busPatchId This is filled with the bus patch ID of the digit. | |
264 | /// [out] \param manuId This is filled with the MANU ID of the digit. | |
265 | /// [out] \param manuChannel This is filled with the MANU channel ID of the digit. | |
266 | /// [out] \param adc This is filled with the ADC signal value of the digit. | |
267 | /// \return kTRUE if we read another digit and kFALSE if we have read all the | |
268 | /// digits already, i.e. at the end of the iteration. | |
269 | ||
8a0dae7c | 270 | retry: |
271 | // Check if we still have data to be returned for the current bus patch. | |
272 | if (fCurrentData != fEndOfData) | |
e3a2b9c9 | 273 | { |
8a0dae7c | 274 | busPatchId = fCurrentBusPatch->GetBusPatchId(); |
275 | AliMUONTrackerDDLDecoderEventHandler::UnpackADC(*fCurrentData, manuId, manuChannel, adc); | |
276 | fCurrentData++; | |
e3a2b9c9 | 277 | return kTRUE; |
278 | } | |
279 | else | |
280 | { | |
8a0dae7c | 281 | // We hit the end of the current bus patch so check if we have any more |
282 | // bus patches to process for the current DDL. If we do, then increment | |
283 | // the current bus patch, make sure it is not the last one and then try | |
284 | // reading the first element again. | |
285 | if (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) | |
e3a2b9c9 | 286 | { |
8a0dae7c | 287 | fCurrentBusPatch++; |
288 | if (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) | |
e3a2b9c9 | 289 | { |
8a0dae7c | 290 | fCurrentData = fCurrentBusPatch->GetData(); |
291 | fEndOfData = fCurrentData + fCurrentBusPatch->GetDataCount(); | |
292 | goto retry; | |
e3a2b9c9 | 293 | } |
294 | } | |
8a0dae7c | 295 | |
296 | // This was the last bus patch in the DDL so read in the next one and | |
297 | // try reading the first data element again. | |
298 | // Note: fCurrentBusPatch is set inside NextDDL(). | |
299 | if (NextDDL()) goto retry; | |
e3a2b9c9 | 300 | } |
301 | return kFALSE; | |
302 | } | |
303 | ||
304 | ||
8a0dae7c | 305 | void AliMUONRawStreamTrackerHP::SetMaxBlock(Int_t blk) |
e3a2b9c9 | 306 | { |
8a0dae7c | 307 | /// Set maximum number of blocks per DDL allowed. |
308 | fDecoder.MaxBlocks( (UInt_t) blk ); | |
e3a2b9c9 | 309 | |
8a0dae7c | 310 | fDecoder.GetHandler().SetMaxStructs( |
311 | fDecoder.MaxBlocks(), | |
312 | fDecoder.MaxDSPs(), | |
313 | fDecoder.MaxBusPatches() | |
314 | ); | |
315 | } | |
316 | ||
317 | ||
318 | void AliMUONRawStreamTrackerHP::SetMaxDsp(Int_t dsp) | |
319 | { | |
320 | /// Set maximum number of Dsp per block allowed. | |
321 | fDecoder.MaxDSPs( (UInt_t) dsp ); | |
322 | ||
323 | fDecoder.GetHandler().SetMaxStructs( | |
324 | fDecoder.MaxBlocks(), | |
325 | fDecoder.MaxDSPs(), | |
326 | fDecoder.MaxBusPatches() | |
327 | ); | |
328 | } | |
329 | ||
330 | ||
331 | void AliMUONRawStreamTrackerHP::SetMaxBus(Int_t bus) | |
332 | { | |
333 | /// Set maximum number of Buspatch per Dsp allowed. | |
334 | fDecoder.MaxBusPatches( (UInt_t) bus ); | |
335 | ||
336 | fDecoder.GetHandler().SetMaxStructs( | |
337 | fDecoder.MaxBlocks(), | |
338 | fDecoder.MaxDSPs(), | |
339 | fDecoder.MaxBusPatches() | |
340 | ); | |
341 | } | |
342 | ||
343 | /////////////////////////////////////////////////////////////////////////////// | |
344 | ||
345 | void AliMUONRawStreamTrackerHP::AliBlockHeader::Print() const | |
346 | { | |
347 | /// Print header to screen. | |
348 | ||
349 | cout << "CRT info" << endl; | |
350 | if (fHeader == NULL) | |
e3a2b9c9 | 351 | { |
8a0dae7c | 352 | cout << "Header is NULL" << endl; |
353 | return; | |
354 | } | |
355 | cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl; | |
356 | cout << "TotalLength: " << fHeader->fTotalLength << endl; | |
357 | cout << "Length: " << fHeader->fLength << endl; | |
358 | cout << "DspId: " << fHeader->fDSPId << endl; | |
359 | cout << "L0Trigger: " << fHeader->fL0Trigger << endl; | |
360 | cout << "MiniEventId: " << fHeader->fMiniEventId<< endl; | |
361 | cout << "EventId1: " << fHeader->fEventId1 << endl; | |
362 | cout << "EventId2: " << fHeader->fEventId2 << endl; | |
363 | } | |
364 | ||
365 | ||
366 | void AliMUONRawStreamTrackerHP::AliDspHeader::Print() const | |
367 | { | |
368 | /// Print header to screen. | |
369 | ||
370 | cout << "FRT info" << endl; | |
371 | if (fHeader == NULL) | |
372 | { | |
373 | cout << "Header is NULL" << endl; | |
374 | return; | |
375 | } | |
376 | cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl; | |
377 | cout << "TotalLength: " << fHeader->fTotalLength << endl; | |
378 | cout << "Length : " << fHeader->fLength << endl; | |
379 | cout << "DspId: " << fHeader->fDSPId << endl; | |
380 | cout << "BlkL1ATrigger: " << fHeader->fBlkL1ATrigger << endl; | |
381 | cout << "MiniEventId: " << fHeader->fMiniEventId << endl; | |
382 | cout << "L1ATrigger: " << fHeader->fL1ATrigger << endl; | |
383 | cout << "L1RTrigger: " << fHeader->fL1RTrigger << endl; | |
384 | cout << "PaddingWord: " << fHeader->fPaddingWord << endl; | |
385 | cout << "ErrorWord: " << fHeader->fErrorWord << endl; | |
386 | } | |
387 | ||
388 | ||
389 | void AliMUONRawStreamTrackerHP::AliBusPatch::Print(const Option_t* opt) const | |
390 | { | |
391 | /// Print header to screen. | |
392 | cout << "Bus patch info" << endl; | |
393 | if (fHeader == NULL) | |
394 | { | |
395 | cout << "Header is NULL" << endl; | |
396 | return; | |
397 | } | |
398 | cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl; | |
399 | cout << "fTotalLength: " << fHeader->fTotalLength << endl; | |
400 | cout << "fLength: " << fHeader->fLength << endl; | |
401 | cout << "fBusPatchId: " << fHeader->fBusPatchId << endl; | |
402 | ||
403 | if (TString(opt).Contains("all")) | |
404 | { | |
405 | for (UInt_t i = 0; i < fHeader->fLength; ++i) | |
406 | cout << "Data["<< i << "] = " << fData[i] << endl; | |
e3a2b9c9 | 407 | } |
e3a2b9c9 | 408 | } |
409 | ||
410 | /////////////////////////////////////////////////////////////////////////////// | |
411 | ||
412 | AliMUONRawStreamTrackerHP::AliDecoderEventHandler::AliDecoderEventHandler() : | |
e3a2b9c9 | 413 | fRawStream(NULL), |
8a0dae7c | 414 | fBufferStart(NULL), |
415 | fBlockCount(0), | |
416 | fBlocks(NULL), | |
417 | fDSPs(NULL), | |
418 | fBusPatches(NULL), | |
419 | fEndOfBusPatches(NULL), | |
420 | fMaxChannels(8192), | |
421 | fParityOk(new Bool_t[8192]), | |
422 | fCurrentBlock(NULL), | |
423 | fCurrentDSP(NULL), | |
424 | fCurrentBusPatch(NULL), | |
425 | fCurrentParityOkFlag(NULL), | |
426 | fParityErrors(0), | |
427 | fGlitchErrors(0), | |
428 | fPaddingErrors(0), | |
429 | fWarnings(kTRUE) | |
e3a2b9c9 | 430 | { |
8a0dae7c | 431 | /// Default constructor initialises the internal parity flags buffer to |
432 | /// store 8192 elements. This array will grow dynamically if needed. | |
e3a2b9c9 | 433 | } |
434 | ||
435 | ||
436 | AliMUONRawStreamTrackerHP::AliDecoderEventHandler::~AliDecoderEventHandler() | |
437 | { | |
438 | /// Default destructor cleans up the allocated memory. | |
439 | ||
8a0dae7c | 440 | if (fParityOk != NULL) delete [] fParityOk; |
441 | if (fBlocks != NULL) delete [] fBlocks; | |
442 | if (fDSPs != NULL) delete [] fDSPs; | |
443 | if (fBusPatches != NULL) delete [] fBusPatches; | |
444 | } | |
445 | ||
446 | ||
447 | void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::SetMaxStructs( | |
448 | UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches | |
449 | ) | |
450 | { | |
451 | /// Sets the maximum number of structures allowed. | |
452 | ||
453 | // Start by clearing the current arrays. | |
454 | if (fBlocks != NULL) | |
455 | { | |
456 | delete [] fBlocks; | |
457 | fBlocks = NULL; | |
458 | } | |
459 | if (fDSPs != NULL) | |
e3a2b9c9 | 460 | { |
8a0dae7c | 461 | delete [] fDSPs; |
462 | fDSPs = NULL; | |
e3a2b9c9 | 463 | } |
8a0dae7c | 464 | if (fBusPatches != NULL) |
465 | { | |
466 | delete [] fBusPatches; | |
467 | fBusPatches = NULL; | |
468 | } | |
469 | fCurrentBlock = NULL; | |
470 | fCurrentDSP = NULL; | |
471 | fCurrentBusPatch = NULL; | |
472 | ||
473 | // Allocate new memory. | |
474 | fBlocks = new AliBlockHeader[maxBlocks]; | |
475 | fDSPs = new AliDspHeader[maxBlocks*maxDsps]; | |
476 | fBusPatches = new AliBusPatch[maxBlocks*maxDsps*maxBusPatches]; | |
477 | fEndOfBusPatches = fEndOfBusPatches; | |
e3a2b9c9 | 478 | } |
479 | ||
8a0dae7c | 480 | |
e3a2b9c9 | 481 | void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer( |
482 | const void* buffer, UInt_t bufferSize | |
483 | ) | |
484 | { | |
485 | /// This is called by the high performance decoder when a new DDL payload | |
486 | /// is about to be decoded. | |
487 | /// \param buffer The pointer to the buffer storing the DDL payload. | |
488 | /// \param bufferSize The size of the buffer in bytes. | |
489 | ||
8a0dae7c | 490 | assert( fRawStream != NULL ); |
491 | ||
e3a2b9c9 | 492 | // remember the start of the buffer to be used in OnError. |
493 | fBufferStart = buffer; | |
8a0dae7c | 494 | |
495 | // Reset error counters. | |
496 | fParityErrors = 0; | |
497 | fGlitchErrors = 0; | |
498 | fPaddingErrors = 0; | |
499 | ||
500 | // Check if we will have enough space in the fParityOk array. | |
e3a2b9c9 | 501 | // If we do not then we need to resize the array. |
502 | // bufferSize / sizeof(UInt_t) will be a safe over estimate of the | |
503 | // number of channels that we will find. | |
8a0dae7c | 504 | UInt_t maxChannelsPossible = bufferSize / sizeof(UInt_t); |
505 | if (maxChannelsPossible > fMaxChannels) | |
e3a2b9c9 | 506 | { |
8a0dae7c | 507 | if (fParityOk != NULL) |
e3a2b9c9 | 508 | { |
8a0dae7c | 509 | delete [] fParityOk; |
510 | fParityOk = NULL; | |
e3a2b9c9 | 511 | fMaxChannels = 0; |
512 | } | |
8a0dae7c | 513 | fParityOk = new Bool_t[maxChannelsPossible]; |
514 | fMaxChannels = maxChannelsPossible; | |
e3a2b9c9 | 515 | } |
e3a2b9c9 | 516 | |
8a0dae7c | 517 | // Reset the current pointers which will be used to track where we need to |
518 | // fill fBlocks, fDSPs, fBusPatches and the parity flag. We have to subtract | |
519 | // one space because we will increment the pointer the first time in the | |
520 | // OnNewXZY methods. | |
521 | fCurrentBlock = fBlocks-1; | |
522 | fCurrentDSP = fDSPs-1; | |
523 | fCurrentBusPatch = fBusPatches-1; | |
524 | fCurrentParityOkFlag = fParityOk-1; | |
525 | fBlockCount = 0; | |
e3a2b9c9 | 526 | } |
527 | ||
528 | ||
529 | void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnError( | |
530 | ErrorCode error, const void* location | |
531 | ) | |
532 | { | |
533 | /// This is called by the high performance decoder when a error occurs | |
534 | /// when trying to decode the DDL payload. This indicates corruption in | |
535 | /// the data. This method converts the error code to a descriptive message | |
536 | /// and log this with the raw reader. | |
537 | /// \param error The error code indicating the problem. | |
538 | /// \param location A pointer to the location within the DDL payload buffer | |
539 | /// being decoded where the problem with the data was found. | |
540 | ||
541 | assert( fRawStream != NULL ); | |
542 | assert( fRawStream->GetReader() != NULL ); | |
543 | ||
8a0dae7c | 544 | Char_t* message = NULL; |
545 | UInt_t word = 0; | |
546 | ||
e3a2b9c9 | 547 | switch (error) |
548 | { | |
8a0dae7c | 549 | case kGlitchFound: |
550 | message = Form( | |
551 | "Glitch error detected in DSP %d, skipping event ", | |
552 | fCurrentBlock->GetDspId() | |
553 | ); | |
554 | fRawStream->GetReader()->AddMajorErrorLog(error, message); | |
555 | break; | |
556 | ||
e3a2b9c9 | 557 | case kBadPaddingWord: |
8a0dae7c | 558 | // We subtract 1 from the current numbers of blocks, DSPs |
559 | // and bus patches to get the indices. | |
560 | message = Form( | |
561 | "Padding word error for iBlock %d, iDsp %d, iBus %d\n", | |
562 | fBlockCount-1, | |
563 | fCurrentBlock->GetDspCount()-1, | |
564 | fCurrentDSP->GetBusPatchCount()-1 | |
565 | ); | |
566 | fRawStream->GetReader()->AddMinorErrorLog(error, message); | |
567 | break; | |
568 | ||
e3a2b9c9 | 569 | case kParityError: |
8a0dae7c | 570 | // location points to the incorrect data word and |
571 | // fCurrentBusPatch->GetData() returns a pointer to the start of | |
572 | // bus patches data, so the difference divided by 4 gives the 32 | |
573 | // bit word number. | |
574 | word = ((unsigned long)location - (unsigned long)fCurrentBusPatch->GetData()) | |
575 | / sizeof(UInt_t); | |
576 | message = Form( | |
577 | "Parity error in word %d for manuId %d and channel %d in buspatch %d\n", | |
578 | word, | |
579 | fCurrentBusPatch->GetManuId(word), | |
580 | fCurrentBusPatch->GetChannelId(word), | |
581 | fCurrentBusPatch->GetBusPatchId() | |
582 | ); | |
583 | fRawStream->GetReader()->AddMinorErrorLog(error, message); | |
e3a2b9c9 | 584 | break; |
8a0dae7c | 585 | |
e3a2b9c9 | 586 | default: |
8a0dae7c | 587 | message = Form( |
588 | "%s (At byte %d in DDL.)", | |
589 | ErrorCodeToMessage(error), | |
590 | (unsigned long)location - (unsigned long)fBufferStart | |
591 | ); | |
592 | fRawStream->GetReader()->AddMajorErrorLog(error, message); | |
e3a2b9c9 | 593 | break; |
594 | } | |
8a0dae7c | 595 | |
596 | if (fWarnings) | |
597 | { | |
598 | AliWarningGeneral( | |
599 | "AliMUONRawStreamTrackerHP::AliDecoderEventHandler", | |
600 | message | |
601 | ); | |
602 | } | |
e3a2b9c9 | 603 | } |
604 |