Update master to aliroot
[u/mrichter/AliRoot.git] / HLT / MUON / utils / dHLTdumpraw.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author:                                                                *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 /**
19  * @file   dHLTdumpraw.cxx
20  * @author Artur Szostak <artursz@iafrica.com>,
21  *         Seforo Mohlalisi <seforomohlalisi@yahoo.co.uk>
22  * @date   1 July 2007
23  * @brief  Command line utility to dump dHLT's internal raw data blocks.
24  */
25
26 // We define NDEBUG for the AliHLTMUONDataBlockReader.h header file since this
27 // program by definition handles corrupt data. So we do not need the assertions
28 // in the AliHLTMUONDataBlockReader class to be checked.
29 #ifndef NDEBUG
30 #define NDEBUG
31 #endif
32 #include "AliHLTMUONDataBlockReader.h"
33 #if defined(DEBUG) && defined(NDEBUG)
34 #undef NDEBUG
35 #endif
36
37 #include "AliHLTMUONUtils.h"
38 #include "AliHLTMUONConstants.h"
39 #include "Rtypes.h"
40 #include "AliRawDataHeader.h"
41 #include "AliMUONTrackerDDLDecoder.h"
42 #include "AliMUONTriggerDDLDecoder.h"
43 #include "AliHLTSystem.h"
44 #include "AliHLTConfiguration.h"
45 #include "AliLog.h"
46 #include "TClassTable.h"
47 #include "TString.h"
48 #include "TRegexp.h"
49
50 #include <cstring>
51 #include <cstdlib>
52 #include <cstdio>
53 #include <cassert>
54 #include <new>
55 #include <fstream>
56
57 #include <iostream>
58 using std::cout;
59 using std::cerr;
60 using std::endl;
61 using std::showbase;
62 using std::noshowbase;
63 using std::hex;
64 using std::dec;
65
66 #include <iomanip>
67 using std::setw;
68 using std::left;
69 using std::right;
70 using std::internal;
71
72
73 #define CMDLINE_ERROR 1
74 #define PARSE_ERROR 2
75 #define SYSTEM_ERROR 3
76 #define FATAL_ERROR 4
77 #define HLTSYSTEM_ERROR 5
78
79
80 // Adding enum types for extending AliHLTMUONDataBlockType with the
81 // raw DDL data types.
82 enum AliHLTMUONDDLRawDataType
83 {
84         kTrackerDDLRawData = 10,
85         kTriggerDDLRawData = 11
86 };
87
88
89 void PrintRubbishData(AliHLTUInt32_t offset, const char* padByte, AliHLTUInt32_t padCount)
90 {
91         if (padCount == 0) return;
92         
93         cerr << "ERROR: Found the following unexpected rubbish data at the"
94                 " end of the data block:" << endl;
95         cerr << "Byte #\tValue\tCharacter" << endl;
96         for (AliHLTUInt32_t i = 0; i < padCount; i++)
97         {
98                 short value = short(padByte[i]) & 0xFF;
99                 char character = padByte[i];
100                 cerr << offset + i + 1 << "\t"
101                         << noshowbase << hex << "0x" << value << dec << "\t"
102                         << character << endl;
103         }
104 }
105
106
107 void PrintBitPattern(AliHLTUInt32_t value, int bitcount = 32)
108 {
109         // Prints a bit pattern to cout.
110         
111         for (int i = bitcount-1; i >= 0; i--)
112         {
113                 if ( ((value >> i) & 0x1) == 1 )
114                         cout << "1";
115                 else
116                         cout << "0";
117         }
118 }
119
120
121 template <typename FieldType>
122 int CheckHeaderField(
123                 FieldType& field, const char* buffer, unsigned long bufferSize,
124                 bool continueParse
125         )
126 {
127         const char* fieldptr = reinterpret_cast<const char*>(&field);
128         const char* endptr = buffer + bufferSize;
129         AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
130         
131         if (bufferRemaining < sizeof(field))
132         {
133                 cout << "..." << endl; // We may be half way through printing a line so end it.
134                 cerr << "ERROR: The data block is too short. The header is corrupt." << endl;
135                 if (continueParse)
136                 {
137                         AliHLTUInt32_t offset = fieldptr - buffer;
138                         PrintRubbishData(offset, fieldptr, bufferRemaining);
139                 }
140                 return PARSE_ERROR;
141         }
142         return EXIT_SUCCESS;
143 }
144
145
146 template <typename FieldType>
147 int CheckField(
148                 FieldType& field, const char* buffer, unsigned long bufferSize,
149                 bool continueParse
150         )
151 {
152         const char* fieldptr = reinterpret_cast<const char*>(&field);
153         const char* endptr = buffer + bufferSize;
154         AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
155         
156         if (bufferRemaining < sizeof(field))
157         {
158                 cout << "..." << endl; // We may be half way through printing a line so end it.
159                 cerr << "ERROR: The data block is too short. The data is corrupt." << endl;
160                 if (continueParse)
161                 {
162                         AliHLTUInt32_t offset = fieldptr - buffer;
163                         PrintRubbishData(offset, fieldptr, bufferRemaining);
164                 }
165                 return PARSE_ERROR;
166         }
167         return EXIT_SUCCESS;
168 }
169
170
171 template <typename BlockType>
172 int CheckCommonHeader(
173                 BlockType& block, const char* /*buffer*/, unsigned long bufferSize,
174                 bool continueParse
175         )
176 {
177         int result = EXIT_SUCCESS;
178
179         // Check the fRecordWidth field in the common header.
180         if (block.CommonBlockHeader().fRecordWidth !=
181                 sizeof(typename BlockType::ElementType))
182         {
183                 cerr << "ERROR: The record width found in the header is incorrect."
184                         " Found a record width of "
185                         << block.CommonBlockHeader().fRecordWidth << " bytes, but expected"
186                         " a value of " << sizeof(typename BlockType::ElementType)
187                         << " bytes." << endl;
188                 result = PARSE_ERROR;
189                 if (not continueParse) return result;
190         }
191         
192         if (not block.BufferSizeOk())
193         {
194                 cerr << "ERROR: The size of the file is incorrect. It is "
195                         << bufferSize << " bytes big, but according"
196                         " to the data block header it should be " << block.BytesUsed()
197                         << " bytes." << endl;
198                 result = PARSE_ERROR;
199                 if (not continueParse) return result;
200         }
201         
202         return result;
203 }
204
205
206 template <typename BlockType>
207 AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize)
208 {
209         // Calculate how many entries we can display. If the buffer size is correct
210         // we just use the number of entries the block specifies. Otherwise we need
211         // to calculate it from the buffer size.
212         AliHLTUInt32_t nentries;
213         if (block.BytesUsed() == bufferSize)
214         {
215                 nentries = block.Nentries();
216         }
217         else
218         {
219                 AliHLTInt32_t dataSize = bufferSize
220                         - sizeof(typename BlockType::HeaderType);
221                 nentries = dataSize / sizeof(typename BlockType::ElementType);
222                 if (dataSize % sizeof(typename BlockType::ElementType) > 0)
223                         nentries++;
224         }
225         return nentries;
226 }
227
228
229 namespace
230 {
231         /**
232          * Common methods for DDL decoder event handlers.
233          */
234         class AliDecoderHandler
235         {
236         public:
237                 AliDecoderHandler() :
238                         fBufferStart(NULL),
239                         fDumpStart(NULL),
240                         fDumpData(false)
241                 {
242                 }
243                 
244                 virtual ~AliDecoderHandler() {}
245                 
246         protected:
247                 
248                 // Do not allow copying of this class.
249                 AliDecoderHandler(const AliDecoderHandler& obj);
250                 AliDecoderHandler& operator = (const AliDecoderHandler& obj);
251                 
252                 void HandleError(
253                                 const char* errorMessage, int errorCode,
254                                 const char* errorCodeString, const void* location
255                         );
256         
257                 void TryDumpCorruptData(const void* dumpEnd);
258                 
259                 const void* fBufferStart;  ///< Start location of buffer.
260                 const void* fDumpStart;  ///< Start location of corrupt data to dump.
261                 bool fDumpData;  ///< Flag indicating if fDumpStart points to corrupt data and should be dumped.
262         };
263         
264         
265         void AliDecoderHandler::HandleError(
266                         const char* errorMessage, int errorCode,
267                         const char* errorCodeString, const void* location
268                 )
269         {
270                 unsigned long offset = (unsigned long)location - (unsigned long)fBufferStart
271                         + sizeof(AliRawDataHeader);
272                 
273                 cerr << "ERROR: " << errorMessage
274                         << " [Error code = " << errorCode << " ("
275                         << errorCodeString << "), at byte "
276                         << offset << " (" << noshowbase << hex << "0x"
277                         << offset << dec << ")]" << endl;
278                 
279                 if (fDumpStart == NULL) fDumpStart = location;
280                 fDumpData = true;
281         }
282         
283         
284         void AliDecoderHandler::TryDumpCorruptData(const void* dumpEnd)
285         {
286                 if (dumpEnd < fDumpStart) return;
287                 if (not fDumpData) return;
288                 
289                 unsigned long startOffset = (unsigned long)fDumpStart - (unsigned long)fBufferStart
290                         + sizeof(AliRawDataHeader);
291                 unsigned long endOffset = (unsigned long)dumpEnd - (unsigned long)fBufferStart
292                         + sizeof(AliRawDataHeader);
293                 if (endOffset - startOffset > 264)
294                 {
295                         endOffset = startOffset + 264;
296                         dumpEnd = reinterpret_cast<const char*>(fBufferStart) + endOffset;
297                 }
298                 cerr << "Dumping corrupt data words from byte " << startOffset
299                         << " (" << noshowbase << hex << "0x" << startOffset
300                         << dec << "), to byte " << endOffset << " (" << noshowbase
301                         << hex << "0x" << endOffset << dec << "):" << endl;
302                 const UInt_t* start = reinterpret_cast<const UInt_t*>(fDumpStart);
303                 const UInt_t* end = reinterpret_cast<const UInt_t*>(dumpEnd);
304                 cerr << "     Start byte     | Data words" << endl;
305                 for (const UInt_t* current = start; current < end; current++)
306                 {
307                         unsigned long currentByte = (unsigned long)current
308                                 - (unsigned long)fBufferStart + sizeof(AliRawDataHeader);
309                         cerr << right << setw(9) << dec << currentByte << setw(0)
310                                 << " 0x" << left << setw(7) << noshowbase << hex
311                                 << currentByte << setw(0) << right << " | ";
312                         char fillChar = cerr.fill();
313                         cerr.fill('0');
314                         for (int i = 0; i < 4 and current < end; i++, current++)
315                         {
316                                 cerr << noshowbase << hex << "0x" << setw(8)
317                                         << (*current) << setw(0) << dec << " ";
318                         }
319                         cerr.fill(fillChar);
320                         cerr << endl;
321                 }
322                 fDumpStart = NULL;
323                 fDumpData = false;
324         }
325
326         /**
327          * Event handler for the tracker DDL decoder.
328          * It simply prints the structure to standard output.
329          */
330         class AliTrackerDecoderHandler :
331                 public AliMUONTrackerDDLDecoderEventHandler, public AliDecoderHandler
332         {
333         public:
334                 AliTrackerDecoderHandler() :
335                         AliMUONTrackerDDLDecoderEventHandler(),
336                         AliDecoderHandler(),
337                         fBlockNum(0),
338                         fDSPNum(0),
339                         fBusPatchNum(0)
340                 {}
341                 
342                 virtual ~AliTrackerDecoderHandler() {}
343         
344                 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
345                 {
346                         fBufferStart = buffer;
347                         fBlockNum = fDSPNum = fBusPatchNum = 0;
348                 }
349                 
350                 void OnEndOfBuffer(const void* buffer, UInt_t bufferSize)
351                 {
352                         const char* bufferEnd =
353                                 reinterpret_cast<const char*>(buffer) + bufferSize;
354                         TryDumpCorruptData(bufferEnd);
355                 }
356                 
357                 void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/);
358                 
359                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
360                 
361                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/);
362                 
363                 void OnData(UInt_t data, bool parityError);
364                 
365                 void OnError(ErrorCode error, const void* location);
366                 
367         private:
368         
369                 UInt_t fBlockNum;     ///< Number of block being processed [1..maxBlock].
370                 UInt_t fDSPNum;       ///< Number of DSP being processed [1..maxDSP].
371                 UInt_t fBusPatchNum;  ///< Number of bus patch being processed [1..maxBusPatch].
372         };
373         
374         
375         void AliTrackerDecoderHandler::OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/)
376         {
377                 TryDumpCorruptData(header);
378                 fBlockNum++;
379                 char fillChar = cout.fill();  // store current fill char to restore it.
380                 cout << "================================ Block header "
381                         << setw(3) << fBlockNum << setw(0)
382                         << " ================================" << endl;
383                 cout << "   Data key word for block : 0x" << noshowbase << setw(8) << setfill('0')
384                         << hex << header->fDataKey << dec << setfill(fillChar) << setw(0) << endl;
385                 cout << "     Total Length of block : " << header->fTotalLength << endl;
386                 cout << "        Length of raw data : " << header->fLength << endl;
387                 cout << "                    DSP ID : " << header->fDSPId << endl;
388                 cout << "           L0 trigger word : " << header->fL0Trigger << " (0x"
389                         << noshowbase << setw(8) << setfill('0') << hex << header->fL0Trigger
390                         << dec << setw(0) << setfill(fillChar) << ")" << endl;
391                 cout << "             Mini event ID : " << header->fMiniEventId << " (0x"
392                         << noshowbase << setw(8) << setfill('0') << hex << header->fMiniEventId
393                         << dec << setw(0) << setfill(fillChar) << ")" << endl;
394                 cout << "Event ID In Bunch Crossing : " << header->fEventId1 << " (0x"
395                         << noshowbase << setw(8) << setfill('0') << hex << header->fEventId1
396                         << dec << setw(0) << setfill(fillChar) << ")" << endl;
397                 cout << "  Event ID In Orbit Number : " << header->fEventId2 << " (0x"
398                         << noshowbase << setw(8) << setfill('0') << hex << header->fEventId2
399                         << dec << setw(0) << setfill(fillChar) << ")" << endl;
400         }
401         
402         
403         void AliTrackerDecoderHandler::OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/)
404         {
405                 TryDumpCorruptData(header);
406                 fDSPNum++;
407                 char fillChar = cout.fill();  // store current fill char to restore it.
408                 cout << "================================= DSP header "
409                         << setw(3) << fDSPNum << setw(0)
410                         << " =================================" << endl;
411                 cout << "                     Data key word for FRT : 0x" << noshowbase
412                         << setw(8) << setfill('0') << hex << header->fDataKey << dec
413                         << setfill(fillChar) << setw(0) << endl;
414                 cout << "                 Total length of structure : " << header->fTotalLength << endl;
415                 cout << "                        Length of raw data : " << header->fLength << endl;
416                 cout << "                                    DSP ID : " << header->fDSPId << endl;
417                 cout << "        L1 accept in block Structure (CRT) : " << header->fBlkL1ATrigger
418                         << " (0x" << noshowbase << setw(8) << setfill('0') << hex
419                         << header->fBlkL1ATrigger << dec << setw(0) << setfill(fillChar) << ")" << endl;
420                 cout << "           Mini event ID in bunch crossing : " << header->fMiniEventId
421                         << " (0x" << noshowbase << setw(8) << setfill('0') << hex
422                         << header->fMiniEventId << dec << setw(0) << setfill(fillChar) << ")" << endl;
423                 cout << "Number of L1 accept in DSP Structure (FRT) : " << header->fL1ATrigger << endl;
424                 cout << "Number of L1 reject in DSP Structure (FRT) : " << header->fL1RTrigger << endl;
425                 const char* paddingWordValue = ") (INVALID)";
426                 if (header->fPaddingWord == 0) paddingWordValue = ") (false)";
427                 if (header->fPaddingWord == 1) paddingWordValue = ") (true)";
428                 cout << "     Padding word set for 64 bits transfer : " << header->fPaddingWord
429                         << " (0x" << noshowbase << setw(8) << setfill('0') << hex
430                         << header->fPaddingWord << setw(0) << setfill(fillChar) << dec
431                         << paddingWordValue << endl;
432                 cout << "                                Error word : " << header->fErrorWord
433                         << " (" << noshowbase << setw(8) << setfill('0') << hex
434                         << header->fErrorWord << setw(0) << setfill(fillChar)
435                         << dec << ")" << endl;
436         }
437         
438         
439         void AliTrackerDecoderHandler::OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
440         {
441                 TryDumpCorruptData(header);
442                 fBusPatchNum++;
443                 char fillChar = cout.fill();  // store current fill char to restore it.
444                 cout << "============================== Bus patch header "
445                         << setw(3) << fBusPatchNum << setw(0)
446                         << " ==============================" << endl;
447                 cout << "Data key word for bus patch : 0x" << noshowbase << setw(8)
448                         << setfill('0') << hex << header->fDataKey << dec
449                         << setfill(fillChar) << setw(0) << endl;
450                 cout << "  Total length of structure : " << header->fTotalLength << endl;
451                 cout << "         Length of raw data : " << header->fLength << endl;
452                 cout << "               Bus patch ID : " << header->fBusPatchId << endl;
453                 if (header->fLength > 0)
454                 {
455                         cout << "    Raw bits |      Manu ID | Manu channel |   ADC Signal" << endl;
456                         cout << "----------------------------------------------------------" << endl;
457                 }
458         }
459         
460         
461         void AliTrackerDecoderHandler::OnData(UInt_t data, bool parityError)
462         {
463                 UShort_t manuId, adc;
464                 UChar_t manuChannel;
465                 UnpackADC(data, manuId, manuChannel, adc);
466                 char fillChar = cout.fill();  // store current fill char to restore it.
467                 cout << noshowbase << "  0x" << setfill('0') << hex << setw(8) << data
468                         << setw(0) << dec << setfill(fillChar) << "   "
469                         << setw(12) << manuId << setw(0) << "   "
470                         << setw(12) << (UInt_t)manuChannel << setw(0) << "   "
471                         << setw(12) << adc << setw(0);
472                 if (parityError)
473                 {
474                         cout << " <= WARNING: Raw data word with parity error!" << endl;
475                 }
476                 else
477                 {
478                         cout << endl;
479                 }
480         }
481         
482         
483         void AliTrackerDecoderHandler::OnError(ErrorCode error, const void* location)
484         {
485                 TryDumpCorruptData(location);
486                 HandleError(
487                         ErrorCodeToMessage(error), error,
488                         ErrorCodeToString(error), location
489                 );
490         }
491
492         /**
493          * Event handler for the trigger DDL decoder.
494          * It simply prints the structure to standard output.
495          */
496         class AliTriggerDecoderHandler :
497                 public AliMUONTriggerDDLDecoderEventHandler, public AliDecoderHandler
498         {
499         public:
500                 AliTriggerDecoderHandler() :
501                         AliMUONTriggerDDLDecoderEventHandler(),
502                         AliDecoderHandler(),
503                         fRegNum(0),
504                         fLocNum(0)
505                 {}
506                 
507                 virtual ~AliTriggerDecoderHandler() {}
508         
509                 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
510                 {
511                         fBufferStart = buffer;
512                         fRegNum = fLocNum = 0;
513                 }
514                 
515                 void OnEndOfBuffer(const void* buffer, UInt_t bufferSize)
516                 {
517                         const char* bufferEnd =
518                                 reinterpret_cast<const char*>(buffer) + bufferSize;
519                         TryDumpCorruptData(bufferEnd);
520                 }
521                 
522                 const char* EventTypeToString(UInt_t type);
523                 
524                 const char* DarcTypeToString(UInt_t type);
525                 
526                 void OnDarcHeader(
527                                 UInt_t header,
528                                 const AliMUONDarcScalarsStruct* scalars,
529                                 const void* data
530                         );
531                 
532                 void OnGlobalHeader(
533                                 const AliMUONGlobalHeaderStruct* header,
534                                 const AliMUONGlobalScalarsStruct* scalars,
535                                 const void* /*data*/
536                         );
537                 
538                 void OnNewRegionalStruct(
539                                 const AliMUONRegionalHeaderStruct* regionalStruct,
540                                 const AliMUONRegionalScalarsStruct* scalars,
541                                 const void* /*data*/
542                         );
543                 
544                 void OnLocalStruct(
545                                 const AliMUONLocalInfoStruct* localStruct,
546                                 const AliMUONLocalScalarsStruct* scalars
547                         );
548                 
549                 void OnError(ErrorCode error, const void* location);
550         
551         private:
552         
553                 UInt_t fRegNum;  ///< Number of block being processed [1..maxReg].
554                 UInt_t fLocNum;  ///< Number of DSP being processed [1..maxLoc].
555         };
556         
557         
558         const char* AliTriggerDecoderHandler::EventTypeToString(UInt_t type)
559         {
560                 switch (type)
561                 {
562                 case 0: return "Other software trigger";
563                 case 1: return "Physics";
564                 case 2: return "Start of run";
565                 case 3: return "End of run";
566                 default: return "UNKNOWN";
567                 }
568         }
569         
570         
571         const char* AliTriggerDecoderHandler::DarcTypeToString(UInt_t type)
572         {
573                 typedef AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler> AliDec;
574                 if (type == AliDec::DarcDefaultType()) return "Default";
575                 if (type == AliDec::DarcVadorhType()) return "Vadorh";
576                 return "UNKNOWN";
577         }
578         
579         
580         void AliTriggerDecoderHandler::OnDarcHeader(
581                         UInt_t header,
582                         const AliMUONDarcScalarsStruct* scalars,
583                         const void* data
584                 )
585         {
586                 if (scalars != NULL)
587                         TryDumpCorruptData(scalars);
588                 else
589                         TryDumpCorruptData(data);
590                 
591                 cout << "================================ DARC header =====================================" << endl;
592                 char fillChar = cout.fill();  // store current fill char to restore it.
593                 cout << noshowbase << "         Header bit pattern : 0x" << setfill('0') << hex << setw(8)
594                         << header << setw(0) << dec << setfill(fillChar) << endl;
595                 UInt_t eventType = GetDarcEventType(header);
596                 cout << "                 Event type : " << eventType << " ("
597                         << EventTypeToString(eventType) << ")" << endl;
598                 cout << "           Application type : " << ((header >> 27) & 0x7) << endl;
599                 UInt_t darcType = GetDarcType(header);
600                 cout << "                  DARC type : " << darcType << " ("
601                         << DarcTypeToString(darcType) << ")" << endl;
602                 cout << "              Serial number : " << (UInt_t)GetDarcSerialNb(header) << endl;
603                 cout << "                    Version : " << (UInt_t)GetDarcVersion(header) << endl;
604                 cout << "           VME trigger used : " << boolalpha << GetDarcVMETrig(header) << endl;
605                 cout << "Global card data occurrence : " << boolalpha << GetDarcGlobalFlag(header) << endl;
606                 cout << "      CTP or LTU interfaced : " << boolalpha << GetDarcCTPTrig(header) << endl;
607                 cout << "             DAQ interfaced : " << boolalpha << GetDarcDAQFlag(header) << endl;
608                 cout << "  Regional cards occurrence : 0x" << noshowbase << hex << setw(2) << setfill('0')
609                         << (UInt_t)GetDarcRegPattern(header) << dec << setfill(fillChar) << setw(0)
610                         << " [bits: ";
611                 PrintBitPattern(((UInt_t)GetDarcRegPattern(header) >> 4) & 0xF, 4); cout << " ";
612                 PrintBitPattern(((UInt_t)GetDarcRegPattern(header) >> 0) & 0xF, 4);
613                 cout << "]" << endl;
614                 
615                 cout << "================================ DARC scalars ====================================" << endl;
616                 if (scalars != NULL)
617                 {
618                         cout << "    Trigger | Received |     Used" << endl;
619                         cout << "----------------------------------" << endl;
620                         cout << "         L0   " << setw(8) << ((scalars->fL0R >> 16) & 0xFFFF) << setw(0)
621                                 << "   " << setw(8) << ((scalars->fL0R >> 0) & 0xFFFF) << setw(0) << endl;
622                         cout << " L1 physics   " << setw(8) << ((scalars->fL1P >> 16) & 0xFFFF) << setw(0)
623                                 << "   " << setw(8) << ((scalars->fL1P >> 0) & 0xFFFF) << setw(0) << endl;
624                         cout << "L1 software   " << setw(8) << ((scalars->fL1S >> 16) & 0xFFFF) << setw(0)
625                                 << "   " << setw(8) << ((scalars->fL1S >> 0) & 0xFFFF) << setw(0) << endl;
626                         cout << "  L2 accept   " << setw(8) << ((scalars->fL2A >> 16) & 0xFFFF) << setw(0)
627                                 << "   " << setw(8) << ((scalars->fL2A >> 0) & 0xFFFF) << setw(0) << endl;
628                         cout << "  L2 reject   " << setw(8) << ((scalars->fL2R >> 16) & 0xFFFF) << setw(0)
629                                 << "   " << setw(8) << ((scalars->fL2R >> 0) & 0xFFFF) << setw(0) << endl;
630                         cout << "           Clock : " << scalars->fClk << endl;
631                         cout << "Hold (dead time) : " << scalars->fHold << endl;
632                         cout << "      Spare word : " << scalars->fSpare << " (0x"
633                                 << setw(8) << setfill('0') << hex << scalars->fSpare <<
634                                 setw(0) << setfill(fillChar) << dec << ")" << endl;
635                 }
636                 else
637                 {
638                         cout << "(None found)" << endl;
639                 }
640         }
641         
642         
643         void AliTriggerDecoderHandler::OnGlobalHeader(
644                         const AliMUONGlobalHeaderStruct* header,
645                         const AliMUONGlobalScalarsStruct* scalars,
646                         const void* /*data*/
647                 )
648         {
649                 TryDumpCorruptData(header);
650                 
651                 cout << "=============================== Global header ====================================" << endl;
652                 cout << "Global input from regional controllers:" << endl;
653                 cout << "      |                 |         High pT           |          Low pT          " << endl;
654                 cout << "      |    Bit pattern  | Single mu |    mu pair    | Single mu |    mu pair   " << endl;
655                 cout << "Input |  Hex |   Binary | -ve | +ve | unlike | like | -ve | +ve | unlike | like" << endl;
656                 cout << "--------------------------------------------------------------------------------" << endl;
657                 char fillChar = cout.fill();  // store current fill char to restore it.
658                 for (int i = 0; i < 4; i++)
659                 {
660                         union
661                         {
662                                 UInt_t fWord;
663                                 UChar_t fByte[4];
664                         } input;
665                         input.fWord = header->fInput[i];
666                         for (int j = 0; j < 4; j++)
667                         {
668                                 cout << setw(5) << (i*4+j) << "   0x" << noshowbase << setw(2)
669                                         << setfill('0') << hex << (UInt_t)input.fByte[j] << setw(0)
670                                         << setfill(fillChar) << dec << "   ";
671                                 PrintBitPattern(input.fByte[j], 8);
672                                 cout << ((((input.fByte[j] >> 7) & 0x1) == 1) ? "   yes" : "    no");
673                                 cout << ((((input.fByte[j] >> 6) & 0x1) == 1) ? "   yes" : "    no");
674                                 cout << ((((input.fByte[j] >> 5) & 0x1) == 1) ? "     yes " : "      no ");
675                                 cout << ((((input.fByte[j] >> 4) & 0x1) == 1) ? "    yes" : "     no");
676                                 cout << ((((input.fByte[j] >> 3) & 0x1) == 1) ? "   yes" : "    no");
677                                 cout << ((((input.fByte[j] >> 2) & 0x1) == 1) ? "   yes" : "    no");
678                                 cout << ((((input.fByte[j] >> 1) & 0x1) == 1) ? "     yes " : "      no ");
679                                 cout << ((((input.fByte[j] >> 0) & 0x1) == 1) ? "    yes" : "     no");
680                                 cout << endl;
681                         }
682                 }
683                 cout << "        Global ouput : 0x" << noshowbase << setw(2) << setfill('0') << hex
684                         << (UInt_t)GetGlobalOutput(header) << setw(0) << setfill(fillChar) << dec << " [Bits: ";
685                 PrintBitPattern(((UInt_t)GetGlobalOutput(header) >> 4) & 0xF, 4); cout << " ";
686                 PrintBitPattern(((UInt_t)GetGlobalOutput(header) >> 0) & 0xF, 4);
687                 cout << "]" << endl;
688                 cout << "          [ unlike sign |  like sign  | single muon ]" << endl;
689                 cout << "          [ high |  low | high |  low | high |  low ]" << endl;
690                 cout << "          [-----------------------------------------]" << endl;
691                 cout << "          [ ";
692                 cout << ((((GetGlobalOutput(header) >> 5) & 0x1) == 1) ? " yes" : "  no");
693                 cout << ((((GetGlobalOutput(header) >> 4) & 0x1) == 1) ? "    yes" : "     no");
694                 cout << ((((GetGlobalOutput(header) >> 3) & 0x1) == 1) ? "    yes" : "     no");
695                 cout << ((((GetGlobalOutput(header) >> 2) & 0x1) == 1) ? "    yes" : "     no");
696                 cout << ((((GetGlobalOutput(header) >> 1) & 0x1) == 1) ? "    yes" : "     no");
697                 cout << ((((GetGlobalOutput(header) >> 0) & 0x1) == 1) ? "    yes" : "     no");
698                 cout << " ]" << endl;
699                 cout << "Global configuration : 0x" << noshowbase << setw(4) << setfill('0') << hex
700                         << GetGlobalConfig(header) << setw(0) << setfill(fillChar) << dec << " [Bits: ";
701                 PrintBitPattern(((UInt_t)GetGlobalConfig(header) >> 12) & 0xF, 4); cout << " ";
702                 PrintBitPattern(((UInt_t)GetGlobalConfig(header) >> 8) & 0xF, 4); cout << " ";
703                 PrintBitPattern(((UInt_t)GetGlobalConfig(header) >> 4) & 0xF, 4); cout << " ";
704                 PrintBitPattern(((UInt_t)GetGlobalConfig(header) >> 0) & 0xF, 4);
705                 cout << "]" << endl;
706                 
707                 cout << "=============================== Global scalars ===================================" << endl;
708                 if (scalars != NULL)
709                 {
710                         cout << "           Number of L0 triggers : " << scalars->fL0 << endl;
711                         cout << "          Number of clock cycles : " << scalars->fClk << endl;
712                         cout << " Number of unlike mu pair low pT : " << scalars->fScaler[0] << endl;
713                         cout << "Number of unlike mu pair high pT : " << scalars->fScaler[1] << endl;
714                         cout << "   Number of like mu pair low pT : " << scalars->fScaler[2] << endl;
715                         cout << "  Number of like mu pair high pT : " << scalars->fScaler[3] << endl;
716                         cout << "      Number of single mu low pT : " << scalars->fScaler[4] << endl;
717                         cout << "     Number of single mu high pT : " << scalars->fScaler[5] << endl;
718                         cout << "                Hold (dead time) : " << scalars->fHold << endl;
719                         cout << "                      Spare word : " << scalars->fSpare << " (0x"
720                                 << setw(8) << setfill('0') << hex << scalars->fSpare <<
721                                 setw(0) << setfill(fillChar) << dec << ")" << endl;
722                 }
723                 else
724                 {
725                         cout << "(None found)" << endl;
726                 }
727         }
728         
729         
730         void AliTriggerDecoderHandler::OnNewRegionalStruct(
731                         const AliMUONRegionalHeaderStruct* regionalStruct,
732                         const AliMUONRegionalScalarsStruct* scalars,
733                         const void* /*data*/
734                 )
735         {
736                 TryDumpCorruptData(regionalStruct);
737                 
738                 fRegNum++;
739                 cout << "========================= Regional structure header "
740                         << setw(3) << fRegNum << setw(0)
741                         << " ==========================" << endl;
742                 char fillChar = cout.fill();  // store current fill char to restore it.
743                 cout << "Darc word bit pattern : 0x" << noshowbase << setw(8) << setfill('0')
744                         << hex << regionalStruct->fDarcWord << setw(0)
745                         << setfill(fillChar) << dec << endl;
746                 UShort_t errBits = GetRegionalErrorBits(regionalStruct);
747                 cout << "  [           Error type : "
748                         << (((errBits >> 7) & 0x1) == 1 ? "1 (Physics) " : "0 (Software)")
749                         << " ]" << endl;
750                 cout << "  [       Regional error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
751                 cout << "  [           Full error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
752                 cout << "  [          Empty error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
753                 cout << "  [ DARC L2 reject error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
754                 cout << "  [        DARC L2 error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
755                 cout << "  [        DARC L1 error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
756                 cout << "  [        DARC L0 error : " << ((errBits >> 6) & 0x1) << "            ]" << endl;
757                 
758                 cout << "  [  FPGA number in card : "
759                         << (UInt_t)GetRegionalFPGANumber(regionalStruct) << " (";
760                 PrintBitPattern((UInt_t)GetRegionalFPGANumber(regionalStruct), 3);
761                 cout << "b)     ]" << endl;
762                 
763                 cout << "  [      Physics trigger : " << setw(13) << boolalpha << left
764                         << GetRegionalDarcPhysFlag(regionalStruct) << setw(0)
765                         << right << "]" << endl;
766                 cout << "  [     Regional present : " << setw(13) << boolalpha << left
767                         << GetRegionalPresentFlag(regionalStruct) << setw(0)
768                         << right << "]" << endl;
769                 cout << "  [         RAM not full : " << setw(13) << boolalpha << left
770                         << GetRegionalRamNotFullFlag(regionalStruct) << setw(0)
771                         << right << "]" << endl;
772                 cout << "  [        RAM not empty : " << setw(13) << boolalpha << left
773                         << GetRegionalRamNotEmptyFlag(regionalStruct) << setw(0)
774                         << right << "]" << endl;
775                 cout << "  [          L2 rejected : " << setw(13) << boolalpha << left
776                         << GetRegionalL2RejStatus(regionalStruct) << setw(0)
777                         << right << "]" << endl;
778                 cout << "  [          L2 accepted : " << setw(13) << boolalpha << left
779                         << GetRegionalL2AccStatus(regionalStruct) << setw(0)
780                         << right << "]" << endl;
781                 cout << "  [             L1 found : " << setw(13) << boolalpha << left
782                         << GetRegionalL1Status(regionalStruct) << setw(0)
783                         << right << "]" << endl;
784                 cout << "  [             L0 found : " << setw(13) << boolalpha << left
785                         << GetRegionalL0Status(regionalStruct) << setw(0)
786                         << right << "]" << endl;
787                 cout << "  [ No. of events in RAM : " << setw(13) << left
788                         << (UInt_t)GetRegionalEventInRam(regionalStruct) << setw(0)
789                         << right << "]" << endl;
790                 cout << "  [            Busy word : 0x"
791                         << (UInt_t)GetRegionalBusy(regionalStruct) << " (";
792                 PrintBitPattern((UInt_t)GetRegionalBusy(regionalStruct), 4);
793                 cout << "b)  ]" << endl;
794                 
795                 cout << "Regional word bit pattern : 0x" << noshowbase << setw(8) << setfill('0')
796                         << hex << regionalStruct->fWord << setw(0)
797                         << setfill(fillChar) << dec << endl;
798                 cout << "  [ Physics trigger occurred : " << setw(27) << boolalpha << left
799                         << (UInt_t)GetRegionalPhysFlag(regionalStruct) << setw(0)
800                         << right << "]" << endl;
801                 cout << "  [         Number of resets : " << setw(27) << left
802                         << (UInt_t)GetRegionalResetNb(regionalStruct) << setw(0)
803                         << right << "]" << endl;
804                 cout << "  [ Controller Serial number : " << setw(27) << left
805                         << (UInt_t)GetRegionalSerialNb(regionalStruct) << setw(0)
806                         << right << "]" << endl;
807                 cout << "  [        Regional crate ID : " << setw(27) << left
808                         << (UInt_t)GetRegionalId(regionalStruct) << setw(0)
809                         << right << "]" << endl;
810                 cout << "  [    FPGA software version : " << setw(27) << left
811                         << (UInt_t)GetRegionalVersion(regionalStruct) << setw(0)
812                         << right << "]" << endl;
813                 UInt_t output = GetRegionalOutput(regionalStruct);
814                 cout << "  [          Regional output : 0x" << setw(2) << setfill('0') << hex
815                         << output << dec << setw(0) << setfill(fillChar) << setw(0) << right << " (";
816                 PrintBitPattern(output, 8);
817                 cout  << "b)           ]" << endl;
818                 
819                 cout << "  [         High pT           |          Low pT           ]" << endl;
820                 cout << "  [ Single mu |    mu pair    | Single mu |    mu pair    ]" << endl;
821                 cout << "  [ -ve | +ve | unlike | like | -ve | +ve | unlike | like ]" << endl;
822                 cout << "  [-------------------------------------------------------]" << endl;
823                 cout << ((((output >> 7) & 0x1) == 1) ? "  [ yes" : "  [  no");
824                 cout << ((((output >> 6) & 0x1) == 1) ? "   yes" : "    no");
825                 cout << ((((output >> 5) & 0x1) == 1) ? "     yes " : "      no ");
826                 cout << ((((output >> 4) & 0x1) == 1) ? "    yes" : "     no");
827                 cout << ((((output >> 3) & 0x1) == 1) ? "   yes" : "    no");
828                 cout << ((((output >> 2) & 0x1) == 1) ? "   yes" : "    no");
829                 cout << ((((output >> 1) & 0x1) == 1) ? "     yes " : "      no ");
830                 cout << ((((output >> 0) & 0x1) == 1) ? "    yes ]" : "     no ]");
831                 cout << endl;
832                 
833                 cout << "Regional input (low pT) bit pattern  : 0x" << noshowbase << setw(8)
834                         << setfill('0') << hex << regionalStruct->fInput[0]
835                         << setw(0) << setfill(fillChar) << dec << endl;
836                 cout << "Regional input (high pT) bit pattern : 0x" << noshowbase << setw(8)
837                         << setfill('0') << hex << regionalStruct->fInput[1]
838                         << setw(0) << setfill(fillChar) << dec << endl;
839                 cout << "Regional input logical dump: " << endl;
840                 cout << "    Local     | Local | low pT mu | high pT mu" << endl;
841                 cout << "structure no. | board | -ve | +ve |  -ve | +ve" << endl;
842                 cout << "-----------------------------------------------" << endl;
843                 for (int i = 15; i >= 0 ; i--)
844                 {
845                         cout << setw(13) << (fLocNum + 16 - i) << setw(0) << "   ";
846                         cout << setw(5) << (15 - i) << setw(0) << "   ";
847                         cout << ((((regionalStruct->fInput[0] >> (i*2+1)) & 0x1) == 1) ? "yes" : " no");
848                         cout << ((((regionalStruct->fInput[0] >> (i*2+0)) & 0x1) == 1) ? "   yes" : "    no");
849                         cout << ((((regionalStruct->fInput[1] >> (i*2+1)) & 0x1) == 1) ? "    yes" : "     no");
850                         cout << ((((regionalStruct->fInput[1] >> (i*2+0)) & 0x1) == 1) ? "   yes" : "    no");
851                         cout << endl;
852                 }
853                 
854                 UInt_t mask = GetRegionalMask(regionalStruct);
855                 cout << "Local mask : 0x" << noshowbase << setw(4) << setfill('0') << hex
856                         << mask << dec << setw(0) << setfill(fillChar) << " [Bits: ";
857                 PrintBitPattern(mask >> 12, 4); cout << " ";
858                 PrintBitPattern(mask >> 8, 4); cout << " ";
859                 PrintBitPattern(mask >> 4, 4); cout << " ";
860                 PrintBitPattern(mask >> 0, 4); cout << "]" << endl;
861                 
862                 cout << "L0 counter : " << GetRegionalL0(regionalStruct) << endl;
863                 
864                 cout << "========================= Regional structure scalars "
865                         << setw(3) << fRegNum << setw(0)
866                         << " =========================" << endl;
867                 if (scalars != NULL)
868                 {
869                         cout << "            Number of clock cycles : " << scalars->fClk << endl;
870                         cout << "   Number of high pT +ve single mu : " << scalars->fScaler[0] << endl;
871                         cout << "   Number of high pT -ve single mu : " << scalars->fScaler[1] << endl;
872                         cout << "Number of high pT unlike sign pair : " << scalars->fScaler[2] << endl;
873                         cout << "  Number of high pT like sign pair : " << scalars->fScaler[3] << endl;
874                         cout << "    Number of low pT +ve single mu : " << scalars->fScaler[4] << endl;
875                         cout << "    Number of low pT -ve single mu : " << scalars->fScaler[5] << endl;
876                         cout << " Number of low pT unlike sign pair : " << scalars->fScaler[6] << endl;
877                         cout << "   Number of low pT like sign pair : " << scalars->fScaler[7] << endl;
878                         cout << "                  Hold (dead time) : " << scalars->fHold << endl;
879                 }
880                 else
881                 {
882                         cout << "(None found)" << endl;
883                 }
884         }
885         
886         
887         void AliTriggerDecoderHandler::OnLocalStruct(
888                         const AliMUONLocalInfoStruct* localStruct,
889                         const AliMUONLocalScalarsStruct* scalars
890                 )
891         {
892                 TryDumpCorruptData(localStruct);
893                 
894                 fLocNum++;
895                 cout << "=========================== Local structure header "
896                         << setw(3) << fLocNum << setw(0)
897                         << " ===========================" << endl;
898                 char fillChar = cout.fill();  // store current fill char to restore it.
899                 cout << "L0 strip patterns:" << endl;
900                 cout << "Chamber |        X         |         Y        " << endl;
901                 cout << "----------------------------------------------" << endl;
902                 cout << "   11     ";
903                 PrintBitPattern(GetLocalX1(localStruct), 16);
904                 cout << "   ";
905                 PrintBitPattern(GetLocalY1(localStruct), 16);
906                 cout << endl;
907                 cout << "   12     ";
908                 PrintBitPattern(GetLocalX2(localStruct), 16);
909                 cout << "   ";
910                 PrintBitPattern(GetLocalY2(localStruct), 16);
911                 cout << endl;
912                 cout << "   13     ";
913                 PrintBitPattern(GetLocalX3(localStruct), 16);
914                 cout << "   ";
915                 PrintBitPattern(GetLocalY3(localStruct), 16);
916                 cout << endl;
917                 cout << "   14     ";
918                 PrintBitPattern(GetLocalX4(localStruct), 16);
919                 cout << "   ";
920                 PrintBitPattern(GetLocalY4(localStruct), 16);
921                 cout << endl;
922                 
923                 cout << "L0 trigger bits: (word = ";
924                 cout << showbase << hex << localStruct->fTriggerBits
925                         << noshowbase << dec << ")" << endl;
926                 cout << "            ID |  Dec | TrigY | YPos | Sign XDev | XDev |  XPos " << endl;
927                 cout << "----------------------------------------------------------------" << endl;
928                 cout << "Decimal : " << setw(4) << (UInt_t)GetLocalId(localStruct) << setw(0) << "   ";
929                 cout << setw(4) << (UInt_t)GetLocalDec(localStruct) << setw(0) << "   ";
930                 cout << setw(3) << (UInt_t)GetLocalTrigY(localStruct) << setw(0) << "     ";
931                 cout << setw(4) << (UInt_t)GetLocalYPos(localStruct) << setw(0) << "   ";
932                 cout << setw(5) << (UInt_t)GetLocalSXDev(localStruct) << setw(0) << "       ";
933                 cout << setw(4) << (UInt_t)GetLocalXDev(localStruct) << setw(0) << "   ";
934                 cout << setw(4) << (UInt_t)GetLocalXPos(localStruct) << setw(0) << endl;
935                 cout << " Binary : ";
936                 PrintBitPattern(AliHLTUInt32_t(GetLocalId(localStruct)), 4);
937                 cout << "   ";
938                 PrintBitPattern(AliHLTUInt32_t(GetLocalDec(localStruct)), 4);
939                 cout << "     ";
940                 PrintBitPattern(AliHLTUInt32_t(GetLocalTrigY(localStruct)), 1);
941                 cout << "     ";
942                 PrintBitPattern(AliHLTUInt32_t(GetLocalYPos(localStruct)), 4);
943                 cout << "       ";
944                 PrintBitPattern(AliHLTUInt32_t(GetLocalSXDev(localStruct)), 1);
945                 cout << "       ";
946                 PrintBitPattern(AliHLTUInt32_t(GetLocalXDev(localStruct)), 4);
947                 cout << "   ";
948                 PrintBitPattern(AliHLTUInt32_t(GetLocalXPos(localStruct)), 5);
949                 cout << endl;
950                 
951                 cout << "L0 decision (Dec): [high pT: ";
952                 PrintBitPattern((UInt_t)GetLocalHpt(localStruct), 2);
953                 cout << "b (";
954                 switch ((UInt_t)GetLocalHpt(localStruct))
955                 {
956                 case 0: cout << "No trigger"; break;
957                 case 1: cout << "-ve particle"; break;
958                 case 2: cout << "+ve particle"; break;
959                 case 3: cout << "No deviation trigger"; break;
960                 default: cout << "UNKNOWN"; break;
961                 }
962                 cout << "), low pT: ";
963                 PrintBitPattern((UInt_t)GetLocalLpt(localStruct), 2);
964                 cout << "b (";
965                 switch ((UInt_t)GetLocalLpt(localStruct))
966                 {
967                 case 0: cout << "No trigger"; break;
968                 case 1: cout << "-ve particle"; break;
969                 case 2: cout << "+ve particle"; break;
970                 case 3: cout << "No deviation trigger"; break;
971                 default: cout << "UNKNOWN"; break;
972                 }
973                 cout << ")]" << endl;
974                 
975                 cout << "=========================== Local structure scalars "
976                         << setw(3) << fLocNum << setw(0)
977                         << " ==========================" << endl;
978                 if (scalars != NULL)
979                 {
980                         cout << "              Number of L0 triggers : " << scalars->fL0 << endl;
981                         cout << "                   Hold (dead time) : " << scalars->fHold << endl;
982                         cout << "             Number of clock cycles : " << scalars->fClk << endl;
983                         cout << "       Number of low pT no triggers : " << scalars->fLPtNTrig << endl;
984                         cout << "      Number of high pT no triggers : " << scalars->fHPtNTrig << endl;
985                         cout << "    Number of low pT right triggers : " << scalars->fLPtRTrig << endl;
986                         cout << "   Number of high pT right triggers : " << scalars->fHPtRTrig << endl;
987                         cout << "     Number of low pT left triggers : " << scalars->fLPtLTrig << endl;
988                         cout << "    Number of high pT left triggers : " << scalars->fHPtLTrig << endl;
989                         cout << " Number of low pT straight triggers : " << scalars->fLPtSTrig << endl;
990                         cout << "Number of high pT straight triggers : " << scalars->fHPtSTrig << endl;
991                         
992                         UInt_t xoryflag = GetLocalComptXY(scalars);
993                         if (xoryflag == 1)
994                         {
995                                 cout << "Y strip counts:" << endl;
996                         }
997                         else
998                         {
999                                 cout << "X strip counts:" << endl;
1000                         }
1001                         cout << "      |               Chamber            " << endl;
1002                         cout << "Strip |     11 |     12 |     13 |     14" << endl;
1003                         cout << "------------------------------------------" << endl;
1004                         for (int i = 0; i < 16; i++)
1005                         {
1006                                 cout << setw(5) << i << setw(0) << "   "
1007                                         << setw(6) << (UInt_t)GetLocalXY1(scalars, i) << setw(0) << "   "
1008                                         << setw(6) << (UInt_t)GetLocalXY2(scalars, i) << setw(0) << "   "
1009                                         << setw(6) << (UInt_t)GetLocalXY3(scalars, i) << setw(0) << "   "
1010                                         << setw(6) << (UInt_t)GetLocalXY4(scalars, i) << setw(0) << endl;
1011                         }
1012                         
1013                         cout << "    EOS word : 0x" << setw(8) << setfill('0')
1014                                 << hex << scalars->fEOS << setw(0) << setfill(fillChar) << dec << endl;
1015                         cout << "    [ Switches : 0x" << setw(3)
1016                                 << setfill('0') << hex << (UInt_t)GetLocalSwitch(scalars)
1017                                 << setw(0) << setfill(fillChar) << dec << " (";
1018                         PrintBitPattern((UInt_t)GetLocalSwitch(scalars) >> 8, 2); cout << " ";
1019                         PrintBitPattern((UInt_t)GetLocalSwitch(scalars) >> 4, 4); cout << " ";
1020                         PrintBitPattern((UInt_t)GetLocalSwitch(scalars) >> 0, 4);
1021                         cout << "b)    ]" << endl;
1022                         cout << "    [   X or Y : " << xoryflag
1023                                 << ((xoryflag == 1) ? " (scalars for Y strips) ]" : " (scalars for X strips) ]")
1024                                 << endl;
1025                         
1026                         cout << "Reset signal : " << scalars->fReset << endl;
1027                 }
1028                 else
1029                 {
1030                         cout << "(None found)" << endl;
1031                 }
1032         }
1033         
1034         
1035         void AliTriggerDecoderHandler::OnError(ErrorCode error, const void* location)
1036         {
1037                 TryDumpCorruptData(location);
1038                 HandleError(
1039                         ErrorCodeToMessage(error), error,
1040                         ErrorCodeToString(error), location
1041                 );
1042         }
1043
1044 } // end of namespace
1045
1046
1047 int DumpRawDataHeader(
1048                 const char* buffer, unsigned long bufferSize, const AliRawDataHeader* header,
1049                 bool continueParse
1050         )
1051 {
1052         // Dumps the common DDL raw data block header.
1053         
1054         cout << "*************************** Common DDL data header *******************************" << endl;
1055         char fillChar = cout.fill();  // remember fill char to set back to original later.
1056         int result = CheckHeaderField(header->fSize, buffer, bufferSize, continueParse);
1057         if (result != EXIT_SUCCESS) return result;
1058         cout << "Size of the raw data in bytes : ";
1059         if (header->fSize != 0xFFFFFFFF)
1060                 cout << header->fSize;
1061         else
1062                 cout << "0xFFFFFFFF (unknown)";
1063         cout << endl;
1064         
1065         result = CheckHeaderField(header->fWord2, buffer, bufferSize, continueParse);
1066         if (result != EXIT_SUCCESS) return result;
1067         cout << "               Format version : " << UInt_t(header->GetVersion()) << endl;
1068         UInt_t l1msg = header->GetL1TriggerMessage();
1069         cout << "           L1 trigger message : 0x"
1070                 << noshowbase << hex << setfill('0') << setw(2) << l1msg
1071                 << setw(0) << setfill(fillChar) << dec
1072                 << " [Spare: " << ((l1msg >> 7) & 0x1)
1073                 << ", ClT: " << ((l1msg >> 6) & 0x1)
1074                 << ", RoC: 0x" << noshowbase << hex << ((l1msg >> 2) & 0x4) << dec
1075                 << ", ESR: " << ((l1msg >> 1) & 0x1)
1076                 << ", L1SwC: " << ((l1msg >> 0) & 0x1) << "]" << endl;
1077         cout << "   Bunch crossing (Event ID1) : " << header->GetEventID1() << " (0x"
1078                 << noshowbase << hex << setfill('0') << setw(3) << header->GetEventID1()
1079                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1080         
1081         result = CheckHeaderField(header->fEventID2, buffer, bufferSize, continueParse);
1082         if (result != EXIT_SUCCESS) return result;
1083         cout << "     Orbit number (Event ID2) : " << header->fEventID2 << " (0x"
1084                 << noshowbase << hex << setfill('0') << setw(6) << header->fEventID2
1085                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1086         
1087         result = CheckHeaderField(header->fAttributesSubDetectors, buffer, bufferSize, continueParse);
1088         if (result != EXIT_SUCCESS) return result;
1089         cout << "             Block attributes : " << UInt_t(header->GetAttributes()) << " (0x"
1090                 << noshowbase << hex << setfill('0') << setw(2) << UInt_t(header->GetAttributes())
1091                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1092         cout << "  Participating sub-detectors : 0x" << noshowbase << hex
1093                 << setfill('0') << setw(6) << header->GetSubDetectors() << dec
1094                 << setw(0) << setfill(fillChar) << "    [Bits: ";
1095         for (int i = 5; i >= 0; i--)
1096         {
1097                 PrintBitPattern(header->GetSubDetectors() >> (i*4), 4);
1098                 if (i != 0)
1099                         cout << " ";
1100                 else
1101                         cout << "]" << endl;
1102         }
1103         
1104         result = CheckHeaderField(header->fStatusMiniEventID, buffer, bufferSize, continueParse);
1105         if (result != EXIT_SUCCESS) return result;
1106         UInt_t statusBits = header->GetStatus();
1107         cout << "          Status & error bits : 0x" << noshowbase << hex
1108                 << setfill('0') << setw(4) << statusBits << setw(0) << setfill(fillChar)
1109                 << dec << endl;
1110         cout << "          [               Original data bit : " << ((statusBits >> 15) & 0x1) << " ]" << endl;
1111         cout << "          [        Multi-event buffer error : " << ((statusBits >> 14) & 0x1) << " ]" << endl;
1112         cout << "          [        Trigger L1 missing error : " << ((statusBits >> 13) & 0x1) << " ]" << endl;
1113         cout << "          [           Trigger error (other) : " << ((statusBits >> 12) & 0x1) << " ]" << endl;
1114         cout << "          [                 Pre-pulse error : " << ((statusBits >> 11) & 0x1) << " ]" << endl;
1115         cout << "          [       Trigger L2 time violation : " << ((statusBits >> 10) & 0x1) << " ]" << endl;
1116         cout << "          [       Trigger L1 time violation : " << ((statusBits >> 9) & 0x1) << " ]" << endl;
1117         cout << "          [                DDG payload flag : " << ((statusBits >> 8) & 0x1) << " ]" << endl;
1118         cout << "          [                HLT payload flag : " << ((statusBits >> 7) & 0x1) << " ]" << endl;
1119         cout << "          [               HLT decision flag : " << ((statusBits >> 6) & 0x1) << " ]" << endl;
1120         cout << "          [                       FEE error : " << ((statusBits >> 5) & 0x1) << " ]" << endl;
1121         cout << "          [ Trigger information unavailable : " << ((statusBits >> 4) & 0x1) << " ]" << endl;
1122         cout << "          [            Control parity error : " << ((statusBits >> 3) & 0x1) << " ]" << endl;
1123         cout << "          [               Data parity error : " << ((statusBits >> 2) & 0x1) << " ]" << endl;
1124         cout << "          [           Trigger missing error : " << ((statusBits >> 1) & 0x1) << " ]" << endl;
1125         cout << "          [           Trigger overlap error : " << ((statusBits >> 0) & 0x1) << " ]" << endl;
1126         cout << "                Mini event ID : " << header->GetMiniEventID() << " (0x"
1127                 << noshowbase << hex << setfill('0') << setw(3) << header->GetMiniEventID()
1128                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1129         
1130         result = CheckHeaderField(header->fTriggerClassLow, buffer, bufferSize, continueParse);
1131         if (result != EXIT_SUCCESS) return result;
1132         result = CheckHeaderField(header->fROILowTriggerClassHigh, buffer, bufferSize, continueParse);
1133         if (result != EXIT_SUCCESS) return result;
1134         ULong64_t triggerClasses = header->GetTriggerClasses();
1135         cout << "              Trigger classes : 0x" << noshowbase << hex << setw(13)
1136                 << setfill('0') << triggerClasses << setw(0) << setfill(fillChar)
1137                 << dec << endl;
1138         cout << "                [Bits: ";
1139         PrintBitPattern(triggerClasses >> (12*4), 2);
1140         cout << " ";
1141         for (int i = 11; i >= 0; i--)
1142         {
1143                 PrintBitPattern(triggerClasses >> (i*4), 4);
1144                 if (i != 0)
1145                         cout << " ";
1146                 else
1147                         cout << "]" << endl;
1148         }
1149         
1150         result = CheckHeaderField(header->fROIHigh, buffer, bufferSize, continueParse);
1151         if (result != EXIT_SUCCESS) return result;
1152         ULong64_t roiBits = header->GetROI();
1153         cout << "           Region of interest : 0x" << noshowbase << hex << setw(9)
1154                 << setfill('0') << roiBits << setw(0) << setfill(fillChar)
1155                 << dec << endl;
1156         cout << "             [Bits: ";
1157         for (int i = 8; i >= 0; i--)
1158         {
1159                 PrintBitPattern(roiBits >> (i*4), 4);
1160                 if (i != 0)
1161                         cout << " ";
1162                 else
1163                         cout << "]" << endl;
1164         }
1165         cout << "**********************************************************************************" <<endl;
1166         return EXIT_SUCCESS;
1167 }
1168
1169
1170 int DumpTrackerDDLRawStream(
1171                 char* buffer, unsigned long bufferSize,
1172                 bool continueParse, bool tryrecover
1173         )
1174 {
1175         // Dumps a tracker DDL raw stream data.
1176         
1177         AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(buffer);
1178         int result = DumpRawDataHeader(buffer, bufferSize, header, continueParse);
1179         if (result != EXIT_SUCCESS) return result;
1180
1181         // Setup the decoder for the DDL payload.
1182         AliMUONTrackerDDLDecoder<AliTrackerDecoderHandler> decoder;
1183         decoder.ExitOnError(not continueParse);
1184         decoder.SendDataOnParityError(true);
1185         decoder.TryRecover(tryrecover);
1186         decoder.AutoDetectTrailer(true);
1187         decoder.CheckForTrailer(true);
1188         char* payload = buffer + sizeof(AliRawDataHeader);
1189         UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
1190         if (decoder.Decode(payload, payloadSize))
1191         {
1192                 return EXIT_SUCCESS;
1193         }
1194         else
1195         {
1196                 return PARSE_ERROR;
1197         }
1198 }
1199
1200
1201 int DumpTriggerDDLRawStream(
1202                 const char* buffer, unsigned long bufferSize,
1203                 bool continueParse, bool tryrecover
1204         )
1205 {
1206         // Dumps a trigger DDL raw stream data.
1207         
1208         const AliRawDataHeader* header =
1209                 reinterpret_cast<const AliRawDataHeader*>(buffer);
1210         int result = DumpRawDataHeader(buffer, bufferSize, header, continueParse);
1211         if(result != EXIT_SUCCESS) return result;
1212         bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
1213         
1214         AliMUONTriggerDDLDecoder<AliTriggerDecoderHandler> decoder;
1215         decoder.ExitOnError(not continueParse);
1216         decoder.TryRecover(tryrecover);
1217         decoder.AutoDetectScalars(false);
1218         const char* payload = buffer + sizeof(AliRawDataHeader);
1219         UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
1220         if (decoder.Decode(payload, payloadSize, scalarEvent))
1221         {
1222                 return EXIT_SUCCESS;
1223         }
1224         else
1225         {
1226                 return PARSE_ERROR;
1227         }
1228 }
1229
1230
1231 int DumpRecHitStruct(
1232                 const char* buffer, unsigned long bufferSize,
1233                 const AliHLTMUONRecHitStruct* hit,
1234                 bool continueParse
1235         )
1236 {
1237         // Step through the fields trying to print them.
1238         // At each step check if we have not overflowed the buffer. If we have
1239         // not, then we can print the field, otherwise we print the left over
1240         // bytes assumed to be corrupted rubbish.
1241         
1242         int result = CheckField(hit->fFlags, buffer, bufferSize, continueParse);
1243         if (result != EXIT_SUCCESS) return result;
1244         AliHLTUInt8_t chamber = 0xFF;
1245         AliHLTUInt16_t detElemId = 0xFFFF;
1246         AliHLTMUONUtils::UnpackRecHitFlags(hit->fFlags, chamber, detElemId);
1247         if (chamber == 0 and detElemId == 0)
1248         {
1249                 cout << setw(10) << left << (int)(chamber) << setw(0);
1250                 cout << setw(12) << left << (int)detElemId << setw(0);
1251         }
1252         else
1253         {
1254                 cout << setw(10) << left << (int)(chamber+1) << setw(0);
1255                 cout << setw(12) << left << (int)detElemId << setw(0);
1256         }
1257         
1258         result = CheckField(hit->fX, buffer, bufferSize, continueParse);
1259         if (result != EXIT_SUCCESS) return result;
1260         cout << setw(13) << left << hit->fX << setw(0);
1261
1262         result = CheckField(hit->fY, buffer, bufferSize, continueParse);
1263         if (result != EXIT_SUCCESS) return result;
1264         cout << setw(13) << left << hit->fY << setw(0);
1265
1266         result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
1267         if (result != EXIT_SUCCESS) return result;
1268         cout << hit->fZ << setw(0) << endl;
1269
1270         return result;
1271 }
1272
1273
1274 int DumpRecHitsBlock(
1275                 const char* buffer, unsigned long bufferSize,
1276                 bool continueParse
1277         )
1278 {
1279         // Dumps a reconstructed hits data block.
1280         
1281         int result = EXIT_SUCCESS;
1282         AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
1283         
1284         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1285         if (result != EXIT_SUCCESS and not continueParse) return result;
1286         
1287         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1288         
1289         // Print the data block record entries.
1290         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1291         cout << "-----------------------------------------------------------" << endl;
1292         const AliHLTMUONRecHitStruct* entry = block.GetArray();
1293         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1294         {
1295                 int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
1296                 if (subResult != EXIT_SUCCESS) return subResult;
1297         }
1298         
1299         return result;
1300 }
1301
1302
1303 int DumpTriggerRecordStruct(
1304                 const char* buffer, unsigned long bufferSize,
1305                 const AliHLTMUONTriggerRecordStruct* record,
1306                 bool continueParse
1307         )
1308 {
1309         // Step through the fields trying to print them.
1310         // At each step check if we have not overflowed the buffer. If we have
1311         // not, then we can print the field, otherwise we print the left over
1312         // bytes assumed to be corrupted rubbish.
1313         int result = CheckField(record->fId, buffer, bufferSize, continueParse);
1314         if (result != EXIT_SUCCESS) return result;
1315         cout << "Trigger Record ID: " << record->fId <<endl;
1316         
1317         result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
1318         if (result != EXIT_SUCCESS) return result;
1319         ios::fmtflags oldflags = cout.flags();
1320         cout << "Flags: " << showbase << hex << record->fFlags << dec;
1321         cout.flags(oldflags);
1322                 
1323         // Print the individual trigger bits.
1324         AliHLTMUONParticleSign sign;
1325         bool hitset[4];
1326         AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
1327         cout << " [Sign: " << sign << ", Hits set on chambers: ";
1328         bool first = true;
1329         for (AliHLTUInt32_t i = 0; i < 4; i++)
1330         {
1331                 if (hitset[i])
1332                 {
1333                         cout << (first ? "" : ", ") << i+11;
1334                         first = false;
1335                 }
1336         }
1337         cout << (first ? "none]" : "]") << endl;
1338
1339         result = CheckField(record->fPx, buffer, bufferSize, continueParse);
1340         if (result != EXIT_SUCCESS) return result;
1341         cout << "Momentum: (px = " << record->fPx << ", ";
1342
1343         result = CheckField(record->fPy, buffer, bufferSize, continueParse);
1344         if (result != EXIT_SUCCESS) return result;
1345         cout << "py = " << record->fPy << ", ";
1346
1347         result = CheckField(record->fPz, buffer, bufferSize, continueParse);
1348         if (result != EXIT_SUCCESS) return result;
1349         cout << "pz = " << record->fPz << ") GeV/c"<<endl;
1350         
1351         cout << "Hits on chambers:" << endl;
1352         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1353         cout << "-----------------------------------------------------------" << endl;
1354         const AliHLTMUONRecHitStruct* hit = &record->fHit[0];
1355         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1356         {
1357                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
1358                 if (result != EXIT_SUCCESS) return result;
1359         }
1360
1361         return result;
1362
1363 }
1364
1365
1366 int DumpTriggerRecordsBlock(
1367                 const char* buffer, unsigned long bufferSize,
1368                 bool continueParse
1369         )
1370 {
1371         // Dumps a trigger records data block.
1372         
1373         AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
1374         
1375         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1376         if (result != EXIT_SUCCESS and not continueParse) return result;
1377         
1378         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1379         
1380         // Print the data block record entries.
1381         const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
1382         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1383         {
1384                 cout << "============================== Trigger Record number " << i+1
1385                         << " of " << nentries << " ==============================" << endl;
1386                 int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse);
1387                 if (subResult != EXIT_SUCCESS) return subResult;
1388         }
1389         
1390         return EXIT_SUCCESS;
1391 }
1392
1393
1394 int DumpLocalStruct(
1395                 const char* buffer, unsigned long bufferSize,
1396                 const AliMUONLocalInfoStruct* localStruct,
1397                 bool continueParse,
1398                 const char* title = ""
1399         )
1400 {
1401         // Prints the fields of a L0 local structure as found in the buffer.
1402         
1403         typedef AliMUONTriggerDDLDecoderEventHandler AliH;
1404         
1405         cout << "L0 strip patterns" << title << ":" << endl;
1406         cout << "Chamber |        X         |         Y        " << endl;
1407         cout << "----------------------------------------------" << endl;
1408         int result = CheckField(localStruct->fX2X1, buffer, bufferSize, continueParse);
1409         if (result != EXIT_SUCCESS) return result;
1410         cout << "   11     ";
1411         PrintBitPattern(AliH::GetLocalX1(localStruct), 16);
1412         result = CheckField(localStruct->fY2Y1, buffer, bufferSize, continueParse);
1413         if (result != EXIT_SUCCESS) return result;
1414         cout << "   ";
1415         PrintBitPattern(AliH::GetLocalY1(localStruct), 16);
1416         cout << endl;
1417         cout << "   12     ";
1418         PrintBitPattern(AliH::GetLocalX2(localStruct), 16);
1419         cout << "   ";
1420         PrintBitPattern(AliH::GetLocalY2(localStruct), 16);
1421         cout << endl;
1422         
1423         result = CheckField(localStruct->fX4X3, buffer, bufferSize, continueParse);
1424         if (result != EXIT_SUCCESS) return result;
1425         cout << "   13     ";
1426         PrintBitPattern(AliH::GetLocalX3(localStruct), 16);
1427         result = CheckField(localStruct->fY4Y3, buffer, bufferSize, continueParse);
1428         if (result != EXIT_SUCCESS) return result;
1429         cout << "   ";
1430         PrintBitPattern(AliH::GetLocalY3(localStruct), 16);
1431         cout << endl;
1432         cout << "   12     ";
1433         PrintBitPattern(AliH::GetLocalX4(localStruct), 16);
1434         cout << "   ";
1435         PrintBitPattern(AliH::GetLocalY4(localStruct), 16);
1436         cout << endl;
1437         
1438         cout << "L0 trigger bits" << title << ": (word = ";
1439         result = CheckField(localStruct->fTriggerBits, buffer, bufferSize, continueParse);
1440         if (result != EXIT_SUCCESS) return result;
1441         cout << showbase << hex << localStruct->fTriggerBits
1442                 << noshowbase << dec << ")" << endl;
1443         cout << "  ID |  Dec | TrigY | YPos | Sign XDev | XDev |  XPos " << endl;
1444         cout << "------------------------------------------------------" << endl;
1445         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalId(localStruct)), 4);
1446         cout << "   ";
1447         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalDec(localStruct)), 4);
1448         cout << "     ";
1449         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalTrigY(localStruct)), 1);
1450         cout << "     ";
1451         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalYPos(localStruct)), 4);
1452         cout << "       ";
1453         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalSXDev(localStruct)), 1);
1454         cout << "       ";
1455         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalXDev(localStruct)), 4);
1456         cout << "   ";
1457         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalXPos(localStruct)), 5);
1458         cout << endl;
1459         
1460         return result;
1461 }
1462
1463
1464 int DumpTrigRecInfoStruct(
1465                 const char* buffer, unsigned long bufferSize,
1466                 const AliHLTMUONTrigRecInfoStruct* debuginfo,
1467                 bool continueParse
1468         )
1469 {
1470         // Step through the fields trying to print them.
1471         // At each step check if we have not overflowed the buffer. If we have
1472         // not, then we can print the field, otherwise we print the left over
1473         // bytes assumed to be corrupted rubbish.
1474         
1475         int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse);
1476         if (result != EXIT_SUCCESS) return result;
1477         cout << "Trigger Record ID: " << debuginfo->fTrigRecId << endl;
1478
1479         cout << "Detector element IDs:" << endl;
1480         cout << "  Chamber :           11 |           12 |           13 |           14" << endl;
1481         cout << "       ID : ";
1482         for (int i = 0; i < 4; i++)
1483         {
1484                 result = CheckField(debuginfo->fDetElemId[i], buffer, bufferSize, continueParse);
1485                 if (result != EXIT_SUCCESS) return result;
1486                 ios::fmtflags oldflags = cout.flags();
1487                 cout << setw(12) << right << debuginfo->fDetElemId[i] << setw(0);
1488                 cout.flags(oldflags);
1489                 if (i != 3) cout << " | ";
1490         }
1491         cout << endl;
1492         
1493         cout << "Momentum estimation parameters:" << endl;
1494         cout << "  Parameter : Z_middle coordinate (cm) | Integrated magnetic field (T.m)" << endl;
1495         cout << "      Value : ";
1496         result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
1497         if(result != EXIT_SUCCESS) return result;
1498         cout << setw(24) << right << debuginfo->fZmiddle << setw(0) << " | ";
1499         
1500         result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
1501         if (result != EXIT_SUCCESS) return result;
1502         cout << setw(31) << right << debuginfo->fBl << setw(0) << endl;
1503         
1504         result = DumpLocalStruct(buffer, bufferSize, &debuginfo->fL0Struct, continueParse, " for central local structure");
1505         if (result != EXIT_SUCCESS) return result;
1506         result = DumpLocalStruct(buffer, bufferSize, &debuginfo->fL0StructPrev, continueParse, " for previous local structure");
1507         if (result != EXIT_SUCCESS) return result;
1508         result = DumpLocalStruct(buffer, bufferSize, &debuginfo->fL0StructNext, continueParse, " for next local structure");
1509         if (result != EXIT_SUCCESS) return result;
1510         
1511         return result;
1512 }
1513
1514
1515 int DumpTrigRecsDebugBlock(
1516                 const char* buffer, unsigned long bufferSize,
1517                 bool continueParse
1518         )
1519 {
1520         // Dumps the debugging information for trigger records.
1521         
1522         AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
1523         
1524         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1525         if (result != EXIT_SUCCESS and not continueParse) return result;
1526         
1527         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1528         
1529         // Print the data block record entries.
1530         const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray();
1531         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1532         {
1533                 cout << "======================= Trigger Record debug data " << i+1
1534                         << " of " << nentries << " =======================" << endl;
1535                 int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
1536                 if (subResult != EXIT_SUCCESS) return subResult;
1537         }
1538         
1539         return EXIT_SUCCESS;
1540 }
1541
1542
1543 int DumpClusterStruct(
1544                 const char* buffer, unsigned long bufferSize,
1545                 const AliHLTMUONClusterStruct* cluster,
1546                 bool continueParse
1547         )
1548 {
1549         // Step through the fields trying to print them.
1550         // At each step check if we have not overflowed the buffer. If we have
1551         // not, then we can print the field, otherwise we print the left over
1552         // bytes assumed to be corrupted rubbish.
1553         int result = CheckField(cluster->fId, buffer, bufferSize, continueParse);
1554         if (result != EXIT_SUCCESS) return result;
1555         cout << "                             Cluster ID: " << cluster->fId << endl;
1556
1557         result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
1558         if (result != EXIT_SUCCESS) return result;
1559         cout << "                    Detector Element ID: " << cluster->fDetElemId << endl;
1560
1561         result = CheckField(cluster->fNchannelsB, buffer, bufferSize, continueParse);
1562         if (result != EXIT_SUCCESS) return result;
1563         cout << "    Number of channels in bending plane: " << cluster->fNchannelsB << endl;
1564
1565         result = CheckField(cluster->fNchannelsNB, buffer, bufferSize, continueParse);
1566         if (result != EXIT_SUCCESS) return result;
1567         cout << "Number of channels in non-bending plane: " << cluster->fNchannelsNB << endl;
1568         
1569         result = CheckField(cluster->fChargeB, buffer, bufferSize, continueParse);
1570         if (result != EXIT_SUCCESS) return result;
1571         cout << "                Charge on bending plane: " << cluster->fChargeB << endl;
1572
1573         result = CheckField(cluster->fChargeNB, buffer, bufferSize, continueParse);
1574         if (result != EXIT_SUCCESS) return result;
1575         cout << "            Charge on non bending plane: " << cluster->fChargeNB << endl;
1576
1577         cout << "Corresponding Hit: "<< endl;
1578         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1579         cout << "-----------------------------------------------------------" << endl;
1580         result = DumpRecHitStruct(buffer, bufferSize, &cluster->fHit, continueParse);
1581
1582         return result;
1583 }
1584
1585
1586 int DumpClustersBlock(
1587                 const char* buffer, unsigned long bufferSize,
1588                 bool continueParse
1589         )
1590 {
1591         // Dumps a clusters block structure.
1592         
1593         int result = EXIT_SUCCESS;
1594         AliHLTMUONClustersBlockReader block(buffer, bufferSize);
1595         
1596         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1597         if (result != EXIT_SUCCESS and not continueParse) return result;
1598         
1599         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1600         
1601         // Print the data block record entries.
1602         const AliHLTMUONClusterStruct* entry = block.GetArray();
1603         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1604         {
1605                 cout << "======================= Cluster Number "
1606                         << i+1 << " =======================" << endl;
1607                 int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
1608                 if (subResult != EXIT_SUCCESS) return subResult;
1609         }       
1610
1611         return result;
1612 }
1613
1614
1615 int DumpChannelStruct(
1616                 const char* buffer, unsigned long bufferSize,
1617                 const AliHLTMUONChannelStruct* channel,
1618                 bool continueParse
1619         )
1620 {
1621         // Step through the fields trying to print them.
1622         // At each step check if we have not overflowed the buffer. If we have
1623         // not, then we can print the field, otherwise we print the left over
1624         // bytes assumed to be corrupted rubbish.
1625         int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse);
1626         if (result != EXIT_SUCCESS) return result;
1627         ios::fmtflags oldflags = cout.flags();
1628         cout << setw(16) << left << channel->fClusterId << setw(0);
1629         cout.flags(oldflags);
1630
1631         result = CheckField(channel->fBusPatch, buffer, bufferSize, continueParse);
1632         if (result != EXIT_SUCCESS) return result;
1633         oldflags = cout.flags();
1634         cout << setw(16) << left << channel->fBusPatch << setw(0);
1635         cout.flags(oldflags);
1636
1637         result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
1638         if (result != EXIT_SUCCESS) return result;
1639         oldflags = cout.flags();
1640         cout << setw(16) << left << channel->fManu << setw(0);
1641         cout.flags(oldflags);
1642
1643         result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
1644         if (result != EXIT_SUCCESS) return result;
1645         oldflags = cout.flags();
1646         cout << setw(16) << left << channel->fChannelAddress << setw(0);
1647         cout.flags(oldflags);
1648
1649         result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
1650         if(result != EXIT_SUCCESS) return result;
1651         oldflags = cout.flags();
1652         cout << setw(16) << left << channel->fSignal << setw(0);
1653         cout.flags(oldflags);
1654
1655         result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse);
1656         if(result != EXIT_SUCCESS) return result;
1657         oldflags = cout.flags();
1658         cout << showbase << hex << channel->fRawDataWord << dec << setw(0) << endl;
1659         cout.flags(oldflags);
1660
1661         return result;
1662 }
1663
1664
1665 int DumpChannelsBlock(
1666                 const char* buffer, unsigned long bufferSize,
1667                 bool continueParse
1668         )
1669 {
1670         // Dumps a channels block structure.
1671         
1672         int result = EXIT_SUCCESS;
1673         AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
1674         
1675         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1676         if (result != EXIT_SUCCESS and not continueParse) return result;
1677         
1678         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1679         
1680         // Print the data block record entries.
1681         cout << "Cluster ID    | Bus Patch     | Manu Address  | Channel Addr  | Signal Value  | Raw Data Word " << endl;
1682         cout << "----------------------------------------------------------------------------------------------" << endl;
1683         const AliHLTMUONChannelStruct* entry = block.GetArray();
1684         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1685         { 
1686                 int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
1687                 if (subResult != EXIT_SUCCESS) return subResult;
1688         }
1689         return EXIT_SUCCESS;
1690 }
1691
1692
1693 int DumpMansoTrackStruct(
1694                 const char* buffer, unsigned long bufferSize,
1695                 const AliHLTMUONMansoTrackStruct* track,
1696                 bool continueParse
1697         )
1698 {
1699         // Step through the fields trying to print them.
1700         // At each step check if we have not overflowed the buffer. If we have
1701         // not, then we can print the field, otherwise we print the left over
1702         // bytes assumed to be corrupted rubbish.
1703         int result = CheckField(track->fId, buffer, bufferSize, continueParse);
1704         if (result != EXIT_SUCCESS) return result;
1705         cout << "Track ID: " << track->fId << "\t";
1706
1707         result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
1708         if (result != EXIT_SUCCESS) return result;
1709         cout << "Trigger Record ID: " << track->fTrigRec << endl;
1710         
1711         result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
1712         if (result != EXIT_SUCCESS) return result;
1713         ios::fmtflags oldflags = cout.flags();
1714         cout << "Flags: " << showbase << hex << track->fFlags << dec;
1715         cout.flags(oldflags);
1716         
1717         // Print the individual trigger bits.
1718         AliHLTMUONParticleSign sign;
1719         bool hitset[4];
1720         AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset);
1721         cout << " [Sign: " << sign << ", Hits set on chambers: ";
1722         bool first = true;
1723         for (AliHLTUInt32_t i = 0; i < 4; i++)
1724         {
1725                 if (hitset[i])
1726                 {
1727                         cout << (first ? "" : ", ") << i+7;
1728                         first = false;
1729                 }
1730         }
1731         cout << (first ? "none]" : "]") << endl;
1732
1733         result = CheckField(track->fPx, buffer, bufferSize, continueParse);
1734         if (result != EXIT_SUCCESS) return result;
1735         cout << "Momentum: (px = " << track->fPx << ", ";
1736
1737         result = CheckField(track->fPy, buffer, bufferSize, continueParse);
1738         if (result != EXIT_SUCCESS) return result;
1739         cout << "py = " << track->fPy << ", ";
1740
1741         result = CheckField(track->fPz, buffer, bufferSize, continueParse);
1742         if (result != EXIT_SUCCESS) return result;
1743         cout << "pz = " << track->fPz << ") GeV/c\t";
1744
1745         result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
1746         if (result != EXIT_SUCCESS) return result;
1747         cout << "Chi squared fit: " << track->fChi2 << endl;
1748         
1749         cout << "Track hits:" << endl;
1750         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1751         cout << "-----------------------------------------------------------" << endl;
1752         const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
1753         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1754         {
1755                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
1756                 if (result != EXIT_SUCCESS) return result;
1757         }
1758
1759         return result;
1760 }
1761
1762
1763 int DumpMansoTracksBlock(
1764                 const char* buffer, unsigned long bufferSize,
1765                 bool continueParse
1766         )
1767 {
1768         // Dumps the Manso tracks block structure.
1769         
1770         int result = EXIT_SUCCESS;
1771         AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize);
1772         
1773         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1774         if (result != EXIT_SUCCESS and not continueParse) return result;
1775         
1776         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1777         
1778         // Print the data block record entries.
1779         const AliHLTMUONMansoTrackStruct* entry = block.GetArray();
1780         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1781         {
1782                 cout << "============================== Manso track number " << i+1
1783                         << " of " << nentries << " ==============================" << endl;
1784                 int subResult = DumpMansoTrackStruct(buffer, bufferSize, entry++, continueParse);
1785                 if (subResult != EXIT_SUCCESS) return subResult;
1786         }
1787         
1788         return result;
1789 }
1790
1791
1792 int DumpMansoRoIStruct(
1793                 const char* buffer, unsigned long bufferSize,
1794                 const AliHLTMUONMansoRoIStruct* roi,
1795                 bool continueParse
1796         )
1797 {
1798         // Step through the fields trying to print them.
1799         // At each step check if we have not overflowed the buffer. If we have
1800         // not, then we can print the field, otherwise we print the left over
1801         // bytes assumed to be corrupted rubbish.
1802         int result = CheckField(roi->fX, buffer, bufferSize, continueParse);
1803         if (result != EXIT_SUCCESS) return result;
1804         ios::fmtflags oldflags = cout.flags();
1805         cout << setw(13) << left << roi->fX << setw(0);
1806         cout.flags(oldflags);
1807
1808         result = CheckField(roi->fY, buffer, bufferSize, continueParse);
1809         if (result != EXIT_SUCCESS) return result;
1810         oldflags = cout.flags();
1811         cout << setw(13) << left << roi->fY << setw(0);
1812         cout.flags(oldflags);
1813
1814         result = CheckField(roi->fZ, buffer, bufferSize, continueParse);
1815         if (result != EXIT_SUCCESS) return result;
1816         oldflags = cout.flags();
1817         cout << setw(13) << left << roi->fZ << setw(0);
1818         cout.flags(oldflags);
1819
1820         result = CheckField(roi->fRadius, buffer, bufferSize, continueParse);
1821         if (result != EXIT_SUCCESS) return result;
1822         oldflags = cout.flags();
1823         cout << roi->fRadius << setw(0) << endl;
1824         cout.flags(oldflags);
1825
1826         return result;
1827 }
1828
1829
1830 int DumpMansoCandidateStruct(
1831                 const char* buffer, unsigned long bufferSize,
1832                 const AliHLTMUONMansoCandidateStruct* candidate,
1833                 bool continueParse
1834         )
1835 {
1836         // Dumps the manso candidate structure.
1837         
1838         int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse);
1839         if (result != EXIT_SUCCESS) return result;
1840         
1841         cout << "Regions of interest:" << endl;
1842         cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)     | Radius (cm)" << endl;
1843         cout << "-------------------------------------------------------------" << endl;
1844         const AliHLTMUONMansoRoIStruct* roi = &candidate->fRoI[0];
1845         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1846         {
1847                 cout << setw(10) << ch + 7;
1848                 result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse);
1849                 if (result != EXIT_SUCCESS) return result;
1850         }
1851         
1852         cout << "Momentum estimation parameters:" << endl;
1853         cout << "  Parameter : Z_middle coordinate (cm) | Integrated magnetic field (T.m)" << endl;
1854         cout << "      Value : ";
1855         result = CheckField(candidate->fZmiddle, buffer, bufferSize, continueParse);
1856         if(result != EXIT_SUCCESS) return result;
1857         ios::fmtflags oldflags = cout.flags();
1858         cout << setw(24) << right << candidate->fZmiddle << setw(0) << " | ";
1859         cout.flags(oldflags);
1860         
1861         result = CheckField(candidate->fBl, buffer, bufferSize, continueParse);
1862         if (result != EXIT_SUCCESS) return result;
1863         oldflags = cout.flags();
1864         cout << setw(31) << right << candidate->fBl << setw(0) << endl;
1865         cout.flags(oldflags);
1866         
1867         return result;
1868 }
1869
1870
1871 int DumpMansoCandidatesBlock(
1872                 const char* buffer, unsigned long bufferSize,
1873                 bool continueParse
1874         )
1875 {
1876         // Dumps the manso candidates block structure.
1877         
1878         int result = EXIT_SUCCESS;
1879         AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize);
1880         
1881         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1882         if (result != EXIT_SUCCESS and not continueParse) return result;
1883         
1884         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1885         
1886         // Print the data block record entries.
1887         const AliHLTMUONMansoCandidateStruct* entry = block.GetArray();
1888         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1889         {
1890                 cout << "=========================== Manso track candidate number " << i+1
1891                         << " of " << nentries << " ===========================" << endl;
1892                 int subResult = DumpMansoCandidateStruct(buffer, bufferSize, entry++, continueParse);
1893                 if (subResult != EXIT_SUCCESS) return subResult;
1894         }
1895         
1896         return result;
1897 }
1898
1899
1900 int DumpTrackStruct(
1901                 const char* buffer, unsigned long bufferSize,
1902                 const AliHLTMUONTrackStruct* track,
1903                 bool continueParse
1904         )
1905 {
1906         // Step through the fields trying to print them.
1907         // At each step check if we have not overflowed the buffer. If we have
1908         // not, then we can print the field, otherwise we print the left over
1909         // bytes assumed to be corrupted rubbish.
1910         int result = CheckField(track->fId, buffer, bufferSize, continueParse);
1911         if (result != EXIT_SUCCESS) return result;
1912         cout << "Track ID: " << track->fId << "\t";
1913
1914         result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
1915         if (result != EXIT_SUCCESS) return result;
1916         cout << "Trigger Record ID: " << track->fTrigRec << endl;
1917         
1918         result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
1919         if (result != EXIT_SUCCESS) return result;
1920         ios::fmtflags oldflags = cout.flags();
1921         cout << "Flags: " << showbase << hex << track->fFlags << dec;
1922         cout.flags(oldflags);
1923         
1924         // Print the individual trigger bits.
1925         AliHLTMUONParticleSign sign;
1926         bool hitset[16];
1927         AliHLTMUONUtils::UnpackTrackFlags(track->fFlags, sign, hitset);
1928         cout << " [Sign: " << sign << ", Hits set: ";
1929         bool first = true;
1930         for (AliHLTUInt32_t i = 0; i < 16; i++)
1931         {
1932                 if (hitset[i])
1933                 {
1934                         cout << (first ? "" : ", ") << i;
1935                         first = false;
1936                 }
1937         }
1938         cout << (first ? "none]" : "]") << endl;
1939
1940         result = CheckField(track->fPx, buffer, bufferSize, continueParse);
1941         if (result != EXIT_SUCCESS) return result;
1942         cout << "Momentum: (px = " << track->fPx << ", ";
1943
1944         result = CheckField(track->fPy, buffer, bufferSize, continueParse);
1945         if (result != EXIT_SUCCESS) return result;
1946         cout << "py = " << track->fPy << ", ";
1947
1948         result = CheckField(track->fPz, buffer, bufferSize, continueParse);
1949         if (result != EXIT_SUCCESS) return result;
1950         cout << "pz = " << track->fPz << ") GeV/c" << endl;
1951         
1952         result = CheckField(track->fInverseBendingMomentum, buffer, bufferSize, continueParse);
1953         if (result != EXIT_SUCCESS) return result;
1954         cout << "Inverse bending momentum: " << track->fInverseBendingMomentum << " c/GeV" << endl;
1955         
1956         result = CheckField(track->fThetaX, buffer, bufferSize, continueParse);
1957         if (result != EXIT_SUCCESS) return result;
1958         cout << "Slope: (non-bending plane = " << track->fThetaX << ", ";
1959         
1960         result = CheckField(track->fThetaY, buffer, bufferSize, continueParse);
1961         if (result != EXIT_SUCCESS) return result;
1962         cout << "bending plane = " << track->fThetaY << ")" << endl;
1963
1964         result = CheckField(track->fX, buffer, bufferSize, continueParse);
1965         if (result != EXIT_SUCCESS) return result;
1966         cout << "DCA vertex: (x = " << track->fX << ", ";
1967
1968         result = CheckField(track->fY, buffer, bufferSize, continueParse);
1969         if (result != EXIT_SUCCESS) return result;
1970         cout << "y = " << track->fY << ", ";
1971
1972         result = CheckField(track->fZ, buffer, bufferSize, continueParse);
1973         if (result != EXIT_SUCCESS) return result;
1974         cout << "z = " << track->fZ << ") cm" << endl;
1975
1976         result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
1977         if (result != EXIT_SUCCESS) return result;
1978         cout << "Chi squared fit: " << track->fChi2 << endl;
1979         
1980         cout << "Track hits:" << endl;
1981         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1982         cout << "-----------------------------------------------------------" << endl;
1983         const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
1984         for(AliHLTUInt32_t ch = 0; ch < 16; ch++)
1985         {
1986                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
1987                 if (result != EXIT_SUCCESS) return result;
1988         }
1989
1990         return result;
1991 }
1992
1993
1994 int DumpTracksBlock(
1995                 const char* buffer, unsigned long bufferSize,
1996                 bool continueParse
1997         )
1998 {
1999         // Dumps the full tracks block structure.
2000         
2001         int result = EXIT_SUCCESS;
2002         AliHLTMUONTracksBlockReader block(buffer, bufferSize);
2003         
2004         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
2005         if (result != EXIT_SUCCESS and not continueParse) return result;
2006         
2007         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
2008         
2009         // Print the data block record entries.
2010         const AliHLTMUONTrackStruct* entry = block.GetArray();
2011         for(AliHLTUInt32_t i = 0; i < nentries; i++)
2012         {
2013                 cout << "================================ track number " << i+1
2014                         << " of " << nentries << " ================================" << endl;
2015                 int subResult = DumpTrackStruct(buffer, bufferSize, entry++, continueParse);
2016                 if (subResult != EXIT_SUCCESS) return subResult;
2017         }
2018         
2019         return result;
2020 }
2021
2022
2023 int DumpSinglesDecisionBlockHeader(
2024                 const char* buffer, unsigned long bufferSize,
2025                 const AliHLTMUONSinglesDecisionBlockStruct* header,
2026                 bool continueParse
2027         )
2028 {
2029         // Step through the header fields trying to print them.
2030         // At each step check if we have not overflowed the buffer, if we have
2031         // not then we can print the field, otherwise we print the left over
2032         // bytes assumed to be corrupted rubbish.
2033         int result = CheckHeaderField(header->fNlowPt, buffer, bufferSize, continueParse);
2034         if (result != EXIT_SUCCESS) return result;
2035         cout << " Number of low pt triggers: " << header->fNlowPt << endl;
2036         
2037         result = CheckHeaderField(header->fNhighPt, buffer, bufferSize, continueParse);
2038         if (result != EXIT_SUCCESS) return result;
2039         cout << "Number of high pt triggers: " << header->fNhighPt << endl;
2040
2041         return result;
2042 }
2043
2044
2045 int DumpTrackDecisionStruct(
2046                 const char* buffer, unsigned long bufferSize,
2047                 const AliHLTMUONTrackDecisionStruct* decision,
2048                 bool continueParse
2049         )
2050 {
2051         // Step through the fields trying to print them.
2052         // At each step check if we have not overflowed the buffer. If we have
2053         // not, then we can print the field, otherwise we print the left over
2054         // bytes assumed to be corrupted rubbish.
2055         int result = CheckField(decision->fTrackId, buffer, bufferSize, continueParse);
2056         if (result != EXIT_SUCCESS) return result;
2057         ios::fmtflags oldflags = cout.flags();
2058         cout << setw(13) << left << decision->fTrackId << setw(0);
2059         cout.flags(oldflags);
2060         
2061         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
2062         if (result != EXIT_SUCCESS) return result;
2063         oldflags = cout.flags();
2064         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
2065                 << setw(0) << dec;
2066                 
2067         // Print the individual trigger bits.
2068         bool highPt, lowPt;
2069         AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
2070         cout << setw(7) << left << (highPt ? "yes" : "no");
2071         cout << setw(8) << left << (lowPt ? "yes" : "no");
2072         cout.flags(oldflags);
2073         
2074         result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
2075         if (result != EXIT_SUCCESS) return result;
2076         cout << setw(0) << decision->fPt << endl;
2077
2078         return result;
2079 }
2080
2081
2082 int DumpSinglesDecisionBlock(
2083                 const char* buffer, unsigned long bufferSize,
2084                 bool continueParse
2085         )
2086 {
2087         int result = EXIT_SUCCESS;
2088         AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
2089         
2090         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
2091         if (result != EXIT_SUCCESS and not continueParse) return result;
2092         
2093         // Dump the rest of the block header.
2094         const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
2095         int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
2096         if (subResult != EXIT_SUCCESS) return subResult;
2097         
2098         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
2099         
2100         // Print the data block record entries.
2101         cout << "           |        Trigger Bits      |" << endl;
2102         cout << "Track ID   | Raw         HighPt LowPt | pT" << endl;
2103         cout << "----------------------------------------------------" << endl;
2104         const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
2105         for(AliHLTUInt32_t i = 0; i < nentries; i++)
2106         {
2107                 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
2108                 if (subResult != EXIT_SUCCESS) return subResult;
2109         }
2110         
2111         return result;
2112 }
2113
2114
2115 int DumpPairsDecisionBlockHeader(
2116                 const char* buffer, unsigned long bufferSize,
2117                 const AliHLTMUONPairsDecisionBlockStruct* header,
2118                 bool continueParse
2119         )
2120 {
2121         // Step through the header fields trying to print them.
2122         // At each step check if we have not overflowed the buffer, if we have
2123         // not then we can print the field, otherwise we print the left over
2124         // bytes assumed to be corrupted rubbish.
2125         int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
2126         if (result != EXIT_SUCCESS) return result;
2127         cout << "      Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
2128         
2129         result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
2130         if (result != EXIT_SUCCESS) return result;
2131         cout << "      Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
2132         
2133         result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
2134         if (result != EXIT_SUCCESS) return result;
2135         cout << "     Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
2136         
2137         result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
2138         if (result != EXIT_SUCCESS) return result;
2139         cout << "        Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
2140         
2141         result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
2142         if (result != EXIT_SUCCESS) return result;
2143         cout << "        Number of like low pt triggers: " << header->fNlikeLowPt << endl;
2144         
2145         result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
2146         if (result != EXIT_SUCCESS) return result;
2147         cout << "       Number of like high pt triggers: " << header->fNlikeHighPt << endl;
2148         
2149         result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
2150         if (result != EXIT_SUCCESS) return result;
2151         cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
2152         
2153         result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
2154         if (result != EXIT_SUCCESS) return result;
2155         cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
2156         
2157         result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
2158         if (result != EXIT_SUCCESS) return result;
2159         cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
2160         
2161         return result;
2162 }
2163
2164
2165 int DumpPairDecisionStruct(
2166                 const char* buffer, unsigned long bufferSize,
2167                 const AliHLTMUONPairDecisionStruct* decision,
2168                 bool continueParse
2169         )
2170 {
2171         // Step through the fields trying to print them.
2172         // At each step check if we have not overflowed the buffer. If we have
2173         // not, then we can print the field, otherwise we print the left over
2174         // bytes assumed to be corrupted rubbish.
2175         int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
2176         if (result != EXIT_SUCCESS) return result;
2177         ios::fmtflags oldflags = cout.flags();
2178         cout << setw(13) << left << decision->fTrackAId << setw(0);
2179         cout.flags(oldflags);
2180         
2181         result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
2182         if (result != EXIT_SUCCESS) return result;
2183         oldflags = cout.flags();
2184         cout << setw(13) << left << decision->fTrackBId << setw(0);
2185         cout.flags(oldflags);
2186         
2187         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
2188         if (result != EXIT_SUCCESS) return result;
2189         oldflags = cout.flags();
2190         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
2191                 << setw(0) << dec;
2192         cout.flags(oldflags);
2193                 
2194         // Print the individual trigger bits.
2195         bool highMass, lowMass, unlike;
2196         AliHLTUInt8_t highPtCount, lowPtCount;
2197         AliHLTMUONUtils::UnpackPairDecisionBits(
2198                         decision->fTriggerBits,
2199                         highMass, lowMass, unlike, highPtCount, lowPtCount
2200                 );
2201         oldflags = cout.flags();
2202         cout << setw(7) << left << (highMass ? "yes" : "no");
2203         cout << setw(7) << left << (lowMass ? "yes" : "no");
2204         cout << setw(7) << left << (unlike ? "yes" : "no");
2205         cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
2206         cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
2207         cout << setw(0);
2208         cout.flags(oldflags);
2209         
2210         result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
2211         if (result != EXIT_SUCCESS) return result;
2212         cout << decision->fInvMass << endl;
2213         
2214         return EXIT_SUCCESS;
2215 }
2216
2217
2218 int DumpPairsDecisionBlock(
2219                 const char* buffer, unsigned long bufferSize,
2220                 bool continueParse
2221         )
2222 {
2223         int result = EXIT_SUCCESS;
2224         AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
2225         
2226         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
2227         if (result != EXIT_SUCCESS and not continueParse) return result;
2228         
2229         // Dump the rest of the block header.
2230         const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
2231         int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
2232         if (subResult != EXIT_SUCCESS) return subResult;
2233         
2234         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
2235         
2236         // Print the data block record entries.
2237         cout << "           |            |                Trigger Bits                  |" << endl;
2238         cout << "Track A ID | Track B ID | Raw         HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
2239         cout << "----------------------------------------------------------------------------------------" << endl;
2240         const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
2241         for(AliHLTUInt32_t i = 0; i < nentries; i++)
2242         {
2243                 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
2244                 if (subResult != EXIT_SUCCESS) return subResult;
2245         }
2246         
2247         return result;
2248 }
2249
2250
2251 int DumpCommonHeader(
2252                 const char* buffer, unsigned long bufferSize,
2253                 const AliHLTMUONDataBlockHeader* header, bool continueParse
2254         )
2255 {
2256         // Step through the header fields trying to print them.
2257         // At each step check if we have not overflowed the buffer, if we have
2258         // not then we can print the field, otherwise we print the left over
2259         // bytes assumed to be corrupted rubbish.
2260         int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
2261         if (result != EXIT_SUCCESS) return result;
2262         AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
2263         cout << "       Block type: " << type << endl;
2264         
2265         result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
2266         if (result != EXIT_SUCCESS) return result;
2267         cout << "     Record width: " << header->fRecordWidth << endl;
2268         
2269         result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
2270         if (result != EXIT_SUCCESS) return result;
2271         cout << "Number of entries: " << header->fNrecords << endl;
2272         
2273         return result;
2274 }
2275
2276 /**
2277  * Method to look for a certain data word key in the buffer.
2278  * \param buffer  The start location in the buffer to search.
2279  * \param end  The end of the buffer.
2280  * \returns  the pointer position just past the word found or
2281  *     NULL if the word was not found in the buffer.
2282  */
2283 const char* FindDataWord(const char* buffer, const char* end, UInt_t word)
2284 {
2285         for (const char* current = buffer; (current+1) <= end; current += sizeof(UInt_t))
2286         {
2287                 const UInt_t* currentWord = reinterpret_cast<const UInt_t*>(current);
2288                 if (*currentWord == word) return current + sizeof(UInt_t);
2289         }
2290         return NULL;
2291 }
2292
2293 /**
2294  * Method to check if the data buffer is really a raw DDL stream.
2295  * \returns  kUnknownDataBlock if this does not look like a raw DDL stream.
2296  *     kTrackerDDLRawData if this looks like a raw DDL stream from the tracker.
2297  *     kTriggerDDLRawData if this looks like a raw DDL stream from the trigger.
2298  */
2299 int CheckIfDDLStream(const char* buffer, unsigned long bufferSize)
2300 {
2301         if (bufferSize < sizeof(AliRawDataHeader)) return kUnknownDataBlock;
2302         
2303         const AliRawDataHeader* cdhHeader =
2304                 reinterpret_cast<const AliRawDataHeader*>(buffer);
2305         
2306         // Keep scores of indicators / tests that show this is a raw DDL stream
2307         // either from the trigger or tracker. We will decide if the stream is
2308         // indeed a raw DDL stream if the largest of the two scores is above a
2309         // minimum threshold.
2310         int trackerScore = 0;
2311         int triggerScore = 0;
2312         
2313         if (cdhHeader->fSize == UInt_t(-1) or cdhHeader->fSize == bufferSize)
2314         {
2315                 trackerScore++;
2316                 triggerScore++;
2317         }
2318         
2319         if (cdhHeader->GetVersion() == 2)
2320         {
2321                 trackerScore++;
2322                 triggerScore++;
2323         }
2324         
2325         const char* payload = buffer + sizeof(AliRawDataHeader);
2326         const char* payloadEnd = buffer + bufferSize;
2327         
2328         typedef AliMUONTrackerDDLDecoder<AliMUONTrackerDDLDecoderEventHandler> AliTrkDecoder;
2329         typedef AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler> AliTrgDecoder;
2330         
2331         // See if the DDL data has a payload with data word keys as expected by
2332         // AliMUONTrackerDDLDecoder.
2333         const char* current = payload;
2334         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BlockDataKeyWord())) != NULL )
2335         {
2336                 trackerScore++;
2337         }
2338         current = payload;
2339         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::DspDataKeyWord())) != NULL )
2340         {
2341                 trackerScore++;
2342         }
2343         current = payload;
2344         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BusPatchDataKeyWord())) != NULL )
2345         {
2346                 trackerScore++;
2347         }
2348         current = payload;
2349         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::EndOfDDLWord())) != NULL )
2350         {
2351                 trackerScore++;
2352         }
2353         
2354         // See if the DDL data has a payload with data word keys as expected by
2355         // AliMUONTriggerDDLDecoder.
2356         current = payload;
2357         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfDarcWord())) != NULL )
2358         {
2359                 triggerScore++;
2360         }
2361         current = payload;
2362         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfGlobalWord())) != NULL )
2363         {
2364                 triggerScore++;
2365         }
2366         current = payload;
2367         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfRegionalWord())) != NULL )
2368         {
2369                 triggerScore++;
2370         }
2371         current = payload;
2372         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfLocalWord())) != NULL )
2373         {
2374                 triggerScore++;
2375         }
2376         
2377         if (triggerScore > trackerScore)
2378         {
2379                 if (triggerScore >= 6) return kTriggerDDLRawData;
2380         }
2381         else
2382         {
2383                 if (trackerScore >= 6) return kTrackerDDLRawData;
2384         }
2385         return kUnknownDataBlock;
2386 }
2387
2388 /**
2389  * Parses the buffer and prints the contents to screen.
2390  * \param [in] buffer  The pointer to the buffer to parse.
2391  * \param [in] bufferSize  The size of the buffer in bytes.
2392  * \param [in] continueParse  If specified then the we try to continue parsing the
2393  *           buffer as much as possible.
2394  * \param [in] tryrecover Indicates if the DDL decoders should have special
2395  *           recovery logic enabled.
2396  * \param [in,out] type  Initialy this should indicate the type of the data block
2397  *           or kUnknownDataBlock if not known. On exit it will be filled with
2398  *           the type of the data block as discovered by this routine if type
2399  *           initially contained kUnknownDataBlock.
2400  * \returns  The error code indicating the problem. EXIT_SUCCESS is returned
2401  *           on success.
2402  */
2403 int ParseBuffer(
2404                 char* buffer, unsigned long bufferSize,
2405                 bool continueParse, bool tryrecover, int& type
2406         )
2407 {
2408         assert( buffer != NULL );
2409         int result = EXIT_SUCCESS;
2410         int subResult = EXIT_FAILURE;
2411         
2412         // If the -type|-t option was not used in the command line then we need to
2413         // figure out what type of data block this is from the data itself.
2414         bool ddlStream = false;
2415         if (type == kUnknownDataBlock)
2416         {
2417                 // First check if this is a raw DDL stream, if not then assume it is
2418                 // some kind of internal dHLT raw data block.
2419                 int streamType = CheckIfDDLStream(buffer, bufferSize);
2420                 if (streamType == kTrackerDDLRawData or streamType == kTriggerDDLRawData)
2421                 {
2422                         type = streamType;
2423                         ddlStream = true;
2424                 }
2425         }
2426         else if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
2427         {
2428                 ddlStream = true;
2429         }
2430         
2431         if (not ddlStream)
2432         {
2433                 if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
2434                 {
2435                         cerr << "ERROR: The size of the file is too small to contain a"
2436                                 " valid data block." << endl;
2437                         result = PARSE_ERROR;
2438                         if (not continueParse) return result;
2439                 }
2440                 const AliHLTMUONDataBlockHeader* header =
2441                         reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
2442         
2443                 subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
2444                 if (subResult != EXIT_SUCCESS) return subResult;
2445         
2446                 
2447                 // Check if the block type in the header corresponds to the type given
2448                 // by the '-type' command line parameter. If they do not then print an
2449                 // error or big fat warning message and force interpretation of the data
2450                 // block with the type given by '-type'.
2451                 AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
2452                 
2453                 if (type == kUnknownDataBlock)
2454                 {
2455                         // -type not used in the command line so just use what is given
2456                         // by the data block header.
2457                         type = headerType;
2458                 }
2459                 else if (type != headerType)
2460                 {
2461                         cerr << "WARNING: The data block header indicates a type"
2462                                 " different from what was specified on the command line."
2463                                 " The data could be corrupt."
2464                                 << endl;
2465                         cerr << "WARNING: The type value in the file is "
2466                                 << showbase << hex << header->fType
2467                                 << " (" << headerType << "), but on the command line it is "
2468                                 << showbase << hex << int(type) << dec
2469                                 << " (" << type << ")."
2470                                 << endl;
2471                         cerr << "WARNING: Will force the interpretation of the data block"
2472                                 " with a type of " << type << "." << endl;
2473                 }
2474         }
2475         
2476         // Now we know what type the data block is supposed to be, so we can
2477         // dump it to screen with the appropriate dump routine.
2478         switch (type)
2479         {
2480         case kTrackerDDLRawData:
2481                 subResult = DumpTrackerDDLRawStream(buffer, bufferSize, continueParse, tryrecover);
2482                 if (subResult != EXIT_SUCCESS) result = subResult;
2483                 break;
2484         case kTriggerDDLRawData:
2485                 subResult = DumpTriggerDDLRawStream(buffer, bufferSize, continueParse, tryrecover);
2486                 if (subResult != EXIT_SUCCESS) result = subResult;
2487                 break;
2488         case kTriggerRecordsDataBlock:
2489                 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
2490                 if (subResult != EXIT_SUCCESS) result = subResult;
2491                 break;
2492         case kTrigRecsDebugDataBlock:
2493                 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
2494                 if (subResult != EXIT_SUCCESS) result = subResult;
2495                 break;
2496         case kRecHitsDataBlock:
2497                 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
2498                 if (subResult != EXIT_SUCCESS) result = subResult;
2499                 break;
2500         case kClustersDataBlock:
2501                 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
2502                 if (subResult != EXIT_SUCCESS) result = subResult;
2503                 break;
2504         case kChannelsDataBlock:
2505                 subResult = DumpChannelsBlock(buffer, bufferSize, continueParse);
2506                 if (subResult != EXIT_SUCCESS) result = subResult;
2507                 break;
2508         case kMansoTracksDataBlock:
2509                 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
2510                 if (subResult != EXIT_SUCCESS) result = subResult;
2511                 break;
2512         case kMansoCandidatesDataBlock:
2513                 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
2514                 if (subResult != EXIT_SUCCESS) result = subResult;
2515                 break;
2516         case kTracksDataBlock:
2517                 subResult = DumpTracksBlock(buffer, bufferSize, continueParse);
2518                 if (subResult != EXIT_SUCCESS) result = subResult;
2519                 break;
2520         case kSinglesDecisionDataBlock:
2521                 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
2522                 if (subResult != EXIT_SUCCESS) result = subResult;
2523                 break;
2524         case kPairsDecisionDataBlock:
2525                 subResult = DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
2526                 if (subResult != EXIT_SUCCESS) result = subResult;
2527                 break;
2528         default :
2529                 cout << "ERROR: Unknown data block type. Found a type number of "
2530                         << showbase << hex << int(type) << noshowbase << dec
2531                         << " (" << int(type) << ")." << endl;
2532                 result = PARSE_ERROR;
2533         }
2534         
2535         return result;
2536 }
2537
2538 /**
2539  * Convert the type code to a string.
2540  */
2541 const char* TypeToString(int type)
2542 {
2543         if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
2544         {
2545                 static char str[kAliHLTComponentDataTypefIDsize+1];
2546                 AliHLTComponentDataType t = AliHLTMUONConstants::DDLRawDataType();
2547                 memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
2548                 // Must insert the NULL character to make this an ANSI C string.
2549                 str[kAliHLTComponentDataTypefIDsize] = '\0';
2550                 return &str[0];
2551         }
2552         else
2553         {
2554                 return AliHLTMUONUtils::DataBlockTypeToString(AliHLTMUONDataBlockType(type));
2555         }
2556 }
2557
2558 /**
2559  * Find the data specification from the filename and return it in string format.
2560  */
2561 const char* TryDecodeDataSpec(const char* filename)
2562 {
2563         TString name = filename;
2564         
2565         TRegexp re1("MUONTR[GK]_[0123456789]+\\.ddl$");
2566         Ssiz_t length = 0;
2567         Ssiz_t pos = re1.Index(name, &length);
2568         if (pos != kNPOS)
2569         {
2570                 TString substr;
2571                 for (Ssiz_t i = 0; i < length; i++)
2572                         substr += name[pos+i];
2573                 TRegexp re("[0123456789]+");
2574                 pos = re.Index(substr, &length);
2575                 TString num;
2576                 for (Ssiz_t i = 0; i < length; i++)
2577                         num += substr[pos+i];
2578                 AliHLTUInt32_t spec = AliHLTMUONUtils::EquipIdToSpec(num.Atoi());
2579                 static char strbuf[32];
2580                 sprintf(&strbuf[0], "0x%8.8X", spec);
2581                 return &strbuf[0];
2582         }
2583         
2584         TRegexp re2("_MUON\\:.+_0x[0123456789abscefABCDEF]+\\.dat$");
2585         pos = re2.Index(name, &length);
2586         if (pos != kNPOS)
2587         {
2588                 TString substr;
2589                 for (Ssiz_t i = 0; i < length; i++)
2590                         substr += name[pos+i];
2591                 TRegexp re("0x[0123456789abscefABCDEF]+");
2592                 pos = re.Index(substr, &length);
2593                 TString num;
2594                 for (Ssiz_t i = 0; i < length; i++)
2595                         num += substr[pos+i];
2596                 static TString result = num;
2597                 return result.Data();
2598         }
2599         
2600         return NULL;
2601 }
2602
2603 namespace
2604 {
2605         // CDB path and run number to use.
2606         const char* gCDBPath = "local://$ALICE_ROOT/OCDB";
2607         Int_t gRunNumber = 0;
2608 }
2609
2610 /**
2611  * Performs basic data integrity checks of the data block using the
2612  * AliHLTMUONDataCheckerComponent.
2613  * \param [in] sys  The HLT system framework.
2614  * \param [in] filename  The name of the file containing the data block to check.
2615  * \param [in] type  Must indicate the type of the data block.
2616  * \param [in] dataspec The data specification of the data block. NULL if none.
2617  * \param [in] maxLogging  If set to true then full logging is turned on for AliHLTSystem.
2618  * \returns  The error code indicating the problem. EXIT_SUCCESS is returned
2619  *           on success.
2620  */
2621 int CheckDataIntegrity(
2622                 AliHLTSystem& sys, const char* filename, int type,
2623                 const char* dataspec, bool maxLogging
2624         )
2625 {
2626         if (maxLogging)
2627         {
2628                 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
2629                 sys.SetGlobalLoggingLevel(kHLTLogAll);
2630         }
2631         else
2632         {
2633                 AliLog::SetGlobalLogLevel(AliLog::kWarning);
2634                 int level = kHLTLogWarning | kHLTLogError | kHLTLogFatal;
2635                 sys.SetGlobalLoggingLevel(AliHLTComponentLogSeverity(level));
2636         }
2637         
2638         sys.LoadComponentLibraries("libAliHLTUtil.so");
2639         sys.LoadComponentLibraries("libAliHLTMUON.so");
2640         
2641         // Setup the component parameter lists and then the components.
2642         TString dcparams = "-return_error -warn_on_unexpected_block -no_global_check -cdbpath ";
2643         dcparams += gCDBPath;
2644         dcparams += " -run ";
2645         dcparams += gRunNumber;
2646         TString fpparams = "-datatype '";
2647         fpparams += TypeToString(type);
2648         fpparams += "' 'MUON'";
2649         if (dataspec != NULL)
2650         {
2651                 fpparams += " -dataspec ";
2652                 fpparams += dataspec;
2653         }
2654         else
2655         {
2656                 const char* spec = TryDecodeDataSpec(filename);
2657                 if (spec != NULL)
2658                 {
2659                         fpparams += " -dataspec ";
2660                         fpparams += spec;
2661                 }
2662                 else
2663                 {
2664                         dcparams += " -ignorespec";
2665                 }
2666         }
2667         fpparams += " -datafile ";
2668         fpparams += filename;
2669         TString fpname = "filePublisher_";
2670         fpname += filename;
2671         TString dcname = "checker_";
2672         dcname += filename;
2673         
2674         if (maxLogging)
2675         {
2676                 cout << "DEBUG: Using the following flags for FilePublisher: \""
2677                         << fpparams.Data() << "\""<< endl;
2678                 cout << "DEBUG: Using the following flags for "
2679                         << AliHLTMUONConstants::DataCheckerComponentId()
2680                         << ": \"" << dcparams.Data() << "\""<< endl;
2681         }
2682         
2683         AliHLTConfiguration(fpname.Data(), "FilePublisher", NULL, fpparams.Data());
2684         AliHLTConfiguration checker(
2685                         dcname.Data(), AliHLTMUONConstants::DataCheckerComponentId(),
2686                         fpname.Data(), dcparams.Data()
2687                 );
2688         
2689         // Build and run the HLT tasks.
2690         if (sys.BuildTaskList(dcname.Data()) != 0) return HLTSYSTEM_ERROR;
2691         if (maxLogging) sys.PrintTaskList();
2692         if (sys.Run() != 1) return HLTSYSTEM_ERROR;
2693         
2694         // Now clean up.
2695         if (sys.CleanTaskList() != 0) return HLTSYSTEM_ERROR;
2696
2697         return EXIT_SUCCESS;
2698 }
2699
2700
2701 /**
2702  * The caller is responsible for freeing memory allocated for buffer with a call
2703  * to delete [] buffer.
2704  */
2705 int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
2706 {
2707         assert( filename != NULL );
2708         
2709         // Open the file and find its size.
2710         fstream file;
2711         file.open(filename, ios::in);
2712         if (not file)
2713         {
2714                 cerr << "ERROR: Could not open the file: " << filename << endl;
2715                 return SYSTEM_ERROR;
2716         }
2717         file.seekg(0, ios::end);
2718         if (not file)
2719         {
2720                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
2721                 return SYSTEM_ERROR;
2722         }
2723         bufferSize = file.tellg();
2724         if (not file)
2725         {
2726                 cerr << "ERROR: Could not get file size for the file: " <<
2727                         filename << endl;
2728                 return SYSTEM_ERROR;
2729         }
2730         file.seekg(0, ios::beg);
2731         if (not file)
2732         {
2733                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
2734                 return SYSTEM_ERROR;
2735         }
2736         
2737         // Allocate the memory for the file.
2738         try
2739         {
2740                 buffer = new char[bufferSize];
2741         }
2742         catch (const std::bad_alloc&)
2743         {
2744                 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
2745                         << " bytes." << endl;
2746                 return SYSTEM_ERROR;
2747         }
2748         
2749         file.read(buffer, bufferSize);
2750         if (not file)
2751         {
2752                 delete [] buffer;
2753                 buffer = NULL;
2754                 bufferSize = 0;
2755                 cerr << "ERROR: Could not read from file: " << filename << endl;
2756                 return SYSTEM_ERROR;
2757         }
2758         
2759         file.close();
2760         if (not file)
2761         {
2762                 delete [] buffer;
2763                 buffer = NULL;
2764                 bufferSize = 0;
2765                 cerr << "ERROR: Could not close the file: " << filename << endl;
2766                 return SYSTEM_ERROR;
2767         }
2768         
2769         return EXIT_SUCCESS;
2770 }
2771
2772 /**
2773  * Prints the command line usage of this program to standard error.
2774  */
2775 void PrintUsage(bool asError = true)
2776 {
2777         std::ostream& os = asError ? cerr : cout;
2778         os << "Usage: dHLTdumpraw [-help|-h] [-continue|-c] [-type|-t <typename>] [-check|-k]" << endl;
2779         os << "         [-debug|-d] [-dataspec|-s <number>] [-cdbpath|-p <url>] [-run|-r <number>]" << endl;
2780         os << "         <filename> [<filename> ...]" << endl;
2781         os << "Where <filename> is the name of a file containing a raw data block." << endl;
2782         os << "Options:" << endl;
2783         os << " -help | -h" << endl;
2784         os << "       Displays this message." << endl;
2785         os << " -continue | -c" << endl;
2786         os << "       If specified, the program will try to continue parsing the data block" << endl;
2787         os << "       as much as possible rather than stopping at the first error." << endl;
2788         os << " -recover | -e" << endl;
2789         os << "       If specified, special DDL decoder recovery logic is enabled to handle" << endl;
2790         os << "       corrupt DDL data." << endl;
2791         os << " -type | -t <typename>" << endl;
2792         os << "       Forces the contents of the subsequent files specified on the command" << endl;
2793         os << "       line to be interpreted as a specific type of data block." << endl;
2794         os << "       Where <typename> can be one of:" << endl;
2795         os << "         rawtracker - raw DDL stream from tracker chambers." << endl;
2796         os << "         rawtrigger - raw DDL stream from trigger chambers." << endl;
2797         os << "         trigrecs - trigger records data." << endl;
2798         os << "         trigrecsdebug - debugging information about trigger records." << endl;
2799         os << "         rechits - reconstructed hits data." << endl;
2800         os << "         channels - channel debugging information from hit reconstruction." << endl;
2801         os << "         clusters - cluster debugging information from hit reconstruction." << endl;
2802         os << "         mansotracks - partial tracks from Manso algorithm." << endl;
2803         os << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
2804         os << "         tracks - tracks from full tracker component." << endl;
2805         os << "         singlesdecision - trigger decisions for single tracks." << endl;
2806         os << "         pairsdecision - trigger decisions for track pairs." << endl;
2807         os << "         autodetect - the type of the data block will be automatically" << endl;
2808         os << "                      detected." << endl;
2809         os << " -check | -k" << endl;
2810         os << "       If specified then data integrity checks are performed on the raw data." << endl;
2811         os << "       Warnings and errors are printed as problems are found with the data, but" << endl;
2812         os << "       the data will still be converted into ROOT objects as best as possible." << endl;
2813         os << " -debug | -d" << endl;
2814         os << "       If specified, then the all debug messages are printed by the AliHLTSystem." << endl;
2815         os << "       This is only useful if experiencing problems with the -check|-k option." << endl;
2816         os << " -dataspec | -s <number>" << endl;
2817         os << "       When specified, then <number> is used as the data specification for the" << endl;
2818         os << "       data file that follows. This option is only useful with the -check|-k option." << endl;
2819         os << " -cdbpath | -p <url>" << endl;
2820         os << "       The path to the CDB to use when running with the -check | -k option." << endl;
2821         os << " -run | -r <number>" << endl;
2822         os << "       The run number to use when running with the -check | -k option." << endl;
2823 }
2824
2825 /**
2826  * Parses the command line.
2827  * @param argc  Number of arguments as given in main().
2828  * @param argv  Array of arguments as given in main().
2829  * @param filenames  Pointer to buffer storing file name strings.
2830  * @param filetypes  Array that receives the type of the data block expected, i.e.
2831  *                   the value of the -type flag for the corresponding file.
2832  * @param dataspecs  Data specifications to use for the data files.
2833  * @param numOfFiles  Receives the number of file name strings that were found
2834  *                    and added to 'filenames'.
2835  * @param continueParse  Set to true if the user requested to continue to parse
2836  *                      after errors.
2837  * @param tryrecover Set to true if the user wants DDL decoder recovery logic enabled.
2838  * @param checkData  Set to true if data integrity checking was requested.
2839  * @param maxLogging  Set to true if maximal logging was requested.
2840  * @return  A status flag suitable for returning from main(), containing either
2841  *          EXIT_SUCCESS or CMDLINE_ERROR.
2842  */
2843 int ParseCommandLine(
2844                 int argc,
2845                 char** argv,
2846                 const char** filenames,
2847                 int* filetypes,
2848                 const char** dataspecs,
2849                 int& numOfFiles,
2850                 bool& continueParse,
2851                 bool& tryrecover,
2852                 bool& checkData,
2853                 bool& maxLogging
2854         )
2855 {
2856         numOfFiles = 0;
2857         continueParse = false;
2858         tryrecover = false;
2859         maxLogging = false;
2860         checkData = false;
2861         int currentType = kUnknownDataBlock;
2862         const char* currentDataSpec = NULL;
2863         bool pathSet = false;
2864         bool runSet = false;
2865
2866         // Parse the command line.
2867         for (int i = 1; i < argc; i++)
2868         {
2869                 if (strcmp(argv[i], "-help") == 0 or strcmp(argv[i], "-h") == 0)
2870                 {
2871                         PrintUsage(false);
2872                         return EXIT_SUCCESS;
2873                 }
2874                 else if (strcmp(argv[i], "-continue") == 0 or strcmp(argv[i], "-c") == 0)
2875                 {
2876                         continueParse = true;
2877                 }
2878                 else if (strcmp(argv[i], "-recover") == 0 or strcmp(argv[i], "-e") == 0)
2879                 {
2880                         tryrecover = true;
2881                 }
2882                 else if (strcmp(argv[i], "-type") == 0 or strcmp(argv[i], "-t") == 0)
2883                 {
2884                         if (++i >= argc)
2885                         {
2886                                 cerr << "ERROR: Missing a type specifier." << endl << endl;
2887                                 PrintUsage();
2888                                 return CMDLINE_ERROR;
2889                         }
2890                         // Now we need to parse the typename in the command line.
2891                         if (strcmp(argv[i], "autodetect") == 0)
2892                         {
2893                                 currentType = kUnknownDataBlock;
2894                         }
2895                         else if (strcmp(argv[i], "rawtracker") == 0)
2896                         {
2897                                 currentType = kTrackerDDLRawData;
2898                         }
2899                         else if (strcmp(argv[i], "rawtrigger") == 0)
2900                         {
2901                                 currentType = kTriggerDDLRawData;
2902                         }
2903                         else
2904                         {
2905                                 currentType = AliHLTMUONUtils::ParseCommandLineTypeString(argv[i]);
2906                                 if (currentType == kUnknownDataBlock)
2907                                 {
2908                                         cerr << "ERROR: Invalid type name '" << argv[i]
2909                                                 << "' specified for argument " << argv[i-1]
2910                                                 << "." << endl << endl;
2911                                         PrintUsage();
2912                                         return CMDLINE_ERROR;
2913                                 }
2914                         }
2915                 }
2916                 else if (strcmp(argv[i], "-debug") == 0 or strcmp(argv[i], "-d") == 0)
2917                 {
2918                         maxLogging = true;
2919                 }
2920                 else if (strcmp(argv[i], "-check") == 0 or strcmp(argv[i], "-k") == 0)
2921                 {
2922                         checkData = true;
2923                 }
2924                 else if (strcmp(argv[i], "-dataspec") == 0 or strcmp(argv[i], "-s") == 0)
2925                 {
2926                         if (++i >= argc)
2927                         {
2928                                 cerr << "ERROR: Missing a specification number." << endl << endl;
2929                                 PrintUsage();
2930                                 return CMDLINE_ERROR;
2931                         }
2932                         
2933                         char* errPos = NULL;
2934                         unsigned long num = strtoul(argv[i], &errPos, 0);
2935                         if (errPos == NULL or *errPos != '\0')
2936                         {
2937                                 cerr << "ERROR: Cannot convert '%s' to a data specification number."
2938                                         << argv[i] << endl;
2939                                 return CMDLINE_ERROR;
2940                         }
2941                         if (not AliHLTMUONUtils::IsSpecValid(num))
2942                         {
2943                                 cerr << "ERROR: The data specification number is not a valid format."
2944                                         << endl;
2945                                 return CMDLINE_ERROR;
2946                         }
2947                         currentDataSpec = argv[i];
2948                 }
2949                 else if (strcmp(argv[i], "-cdbpath") == 0 or strcmp(argv[i], "-p") == 0)
2950                 {
2951                         if (pathSet)
2952                         {
2953                                 cerr << "WARNING: Already used -cdbpath|-p with '" << gCDBPath
2954                                         << "' before. Will override it with the last value specified with -cdbpath|-p."
2955                                         << endl;
2956                         }
2957                         if (++i >= argc)
2958                         {
2959                                 cerr << "ERROR: Missing the URL for the CDB path." << endl << endl;
2960                                 PrintUsage();
2961                                 return CMDLINE_ERROR;
2962                         }
2963                         gCDBPath = argv[i];
2964                         pathSet = true;
2965                 }
2966                 else if (strcmp(argv[i], "-run") == 0 or strcmp(argv[i], "-r") == 0)
2967                 {
2968                         if (runSet)
2969                         {
2970                                 cerr << "WARNING: Already used -run|-r with " << gRunNumber
2971                                         << " before. Will override it with the last value specified with -run|-r."
2972                                         << endl;
2973                         }
2974                         if (++i >= argc)
2975                         {
2976                                 cerr << "ERROR: Missing the run number." << endl << endl;
2977                                 PrintUsage();
2978                                 return CMDLINE_ERROR;
2979                         }
2980                         
2981                         char* cpErr = NULL;
2982                         Int_t run = Int_t( strtol(argv[i], &cpErr, 0) );
2983                         if (cpErr == NULL or *cpErr != '\0' or run < 0)
2984                         {
2985                                 cerr << "ERROR: Cannot convert '" << argv[i] << "' to a valid run number."
2986                                         " Expected a positive integer value." << endl;
2987                                 return CMDLINE_ERROR;
2988                         }
2989
2990                         gRunNumber = run;
2991                         runSet = true;
2992                 }
2993                 else
2994                 {
2995                         assert( numOfFiles < argc );
2996                         filenames[numOfFiles] = argv[i];
2997                         filetypes[numOfFiles] = currentType;
2998                         dataspecs[numOfFiles] = currentDataSpec;
2999                         currentDataSpec = NULL;  // Reset because '-dataspec' option is only valid for one file.
3000                         numOfFiles++;
3001                 }
3002         }
3003         
3004         // Now check that we have at least one filename and all the flags we need.
3005         if (numOfFiles == 0)
3006         {
3007                 cerr << "ERROR: Missing a file name. You must specify at least one file to process."
3008                         << endl << endl;
3009                 PrintUsage();
3010                 return CMDLINE_ERROR;
3011         }
3012         
3013         return EXIT_SUCCESS;
3014 }
3015
3016
3017 int main(int argc, char** argv)
3018 {
3019         // Test endianess of this machine during runtime and print warning if it is not
3020         // little endian.
3021         union
3022         {
3023                 int dword;
3024                 char byte[4];
3025         } endianTest;
3026         endianTest.dword = 0x1;
3027         if (endianTest.byte[0] != 0x1)
3028         {
3029                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
3030                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
3031                 cerr << "!!                                                                     !!" << endl;
3032                 cerr << "!! This is not a little endian machine, but dHLT raw data is normally  !!" << endl;
3033                 cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
3034                 cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
3035                 cerr << "!! output.                                                             !!" << endl;
3036                 cerr << "!!                                                                     !!" << endl;
3037                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
3038                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
3039                 cerr << endl;
3040         }
3041
3042
3043         int numOfFiles = 0;
3044         bool continueParse = false;
3045         bool tryrecover = false;
3046         bool checkData = false;
3047         bool maxLogging = false;
3048         int returnCode = EXIT_SUCCESS;
3049         char* buffer = NULL;
3050         const char** filename = NULL;
3051         int* filetype = NULL;
3052         const char** dataspec = NULL;
3053
3054         try
3055         {
3056                 // Reduce logging now to get rid of informationals from AliHLTSystem constructor.
3057                 AliLog::SetGlobalLogLevel(AliLog::kWarning);
3058                 AliHLTSystem sys;
3059         
3060                 // There will be at least 'argc' number of filenames.
3061                 typedef const char* AnsiString;
3062                 filename = new AnsiString[argc];
3063                 filetype = new int[argc];
3064                 dataspec = new AnsiString[argc];
3065                 
3066                 returnCode = ParseCommandLine(
3067                                 argc, argv, filename, filetype, dataspec, numOfFiles,
3068                                 continueParse, tryrecover, checkData, maxLogging
3069                         );
3070
3071                 if (returnCode == EXIT_SUCCESS)
3072                 {
3073                         for (int i = 0; i < numOfFiles; i++)
3074                         {
3075                                 unsigned long bufferSize = 0;
3076                                 returnCode = ReadFile(filename[i], buffer, bufferSize);
3077                                 if (returnCode != EXIT_SUCCESS) break;
3078                                 if (numOfFiles > 1)
3079                                 {
3080                                         cout << "########## Start of dump for file: "
3081                                                 << filename[i] << " ##########" << endl;
3082                                 }
3083                                 int result = ParseBuffer(buffer, bufferSize, continueParse, tryrecover, filetype[i]);
3084                                 if (buffer != NULL) delete [] buffer;
3085                                 if (result != EXIT_SUCCESS)
3086                                 {
3087                                         returnCode = result;
3088                                         if (not continueParse) break;
3089                                 }
3090                                 if (checkData)
3091                                 {
3092                                         result = CheckDataIntegrity(
3093                                                         sys, filename[i], filetype[i],
3094                                                         dataspec[i], maxLogging
3095                                                 );
3096                                         if (result != EXIT_SUCCESS)
3097                                         {
3098                                                 returnCode = result;
3099                                                 if (not continueParse) break;
3100                                         }
3101                                 }
3102                                 if (numOfFiles > 1)
3103                                 {
3104                                         cout << "##########   End of dump for file: " <<
3105                                                 filename[i] << " ##########" << endl;
3106                                 }
3107                         }
3108                 }
3109                 
3110                 delete [] filename;
3111                 delete [] filetype;
3112                 delete [] dataspec;
3113         }
3114         catch (...)
3115         {
3116                 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
3117                 returnCode = FATAL_ERROR;
3118                 if (buffer != NULL) delete [] buffer;
3119                 if (filename != NULL) delete [] filename;
3120                 if (filetype != NULL) delete [] filetype;
3121                 if (dataspec != NULL) delete [] dataspec;
3122         }
3123         
3124         return returnCode;
3125 }