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