Skipping buspatches with parity error in the Next() method
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTrackerHP.cxx
CommitLineData
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"
586dda01 47#include "AliMUONTrackerDDLDecoder.h"
481d8064 48#include "AliMUONDspHeader.h"
49#include "AliMUONBlockHeader.h"
50#include "AliMUONBusStruct.h"
51#include "AliMUONDDLTracker.h"
e3a2b9c9 52#include "AliRawReader.h"
53#include "AliLog.h"
54#include <cassert>
8a0dae7c 55#include <iostream>
8a0dae7c 56using std::cout;
57using std::endl;
58using std::hex;
59using std::dec;
e3a2b9c9 60
61/// \cond CLASSIMP
62ClassImp(AliMUONRawStreamTrackerHP)
63/// \endcond
64
65
66AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() :
67 AliMUONVRawStreamTracker(),
68 fDecoder(),
69 fDDL(0),
e3a2b9c9 70 fBufferSize(8192),
71 fBuffer(new UChar_t[8192]),
586dda01 72 fkCurrentBusPatch(NULL),
73 fkCurrentData(NULL),
74 fkEndOfData(NULL),
8a0dae7c 75 fHadError(kFALSE),
481d8064 76 fDone(kFALSE),
77 fDDLObject(NULL)
e3a2b9c9 78{
79 ///
80 /// Default constructor.
81 ///
8a0dae7c 82
83 // Must set this flag to get all information about parity errors though
84 // the OnData method. OnError gets them either way.
85 fDecoder.ExitOnError(false);
86 fDecoder.SendDataOnParityError(true);
87
88 fDecoder.GetHandler().SetMaxStructs(
89 fDecoder.MaxBlocks(),
90 fDecoder.MaxDSPs(),
91 fDecoder.MaxBusPatches()
92 );
93
94 fDecoder.GetHandler().SetRawStream(this);
e3a2b9c9 95}
96
97
98AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP(AliRawReader* rawReader) :
99 AliMUONVRawStreamTracker(rawReader),
100 fDecoder(),
101 fDDL(0),
e3a2b9c9 102 fBufferSize(8192),
103 fBuffer(new UChar_t[8192]),
586dda01 104 fkCurrentBusPatch(NULL),
105 fkCurrentData(NULL),
106 fkEndOfData(NULL),
8a0dae7c 107 fHadError(kFALSE),
481d8064 108 fDone(kFALSE),
109 fDDLObject(NULL)
e3a2b9c9 110{
111 ///
112 /// Constructor with AliRawReader as argument.
113 ///
114
8a0dae7c 115 // Must set this flag to get all information about parity errors though
116 // the OnData method. OnError gets them either way.
117 fDecoder.ExitOnError(false);
118 fDecoder.SendDataOnParityError(true);
119
120 fDecoder.GetHandler().SetMaxStructs(
121 fDecoder.MaxBlocks(),
122 fDecoder.MaxDSPs(),
123 fDecoder.MaxBusPatches()
124 );
125
e3a2b9c9 126 fDecoder.GetHandler().SetRawStream(this);
127}
128
129
130AliMUONRawStreamTrackerHP::~AliMUONRawStreamTrackerHP()
131{
132 ///
133 /// Default destructor.
134 ///
135
136 if (fBuffer != NULL)
137 {
138 delete [] fBuffer;
139 }
481d8064 140 if (fDDLObject != NULL)
141 {
142 delete fDDLObject;
143 }
e3a2b9c9 144}
145
146
147void AliMUONRawStreamTrackerHP::First()
148{
149 /// Initialise or reset the iterator.
150 /// The first DDL will be found and decoded.
151
152 assert( GetReader() != NULL );
153
154 fDDL = 0;
8a0dae7c 155 fDone = kFALSE;
e3a2b9c9 156 NextDDL();
157}
158
159
160Bool_t AliMUONRawStreamTrackerHP::NextDDL()
161{
162 /// Reading the next tracker DDL and decode the payload with the
163 /// high performance decoder.
164 /// \return kTRUE if the next DDL was successfully read and kFALSE otherwise.
165
166 assert( GetReader() != NULL );
167
481d8064 168 // The temporary object if generated in GetDDLTracker, is now stale,
169 // so delete it.
170 if (fDDLObject != NULL)
171 {
172 delete fDDLObject;
173 fDDLObject = NULL;
174 }
175
1788245f 176 // Better to reset these pointers.
586dda01 177 fkCurrentBusPatch = NULL;
178 fkCurrentData = NULL;
179 fkEndOfData = NULL;
1788245f 180
8a0dae7c 181 while (fDDL < GetMaxDDL())
e3a2b9c9 182 {
183 GetReader()->Reset();
184 GetReader()->Select("MUONTRK", fDDL, fDDL); // Select the DDL file to be read.
185 if (GetReader()->ReadHeader()) break;
186 AliDebug(3, Form("Skipping DDL %d which does not seem to be there", fDDL+1));
187 fDDL++;
188 }
8a0dae7c 189
190 // If we reach the end of the DDL list for this event then reset the
1788245f 191 // DDL counter, mark the iteration as done and exit.
8a0dae7c 192 if (fDDL >= GetMaxDDL())
193 {
194 fDDL = 0;
195 fDone = kTRUE;
196 return kFALSE;
197 }
198 else
199 {
200 fDone = kFALSE;
201 }
202
e3a2b9c9 203 AliDebug(3, Form("DDL Number %d\n", fDDL));
204
205 Int_t dataSize = GetReader()->GetDataSize(); // in bytes
206 // Check if we have enough buffer space already in fBuffer. If we do then
207 // just continue reading otherwise we need to resize the buffer.
208 if (fBufferSize < dataSize)
209 {
210 if (fBuffer != NULL)
211 {
212 delete [] fBuffer;
213 fBuffer = NULL;
214 fBufferSize = 0;
215 }
216 try
217 {
218 fBuffer = new UChar_t[dataSize];
219 fBufferSize = dataSize;
220 }
221 catch (const std::bad_alloc&)
222 {
223 AliError("Could not allocate more buffer space. Cannot decode DDL.");
224 return kFALSE;
225 }
226 }
227
228 if (not GetReader()->ReadNext(fBuffer, dataSize))
229 {
230 return kFALSE;
231 }
232
233#ifndef R__BYTESWAP
ab0129ae 234 Swap(reinterpret_cast<UInt_t*>(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc.
e3a2b9c9 235#endif
236
237 bool result = false;
238 try
239 {
240 // Since we might allocate memory inside OnNewBuffer in the event
241 // handler we need to trap any memory allocation exception to be robust.
242 result = fDecoder.Decode(fBuffer, dataSize);
8a0dae7c 243 fHadError = (result == true ? kFALSE : kTRUE);
e3a2b9c9 244 }
245 catch (const std::bad_alloc&)
246 {
247 AliError("Could not allocate more buffer space. Cannot decode DDL.");
248 return kFALSE;
249 }
8a0dae7c 250
251 // Update the current bus patch pointers.
586dda01 252 fkCurrentBusPatch = fDecoder.GetHandler().FirstBusPatch();
253 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
8a0dae7c 254 {
586dda01 255 fkCurrentData = fkCurrentBusPatch->GetData();
256 fkEndOfData = fkCurrentData + fkCurrentBusPatch->GetDataCount();
8a0dae7c 257 }
258 else
259 {
260 // If the DDL did not have any bus patches then mark both fCurrentData
261 // and fEndOfData as NULL so that in Next() we are forced to find the
262 // first non empty DDL.
586dda01 263 fkCurrentData = fkEndOfData = NULL;
8a0dae7c 264 }
265
e3a2b9c9 266 fDDL++; // Remember to increment index to next DDL.
29ee96d8 267 return kTRUE;
e3a2b9c9 268}
269
270
271Bool_t AliMUONRawStreamTrackerHP::IsDone() const
272{
273 /// Indicates whether the iteration is finished or not.
274 /// \return kTRUE if we already read all the digits and kFALSE if not.
275
8a0dae7c 276 return fDone;
e3a2b9c9 277}
278
279
280Bool_t AliMUONRawStreamTrackerHP::Next(
281 Int_t& busPatchId, UShort_t& manuId, UChar_t& manuChannel,
bc057b0a 282 UShort_t& adc, Bool_t skipParityErrors
e3a2b9c9 283 )
284{
285 /// Advance one step in the iteration. Returns false if finished.
286 /// [out] \param busPatchId This is filled with the bus patch ID of the digit.
287 /// [out] \param manuId This is filled with the MANU ID of the digit.
288 /// [out] \param manuChannel This is filled with the MANU channel ID of the digit.
289 /// [out] \param adc This is filled with the ADC signal value of the digit.
bc057b0a 290 /// [in] \param skipParityErrors If this is kTRUE, we'll skip the buspatches that
291 /// have some parity errors
e3a2b9c9 292 /// \return kTRUE if we read another digit and kFALSE if we have read all the
293 /// digits already, i.e. at the end of the iteration.
294
586dda01 295 if (fkCurrentData == NULL) return kFALSE;
1788245f 296
bc057b0a 297 fDecoder.SendDataOnParityError(skipParityErrors);
298
8a0dae7c 299retry:
300 // Check if we still have data to be returned for the current bus patch.
586dda01 301 if (fkCurrentData != fkEndOfData)
e3a2b9c9 302 {
586dda01 303 busPatchId = fkCurrentBusPatch->GetBusPatchId();
304 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(*fkCurrentData, manuId, manuChannel, adc);
305 fkCurrentData++;
e3a2b9c9 306 return kTRUE;
307 }
308 else
309 {
8a0dae7c 310 // We hit the end of the current bus patch so check if we have any more
311 // bus patches to process for the current DDL. If we do, then increment
312 // the current bus patch, make sure it is not the last one and then try
313 // reading the first element again.
586dda01 314 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
e3a2b9c9 315 {
586dda01 316 fkCurrentBusPatch++;
317 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
e3a2b9c9 318 {
586dda01 319 fkCurrentData = fkCurrentBusPatch->GetData();
320 fkEndOfData = fkCurrentData + fkCurrentBusPatch->GetDataCount();
8a0dae7c 321 goto retry;
e3a2b9c9 322 }
323 }
8a0dae7c 324
325 // This was the last bus patch in the DDL so read in the next one and
326 // try reading the first data element again.
327 // Note: fCurrentBusPatch is set inside NextDDL().
328 if (NextDDL()) goto retry;
e3a2b9c9 329 }
330 return kFALSE;
331}
332
333
481d8064 334AliMUONDDLTracker* AliMUONRawStreamTrackerHP::GetDDLTracker() const
335{
336 /// Construct and return a pointer to the DDL payload object.
337 /// \return Pointer to internally constructed AliMUONDDLTracker object.
338 /// The object is owned by this class and should not be deleted
339 /// by the caller.
340 ///
341 /// \note This method should not be used just to gain access to the DDL
342 /// payload, unless there is a good reason to have the AliMUONDDLTracker
343 /// object. For example, if you want to modify the data and then save it
344 /// to another DDL stream. Otherwise it can be an order of magnitude
345 /// faster to access the DDL headers and data with the GetBlockHeader,
346 /// GetDspHeader and GetBusPatch methods for example.
347 /// Refer to the MUONRawStreamTracker.C macro to see how to use the fast
348 /// decoder interface optimally.
349
350 if (fDDLObject != NULL) return fDDLObject;
351
352 fDDLObject = new AliMUONDDLTracker;
353 for (Int_t iBlock = 0; iBlock < (Int_t)GetBlockCount(); iBlock++)
354 {
355 AliMUONBlockHeader blockHeader;
356 AliMUONDspHeader dspHeader;
357 AliMUONBusStruct busPatch;
358
359 const AliBlockHeader* bh = GetBlockHeader(iBlock);
360 // Copy block header and add it to the DDL object.
361 memcpy(blockHeader.GetHeader(), bh->GetHeader(), sizeof(AliMUONBlockHeaderStruct));
362 fDDLObject->AddBlkHeader(blockHeader);
363
364 for (Int_t iDsp = 0; iDsp < (Int_t)bh->GetDspCount(); iDsp++)
365 {
366 const AliDspHeader* dh = bh->GetDspHeader(iDsp);
367 // Copy DSP header and add it to the DDL object.
368 memcpy(dspHeader.GetHeader(), dh->GetHeader(), sizeof(AliMUONDSPHeaderStruct));
369 fDDLObject->AddDspHeader(dspHeader, iBlock);
370
371 const AliBusPatch* bp = dh->GetFirstBusPatch();
372 while (bp != NULL)
373 {
374 // Copy bus patch header, data and add everything into DDL object.
375 memcpy(busPatch.GetHeader(), bp->GetHeader(), sizeof(AliMUONBusPatchHeaderStruct));
376 busPatch.SetAlloc(bp->GetLength());
377 memcpy(busPatch.GetData(), bp->GetData(), bp->GetDataCount()*sizeof(UInt_t));
378 busPatch.SetBlockId(iBlock);
379 busPatch.SetDspId(iDsp);
380 fDDLObject->AddBusPatch(busPatch, iBlock, iDsp);
381 bp = bp->Next();
382 }
383 }
384 }
385
386 return fDDLObject;
387}
388
389
8a0dae7c 390void AliMUONRawStreamTrackerHP::SetMaxBlock(Int_t blk)
e3a2b9c9 391{
8a0dae7c 392 /// Set maximum number of blocks per DDL allowed.
393 fDecoder.MaxBlocks( (UInt_t) blk );
e3a2b9c9 394
8a0dae7c 395 fDecoder.GetHandler().SetMaxStructs(
396 fDecoder.MaxBlocks(),
397 fDecoder.MaxDSPs(),
398 fDecoder.MaxBusPatches()
399 );
400}
401
402
403void AliMUONRawStreamTrackerHP::SetMaxDsp(Int_t dsp)
404{
405 /// Set maximum number of Dsp per block allowed.
406 fDecoder.MaxDSPs( (UInt_t) dsp );
407
408 fDecoder.GetHandler().SetMaxStructs(
409 fDecoder.MaxBlocks(),
410 fDecoder.MaxDSPs(),
411 fDecoder.MaxBusPatches()
412 );
413}
414
415
416void AliMUONRawStreamTrackerHP::SetMaxBus(Int_t bus)
417{
418 /// Set maximum number of Buspatch per Dsp allowed.
419 fDecoder.MaxBusPatches( (UInt_t) bus );
420
421 fDecoder.GetHandler().SetMaxStructs(
422 fDecoder.MaxBlocks(),
423 fDecoder.MaxDSPs(),
424 fDecoder.MaxBusPatches()
425 );
426}
427
428///////////////////////////////////////////////////////////////////////////////
429
430void AliMUONRawStreamTrackerHP::AliBlockHeader::Print() const
431{
432 /// Print header to screen.
433
434 cout << "CRT info" << endl;
435 if (fHeader == NULL)
e3a2b9c9 436 {
8a0dae7c 437 cout << "Header is NULL" << endl;
438 return;
439 }
440 cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl;
441 cout << "TotalLength: " << fHeader->fTotalLength << endl;
442 cout << "Length: " << fHeader->fLength << endl;
443 cout << "DspId: " << fHeader->fDSPId << endl;
444 cout << "L0Trigger: " << fHeader->fL0Trigger << endl;
445 cout << "MiniEventId: " << fHeader->fMiniEventId<< endl;
446 cout << "EventId1: " << fHeader->fEventId1 << endl;
447 cout << "EventId2: " << fHeader->fEventId2 << endl;
448}
449
450
451void AliMUONRawStreamTrackerHP::AliDspHeader::Print() const
452{
453 /// Print header to screen.
454
455 cout << "FRT info" << endl;
456 if (fHeader == NULL)
457 {
458 cout << "Header is NULL" << endl;
459 return;
460 }
461 cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl;
462 cout << "TotalLength: " << fHeader->fTotalLength << endl;
463 cout << "Length : " << fHeader->fLength << endl;
464 cout << "DspId: " << fHeader->fDSPId << endl;
465 cout << "BlkL1ATrigger: " << fHeader->fBlkL1ATrigger << endl;
466 cout << "MiniEventId: " << fHeader->fMiniEventId << endl;
467 cout << "L1ATrigger: " << fHeader->fL1ATrigger << endl;
468 cout << "L1RTrigger: " << fHeader->fL1RTrigger << endl;
469 cout << "PaddingWord: " << fHeader->fPaddingWord << endl;
470 cout << "ErrorWord: " << fHeader->fErrorWord << endl;
471}
472
473
474void AliMUONRawStreamTrackerHP::AliBusPatch::Print(const Option_t* opt) const
475{
476 /// Print header to screen.
477 cout << "Bus patch info" << endl;
478 if (fHeader == NULL)
479 {
480 cout << "Header is NULL" << endl;
481 return;
482 }
483 cout << "DataKey: 0x" << hex << fHeader->fDataKey << dec << endl;
484 cout << "fTotalLength: " << fHeader->fTotalLength << endl;
485 cout << "fLength: " << fHeader->fLength << endl;
486 cout << "fBusPatchId: " << fHeader->fBusPatchId << endl;
487
488 if (TString(opt).Contains("all"))
489 {
490 for (UInt_t i = 0; i < fHeader->fLength; ++i)
491 cout << "Data["<< i << "] = " << fData[i] << endl;
e3a2b9c9 492 }
e3a2b9c9 493}
494
495///////////////////////////////////////////////////////////////////////////////
496
497AliMUONRawStreamTrackerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
e3a2b9c9 498 fRawStream(NULL),
8a0dae7c 499 fBufferStart(NULL),
500 fBlockCount(0),
501 fBlocks(NULL),
502 fDSPs(NULL),
503 fBusPatches(NULL),
504 fEndOfBusPatches(NULL),
505 fMaxChannels(8192),
506 fParityOk(new Bool_t[8192]),
507 fCurrentBlock(NULL),
508 fCurrentDSP(NULL),
509 fCurrentBusPatch(NULL),
510 fCurrentParityOkFlag(NULL),
511 fParityErrors(0),
512 fGlitchErrors(0),
513 fPaddingErrors(0),
514 fWarnings(kTRUE)
e3a2b9c9 515{
8a0dae7c 516 /// Default constructor initialises the internal parity flags buffer to
517 /// store 8192 elements. This array will grow dynamically if needed.
e3a2b9c9 518}
519
520
521AliMUONRawStreamTrackerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
522{
523 /// Default destructor cleans up the allocated memory.
524
8a0dae7c 525 if (fParityOk != NULL) delete [] fParityOk;
526 if (fBlocks != NULL) delete [] fBlocks;
527 if (fDSPs != NULL) delete [] fDSPs;
528 if (fBusPatches != NULL) delete [] fBusPatches;
529}
530
531
532void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::SetMaxStructs(
533 UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches
534 )
535{
536 /// Sets the maximum number of structures allowed.
537
538 // Start by clearing the current arrays.
539 if (fBlocks != NULL)
540 {
541 delete [] fBlocks;
542 fBlocks = NULL;
543 }
544 if (fDSPs != NULL)
e3a2b9c9 545 {
8a0dae7c 546 delete [] fDSPs;
547 fDSPs = NULL;
e3a2b9c9 548 }
8a0dae7c 549 if (fBusPatches != NULL)
550 {
551 delete [] fBusPatches;
552 fBusPatches = NULL;
553 }
554 fCurrentBlock = NULL;
555 fCurrentDSP = NULL;
556 fCurrentBusPatch = NULL;
557
558 // Allocate new memory.
559 fBlocks = new AliBlockHeader[maxBlocks];
560 fDSPs = new AliDspHeader[maxBlocks*maxDsps];
561 fBusPatches = new AliBusPatch[maxBlocks*maxDsps*maxBusPatches];
1788245f 562 fEndOfBusPatches = fBusPatches;
e3a2b9c9 563}
564
8a0dae7c 565
e3a2b9c9 566void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer(
567 const void* buffer, UInt_t bufferSize
568 )
569{
570 /// This is called by the high performance decoder when a new DDL payload
571 /// is about to be decoded.
572 /// \param buffer The pointer to the buffer storing the DDL payload.
573 /// \param bufferSize The size of the buffer in bytes.
574
8a0dae7c 575 assert( fRawStream != NULL );
576
e3a2b9c9 577 // remember the start of the buffer to be used in OnError.
578 fBufferStart = buffer;
8a0dae7c 579
580 // Reset error counters.
581 fParityErrors = 0;
582 fGlitchErrors = 0;
583 fPaddingErrors = 0;
584
585 // Check if we will have enough space in the fParityOk array.
e3a2b9c9 586 // If we do not then we need to resize the array.
587 // bufferSize / sizeof(UInt_t) will be a safe over estimate of the
588 // number of channels that we will find.
8a0dae7c 589 UInt_t maxChannelsPossible = bufferSize / sizeof(UInt_t);
590 if (maxChannelsPossible > fMaxChannels)
e3a2b9c9 591 {
8a0dae7c 592 if (fParityOk != NULL)
e3a2b9c9 593 {
8a0dae7c 594 delete [] fParityOk;
595 fParityOk = NULL;
e3a2b9c9 596 fMaxChannels = 0;
597 }
8a0dae7c 598 fParityOk = new Bool_t[maxChannelsPossible];
599 fMaxChannels = maxChannelsPossible;
e3a2b9c9 600 }
e3a2b9c9 601
8a0dae7c 602 // Reset the current pointers which will be used to track where we need to
603 // fill fBlocks, fDSPs, fBusPatches and the parity flag. We have to subtract
604 // one space because we will increment the pointer the first time in the
605 // OnNewXZY methods.
606 fCurrentBlock = fBlocks-1;
607 fCurrentDSP = fDSPs-1;
608 fCurrentBusPatch = fBusPatches-1;
609 fCurrentParityOkFlag = fParityOk-1;
610 fBlockCount = 0;
e3a2b9c9 611}
612
613
614void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnError(
615 ErrorCode error, const void* location
616 )
617{
618 /// This is called by the high performance decoder when a error occurs
619 /// when trying to decode the DDL payload. This indicates corruption in
620 /// the data. This method converts the error code to a descriptive message
1788245f 621 /// and logs this with the raw reader.
e3a2b9c9 622 /// \param error The error code indicating the problem.
623 /// \param location A pointer to the location within the DDL payload buffer
624 /// being decoded where the problem with the data was found.
625
626 assert( fRawStream != NULL );
627 assert( fRawStream->GetReader() != NULL );
628
8a0dae7c 629 Char_t* message = NULL;
630 UInt_t word = 0;
631
e3a2b9c9 632 switch (error)
633 {
8a0dae7c 634 case kGlitchFound:
1788245f 635 fGlitchErrors++;
8a0dae7c 636 message = Form(
637 "Glitch error detected in DSP %d, skipping event ",
638 fCurrentBlock->GetDspId()
639 );
640 fRawStream->GetReader()->AddMajorErrorLog(error, message);
641 break;
642
e3a2b9c9 643 case kBadPaddingWord:
1788245f 644 fPaddingErrors++;
8a0dae7c 645 // We subtract 1 from the current numbers of blocks, DSPs
646 // and bus patches to get the indices.
647 message = Form(
648 "Padding word error for iBlock %d, iDsp %d, iBus %d\n",
649 fBlockCount-1,
650 fCurrentBlock->GetDspCount()-1,
651 fCurrentDSP->GetBusPatchCount()-1
652 );
653 fRawStream->GetReader()->AddMinorErrorLog(error, message);
654 break;
655
e3a2b9c9 656 case kParityError:
1788245f 657 fParityErrors++;
8a0dae7c 658 // location points to the incorrect data word and
659 // fCurrentBusPatch->GetData() returns a pointer to the start of
660 // bus patches data, so the difference divided by 4 gives the 32
661 // bit word number.
662 word = ((unsigned long)location - (unsigned long)fCurrentBusPatch->GetData())
663 / sizeof(UInt_t);
664 message = Form(
665 "Parity error in word %d for manuId %d and channel %d in buspatch %d\n",
666 word,
667 fCurrentBusPatch->GetManuId(word),
668 fCurrentBusPatch->GetChannelId(word),
669 fCurrentBusPatch->GetBusPatchId()
670 );
671 fRawStream->GetReader()->AddMinorErrorLog(error, message);
e3a2b9c9 672 break;
8a0dae7c 673
e3a2b9c9 674 default:
8a0dae7c 675 message = Form(
676 "%s (At byte %d in DDL.)",
677 ErrorCodeToMessage(error),
29ee96d8 678 (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader)
8a0dae7c 679 );
680 fRawStream->GetReader()->AddMajorErrorLog(error, message);
e3a2b9c9 681 break;
682 }
8a0dae7c 683
684 if (fWarnings)
685 {
686 AliWarningGeneral(
687 "AliMUONRawStreamTrackerHP::AliDecoderEventHandler",
688 message
689 );
690 }
e3a2b9c9 691}
692