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