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