Update of HP decoders:
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTriggerHP.cxx
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 /// \class AliMUONRawStreamTriggerHP
20 ///
21 /// Implementation of a streamer interface to the high performance trigger decoder.
22 /// This is the raw stream class which interfaces between the high performance
23 /// core decoder for MUON trigger chambers and the AliRawReader class.
24 /// To gain the most out of the decoder, the Next() method should be used,
25 /// for example:
26 /// \code
27 ///   AliMUONRawStreamTriggerHP* rawStream;  // assume initialised
28 ///   const AliMUONRawStreamTriggerHP::AliLocalStruct* localStruct;
29 ///   while ((localStruct = rawStream->Next()) != NULL)
30 ///   {
31 ///      // Do something with localStruct here.
32 ///   }
33 /// \endcode
34 ///
35 /// This decoder tries to implement as similar an interface as possible to
36 /// AliMUONRawStreamTrigger where possible. However certain constructs which
37 /// would slow us down too much are avoided.
38 ///
39 /// \author Artur Szostak <artursz@iafrica.com>
40
41 #include "AliMUONRawStreamTriggerHP.h"
42 #include "AliMUONDarcHeader.h"
43 #include "AliMUONRegHeader.h"
44 #include "AliMUONLocalStruct.h"
45 #include "AliMUONDDLTrigger.h"
46 #include "AliRawReader.h"
47 #include "AliLog.h"
48 #include <cassert>
49 #include <iostream>
50 #include <iomanip>
51 using std::cout;
52 using std::endl;
53 using std::hex;
54 using std::dec;
55
56 /// \cond CLASSIMP
57 ClassImp(AliMUONRawStreamTriggerHP)
58 /// \endcond
59
60 const Int_t AliMUONRawStreamTriggerHP::fgkMaxDDL = 2;
61
62
63 AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP() :
64         AliMUONVRawStreamTrigger(),
65         fDecoder(),
66         fDDL(0),
67         fBufferSize(8192),
68         fBuffer(new UChar_t[8192]),
69         fCurrentLocalStruct(NULL),
70         fHadError(kFALSE),
71         fDone(kFALSE),
72         fDDLObject(NULL)
73 {
74         ///
75         /// Default constructor.
76         ///
77         
78         fDecoder.ExitOnError(false);
79
80         fDecoder.GetHandler().SetMaxStructs(
81                         fDecoder.MaxRegionals(),
82                         fDecoder.MaxLocals()
83                 );
84
85         fDecoder.GetHandler().SetRawStream(this);
86 }
87
88
89 AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP(AliRawReader* rawReader) :
90         AliMUONVRawStreamTrigger(rawReader),
91         fDecoder(),
92         fDDL(0),
93         fBufferSize(8192),
94         fBuffer(new UChar_t[8192]),
95         fCurrentLocalStruct(NULL),
96         fHadError(kFALSE),
97         fDone(kFALSE),
98         fDDLObject(NULL)
99 {
100         ///
101         /// Constructor with AliRawReader as argument.
102         ///
103         
104         fDecoder.ExitOnError(false);
105
106         fDecoder.GetHandler().SetMaxStructs(
107                         fDecoder.MaxRegionals(),
108                         fDecoder.MaxLocals()
109                 );
110         
111         fDecoder.GetHandler().SetRawStream(this);
112 }
113
114
115 AliMUONRawStreamTriggerHP::~AliMUONRawStreamTriggerHP()
116 {
117         ///
118         /// Default destructor which cleans up the memory allocated.
119         ///
120         
121         if (fBuffer != NULL)
122         {
123                 delete [] fBuffer;
124         }
125         if (fDDLObject != NULL)
126         {
127                 delete fDDLObject;
128         }
129 }
130
131
132 void AliMUONRawStreamTriggerHP::First()
133 {
134         /// Initialise or reset the iterator.
135         /// The first DDL will be found and decoded.
136         
137         assert( GetReader() != NULL );
138         
139         fDDL = 0;
140         fDone = kFALSE;
141         NextDDL();
142 }
143
144
145 Bool_t AliMUONRawStreamTriggerHP::NextDDL()
146 {
147         /// Read in the next trigger DDL and decode the payload with the
148         /// high performance decoder.
149         /// \return kTRUE if the next DDL was successfully read and kFALSE
150         ///    otherwise.
151
152         assert( GetReader() != NULL );
153         
154         // The temporary object if generated in GetDDLTracker, is now stale,
155         // so delete it.
156         if (fDDLObject != NULL)
157         {
158                 delete fDDLObject;
159                 fDDLObject = NULL;
160         }
161         
162         fCurrentLocalStruct = NULL;
163         
164         while (fDDL < GetMaxDDL())
165         {
166                 GetReader()->Reset();
167                 GetReader()->Select("MUONTRG", fDDL, fDDL);  // Select the DDL file to be read.
168                 if (GetReader()->ReadHeader()) break;
169                 AliDebug(3, Form("Skipping DDL %d which does not seem to be there", fDDL+1));
170                 fDDL++;
171         }
172
173         // If we reach the end of the DDL list for this event then reset the
174         // DDL counter, mark the iteration as done and exit.
175         if (fDDL >= GetMaxDDL())
176         {
177                 fDDL = 0;
178                 fDone = kTRUE;
179                 return kFALSE;
180         }
181         else
182         {
183                 fDone = kFALSE;
184         }
185
186         AliDebug(3, Form("DDL Number %d\n", fDDL));
187         
188         Int_t dataSize = GetReader()->GetDataSize(); // in bytes
189         // Check if we have enough buffer space already in fBuffer. If we do then
190         // just continue reading otherwise we need to resize the buffer.
191         if (fBufferSize < dataSize)
192         {
193                 if (fBuffer != NULL)
194                 {
195                         delete [] fBuffer;
196                         fBuffer = NULL;
197                         fBufferSize = 0;
198                 }
199                 try
200                 {
201                         fBuffer = new UChar_t[dataSize];
202                         fBufferSize = dataSize;
203                 }
204                 catch (const std::bad_alloc&)
205                 {
206                         AliError("Could not allocate more buffer space. Cannot decode DDL.");
207                         return kFALSE;
208                 }
209         }
210         
211         if (not GetReader()->ReadNext(fBuffer, dataSize))
212         {
213                 return kFALSE;
214         }
215         
216 #ifndef R__BYTESWAP
217         Swap(reinterpret_cast<UInt_t*>(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc.
218 #endif
219         
220         bool result = false;
221         try
222         {
223                 // Since we might allocate memory inside OnNewBuffer in the event
224                 // handler we need to trap any memory allocation exception to be robust.
225                 result = fDecoder.Decode(fBuffer, dataSize);
226                 fHadError = (result == true ? kFALSE : kTRUE);
227         }
228         catch (const std::bad_alloc&)
229         {
230                 AliError("Could not allocate more buffer space. Cannot decode DDL.");
231                 return kFALSE;
232         }
233
234         // Update the current local structure pointer.
235         fCurrentLocalStruct = fDecoder.GetHandler().FirstLocalStruct();
236
237         fDDL++; // Remember to increment index to next DDL.
238         return kTRUE;
239 }
240
241
242 Bool_t AliMUONRawStreamTriggerHP::IsDone() const
243 {
244         /// Indicates whether the iteration is finished or not.
245         /// \return kTRUE if we already read all the digits and kFALSE if not.
246         
247         return fDone;
248 }
249
250
251 Bool_t AliMUONRawStreamTriggerHP::Next(
252                 UChar_t& id,   UChar_t& dec,     Bool_t& trigY,
253                 UChar_t& yPos, UChar_t& sXDev,   UChar_t& xDev,
254                 UChar_t& xPos, Bool_t& triggerY, Bool_t& triggerX,
255                 TArrayS& xPattern, TArrayS& yPattern
256         )
257 {
258         const AliLocalStruct* localStruct = Next();
259         if (localStruct == NULL) return kFALSE;
260         
261         id    = localStruct->GetId();
262         dec   = localStruct->GetDec();
263         trigY = localStruct->GetTrigY();
264         yPos  = localStruct->GetYPos();
265         sXDev = localStruct->GetSXDev();
266         xDev  = localStruct->GetXDev();
267         xPos  = localStruct->GetXPos();
268         
269         triggerX = localStruct->GetTriggerX();
270         triggerY = localStruct->GetTriggerY();
271         
272         localStruct->GetXPattern(xPattern);
273         localStruct->GetYPattern(yPattern);
274
275         return kTRUE;
276 }
277
278
279 AliMUONDDLTrigger* AliMUONRawStreamTriggerHP::GetDDLTrigger() const
280 {
281         /// Construct and return a pointer to the DDL payload object.
282         /// \return Pointer to internally constructed AliMUONDDLTrigger object.
283         ///         The object is owned by this class and should not be deleted
284         ///         by the caller.
285         ///
286         /// \note This method should not be used just to gain access to the DDL
287         /// payload, unless there is a good reason to have the AliMUONDDLTrigger
288         /// object. For example, if you want to modify the data and then save it
289         /// to another DDL stream. Otherwise it can be an order of magnitude
290         /// faster to access the DDL headers and data with the GetHeaders,
291         /// GetRegionalHeader and GetLocalStruct methods for example.
292         /// Refer to the MUONRawStreamTrigger.C macro to see how to use the fast
293         /// decoder interface optimally.
294         
295         if (fDDLObject != NULL) return fDDLObject;
296         
297         fDDLObject = new AliMUONDDLTrigger;
298         
299         // Copy over all DARC, global headers and scalars.
300         AliMUONDarcHeader* darcHeader = fDDLObject->GetDarcHeader();
301         const AliHeader* hdr = GetHeaders();
302         UInt_t word = hdr->GetDarcHeader();
303         memcpy(darcHeader->GetHeader(), &word, sizeof(word));
304         if (hdr->GetDarcScalars() != NULL)
305         {
306                 memcpy(darcHeader->GetDarcScalers(), hdr->GetDarcScalars(), sizeof(AliMUONDarcScalarsStruct));
307         }
308         memcpy(darcHeader->GetGlobalInput(), hdr->GetGlobalHeader(), sizeof(AliMUONGlobalHeaderStruct));
309         if (hdr->GetGlobalScalars() != NULL)
310         {
311                 memcpy(darcHeader->GetGlobalScalers(), hdr->GetGlobalScalars(), sizeof(AliMUONGlobalScalarsStruct));
312         }
313         
314         for (Int_t iReg = 0; iReg < (Int_t)GetRegionalHeaderCount(); iReg++)
315         {
316                 AliMUONRegHeader regHeader;
317                 AliMUONLocalStruct localStruct;
318                 
319                 const AliRegionalHeader* rh = GetRegionalHeader(iReg);
320                 // Copy local structure and scalars and add everything into DDL object.
321                 memcpy(regHeader.GetHeader(), rh->GetHeader(), sizeof(AliMUONRegionalHeaderStruct));
322                 if (rh->GetScalars() != NULL)
323                 {
324                         memcpy(regHeader.GetScalers(), rh->GetScalars(), sizeof(AliMUONRegionalScalarsStruct));
325                 }
326                 fDDLObject->AddRegHeader(regHeader);
327                 
328                 const AliLocalStruct* ls = rh->GetFirstLocalStruct();
329                 while (ls != NULL)
330                 {
331                         // Copy local structure and scalars and add everything into DDL object.
332                         memcpy(localStruct.GetData(), ls->GetData(), sizeof(AliMUONLocalInfoStruct));
333                         if (ls->GetScalars() != NULL)
334                         {
335                                 memcpy(localStruct.GetScalers(), ls->GetScalars(), sizeof(AliMUONLocalScalarsStruct));
336                         }
337                         fDDLObject->AddLocStruct(localStruct, iReg);
338                         ls = ls->Next();
339                 }
340         }
341         
342         return fDDLObject;
343 }
344
345
346 void AliMUONRawStreamTriggerHP::SetMaxRegAllowed(Int_t reg)
347 {
348         /// Set the maximum allowed number of regional cards in the DDL.
349         
350         fDecoder.MaxRegionals( (UInt_t) reg );
351         
352         fDecoder.GetHandler().SetMaxStructs(
353                         fDecoder.MaxRegionals(),
354                         fDecoder.MaxLocals()
355                 );
356 }
357
358
359 void AliMUONRawStreamTriggerHP::SetMaxLoc(Int_t loc)
360 {
361         /// Sets the maximum number of local cards in the DDL.
362         
363         fDecoder.MaxLocals( (UInt_t) loc );
364         
365         fDecoder.GetHandler().SetMaxStructs(
366                         fDecoder.MaxRegionals(),
367                         fDecoder.MaxLocals()
368                 );
369 }
370
371 ///////////////////////////////////////////////////////////////////////////////
372
373 void AliMUONRawStreamTriggerHP::AliHeader::Print() const
374 {
375         /// Print DARC header, global header and global scalars to screen.
376         
377         cout << "===== DARC info =====" << endl;
378         cout << "Header bits : 0x" << hex << fDarcHeader << dec << endl;
379         if (fDarcScalars != NULL)
380         {
381                 cout << "L0R :   " << fDarcScalars->fL0R << " (0x"
382                         << hex << fDarcScalars->fL0R << dec << ")" << endl;
383                 cout << "L1P :   " << fDarcScalars->fL1P << " (0x"
384                         << hex << fDarcScalars->fL1P << dec << ")" << endl;
385                 cout << "L1S :   " << fDarcScalars->fL1S << " (0x"
386                         << hex << fDarcScalars->fL1S << dec << ")" << endl;
387                 cout << "L2A :   " << fDarcScalars->fL2A << " (0x"
388                         << hex << fDarcScalars->fL2A << dec << ")" << endl;
389                 cout << "L2R :   " << fDarcScalars->fL2R << " (0x"
390                         << hex << fDarcScalars->fL2R << dec << ")" << endl;
391                 cout << "Clock : " << fDarcScalars->fClk << " (0x"
392                         << hex << fDarcScalars->fClk << dec << ")" << endl;
393                 cout << "Hold :  " << fDarcScalars->fHold << " (0x"
394                         << hex << fDarcScalars->fHold << dec << ")" << endl;
395                 cout << "Spare : " << fDarcScalars->fSpare << " (0x"
396                         << hex << fDarcScalars->fSpare << dec << ")" << endl;
397         }
398         else
399         {
400                 cout << "Scalars == NULL" << endl;
401         }
402         
403         cout << "===== Global info =====" << endl;
404         for (int i = 0; i < 4; i++)
405         {
406                 cout << "Input[" << i << "] : " << fGlobalHeader->fInput[i] << " (0x"
407                         << hex << fGlobalHeader->fInput[i] << dec << ")" << endl;
408         }
409         cout << "Output :    " << fGlobalHeader->fOutput << " (0x"
410                 << hex << fGlobalHeader->fOutput << dec << ")" << endl;
411         if (fGlobalScalars != NULL)
412         {
413                 cout << "L0 :         " << fGlobalScalars->fL0 << " (0x"
414                         << hex << fGlobalScalars->fL0 << dec << ")" << endl;
415                 cout << "Clock :     " << fGlobalScalars->fClk << " (0x"
416                         << hex << fGlobalScalars->fClk << dec << ")" << endl;
417                 for (int j = 0; j < 4; j++)
418                 {
419                         cout << "Scaler[" << j << "] : " << fGlobalScalars->fScaler[j] << " (0x"
420                                 << hex << fGlobalScalars->fScaler[j] << dec << ")" << endl;
421                 }
422                 cout << "Hold :      " << fGlobalScalars->fHold << " (0x"
423                         << hex << fGlobalScalars->fHold << dec << ")" << endl;
424                 cout << "Spare :     " << fGlobalScalars->fSpare << " (0x"
425                         << hex << fGlobalScalars->fSpare << dec << ")" << endl;
426         }
427         else
428         {
429                 cout << "Scalars == NULL" << endl;
430         }
431 }
432
433 void AliMUONRawStreamTriggerHP::AliRegionalHeader::Print() const
434 {
435         /// Print the regional header and scalars to screen.
436         
437         cout << "===== Regional card info =====" << endl;
438         cout << "DarcWord : " << fHeader->fDarcWord << " (0x"
439                 << hex << fHeader->fDarcWord << dec << ")" << endl;
440         cout << "Word :     " << fHeader->fWord << " (0x"
441                 << hex << fHeader->fWord << dec << ")" << endl;
442         cout << "Input[0] : " << fHeader->fInput[0] << " (0x"
443                 << hex << fHeader->fInput[0] << dec << ")" << endl;
444         cout << "Input[1] : " << fHeader->fInput[1] << " (0x"
445                 << hex << fHeader->fInput[1] << dec << ")" << endl;
446         cout << "L0/Mask :  " << fHeader->fL0CountAndMask << " (0x"
447                 << hex << fHeader->fL0CountAndMask << dec << ")" << endl;
448         if (fScalars != NULL)
449         {
450                 cout << "Clock :     " << fScalars->fClk << " (0x"
451                         << hex << fScalars->fClk << dec << ")" << endl;
452                 for (int i = 0; i < 8; i++)
453                 {
454                         cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
455                                 << hex << fScalars->fScaler[i] << dec << ")" << endl;
456                 }
457                 cout << "Hold :      " << fScalars->fHold << " (0x"
458                         << hex << fScalars->fHold << dec << ")" << endl;
459         }
460         else
461         {
462                 cout << "Scalars == NULL" << endl;
463         }
464 }
465
466 void AliMUONRawStreamTriggerHP::AliLocalStruct::Print() const
467 {
468         /// Print local trigger structure and scalars to screen.
469         
470         cout << "===== Local card info =====" << endl;
471         cout << "X2X1 :         " << fLocalStruct->fX2X1 << " (0x"
472                 << hex << fLocalStruct->fX2X1 << dec << ")" << endl;
473         cout << "X4X3 :         " << fLocalStruct->fX4X3 << " (0x"
474                 << hex << fLocalStruct->fX4X3 << dec << ")" << endl;
475         cout << "Y2Y1 :         " << fLocalStruct->fY2Y1 << " (0x"
476                 << hex << fLocalStruct->fY2Y1 << dec << ")" << endl;
477         cout << "Y4Y3 :         " << fLocalStruct->fY4Y3 << " (0x"
478                 << hex << fLocalStruct->fY4Y3 << dec << ")" << endl;
479         cout << "Trigger bits : " << fLocalStruct->fTriggerBits << " (0x"
480                 << hex << fLocalStruct->fTriggerBits << dec << ")" << endl;
481         if (fScalars != NULL)
482         {
483                 cout << "L0 :           " << fScalars->fL0 << " (0x"
484                         << hex << fScalars->fL0 << dec << ")" << endl;
485                 cout << "Hold :         " << fScalars->fHold << " (0x"
486                         << hex << fScalars->fHold << dec << ")" << endl;
487                 cout << "Clock :        " << fScalars->fClk << " (0x"
488                         << hex << fScalars->fClk << dec << ")" << endl;
489                 cout << "LPtNTrig :     " << fScalars->fLPtNTrig << " (0x"
490                         << hex << fScalars->fLPtNTrig << dec << ")" << endl;
491                 cout << "HPtNTrig :     " << fScalars->fHPtNTrig << " (0x"
492                         << hex << fScalars->fHPtNTrig << dec << ")" << endl;
493                 cout << "LPtRTrig :     " << fScalars->fLPtRTrig << " (0x"
494                         << hex << fScalars->fLPtRTrig << dec << ")" << endl;
495                 cout << "HPtRTrig :     " << fScalars->fHPtRTrig << " (0x"
496                         << hex << fScalars->fHPtRTrig << dec << ")" << endl;
497                 cout << "LPtLTrig :     " << fScalars->fLPtLTrig << " (0x"
498                         << hex << fScalars->fLPtLTrig << dec << ")" << endl;
499                 cout << "HPtLTrig :     " << fScalars->fHPtLTrig << " (0x"
500                         << hex << fScalars->fHPtLTrig << dec << ")" << endl;
501                 cout << "LPtSTrig :     " << fScalars->fLPtSTrig << " (0x"
502                         << hex << fScalars->fLPtSTrig << dec << ")" << endl;
503                 cout << "HPtSTrig :     " << fScalars->fHPtSTrig << " (0x"
504                         << hex << fScalars->fHPtSTrig << dec << ")" << endl;
505                 for (int i = 0; i < 8*4; i++)
506                 {
507                         cout << "Scaler[" << i << "] :  " << fScalars->fScaler[i] << " (0x"
508                                 << hex << fScalars->fScaler[i] << dec << ")" << endl;
509                 }
510                 cout << "EOS :          " << fScalars->fEOS << " (0x"
511                         << hex << fScalars->fEOS << dec << ")" << endl;
512                 cout << "Reset :        " << fScalars->fReset << " (0x"
513                         << hex << fScalars->fReset << dec << ")" << endl;
514         }
515         else
516         {
517                 cout << "Scalars == NULL" << endl;
518         }
519 }
520
521 ///////////////////////////////////////////////////////////////////////////////
522
523 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
524         fRawStream(NULL),
525         fBufferStart(NULL),
526         fDarcHeader(0),
527         fDarcScalars(NULL),
528         fHeaders(),
529         fRegionalsCount(0),
530         fRegionals(NULL),
531         fLocals(NULL),
532         fEndOfLocals(NULL),
533         fCurrentRegional(NULL),
534         fCurrentLocal(NULL),
535         fDarcEoWErrors(0),
536         fGlobalEoWErrors(0),
537         fRegEoWErrors(0),
538         fLocalEoWErrors(0),
539         fWarnings(kTRUE)
540 {
541         /// Default constructor
542 }
543
544
545 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
546 {
547         /// Default destructor cleans up the allocated memory.
548         
549         if (fRegionals != NULL) delete [] fRegionals;
550         if (fLocals != NULL) delete [] fLocals;
551 }
552
553
554 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::SetMaxStructs(
555                 UInt_t maxRegionals, UInt_t maxLocals
556         )
557 {
558         /// Sets the maximum number of structures allowed.
559         
560         // Start by clearing the current arrays.
561         if (fRegionals != NULL)
562         {
563                 delete [] fRegionals;
564                 fRegionals = NULL;
565         }
566         if (fLocals != NULL)
567         {
568                 delete [] fLocals;
569                 fLocals = NULL;
570                 fEndOfLocals = NULL;
571         }
572         fCurrentRegional = NULL;
573         fCurrentLocal = NULL;
574         
575         // Allocate new memory.
576         fRegionals = new AliRegionalHeader[maxRegionals];
577         fLocals = new AliLocalStruct[maxRegionals*maxLocals];
578         fEndOfLocals = fLocals;
579 }
580
581
582 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnNewBuffer(
583                 const void* buffer, UInt_t /*bufferSize*/
584         )
585 {
586         /// This is called by the high performance decoder when a new DDL payload
587         /// is about to be decoded.
588
589         assert( fRawStream != NULL );
590         
591         // remember the start of the buffer to be used in OnError.
592         fBufferStart = buffer;
593
594         // Reset error counters.
595         fDarcEoWErrors = 0;
596         fGlobalEoWErrors = 0;
597         fRegEoWErrors = 0;
598         fLocalEoWErrors = 0;
599         
600         // Reset the current pointers which will be used to track where we need to
601         // fill fRegionals and fLocals. We have to subtract one space because we
602         // will increment the pointer the first time in the OnNewRegionalStruct
603         // and OnLocalStruct methods.
604         fCurrentRegional = fRegionals-1;
605         fCurrentLocal = fLocals-1;
606         fRegionalsCount = 0;
607 }
608
609
610 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnError(
611                 ErrorCode error, const void* location
612         )
613 {
614         /// This is called by the high performance decoder when a error occurs
615         /// when trying to decode the DDL payload. This indicates corruption in
616         /// the data. This method converts the error code to a descriptive message
617         /// and logs this with the raw reader.
618         /// \param error  The error code indicating the problem.
619         /// \param location  A pointer to the location within the DDL payload buffer
620         ///              being decoded where the problem with the data was found.
621
622         assert( fRawStream != NULL );
623         assert( fRawStream->GetReader() != NULL );
624         
625         Char_t* message = NULL;
626         //UInt_t word = 0;
627
628         switch (error)
629         {
630         case kWrongEventType:
631                 message = Form("Wrong event type obtained from the Darc header, take the one of CDH");
632                 break;
633                 
634         case kBadEndOfDarc:
635                 fDarcEoWErrors++;
636                 message = Form(
637                         "Wrong end of Darc word %x instead of %x\n",
638                         *reinterpret_cast<const UInt_t*>(location),
639                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfDarcWord()
640                 );
641                 fRawStream->GetReader()->AddMajorErrorLog(kDarcEoWErr, message);
642                 break;
643                 
644         case kBadEndOfGlobal:
645                 fGlobalEoWErrors++;
646                 message = Form(
647                         "Wrong end of Global word %x instead of %x\n",
648                         *reinterpret_cast<const UInt_t*>(location),
649                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfGlobalWord()
650                 );
651                 fRawStream->GetReader()->AddMajorErrorLog(kGlobalEoWErr, message);
652                 break;
653                 
654         case kBadEndOfRegional:
655                 fRegEoWErrors++;
656                 message = Form(
657                         "Wrong end of Regional word %x instead of %x\n",
658                         *reinterpret_cast<const UInt_t*>(location),
659                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfRegionalWord()
660                 );
661                 fRawStream->GetReader()->AddMajorErrorLog(kRegEoWErr, message);
662                 break;
663                 
664         case kBadEndOfLocal:
665                 fLocalEoWErrors++;
666                 message = Form(
667                         "Wrong end of Local word %x instead of %x\n",
668                         *reinterpret_cast<const UInt_t*>(location),
669                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfLocalWord()
670                 );
671                 fRawStream->GetReader()->AddMajorErrorLog(kLocalEoWErr, message);
672                 break;
673                 
674         default:
675                 message = Form(
676                         "%s (At byte %d in DDL.)",
677                         ErrorCodeToMessage(error),
678                         (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader)
679                 );
680                 fRawStream->GetReader()->AddMajorErrorLog(error, message);
681                 break;
682         }
683
684         if (fWarnings)
685         {
686                 AliWarningGeneral(
687                                 "AliMUONRawStreamTriggerHP::AliDecoderEventHandler",
688                                 message
689                         );
690         }
691 }
692