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