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