]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawStreamTriggerHP.cxx
new cuts and tasks added
[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         // Check if this is a scalar event.
241         bool scalerEvent = (GetReader()->GetDataHeader()->GetL1TriggerMessage() & 0x1) == 0x1;
242         
243         bool result = false;
244         try
245         {
246                 // Since we might allocate memory inside OnNewBuffer in the event
247                 // handler we need to trap any memory allocation exception to be robust.
248                 result = fDecoder.Decode(fBuffer, dataSize, scalerEvent);
249                 fHadError = (result == true ? kFALSE : kTRUE);
250                 fTotalNumberOfDarcEoWErrors += fDecoder.GetHandler().GetDarcEoWErrors();
251                 fTotalNumberOfGlobalEoWErrors += fDecoder.GetHandler().GetGlobalEoWErrors();
252                 fTotalNumberOfRegEoWErrors += fDecoder.GetHandler().GetRegEoWErrors();
253                 fTotalNumberOfLocalEoWErrors += fDecoder.GetHandler().GetLocalEoWErrors();
254         }
255         catch (const std::bad_alloc&)
256         {
257                 AliError("Could not allocate more buffer space. Cannot decode DDL.");
258                 return kFALSE;
259         }
260
261         // Update the current local structure pointer.
262         fkCurrentLocalStruct = fDecoder.GetHandler().FirstLocalStruct();
263
264         fDDL++; // Remember to increment index to next DDL.
265         return kTRUE;
266 }
267
268
269 Bool_t AliMUONRawStreamTriggerHP::IsDone() const
270 {
271         /// Indicates whether the iteration is finished or not.
272         /// \return kTRUE if we already read all the digits and kFALSE if not.
273         
274         return fDone;
275 }
276
277
278 Bool_t AliMUONRawStreamTriggerHP::Next(
279                 UChar_t& id,   UChar_t& dec,     Bool_t& trigY,
280                 UChar_t& yPos, UChar_t& sXDev,   UChar_t& xDev,
281                 UChar_t& xPos, Bool_t& triggerY, Bool_t& triggerX,
282                 TArrayS& xPattern, TArrayS& yPattern
283         )
284 {
285         /// Advance one step in the iteration. Returns kFALSE if finished.
286         /// If kTRUE is returned then the output parameters are filled with
287         /// the values found in the next local trigger circuit structure.
288         
289         const AliLocalStruct* localStruct = Next();
290         if (localStruct == NULL) return kFALSE;
291         
292         id    = localStruct->GetId();
293         dec   = localStruct->GetDec();
294         trigY = localStruct->GetTrigY();
295         yPos  = localStruct->GetYPos();
296         sXDev = localStruct->GetSXDev();
297         xDev  = localStruct->GetXDev();
298         xPos  = localStruct->GetXPos();
299         
300         triggerX = localStruct->GetTriggerX();
301         triggerY = localStruct->GetTriggerY();
302         
303         localStruct->GetXPattern(xPattern);
304         localStruct->GetYPattern(yPattern);
305
306         return kTRUE;
307 }
308
309
310 AliMUONDDLTrigger* AliMUONRawStreamTriggerHP::GetDDLTrigger() const
311 {
312         /// Construct and return a pointer to the DDL payload object.
313         /// \return Pointer to internally constructed AliMUONDDLTrigger object.
314         ///         The object is owned by this class and should not be deleted
315         ///         by the caller.
316         ///
317         /// \note This method should not be used just to gain access to the DDL
318         /// payload, unless there is a good reason to have the AliMUONDDLTrigger
319         /// object. For example, if you want to modify the data and then save it
320         /// to another DDL stream. Otherwise it can be an order of magnitude
321         /// faster to access the DDL headers and data with the GetHeaders,
322         /// GetRegionalHeader and GetLocalStruct methods for example.
323         /// Refer to the MUONRawStreamTrigger.C macro to see how to use the fast
324         /// decoder interface optimally.
325         
326         if (fDDLObject != NULL) return fDDLObject;
327         
328         fDDLObject = new AliMUONDDLTrigger;
329         
330         // Copy over all DARC, global headers and scalars.
331         AliMUONDarcHeader* darcHeader = fDDLObject->GetDarcHeader();
332         const AliHeader* hdr = GetHeaders();
333         UInt_t word = hdr->GetDarcHeader();
334         memcpy(darcHeader->GetHeader(), &word, sizeof(word));
335         if (hdr->GetDarcScalars() != NULL)
336         {
337                 memcpy(darcHeader->GetDarcScalers(), hdr->GetDarcScalars(), sizeof(AliMUONDarcScalarsStruct));
338         }
339         memcpy(darcHeader->GetGlobalInput(), hdr->GetGlobalHeader(), sizeof(AliMUONGlobalHeaderStruct));
340         if (hdr->GetGlobalScalars() != NULL)
341         {
342                 memcpy(darcHeader->GetGlobalScalers(), hdr->GetGlobalScalars(), sizeof(AliMUONGlobalScalarsStruct));
343         }
344         
345         for (Int_t iReg = 0; iReg < (Int_t)GetRegionalHeaderCount(); iReg++)
346         {
347                 AliMUONRegHeader regHeader;
348                 AliMUONLocalStruct localStruct;
349                 
350                 const AliRegionalHeader* rh = GetRegionalHeader(iReg);
351                 // Copy local structure and scalars and add everything into DDL object.
352                 memcpy(regHeader.GetHeader(), rh->GetHeader(), sizeof(AliMUONRegionalHeaderStruct));
353                 if (rh->GetScalars() != NULL)
354                 {
355                         memcpy(regHeader.GetScalers(), rh->GetScalars(), sizeof(AliMUONRegionalScalarsStruct));
356                 }
357                 fDDLObject->AddRegHeader(regHeader);
358                 
359                 const AliLocalStruct* lstruct = rh->GetFirstLocalStruct();
360                 while (lstruct != NULL)
361                 {
362                         // Copy local structure and scalars and add everything into DDL object.
363                         memcpy(localStruct.GetData(), lstruct->GetData(), sizeof(AliMUONLocalInfoStruct));
364                         if (lstruct->GetScalars() != NULL)
365                         {
366                                 memcpy(localStruct.GetScalers(), lstruct->GetScalars(), sizeof(AliMUONLocalScalarsStruct));
367                         }
368                         if (AliMUONRawStreamTriggerHP::AliLocalStruct::GetOverrideIdFlag() == true)
369                         {
370                                 // Since the override ID flag is set, we need to replace the
371                                 // ID in the structure with the calculated one returned by GetId().
372                                 AliMUONLocalInfoStruct* strptr = reinterpret_cast<AliMUONLocalInfoStruct*>( localStruct.GetData() );
373                                 UInt_t triggerBits = strptr->fTriggerBits;
374                                 triggerBits &= ~(0xF << 19);
375                                 strptr->fTriggerBits = triggerBits | ((lstruct->GetId() & 0xF) << 19);
376                         }
377                         fDDLObject->AddLocStruct(localStruct, iReg);
378                         lstruct = lstruct->Next();
379                 }
380         }
381         
382         return fDDLObject;
383 }
384
385
386 void AliMUONRawStreamTriggerHP::SetMaxReg(Int_t reg)
387 {
388         /// Set the maximum allowed number of regional cards in the DDL.
389         
390         fDecoder.MaxRegionals( (UInt_t) reg );
391         
392         fDecoder.GetHandler().SetMaxStructs(
393                         fDecoder.MaxRegionals(),
394                         fDecoder.MaxLocals()
395                 );
396 }
397
398
399 void AliMUONRawStreamTriggerHP::SetMaxLoc(Int_t loc)
400 {
401         /// Sets the maximum number of local cards in the DDL.
402         
403         fDecoder.MaxLocals( (UInt_t) loc );
404         
405         fDecoder.GetHandler().SetMaxStructs(
406                         fDecoder.MaxRegionals(),
407                         fDecoder.MaxLocals()
408                 );
409 }
410
411 ///////////////////////////////////////////////////////////////////////////////
412
413 void AliMUONRawStreamTriggerHP::AliHeader::Print() const
414 {
415         /// Print DARC header, global header and global scalars to screen.
416         
417         cout << "===== DARC info =====" << endl;
418         cout << "Header bits : 0x" << hex << fDarcHeader << dec << endl;
419         if (fDarcScalars != NULL)
420         {
421                 cout << "L0R :   " << fDarcScalars->fL0R << " (0x"
422                         << hex << fDarcScalars->fL0R << dec << ")" << endl;
423                 cout << "L1P :   " << fDarcScalars->fL1P << " (0x"
424                         << hex << fDarcScalars->fL1P << dec << ")" << endl;
425                 cout << "L1S :   " << fDarcScalars->fL1S << " (0x"
426                         << hex << fDarcScalars->fL1S << dec << ")" << endl;
427                 cout << "L2A :   " << fDarcScalars->fL2A << " (0x"
428                         << hex << fDarcScalars->fL2A << dec << ")" << endl;
429                 cout << "L2R :   " << fDarcScalars->fL2R << " (0x"
430                         << hex << fDarcScalars->fL2R << dec << ")" << endl;
431                 cout << "Clock : " << fDarcScalars->fClk << " (0x"
432                         << hex << fDarcScalars->fClk << dec << ")" << endl;
433                 cout << "Hold :  " << fDarcScalars->fHold << " (0x"
434                         << hex << fDarcScalars->fHold << dec << ")" << endl;
435                 cout << "Spare : " << fDarcScalars->fSpare << " (0x"
436                         << hex << fDarcScalars->fSpare << dec << ")" << endl;
437         }
438         else
439         {
440                 cout << "Scalars == NULL" << endl;
441         }
442         
443         cout << "===== Global info =====" << endl;
444         for (int i = 0; i < 4; i++)
445         {
446                 cout << "Input[" << i << "] : " << fGlobalHeader->fInput[i] << " (0x"
447                         << hex << fGlobalHeader->fInput[i] << dec << ")" << endl;
448         }
449         cout << "Output :    " << fGlobalHeader->fOutput << " (0x"
450                 << hex << fGlobalHeader->fOutput << dec << ")" << endl;
451         if (fGlobalScalars != NULL)
452         {
453                 cout << "L0 :         " << fGlobalScalars->fL0 << " (0x"
454                         << hex << fGlobalScalars->fL0 << dec << ")" << endl;
455                 cout << "Clock :     " << fGlobalScalars->fClk << " (0x"
456                         << hex << fGlobalScalars->fClk << dec << ")" << endl;
457                 for (int j = 0; j < 4; j++)
458                 {
459                         cout << "Scaler[" << j << "] : " << fGlobalScalars->fScaler[j] << " (0x"
460                                 << hex << fGlobalScalars->fScaler[j] << dec << ")" << endl;
461                 }
462                 cout << "Hold :      " << fGlobalScalars->fHold << " (0x"
463                         << hex << fGlobalScalars->fHold << dec << ")" << endl;
464                 cout << "Spare :     " << fGlobalScalars->fSpare << " (0x"
465                         << hex << fGlobalScalars->fSpare << dec << ")" << endl;
466         }
467         else
468         {
469                 cout << "Scalars == NULL" << endl;
470         }
471 }
472
473 void AliMUONRawStreamTriggerHP::AliRegionalHeader::Print() const
474 {
475         /// Print the regional header and scalars to screen.
476         
477         cout << "===== Regional card info =====" << endl;
478         cout << "DarcWord : " << fHeader->fDarcWord << " (0x"
479                 << hex << fHeader->fDarcWord << dec << ")" << endl;
480         cout << "Word :     " << fHeader->fWord << " (0x"
481                 << hex << fHeader->fWord << dec << ")" << endl;
482         cout << "Input[0] : " << fHeader->fInput[0] << " (0x"
483                 << hex << fHeader->fInput[0] << dec << ")" << endl;
484         cout << "Input[1] : " << fHeader->fInput[1] << " (0x"
485                 << hex << fHeader->fInput[1] << dec << ")" << endl;
486         cout << "L0/Mask :  " << fHeader->fL0CountAndMask << " (0x"
487                 << hex << fHeader->fL0CountAndMask << dec << ")" << endl;
488         if (fScalars != NULL)
489         {
490                 cout << "Clock :     " << fScalars->fClk << " (0x"
491                         << hex << fScalars->fClk << dec << ")" << endl;
492                 for (int i = 0; i < 8; i++)
493                 {
494                         cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
495                                 << hex << fScalars->fScaler[i] << dec << ")" << endl;
496                 }
497                 cout << "Hold :      " << fScalars->fHold << " (0x"
498                         << hex << fScalars->fHold << dec << ")" << endl;
499         }
500         else
501         {
502                 cout << "Scalars == NULL" << endl;
503         }
504 }
505
506 void AliMUONRawStreamTriggerHP::AliLocalStruct::Print() const
507 {
508         /// Print local trigger structure and scalars to screen.
509         
510         cout << "===== Local card info =====" << endl;
511         cout << "X2X1 :         " << fLocalStruct->fX2X1 << " (0x"
512                 << hex << fLocalStruct->fX2X1 << dec << ")" << endl;
513         cout << "X4X3 :         " << fLocalStruct->fX4X3 << " (0x"
514                 << hex << fLocalStruct->fX4X3 << dec << ")" << endl;
515         cout << "Y2Y1 :         " << fLocalStruct->fY2Y1 << " (0x"
516                 << hex << fLocalStruct->fY2Y1 << dec << ")" << endl;
517         cout << "Y4Y3 :         " << fLocalStruct->fY4Y3 << " (0x"
518                 << hex << fLocalStruct->fY4Y3 << dec << ")" << endl;
519         cout << "Trigger bits : " << fLocalStruct->fTriggerBits << " (0x"
520                 << hex << fLocalStruct->fTriggerBits << dec << ")" << endl;
521         if (fScalars != NULL)
522         {
523                 cout << "L0 :           " << fScalars->fL0 << " (0x"
524                         << hex << fScalars->fL0 << dec << ")" << endl;
525                 cout << "Hold :         " << fScalars->fHold << " (0x"
526                         << hex << fScalars->fHold << dec << ")" << endl;
527                 cout << "Clock :        " << fScalars->fClk << " (0x"
528                         << hex << fScalars->fClk << dec << ")" << endl;
529                 cout << "LPtNTrig :     " << fScalars->fLPtNTrig << " (0x"
530                         << hex << fScalars->fLPtNTrig << dec << ")" << endl;
531                 cout << "HPtNTrig :     " << fScalars->fHPtNTrig << " (0x"
532                         << hex << fScalars->fHPtNTrig << dec << ")" << endl;
533                 cout << "LPtRTrig :     " << fScalars->fLPtRTrig << " (0x"
534                         << hex << fScalars->fLPtRTrig << dec << ")" << endl;
535                 cout << "HPtRTrig :     " << fScalars->fHPtRTrig << " (0x"
536                         << hex << fScalars->fHPtRTrig << dec << ")" << endl;
537                 cout << "LPtLTrig :     " << fScalars->fLPtLTrig << " (0x"
538                         << hex << fScalars->fLPtLTrig << dec << ")" << endl;
539                 cout << "HPtLTrig :     " << fScalars->fHPtLTrig << " (0x"
540                         << hex << fScalars->fHPtLTrig << dec << ")" << endl;
541                 cout << "LPtSTrig :     " << fScalars->fLPtSTrig << " (0x"
542                         << hex << fScalars->fLPtSTrig << dec << ")" << endl;
543                 cout << "HPtSTrig :     " << fScalars->fHPtSTrig << " (0x"
544                         << hex << fScalars->fHPtSTrig << dec << ")" << endl;
545                 for (int i = 0; i < 8*4; i++)
546                 {
547                         cout << "Scaler[" << i << "] :  " << fScalars->fScaler[i] << " (0x"
548                                 << hex << fScalars->fScaler[i] << dec << ")" << endl;
549                 }
550                 cout << "EOS :          " << fScalars->fEOS << " (0x"
551                         << hex << fScalars->fEOS << dec << ")" << endl;
552                 cout << "Reset :        " << fScalars->fReset << " (0x"
553                         << hex << fScalars->fReset << dec << ")" << endl;
554         }
555         else
556         {
557                 cout << "Scalars == NULL" << endl;
558         }
559 }
560
561 ///////////////////////////////////////////////////////////////////////////////
562
563 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
564         fRawStream(NULL),
565         fBufferStart(NULL),
566         fDarcHeader(0),
567         fDarcScalars(NULL),
568         fHeaders(),
569         fRegionalsCount(0),
570         fRegionals(NULL),
571         fLocals(NULL),
572         fEndOfLocals(NULL),
573         fCurrentRegional(NULL),
574         fCurrentLocal(NULL),
575         fDarcEoWErrors(0),
576         fGlobalEoWErrors(0),
577         fRegEoWErrors(0),
578         fLocalEoWErrors(0),
579         fWarnings(kTRUE)
580 {
581         /// Default constructor
582 }
583
584
585 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
586 {
587         /// Default destructor cleans up the allocated memory.
588         
589         if (fRegionals != NULL) delete [] fRegionals;
590         if (fLocals != NULL) delete [] fLocals;
591 }
592
593
594 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::SetMaxStructs(
595                 UInt_t maxRegionals, UInt_t maxLocals
596         )
597 {
598         /// Sets the maximum number of structures allowed.
599         
600         // Start by clearing the current arrays.
601         if (fRegionals != NULL)
602         {
603                 delete [] fRegionals;
604                 fRegionals = NULL;
605         }
606         if (fLocals != NULL)
607         {
608                 delete [] fLocals;
609                 fLocals = NULL;
610                 fEndOfLocals = NULL;
611         }
612         fCurrentRegional = NULL;
613         fCurrentLocal = NULL;
614         
615         // Allocate new memory.
616         fRegionals = new AliRegionalHeader[maxRegionals];
617         fLocals = new AliLocalStruct[maxRegionals*maxLocals];
618         fEndOfLocals = fLocals;
619         
620         fRegionalsCount = maxRegionals;
621 }
622
623
624 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnNewBuffer(
625                 const void* buffer, UInt_t /*bufferSize*/
626         )
627 {
628         /// This is called by the high performance decoder when a new DDL payload
629         /// is about to be decoded.
630
631         assert( fRawStream != NULL );
632         
633         // remember the start of the buffer to be used in OnError.
634         fBufferStart = buffer;
635
636         // Reset error counters.
637         fDarcEoWErrors = 0;
638         fGlobalEoWErrors = 0;
639         fRegEoWErrors = 0;
640         fLocalEoWErrors = 0;
641         
642         // Reset the current local structure pointer which will be used to track
643         // where we need to fill fLocals. We have to subtract one space because we
644         // will increment the pointer the first time in the OnLocalStruct method.
645         fCurrentLocal = fLocals-1;
646         
647         fCurrentRegional = NULL;
648         
649         // Reset and link up all the regional structures together.
650         for (UInt_t i = 0; i+1 < fRegionalsCount; i++)
651         {
652                 fRegionals[i] = AliRegionalHeader(fLocals, &fgkEmptyHeader, NULL);
653                 fRegionals[i].SetNext(&fRegionals[i+1]);
654         }
655         // Reset the last structure.
656         fRegionals[fRegionalsCount-1] = AliRegionalHeader(fLocals, &fgkEmptyHeader, NULL);
657 }
658
659
660 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnError(
661                 ErrorCode error, const void* location
662         )
663 {
664         /// This is called by the high performance decoder when a error occurs
665         /// when trying to decode the DDL payload. This indicates corruption in
666         /// the data. This method converts the error code to a descriptive message
667         /// and logs this with the raw reader.
668         /// \param error  The error code indicating the problem.
669         /// \param location  A pointer to the location within the DDL payload buffer
670         ///              being decoded where the problem with the data was found.
671
672         assert( fRawStream != NULL );
673         assert( fRawStream->GetReader() != NULL );
674         
675         Char_t* message = NULL;
676         //UInt_t word = 0;
677
678         switch (error)
679         {
680         case kWrongEventType:
681                 message = Form("Wrong event type obtained from the Darc header, take the one of CDH");
682                 break;
683                 
684         case kBadEndOfDarc:
685                 fDarcEoWErrors++;
686                 message = Form(
687                         "Wrong end of Darc word %x instead of %x\n",
688                         *reinterpret_cast<const UInt_t*>(location),
689                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfDarcWord()
690                 );
691                 fRawStream->GetReader()->AddMajorErrorLog(kDarcEoWErr, message);
692                 break;
693                 
694         case kBadEndOfGlobal:
695                 fGlobalEoWErrors++;
696                 message = Form(
697                         "Wrong end of Global word %x instead of %x\n",
698                         *reinterpret_cast<const UInt_t*>(location),
699                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfGlobalWord()
700                 );
701                 fRawStream->GetReader()->AddMajorErrorLog(kGlobalEoWErr, message);
702                 break;
703                 
704         case kBadEndOfRegional:
705                 fRegEoWErrors++;
706                 message = Form(
707                         "Wrong end of Regional word %x instead of %x\n",
708                         *reinterpret_cast<const UInt_t*>(location),
709                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfRegionalWord()
710                 );
711                 fRawStream->GetReader()->AddMajorErrorLog(kRegEoWErr, message);
712                 break;
713                 
714         case kBadEndOfLocal:
715                 fLocalEoWErrors++;
716                 message = Form(
717                         "Wrong end of Local word %x instead of %x\n",
718                         *reinterpret_cast<const UInt_t*>(location),
719                         AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfLocalWord()
720                 );
721                 fRawStream->GetReader()->AddMajorErrorLog(kLocalEoWErr, message);
722                 break;
723                 
724         default:
725                 message = Form(
726                         "%s (At byte %d in DDL.)",
727                         ErrorCodeToMessage(error),
728                         (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader)
729                 );
730                 fRawStream->GetReader()->AddMajorErrorLog(error, message);
731                 break;
732         }
733
734         if (fWarnings)
735         {
736                 AliWarningGeneral(
737                                 "AliMUONRawStreamTriggerHP::AliDecoderEventHandler",
738                                 message
739                         );
740         }
741 }
742