]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/utils/dHLTdumpraw.cxx
Improving documentation and macros.
[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         cout << "*************************** Common DDL data header *******************************" << endl;
1053         char fillChar = cout.fill();  // remember fill char to set back to original later.
1054         int result = CheckHeaderField(header->fSize, buffer, bufferSize, continueParse);
1055         if (result != EXIT_SUCCESS) return result;
1056         cout << "Size of the raw data in bytes : ";
1057         if (header->fSize != 0xFFFFFFFF)
1058                 cout << header->fSize;
1059         else
1060                 cout << "0xFFFFFFFF (unknown)";
1061         cout << endl;
1062         
1063         result = CheckHeaderField(header->fWord2, buffer, bufferSize, continueParse);
1064         if (result != EXIT_SUCCESS) return result;
1065         cout << "               Format version : " << UInt_t(header->GetVersion()) << endl;
1066         UInt_t l1msg = header->GetL1TriggerMessage();
1067         cout << "           L1 trigger message : 0x"
1068                 << noshowbase << hex << setfill('0') << setw(2) << l1msg
1069                 << setw(0) << setfill(fillChar) << dec
1070                 << " [Spare: " << ((l1msg >> 7) & 0x1)
1071                 << ", ClT: " << ((l1msg >> 6) & 0x1)
1072                 << ", RoC: 0x" << noshowbase << hex << ((l1msg >> 2) & 0x4) << dec
1073                 << ", ESR: " << ((l1msg >> 1) & 0x1)
1074                 << ", L1SwC: " << ((l1msg >> 0) & 0x1) << "]" << endl;
1075         cout << "   Bunch crossing (Event ID1) : " << header->GetEventID1() << " (0x"
1076                 << noshowbase << hex << setfill('0') << setw(3) << header->GetEventID1()
1077                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1078         
1079         result = CheckHeaderField(header->fEventID2, buffer, bufferSize, continueParse);
1080         if (result != EXIT_SUCCESS) return result;
1081         cout << "     Orbit number (Event ID2) : " << header->fEventID2 << " (0x"
1082                 << noshowbase << hex << setfill('0') << setw(6) << header->fEventID2
1083                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1084         
1085         result = CheckHeaderField(header->fAttributesSubDetectors, buffer, bufferSize, continueParse);
1086         if (result != EXIT_SUCCESS) return result;
1087         cout << "             Block attributes : " << UInt_t(header->GetAttributes()) << " (0x"
1088                 << noshowbase << hex << setfill('0') << setw(2) << UInt_t(header->GetAttributes())
1089                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1090         cout << "  Participating sub-detectors : 0x" << noshowbase << hex
1091                 << setfill('0') << setw(6) << header->GetSubDetectors() << dec
1092                 << setw(0) << setfill(fillChar) << "    [Bits: ";
1093         for (int i = 5; i >= 0; i--)
1094         {
1095                 PrintBitPattern(header->GetSubDetectors() >> (i*4), 4);
1096                 if (i != 0)
1097                         cout << " ";
1098                 else
1099                         cout << "]" << endl;
1100         }
1101         
1102         result = CheckHeaderField(header->fStatusMiniEventID, buffer, bufferSize, continueParse);
1103         if (result != EXIT_SUCCESS) return result;
1104         UInt_t statusBits = header->GetStatus();
1105         cout << "          Status & error bits : 0x" << noshowbase << hex
1106                 << setfill('0') << setw(4) << statusBits << setw(0) << setfill(fillChar)
1107                 << dec << endl;
1108         cout << "          [                        Reserved : " << ((statusBits >> 15) & 0x1) << " ]" << endl;
1109         cout << "          [        Multi-event buffer error : " << ((statusBits >> 14) & 0x1) << " ]" << endl;
1110         cout << "          [        Trigger L1 missing error : " << ((statusBits >> 13) & 0x1) << " ]" << endl;
1111         cout << "          [           Trigger error (other) : " << ((statusBits >> 12) & 0x1) << " ]" << endl;
1112         cout << "          [                 Pre-pulse error : " << ((statusBits >> 11) & 0x1) << " ]" << endl;
1113         cout << "          [       Trigger L2 time violation : " << ((statusBits >> 10) & 0x1) << " ]" << endl;
1114         cout << "          [       Trigger L1 time violation : " << ((statusBits >> 9) & 0x1) << " ]" << endl;
1115         cout << "          [                DDG payload flag : " << ((statusBits >> 8) & 0x1) << " ]" << endl;
1116         cout << "          [                HLT payload flag : " << ((statusBits >> 7) & 0x1) << " ]" << endl;
1117         cout << "          [               HLT decision flag : " << ((statusBits >> 6) & 0x1) << " ]" << endl;
1118         cout << "          [                       FEE error : " << ((statusBits >> 5) & 0x1) << " ]" << endl;
1119         cout << "          [ Trigger information unavailable : " << ((statusBits >> 4) & 0x1) << " ]" << endl;
1120         cout << "          [            Control parity error : " << ((statusBits >> 3) & 0x1) << " ]" << endl;
1121         cout << "          [               Data parity error : " << ((statusBits >> 2) & 0x1) << " ]" << endl;
1122         cout << "          [           Trigger missing error : " << ((statusBits >> 1) & 0x1) << " ]" << endl;
1123         cout << "          [           Trigger overlap error : " << ((statusBits >> 0) & 0x1) << " ]" << endl;
1124         cout << "                Mini event ID : " << header->GetMiniEventID() << " (0x"
1125                 << noshowbase << hex << setfill('0') << setw(3) << header->GetMiniEventID()
1126                 << dec << setw(0) << setfill(fillChar) << ")" << endl;
1127         
1128         result = CheckHeaderField(header->fTriggerClassLow, buffer, bufferSize, continueParse);
1129         if (result != EXIT_SUCCESS) return result;
1130         result = CheckHeaderField(header->fROILowTriggerClassHigh, buffer, bufferSize, continueParse);
1131         if (result != EXIT_SUCCESS) return result;
1132         ULong64_t triggerClasses = header->GetTriggerClasses();
1133         cout << "              Trigger classes : 0x" << noshowbase << hex << setw(13)
1134                 << setfill('0') << triggerClasses << setw(0) << setfill(fillChar)
1135                 << dec << endl;
1136         cout << "                [Bits: ";
1137         PrintBitPattern(triggerClasses >> (12*4), 2);
1138         cout << " ";
1139         for (int i = 11; i >= 0; i--)
1140         {
1141                 PrintBitPattern(triggerClasses >> (i*4), 4);
1142                 if (i != 0)
1143                         cout << " ";
1144                 else
1145                         cout << "]" << endl;
1146         }
1147         
1148         result = CheckHeaderField(header->fROIHigh, buffer, bufferSize, continueParse);
1149         if (result != EXIT_SUCCESS) return result;
1150         ULong64_t roiBits = header->GetROI();
1151         cout << "           Region of interest : 0x" << noshowbase << hex << setw(9)
1152                 << setfill('0') << roiBits << setw(0) << setfill(fillChar)
1153                 << dec << endl;
1154         cout << "             [Bits: ";
1155         for (int i = 8; i >= 0; i--)
1156         {
1157                 PrintBitPattern(roiBits >> (i*4), 4);
1158                 if (i != 0)
1159                         cout << " ";
1160                 else
1161                         cout << "]" << endl;
1162         }
1163         cout << "**********************************************************************************" <<endl;
1164         return EXIT_SUCCESS;
1165 }
1166
1167
1168 int DumpTrackerDDLRawStream(
1169                 const char* buffer, unsigned long bufferSize,
1170                 bool continueParse
1171         )
1172 {
1173         const AliRawDataHeader* header =
1174                 reinterpret_cast<const AliRawDataHeader*>(buffer);
1175         int result = DumpRawDataHeader(buffer, bufferSize, header, continueParse);
1176         if (result != EXIT_SUCCESS) return result;
1177
1178         // Setup the decoder for the DDL payload.
1179         AliMUONTrackerDDLDecoder<AliTrackerDecoderHandler> decoder;
1180         decoder.ExitOnError(not continueParse);
1181         decoder.SendDataOnParityError(true);
1182         decoder.TryRecover(false);
1183         decoder.AutoDetectTrailer(true);
1184         decoder.CheckForTrailer(true);
1185         const char* payload = buffer + sizeof(AliRawDataHeader);
1186         UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
1187         if (decoder.Decode(payload, payloadSize))
1188         {
1189                 return EXIT_SUCCESS;
1190         }
1191         else
1192         {
1193                 return PARSE_ERROR;
1194         }
1195 }
1196
1197
1198 int DumpTriggerDDLRawStream(
1199                 const char* buffer, unsigned long bufferSize,
1200                 bool continueParse
1201         )
1202 {
1203         const AliRawDataHeader* header =
1204                 reinterpret_cast<const AliRawDataHeader*>(buffer);
1205         int result = DumpRawDataHeader(buffer, bufferSize, header, continueParse);
1206         if(result != EXIT_SUCCESS) return result;
1207         bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
1208         
1209         AliMUONTriggerDDLDecoder<AliTriggerDecoderHandler> decoder;
1210         decoder.ExitOnError(not continueParse);
1211         decoder.TryRecover(false);
1212         decoder.AutoDetectScalars(false);
1213         const char* payload = buffer + sizeof(AliRawDataHeader);
1214         UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
1215         if (decoder.Decode(payload, payloadSize, scalarEvent))
1216         {
1217                 return EXIT_SUCCESS;
1218         }
1219         else
1220         {
1221                 return PARSE_ERROR;
1222         }
1223 }
1224
1225
1226 int DumpRecHitStruct(
1227                 const char* buffer, unsigned long bufferSize,
1228                 const AliHLTMUONRecHitStruct* hit,
1229                 bool continueParse
1230         )
1231 {
1232         // Step through the fields trying to print them.
1233         // At each step check if we have not overflowed the buffer. If we have
1234         // not, then we can print the field, otherwise we print the left over
1235         // bytes assumed to be corrupted rubbish.
1236         
1237         int result = CheckField(hit->fFlags, buffer, bufferSize, continueParse);
1238         if (result != EXIT_SUCCESS) return result;
1239         AliHLTUInt8_t chamber = 0xFF;
1240         AliHLTUInt16_t detElemId = 0xFFFF;
1241         AliHLTMUONUtils::UnpackRecHitFlags(hit->fFlags, chamber, detElemId);
1242         if (chamber == 0 and detElemId == 0)
1243         {
1244                 cout << setw(10) << left << (int)(chamber) << setw(0);
1245                 cout << setw(12) << left << (int)detElemId << setw(0);
1246         }
1247         else
1248         {
1249                 cout << setw(10) << left << (int)(chamber+1) << setw(0);
1250                 cout << setw(12) << left << (int)detElemId << setw(0);
1251         }
1252         
1253         result = CheckField(hit->fX, buffer, bufferSize, continueParse);
1254         if (result != EXIT_SUCCESS) return result;
1255         cout << setw(13) << left << hit->fX << setw(0);
1256
1257         result = CheckField(hit->fY, buffer, bufferSize, continueParse);
1258         if (result != EXIT_SUCCESS) return result;
1259         cout << setw(13) << left << hit->fY << setw(0);
1260
1261         result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
1262         if (result != EXIT_SUCCESS) return result;
1263         cout << hit->fZ << setw(0) << endl;
1264
1265         return result;
1266 }
1267
1268
1269 int DumpRecHitsBlock(
1270                 const char* buffer, unsigned long bufferSize,
1271                 bool continueParse
1272         )
1273 {
1274         int result = EXIT_SUCCESS;
1275         AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
1276         
1277         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1278         if (result != EXIT_SUCCESS and not continueParse) return result;
1279         
1280         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1281         
1282         // Print the data block record entries.
1283         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1284         cout << "-----------------------------------------------------------" << endl;
1285         const AliHLTMUONRecHitStruct* entry = block.GetArray();
1286         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1287         {
1288                 int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
1289                 if (subResult != EXIT_SUCCESS) return subResult;
1290         }
1291         
1292         return result;
1293 }
1294
1295
1296 int DumpTriggerRecordStruct(
1297                 const char* buffer, unsigned long bufferSize,
1298                 const AliHLTMUONTriggerRecordStruct* record,
1299                 bool continueParse
1300         )
1301 {
1302         // Step through the fields trying to print them.
1303         // At each step check if we have not overflowed the buffer. If we have
1304         // not, then we can print the field, otherwise we print the left over
1305         // bytes assumed to be corrupted rubbish.
1306         int result = CheckField(record->fId, buffer, bufferSize, continueParse);
1307         if (result != EXIT_SUCCESS) return result;
1308         cout << "Trigger Record ID: " << record->fId <<endl;
1309         
1310         result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
1311         if (result != EXIT_SUCCESS) return result;
1312         cout << "Flags: " << showbase << hex << record->fFlags << dec;
1313                 
1314         // Print the individual trigger bits.
1315         AliHLTMUONParticleSign sign;
1316         bool hitset[4];
1317         AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
1318         cout << " [Sign: " << sign << ", Hits set on chambers: ";
1319         bool first = true;
1320         for (AliHLTUInt32_t i = 0; i < 4; i++)
1321         {
1322                 if (hitset[i])
1323                 {
1324                         cout << (first ? "" : ", ") << i+11;
1325                         first = false;
1326                 }
1327         }
1328         cout << (first ? "none]" : "]") << endl;
1329
1330         result = CheckField(record->fPx, buffer, bufferSize, continueParse);
1331         if (result != EXIT_SUCCESS) return result;
1332         cout << "Momentum: (px = " << record->fPx << ", ";
1333
1334         result = CheckField(record->fPy, buffer, bufferSize, continueParse);
1335         if (result != EXIT_SUCCESS) return result;
1336         cout << "py = " << record->fPy << ", ";
1337
1338         result = CheckField(record->fPz, buffer, bufferSize, continueParse);
1339         if (result != EXIT_SUCCESS) return result;
1340         cout << "pz = " << record->fPz << ") GeV/c"<<endl;
1341         
1342         cout << "Hits on chambers:" << endl;
1343         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1344         cout << "-----------------------------------------------------------" << endl;
1345         const AliHLTMUONRecHitStruct* hit = &record->fHit[0];
1346         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1347         {
1348                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
1349                 if (result != EXIT_SUCCESS) return result;
1350         }
1351
1352         return result;
1353
1354 }
1355
1356
1357 int DumpTriggerRecordsBlock(
1358                 const char* buffer, unsigned long bufferSize,
1359                 bool continueParse
1360         )
1361 {
1362         AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
1363         
1364         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1365         if (result != EXIT_SUCCESS and not continueParse) return result;
1366         
1367         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1368         
1369         // Print the data block record entries.
1370         const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
1371         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1372         {
1373                 cout << "============================== Trigger Record number " << i+1
1374                         << " of " << nentries << " ==============================" << endl;
1375                 int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse);
1376                 if (subResult != EXIT_SUCCESS) return subResult;
1377         }
1378         
1379         return EXIT_SUCCESS;
1380 }
1381
1382
1383 int DumpTrigRecInfoStruct(
1384                 const char* buffer, unsigned long bufferSize,
1385                 const AliHLTMUONTrigRecInfoStruct* debuginfo,
1386                 bool continueParse
1387         )
1388 {
1389         // Step through the fields trying to print them.
1390         // At each step check if we have not overflowed the buffer. If we have
1391         // not, then we can print the field, otherwise we print the left over
1392         // bytes assumed to be corrupted rubbish.
1393         
1394         int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse);
1395         if (result != EXIT_SUCCESS) return result;
1396         cout << "Trigger Record ID: " << debuginfo->fTrigRecId << endl;
1397
1398         cout << "Detector element IDs:" << endl;
1399         cout << "  Chamber :           11 |           12 |           13 |           14" << endl;
1400         cout << "       ID : ";
1401         for (int i = 0; i < 4; i++)
1402         {
1403                 result = CheckField(debuginfo->fDetElemId[i], buffer, bufferSize, continueParse);
1404                 if (result != EXIT_SUCCESS) return result;
1405                 cout << setw(12) << right << debuginfo->fDetElemId[i] << setw(0);
1406                 if (i != 3) cout << " | ";
1407         }
1408         cout << endl;
1409         
1410         cout << "Momentum estimation parameters:" << endl;
1411         cout << "  Parameter : Z_middle coordinate (cm) | Integrated magnetic field (T.m)" << endl;
1412         cout << "      Value : ";
1413         result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
1414         if(result != EXIT_SUCCESS) return result;
1415         cout << setw(24) << right << debuginfo->fZmiddle << setw(0) << " | ";
1416         
1417         result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
1418         if (result != EXIT_SUCCESS) return result;
1419         cout << setw(31) << right << debuginfo->fBl << setw(0) << endl;
1420         
1421         typedef AliMUONTriggerDDLDecoderEventHandler AliH;
1422         
1423         cout << "L0 strip patterns:" << endl;
1424         cout << "Chamber |        X         |         Y        " << endl;
1425         cout << "----------------------------------------------" << endl;
1426         result = CheckField(debuginfo->fL0Struct.fX2X1, buffer, bufferSize, continueParse);
1427         if (result != EXIT_SUCCESS) return result;
1428         cout << "   11     ";
1429         PrintBitPattern(AliH::GetLocalX1(&debuginfo->fL0Struct), 16);
1430         result = CheckField(debuginfo->fL0Struct.fY2Y1, buffer, bufferSize, continueParse);
1431         if (result != EXIT_SUCCESS) return result;
1432         cout << "   ";
1433         PrintBitPattern(AliH::GetLocalY1(&debuginfo->fL0Struct), 16);
1434         cout << endl;
1435         cout << "   12     ";
1436         PrintBitPattern(AliH::GetLocalX2(&debuginfo->fL0Struct), 16);
1437         cout << "   ";
1438         PrintBitPattern(AliH::GetLocalY2(&debuginfo->fL0Struct), 16);
1439         cout << endl;
1440         
1441         result = CheckField(debuginfo->fL0Struct.fX4X3, buffer, bufferSize, continueParse);
1442         if (result != EXIT_SUCCESS) return result;
1443         cout << "   13     ";
1444         PrintBitPattern(AliH::GetLocalX3(&debuginfo->fL0Struct), 16);
1445         result = CheckField(debuginfo->fL0Struct.fY4Y3, buffer, bufferSize, continueParse);
1446         if (result != EXIT_SUCCESS) return result;
1447         cout << "   ";
1448         PrintBitPattern(AliH::GetLocalY3(&debuginfo->fL0Struct), 16);
1449         cout << endl;
1450         cout << "   12     ";
1451         PrintBitPattern(AliH::GetLocalX4(&debuginfo->fL0Struct), 16);
1452         cout << "   ";
1453         PrintBitPattern(AliH::GetLocalY4(&debuginfo->fL0Struct), 16);
1454         cout << endl;
1455         
1456         cout << "L0 trigger bits: (word = ";
1457         result = CheckField(debuginfo->fL0Struct.fTriggerBits, buffer, bufferSize, continueParse);
1458         if (result != EXIT_SUCCESS) return result;
1459         cout << showbase << hex << debuginfo->fL0Struct.fTriggerBits
1460                 << noshowbase << dec << ")" << endl;
1461         cout << "  ID |  Dec | TrigY | YPos | Sign XDev | XDev |  XPos " << endl;
1462         cout << "------------------------------------------------------" << endl;
1463         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalId(&debuginfo->fL0Struct)), 4);
1464         cout << "   ";
1465         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalDec(&debuginfo->fL0Struct)), 4);
1466         cout << "     ";
1467         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalTrigY(&debuginfo->fL0Struct)), 1);
1468         cout << "     ";
1469         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalYPos(&debuginfo->fL0Struct)), 4);
1470         cout << "       ";
1471         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalSXDev(&debuginfo->fL0Struct)), 1);
1472         cout << "       ";
1473         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalXDev(&debuginfo->fL0Struct)), 4);
1474         cout << "   ";
1475         PrintBitPattern(AliHLTUInt32_t(AliH::GetLocalXPos(&debuginfo->fL0Struct)), 5);
1476         cout << endl;
1477         
1478         return result;
1479 }
1480
1481
1482 int DumpTrigRecsDebugBlock(
1483                 const char* buffer, unsigned long bufferSize,
1484                 bool continueParse
1485         )
1486 {
1487         AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
1488         
1489         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1490         if (result != EXIT_SUCCESS and not continueParse) return result;
1491         
1492         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1493         
1494         // Print the data block record entries.
1495         const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray();
1496         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1497         {
1498                 cout << "======================= Trigger Record debug data " << i+1
1499                         << " of " << nentries << " =======================" << endl;
1500                 int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
1501                 if (subResult != EXIT_SUCCESS) return subResult;
1502         }
1503         
1504         return EXIT_SUCCESS;
1505 }
1506
1507
1508 int DumpClusterStruct(
1509                 const char* buffer, unsigned long bufferSize,
1510                 const AliHLTMUONClusterStruct* cluster,
1511                 bool continueParse
1512         )
1513 {
1514         // Step through the fields trying to print them.
1515         // At each step check if we have not overflowed the buffer. If we have
1516         // not, then we can print the field, otherwise we print the left over
1517         // bytes assumed to be corrupted rubbish.
1518         int result = CheckField(cluster->fId, buffer, bufferSize, continueParse);
1519         if (result != EXIT_SUCCESS) return result;
1520         cout << "                             Cluster ID: " << cluster->fId << endl;
1521
1522         result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
1523         if (result != EXIT_SUCCESS) return result;
1524         cout << "                    Detector Element ID: " << cluster->fDetElemId << endl;
1525
1526         result = CheckField(cluster->fNchannelsB, buffer, bufferSize, continueParse);
1527         if (result != EXIT_SUCCESS) return result;
1528         cout << "    Number of channels in bending plane: " << cluster->fNchannelsB << endl;
1529
1530         result = CheckField(cluster->fNchannelsNB, buffer, bufferSize, continueParse);
1531         if (result != EXIT_SUCCESS) return result;
1532         cout << "Number of channels in non-bending plane: " << cluster->fNchannelsNB << endl;
1533         
1534         result = CheckField(cluster->fChargeB, buffer, bufferSize, continueParse);
1535         if (result != EXIT_SUCCESS) return result;
1536         cout << "                Charge on bending plane: " << cluster->fChargeB << endl;
1537
1538         result = CheckField(cluster->fChargeNB, buffer, bufferSize, continueParse);
1539         if (result != EXIT_SUCCESS) return result;
1540         cout << "            Charge on non bending plane: " << cluster->fChargeNB << endl;
1541
1542         cout << "Corresponding Hit: "<< endl;
1543         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1544         cout << "-----------------------------------------------------------" << endl;
1545         result = DumpRecHitStruct(buffer, bufferSize, &cluster->fHit, continueParse);
1546
1547         return result;
1548 }
1549
1550
1551 int DumpClustersBlock(
1552                 const char* buffer, unsigned long bufferSize,
1553                 bool continueParse
1554         )
1555 {
1556         int result = EXIT_SUCCESS;
1557         AliHLTMUONClustersBlockReader block(buffer, bufferSize);
1558         
1559         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1560         if (result != EXIT_SUCCESS and not continueParse) return result;
1561         
1562         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1563         
1564         // Print the data block record entries.
1565         const AliHLTMUONClusterStruct* entry = block.GetArray();
1566         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1567         {
1568                 cout << "======================= Cluster Number "
1569                         << i+1 << " =======================" << endl;
1570                 int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
1571                 if (subResult != EXIT_SUCCESS) return subResult;
1572         }       
1573
1574         return result;
1575 }
1576
1577
1578 int DumpChannelStruct(
1579                 const char* buffer, unsigned long bufferSize,
1580                 const AliHLTMUONChannelStruct* channel,
1581                 bool continueParse
1582         )
1583 {
1584         // Step through the fields trying to print them.
1585         // At each step check if we have not overflowed the buffer. If we have
1586         // not, then we can print the field, otherwise we print the left over
1587         // bytes assumed to be corrupted rubbish.
1588         int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse);
1589         if (result != EXIT_SUCCESS) return result;
1590         cout << setw(16) << left << channel->fClusterId << setw(0);
1591
1592         result = CheckField(channel->fBusPatch, buffer, bufferSize, continueParse);
1593         if (result != EXIT_SUCCESS) return result;
1594         cout << setw(16) << left << channel->fBusPatch << setw(0);
1595
1596         result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
1597         if (result != EXIT_SUCCESS) return result;
1598         cout << setw(16) << left << channel->fManu << setw(0);
1599
1600         result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
1601         if (result != EXIT_SUCCESS) return result;
1602         cout << setw(16) << left << channel->fChannelAddress << setw(0);
1603
1604         result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
1605         if(result != EXIT_SUCCESS) return result;
1606         cout << setw(16) << left << channel->fSignal << setw(0);
1607
1608         result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse);
1609         if(result != EXIT_SUCCESS) return result;
1610         cout << showbase << hex << channel->fRawDataWord << dec << setw(0) <<endl;
1611
1612         return result;
1613 }
1614
1615
1616 int DumpChannelsBlock(
1617                 const char* buffer, unsigned long bufferSize,
1618                 bool continueParse
1619         )
1620 {
1621         int result = EXIT_SUCCESS;
1622         AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
1623         
1624         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1625         if (result != EXIT_SUCCESS and not continueParse) return result;
1626         
1627         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1628         
1629         // Print the data block record entries.
1630         cout << "Cluster ID    | Bus Patch     | Manu Address  | Channel Addr  | Signal Value  | Raw Data Word " << endl;
1631         cout << "----------------------------------------------------------------------------------------------" << endl;
1632         const AliHLTMUONChannelStruct* entry = block.GetArray();
1633         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1634         { 
1635                 int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
1636                 if (subResult != EXIT_SUCCESS) return subResult;
1637         }
1638         return EXIT_SUCCESS;
1639 }
1640
1641
1642 int DumpMansoTrackStruct(
1643                 const char* buffer, unsigned long bufferSize,
1644                 const AliHLTMUONMansoTrackStruct* track,
1645                 bool continueParse
1646         )
1647 {
1648         // Step through the fields trying to print them.
1649         // At each step check if we have not overflowed the buffer. If we have
1650         // not, then we can print the field, otherwise we print the left over
1651         // bytes assumed to be corrupted rubbish.
1652         int result = CheckField(track->fId, buffer, bufferSize, continueParse);
1653         if (result != EXIT_SUCCESS) return result;
1654         cout << "Track ID: " << track->fId << "\t";
1655
1656         result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
1657         if (result != EXIT_SUCCESS) return result;
1658         cout << "Trigger Record ID: " << track->fTrigRec << endl;
1659         
1660         result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
1661         if (result != EXIT_SUCCESS) return result;
1662         cout << "Flags: " << showbase << hex << track->fFlags << dec;
1663         
1664         // Print the individual trigger bits.
1665         AliHLTMUONParticleSign sign;
1666         bool hitset[4];
1667         AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset);
1668         cout << " [Sign: " << sign << ", Hits set on chambers: ";
1669         bool first = true;
1670         for (AliHLTUInt32_t i = 0; i < 4; i++)
1671         {
1672                 if (hitset[i])
1673                 {
1674                         cout << (first ? "" : ", ") << i+7;
1675                         first = false;
1676                 }
1677         }
1678         cout << (first ? "none]" : "]") << endl;
1679
1680         result = CheckField(track->fPx, buffer, bufferSize, continueParse);
1681         if (result != EXIT_SUCCESS) return result;
1682         cout << "Momentum: (px = " << track->fPx << ", ";
1683
1684         result = CheckField(track->fPy, buffer, bufferSize, continueParse);
1685         if (result != EXIT_SUCCESS) return result;
1686         cout << "py = " << track->fPy << ", ";
1687
1688         result = CheckField(track->fPz, buffer, bufferSize, continueParse);
1689         if (result != EXIT_SUCCESS) return result;
1690         cout << "pz = " << track->fPz << ") GeV/c\t";
1691
1692         result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
1693         if (result != EXIT_SUCCESS) return result;
1694         cout << "Chi squared fit: " << track->fChi2 << endl;
1695         
1696         cout << "Track hits:" << endl;
1697         cout << "Chamber | DetElemID | X (cm)     | Y (cm)     | Z (cm)" << endl;
1698         cout << "-----------------------------------------------------------" << endl;
1699         const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
1700         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1701         {
1702                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
1703                 if (result != EXIT_SUCCESS) return result;
1704         }
1705
1706         return result;
1707 }
1708
1709
1710 int DumpMansoTracksBlock(
1711                 const char* buffer, unsigned long bufferSize,
1712                 bool continueParse
1713         )
1714 {
1715         int result = EXIT_SUCCESS;
1716         AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize);
1717         
1718         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1719         if (result != EXIT_SUCCESS and not continueParse) return result;
1720         
1721         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1722         
1723         // Print the data block record entries.
1724         const AliHLTMUONMansoTrackStruct* entry = block.GetArray();
1725         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1726         {
1727                 cout << "============================== Manso track number " << i+1
1728                         << " of " << nentries << " ==============================" << endl;
1729                 int subResult = DumpMansoTrackStruct(buffer, bufferSize, entry++, continueParse);
1730                 if (subResult != EXIT_SUCCESS) return subResult;
1731         }
1732         
1733         return result;
1734 }
1735
1736
1737 int DumpMansoRoIStruct(
1738                 const char* buffer, unsigned long bufferSize,
1739                 const AliHLTMUONMansoRoIStruct* roi,
1740                 bool continueParse
1741         )
1742 {
1743         // Step through the fields trying to print them.
1744         // At each step check if we have not overflowed the buffer. If we have
1745         // not, then we can print the field, otherwise we print the left over
1746         // bytes assumed to be corrupted rubbish.
1747         int result = CheckField(roi->fX, buffer, bufferSize, continueParse);
1748         if (result != EXIT_SUCCESS) return result;
1749         cout << setw(13) << left << roi->fX << setw(0);
1750
1751         result = CheckField(roi->fY, buffer, bufferSize, continueParse);
1752         if (result != EXIT_SUCCESS) return result;
1753         cout << setw(13) << left << roi->fY << setw(0);
1754
1755         result = CheckField(roi->fZ, buffer, bufferSize, continueParse);
1756         if (result != EXIT_SUCCESS) return result;
1757         cout << setw(13) << left << roi->fZ << setw(0);
1758
1759         result = CheckField(roi->fRadius, buffer, bufferSize, continueParse);
1760         if (result != EXIT_SUCCESS) return result;
1761         cout << roi->fRadius << setw(0) << endl;
1762
1763         return result;
1764 }
1765
1766
1767 int DumpMansoCandidateStruct(
1768                 const char* buffer, unsigned long bufferSize,
1769                 const AliHLTMUONMansoCandidateStruct* candidate,
1770                 bool continueParse
1771         )
1772 {
1773         int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse);
1774         if (result != EXIT_SUCCESS) return result;
1775         
1776         cout << "Regions of interest:" << endl;
1777         cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)     | Radius (cm)" << endl;
1778         cout << "-------------------------------------------------------------" << endl;
1779         const AliHLTMUONMansoRoIStruct* roi = &candidate->fRoI[0];
1780         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1781         {
1782                 cout << setw(10) << ch + 7;
1783                 result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse);
1784                 if (result != EXIT_SUCCESS) return result;
1785         }
1786         
1787         cout << "Momentum estimation parameters:" << endl;
1788         cout << "  Parameter : Z_middle coordinate (cm) | Integrated magnetic field (T.m)" << endl;
1789         cout << "      Value : ";
1790         result = CheckField(candidate->fZmiddle, buffer, bufferSize, continueParse);
1791         if(result != EXIT_SUCCESS) return result;
1792         cout << setw(24) << right << candidate->fZmiddle << setw(0) << " | ";
1793         
1794         result = CheckField(candidate->fBl, buffer, bufferSize, continueParse);
1795         if (result != EXIT_SUCCESS) return result;
1796         cout << setw(31) << right << candidate->fBl << setw(0) << endl;
1797         
1798         return result;
1799 }
1800
1801
1802 int DumpMansoCandidatesBlock(
1803                 const char* buffer, unsigned long bufferSize,
1804                 bool continueParse
1805         )
1806 {
1807         int result = EXIT_SUCCESS;
1808         AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize);
1809         
1810         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1811         if (result != EXIT_SUCCESS and not continueParse) return result;
1812         
1813         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1814         
1815         // Print the data block record entries.
1816         const AliHLTMUONMansoCandidateStruct* entry = block.GetArray();
1817         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1818         {
1819                 cout << "=========================== Manso track candidate number " << i+1
1820                         << " of " << nentries << " ===========================" << endl;
1821                 int subResult = DumpMansoCandidateStruct(buffer, bufferSize, entry++, continueParse);
1822                 if (subResult != EXIT_SUCCESS) return subResult;
1823         }
1824         
1825         return result;
1826 }
1827
1828
1829 int DumpSinglesDecisionBlockHeader(
1830                 const char* buffer, unsigned long bufferSize,
1831                 const AliHLTMUONSinglesDecisionBlockStruct* header,
1832                 bool continueParse
1833         )
1834 {
1835         // Step through the header fields trying to print them.
1836         // At each step check if we have not overflowed the buffer, if we have
1837         // not then we can print the field, otherwise we print the left over
1838         // bytes assumed to be corrupted rubbish.
1839         int result = CheckHeaderField(header->fNlowPt, buffer, bufferSize, continueParse);
1840         if (result != EXIT_SUCCESS) return result;
1841         cout << " Number of low pt triggers: " << header->fNlowPt << endl;
1842         
1843         result = CheckHeaderField(header->fNhighPt, buffer, bufferSize, continueParse);
1844         if (result != EXIT_SUCCESS) return result;
1845         cout << "Number of high pt triggers: " << header->fNhighPt << endl;
1846
1847         return result;
1848 }
1849
1850
1851 int DumpTrackDecisionStruct(
1852                 const char* buffer, unsigned long bufferSize,
1853                 const AliHLTMUONTrackDecisionStruct* decision,
1854                 bool continueParse
1855         )
1856 {
1857         // Step through the fields trying to print them.
1858         // At each step check if we have not overflowed the buffer. If we have
1859         // not, then we can print the field, otherwise we print the left over
1860         // bytes assumed to be corrupted rubbish.
1861         int result = CheckField(decision->fTrackId, buffer, bufferSize, continueParse);
1862         if (result != EXIT_SUCCESS) return result;
1863         cout << setw(13) << left << decision->fTrackId << setw(0);
1864         
1865         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
1866         if (result != EXIT_SUCCESS) return result;
1867         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
1868                 << setw(0) << dec;
1869                 
1870         // Print the individual trigger bits.
1871         bool highPt, lowPt;
1872         AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
1873         cout << setw(7) << left << (highPt ? "yes" : "no");
1874         cout << setw(8) << left << (lowPt ? "yes" : "no");
1875         
1876         result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
1877         if (result != EXIT_SUCCESS) return result;
1878         cout << setw(0) << decision->fPt << endl;
1879
1880         return result;
1881 }
1882
1883
1884 int DumpSinglesDecisionBlock(
1885                 const char* buffer, unsigned long bufferSize,
1886                 bool continueParse
1887         )
1888 {
1889         int result = EXIT_SUCCESS;
1890         AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
1891         
1892         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1893         if (result != EXIT_SUCCESS and not continueParse) return result;
1894         
1895         // Dump the rest of the block header.
1896         const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
1897         int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
1898         if (subResult != EXIT_SUCCESS) return subResult;
1899         
1900         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1901         
1902         // Print the data block record entries.
1903         cout << "           |        Trigger Bits      |" << endl;
1904         cout << "Track ID   | Raw         HighPt LowPt | pT" << endl;
1905         cout << "----------------------------------------------------" << endl;
1906         const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
1907         for(AliHLTUInt32_t i = 0; i < nentries; i++)
1908         {
1909                 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
1910                 if (subResult != EXIT_SUCCESS) return subResult;
1911         }
1912         
1913         return result;
1914 }
1915
1916
1917 int DumpPairsDecisionBlockHeader(
1918                 const char* buffer, unsigned long bufferSize,
1919                 const AliHLTMUONPairsDecisionBlockStruct* header,
1920                 bool continueParse
1921         )
1922 {
1923         // Step through the header fields trying to print them.
1924         // At each step check if we have not overflowed the buffer, if we have
1925         // not then we can print the field, otherwise we print the left over
1926         // bytes assumed to be corrupted rubbish.
1927         int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
1928         if (result != EXIT_SUCCESS) return result;
1929         cout << "      Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
1930         
1931         result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
1932         if (result != EXIT_SUCCESS) return result;
1933         cout << "      Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
1934         
1935         result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
1936         if (result != EXIT_SUCCESS) return result;
1937         cout << "     Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
1938         
1939         result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
1940         if (result != EXIT_SUCCESS) return result;
1941         cout << "        Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
1942         
1943         result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
1944         if (result != EXIT_SUCCESS) return result;
1945         cout << "        Number of like low pt triggers: " << header->fNlikeLowPt << endl;
1946         
1947         result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
1948         if (result != EXIT_SUCCESS) return result;
1949         cout << "       Number of like high pt triggers: " << header->fNlikeHighPt << endl;
1950         
1951         result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
1952         if (result != EXIT_SUCCESS) return result;
1953         cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
1954         
1955         result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
1956         if (result != EXIT_SUCCESS) return result;
1957         cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
1958         
1959         result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
1960         if (result != EXIT_SUCCESS) return result;
1961         cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
1962         
1963         return result;
1964 }
1965
1966
1967 int DumpPairDecisionStruct(
1968                 const char* buffer, unsigned long bufferSize,
1969                 const AliHLTMUONPairDecisionStruct* decision,
1970                 bool continueParse
1971         )
1972 {
1973         // Step through the fields trying to print them.
1974         // At each step check if we have not overflowed the buffer. If we have
1975         // not, then we can print the field, otherwise we print the left over
1976         // bytes assumed to be corrupted rubbish.
1977         int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
1978         if (result != EXIT_SUCCESS) return result;
1979         cout << setw(13) << left << decision->fTrackAId << setw(0);
1980         
1981         result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
1982         if (result != EXIT_SUCCESS) return result;
1983         cout << setw(13) << left << decision->fTrackBId << setw(0);
1984         
1985         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
1986         if (result != EXIT_SUCCESS) return result;
1987         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
1988                 << setw(0) << dec;
1989                 
1990         // Print the individual trigger bits.
1991         bool highMass, lowMass, unlike;
1992         AliHLTUInt8_t highPtCount, lowPtCount;
1993         AliHLTMUONUtils::UnpackPairDecisionBits(
1994                         decision->fTriggerBits,
1995                         highMass, lowMass, unlike, highPtCount, lowPtCount
1996                 );
1997         cout << setw(7) << left << (highMass ? "yes" : "no");
1998         cout << setw(7) << left << (lowMass ? "yes" : "no");
1999         cout << setw(7) << left << (unlike ? "yes" : "no");
2000         cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
2001         cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
2002         cout << setw(0);
2003         
2004         result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
2005         if (result != EXIT_SUCCESS) return result;
2006         cout << decision->fInvMass << endl;
2007         
2008         return EXIT_SUCCESS;
2009 }
2010
2011
2012 int DumpPairsDecisionBlock(
2013                 const char* buffer, unsigned long bufferSize,
2014                 bool continueParse
2015         )
2016 {
2017         int result = EXIT_SUCCESS;
2018         AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
2019         
2020         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
2021         if (result != EXIT_SUCCESS and not continueParse) return result;
2022         
2023         // Dump the rest of the block header.
2024         const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
2025         int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
2026         if (subResult != EXIT_SUCCESS) return subResult;
2027         
2028         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
2029         
2030         // Print the data block record entries.
2031         cout << "           |            |                Trigger Bits                  |" << endl;
2032         cout << "Track A ID | Track B ID | Raw         HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
2033         cout << "----------------------------------------------------------------------------------------" << endl;
2034         const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
2035         for(AliHLTUInt32_t i = 0; i < nentries; i++)
2036         {
2037                 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
2038                 if (subResult != EXIT_SUCCESS) return subResult;
2039         }
2040         
2041         return result;
2042 }
2043
2044
2045 int DumpCommonHeader(
2046                 const char* buffer, unsigned long bufferSize,
2047                 const AliHLTMUONDataBlockHeader* header, bool continueParse
2048         )
2049 {
2050         // Step through the header fields trying to print them.
2051         // At each step check if we have not overflowed the buffer, if we have
2052         // not then we can print the field, otherwise we print the left over
2053         // bytes assumed to be corrupted rubbish.
2054         int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
2055         if (result != EXIT_SUCCESS) return result;
2056         AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
2057         cout << "       Block type: " << type << endl;
2058         
2059         result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
2060         if (result != EXIT_SUCCESS) return result;
2061         cout << "     Record width: " << header->fRecordWidth << endl;
2062         
2063         result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
2064         if (result != EXIT_SUCCESS) return result;
2065         cout << "Number of entries: " << header->fNrecords << endl;
2066         
2067         return result;
2068 }
2069
2070 /**
2071  * Method to look for a certain data word key in the buffer.
2072  * \param buffer  The start location in the buffer to search.
2073  * \param end  The end of the buffer.
2074  * \returns  the pointer position just past the word found or
2075  *     NULL if the word was not found in the buffer.
2076  */
2077 const char* FindDataWord(const char* buffer, const char* end, UInt_t word)
2078 {
2079         for (const char* current = buffer; (current+1) <= end; current += sizeof(UInt_t))
2080         {
2081                 const UInt_t* currentWord = reinterpret_cast<const UInt_t*>(current);
2082                 if (*currentWord == word) return current + sizeof(UInt_t);
2083         }
2084         return NULL;
2085 }
2086
2087 /**
2088  * Method to check if the data buffer is really a raw DDL stream.
2089  * \returns  kUnknownDataBlock if this does not look like a raw DDL stream.
2090  *     kTrackerDDLRawData if this looks like a raw DDL stream from the tracker.
2091  *     kTriggerDDLRawData if this looks like a raw DDL stream from the trigger.
2092  */
2093 int CheckIfDDLStream(const char* buffer, unsigned long bufferSize)
2094 {
2095         if (bufferSize < sizeof(AliRawDataHeader)) return kUnknownDataBlock;
2096         
2097         const AliRawDataHeader* cdhHeader =
2098                 reinterpret_cast<const AliRawDataHeader*>(buffer);
2099         
2100         // Keep scores of indicators / tests that show this is a raw DDL stream
2101         // either from the trigger or tracker. We will decide if the stream is
2102         // indeed a raw DDL stream if the largest of the two scores is above a
2103         // minimum threshold.
2104         int trackerScore = 0;
2105         int triggerScore = 0;
2106         
2107         if (cdhHeader->fSize == UInt_t(-1) or cdhHeader->fSize == bufferSize)
2108         {
2109                 trackerScore++;
2110                 triggerScore++;
2111         }
2112         
2113         if (cdhHeader->GetVersion() == 2)
2114         {
2115                 trackerScore++;
2116                 triggerScore++;
2117         }
2118         
2119         const char* payload = buffer + sizeof(AliRawDataHeader);
2120         const char* payloadEnd = buffer + bufferSize;
2121         
2122         typedef AliMUONTrackerDDLDecoder<AliMUONTrackerDDLDecoderEventHandler> AliTrkDecoder;
2123         typedef AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler> AliTrgDecoder;
2124         
2125         // See if the DDL data has a payload with data word keys as expected by
2126         // AliMUONTrackerDDLDecoder.
2127         const char* current = payload;
2128         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BlockDataKeyWord())) != NULL )
2129         {
2130                 trackerScore++;
2131         }
2132         current = payload;
2133         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::DspDataKeyWord())) != NULL )
2134         {
2135                 trackerScore++;
2136         }
2137         current = payload;
2138         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BusPatchDataKeyWord())) != NULL )
2139         {
2140                 trackerScore++;
2141         }
2142         current = payload;
2143         while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::EndOfDDLWord())) != NULL )
2144         {
2145                 trackerScore++;
2146         }
2147         
2148         // See if the DDL data has a payload with data word keys as expected by
2149         // AliMUONTriggerDDLDecoder.
2150         current = payload;
2151         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfDarcWord())) != NULL )
2152         {
2153                 triggerScore++;
2154         }
2155         current = payload;
2156         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfGlobalWord())) != NULL )
2157         {
2158                 triggerScore++;
2159         }
2160         current = payload;
2161         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfRegionalWord())) != NULL )
2162         {
2163                 triggerScore++;
2164         }
2165         current = payload;
2166         while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfLocalWord())) != NULL )
2167         {
2168                 triggerScore++;
2169         }
2170         
2171         if (triggerScore > trackerScore)
2172         {
2173                 if (triggerScore >= 6) return kTriggerDDLRawData;
2174         }
2175         else
2176         {
2177                 if (trackerScore >= 6) return kTrackerDDLRawData;
2178         }
2179         return kUnknownDataBlock;
2180 }
2181
2182 /**
2183  * Parses the buffer and prints the contents to screen.
2184  * [in] \param buffer  The pointer to the buffer to parse.
2185  * [in] \param bufferSize  The size of the buffer in bytes.
2186  * [in] \param continueParse  If specified then the we try to continue parsing the
2187  *           buffer as much as possible.
2188  * [in/out] \param type  Initialy this should indicate the type of the data block
2189  *           or kUnknownDataBlock if not known. On exit it will be filled with
2190  *           the type of the data block as discovered by this routine if type
2191  *           initially contained kUnknownDataBlock.
2192  * \returns  The error code indicating the problem. EXIT_SUCCESS is returned
2193  *           on success.
2194  */
2195 int ParseBuffer(
2196                 const char* buffer, unsigned long bufferSize,
2197                 bool continueParse, int& type
2198         )
2199 {
2200         assert( buffer != NULL );
2201         int result = EXIT_SUCCESS;
2202         int subResult = EXIT_FAILURE;
2203         
2204         // If the -type|-t option was not used in the command line then we need to
2205         // figure out what type of data block this is from the data itself.
2206         bool ddlStream = false;
2207         if (type == kUnknownDataBlock)
2208         {
2209                 // First check if this is a raw DDL stream, if not then assume it is
2210                 // some kind of internal dHLT raw data block.
2211                 int streamType = CheckIfDDLStream(buffer, bufferSize);
2212                 if (streamType == kTrackerDDLRawData or streamType == kTriggerDDLRawData)
2213                 {
2214                         type = streamType;
2215                         ddlStream = true;
2216                 }
2217         }
2218         else if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
2219         {
2220                 ddlStream = true;
2221         }
2222         
2223         if (not ddlStream)
2224         {
2225                 if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
2226                 {
2227                         cerr << "ERROR: The size of the file is too small to contain a"
2228                                 " valid data block." << endl;
2229                         result = PARSE_ERROR;
2230                         if (not continueParse) return result;
2231                 }
2232                 const AliHLTMUONDataBlockHeader* header =
2233                         reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
2234         
2235                 subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
2236                 if (subResult != EXIT_SUCCESS) return subResult;
2237         
2238                 
2239                 // Check if the block type in the header corresponds to the type given
2240                 // by the '-type' command line parameter. If they do not then print an
2241                 // error or big fat warning message and force interpretation of the data
2242                 // block with the type given by '-type'.
2243                 AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
2244                 
2245                 if (type == kUnknownDataBlock)
2246                 {
2247                         // -type not used in the command line so just use what is given
2248                         // by the data block header.
2249                         type = headerType;
2250                 }
2251                 else if (type != headerType)
2252                 {
2253                         cerr << "WARNING: The data block header indicates a type"
2254                                 " different from what was specified on the command line."
2255                                 " The data could be corrupt."
2256                                 << endl;
2257                         cerr << "WARNING: The type value in the file is "
2258                                 << showbase << hex << header->fType
2259                                 << " (" << headerType << "), but on the command line it is "
2260                                 << showbase << hex << int(type) << dec
2261                                 << " (" << type << ")."
2262                                 << endl;
2263                         cerr << "WARNING: Will force the interpretation of the data block"
2264                                 " with a type of " << type << "." << endl;
2265                 }
2266         }
2267         
2268         // Now we know what type the data block is supposed to be, so we can
2269         // dump it to screen with the appropriate dump routine.
2270         switch (type)
2271         {
2272         case kTrackerDDLRawData:
2273                 subResult = DumpTrackerDDLRawStream(buffer, bufferSize, continueParse);
2274                 if (subResult != EXIT_SUCCESS) result = subResult;
2275                 break;
2276         case kTriggerDDLRawData:
2277                 subResult = DumpTriggerDDLRawStream(buffer, bufferSize, continueParse);
2278                 if (subResult != EXIT_SUCCESS) result = subResult;
2279                 break;
2280         case kTriggerRecordsDataBlock:
2281                 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
2282                 if (subResult != EXIT_SUCCESS) result = subResult;
2283                 break;
2284         case kTrigRecsDebugDataBlock:
2285                 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
2286                 if (subResult != EXIT_SUCCESS) result = subResult;
2287                 break;
2288         case kRecHitsDataBlock:
2289                 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
2290                 if (subResult != EXIT_SUCCESS) result = subResult;
2291                 break;
2292         case kClustersDataBlock:
2293                 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
2294                 if (subResult != EXIT_SUCCESS) result = subResult;
2295                 break;
2296         case kChannelsDataBlock:
2297                 return DumpChannelsBlock(buffer, bufferSize, continueParse);
2298                 if (subResult != EXIT_SUCCESS) result = subResult;
2299                 break;
2300         case kMansoTracksDataBlock:
2301                 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
2302                 if (subResult != EXIT_SUCCESS) result = subResult;
2303                 break;
2304         case kMansoCandidatesDataBlock:
2305                 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
2306                 if (subResult != EXIT_SUCCESS) result = subResult;
2307                 break;
2308         case kSinglesDecisionDataBlock:
2309                 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
2310                 if (subResult != EXIT_SUCCESS) result = subResult;
2311                 break;
2312         case kPairsDecisionDataBlock:
2313                 return DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
2314                 if (subResult != EXIT_SUCCESS) result = subResult;
2315                 break;
2316         default :
2317                 cout << "ERROR: Unknown data block type. Found a type number of "
2318                         << showbase << hex << int(type) << dec
2319                         << " (" << int(type) << ")." << endl;
2320                 result = PARSE_ERROR;
2321         }
2322         
2323         return result;
2324 }
2325
2326 /**
2327  * Convert the type code to a string.
2328  */
2329 const char* TypeToString(int type)
2330 {
2331         if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
2332         {
2333                 static char str[kAliHLTComponentDataTypefIDsize+1];
2334                 AliHLTComponentDataType t = AliHLTMUONConstants::DDLRawDataType();
2335                 memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
2336                 // Must insert the NULL character to make this an ANSI C string.
2337                 str[kAliHLTComponentDataTypefIDsize] = '\0';
2338                 return &str[0];
2339         }
2340         else
2341         {
2342                 return AliHLTMUONUtils::DataBlockTypeToString(AliHLTMUONDataBlockType(type));
2343         }
2344 }
2345
2346 /**
2347  * Find the data specification from the filename and return it in string format.
2348  */
2349 const char* TryDecodeDataSpec(const char* filename)
2350 {
2351         TString name = filename;
2352         
2353         TRegexp re1("MUONTR[GK]_[0123456789]+\\.ddl$");
2354         Ssiz_t length = 0;
2355         Ssiz_t pos = re1.Index(name, &length);
2356         if (pos != kNPOS)
2357         {
2358                 TString substr;
2359                 for (Ssiz_t i = 0; i < length; i++)
2360                         substr += name[pos+i];
2361                 TRegexp re("[0123456789]+");
2362                 pos = re.Index(substr, &length);
2363                 TString num;
2364                 for (Ssiz_t i = 0; i < length; i++)
2365                         num += substr[pos+i];
2366                 AliHLTUInt32_t spec = AliHLTMUONUtils::EquipIdToSpec(num.Atoi());
2367                 static char strbuf[32];
2368                 sprintf(&strbuf[0], "0x%8.8X", spec);
2369                 return &strbuf[0];
2370         }
2371         
2372         TRegexp re2("_MUON\\:.+_0x[0123456789abscefABCDEF]+\\.dat$");
2373         pos = re2.Index(name, &length);
2374         if (pos != kNPOS)
2375         {
2376                 TString substr;
2377                 for (Ssiz_t i = 0; i < length; i++)
2378                         substr += name[pos+i];
2379                 TRegexp re("0x[0123456789abscefABCDEF]+");
2380                 pos = re.Index(substr, &length);
2381                 TString num;
2382                 for (Ssiz_t i = 0; i < length; i++)
2383                         num += substr[pos+i];
2384                 static TString result = num;
2385                 return result.Data();
2386         }
2387         
2388         return NULL;
2389 }
2390
2391 namespace
2392 {
2393         // CDB path and run number to use.
2394         const char* gCDBPath = "local://$ALICE_ROOT/OCDB";
2395         Int_t gRunNumber = 0;
2396 }
2397
2398 /**
2399  * Performs basic data integrity checks of the data block using the
2400  * AliHLTMUONDataCheckerComponent.
2401  * [in] \param sys  The HLT system framework.
2402  * [in] \param filename  The name of the file containing the data block to check.
2403  * [in] \param type  Must indicate the type of the data block.
2404  * [in] \param dataspec The data specification of the data block. NULL if none.
2405  * [in] \param maxLogging  If set to true then full logging is turned on for AliHLTSystem.
2406  * \returns  The error code indicating the problem. EXIT_SUCCESS is returned
2407  *           on success.
2408  */
2409 int CheckDataIntegrity(
2410                 AliHLTSystem& sys, const char* filename, int type,
2411                 const char* dataspec, bool maxLogging
2412         )
2413 {
2414         if (maxLogging)
2415         {
2416                 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
2417                 sys.SetGlobalLoggingLevel(kHLTLogAll);
2418         }
2419         else
2420         {
2421                 AliLog::SetGlobalLogLevel(AliLog::kWarning);
2422                 int level = kHLTLogWarning | kHLTLogError | kHLTLogFatal;
2423                 sys.SetGlobalLoggingLevel(AliHLTComponentLogSeverity(level));
2424         }
2425         
2426         sys.LoadComponentLibraries("libAliHLTUtil.so");
2427         sys.LoadComponentLibraries("libAliHLTMUON.so");
2428         
2429         // Setup the component parameter lists and then the components.
2430         TString dcparams = "-return_error -warn_on_unexpected_block -no_global_check -cdbpath ";
2431         dcparams += gCDBPath;
2432         dcparams += " -run ";
2433         dcparams += gRunNumber;
2434         TString fpparams = "-datatype '";
2435         fpparams += TypeToString(type);
2436         fpparams += "' 'MUON'";
2437         if (dataspec != NULL)
2438         {
2439                 fpparams += " -dataspec ";
2440                 fpparams += dataspec;
2441         }
2442         else
2443         {
2444                 const char* spec = TryDecodeDataSpec(filename);
2445                 if (spec != NULL)
2446                 {
2447                         fpparams += " -dataspec ";
2448                         fpparams += spec;
2449                 }
2450                 else
2451                 {
2452                         dcparams += " -ignorespec";
2453                 }
2454         }
2455         fpparams += " -datafile ";
2456         fpparams += filename;
2457         TString fpname = "filePublisher_";
2458         fpname += filename;
2459         TString dcname = "checker_";
2460         dcname += filename;
2461         
2462         if (maxLogging)
2463         {
2464                 cout << "DEBUG: Using the following flags for FilePublisher: \""
2465                         << fpparams.Data() << "\""<< endl;
2466                 cout << "DEBUG: Using the following flags for "
2467                         << AliHLTMUONConstants::DataCheckerComponentId()
2468                         << ": \"" << dcparams.Data() << "\""<< endl;
2469         }
2470         
2471         AliHLTConfiguration(fpname.Data(), "FilePublisher", NULL, fpparams.Data());
2472         AliHLTConfiguration checker(
2473                         dcname.Data(), AliHLTMUONConstants::DataCheckerComponentId(),
2474                         fpname.Data(), dcparams.Data()
2475                 );
2476         
2477         // Build and run the HLT tasks.
2478         if (sys.BuildTaskList(dcname.Data()) != 0) return HLTSYSTEM_ERROR;
2479         if (maxLogging) sys.PrintTaskList();
2480         if (sys.Run() != 1) return HLTSYSTEM_ERROR;
2481         
2482         // Now clean up.
2483         if (sys.CleanTaskList() != 0) return HLTSYSTEM_ERROR;
2484
2485         return EXIT_SUCCESS;
2486 }
2487
2488
2489 /**
2490  * The caller is responsible for freeing memory allocated for buffer with a call
2491  * to delete [] buffer.
2492  */
2493 int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
2494 {
2495         assert( filename != NULL );
2496         
2497         // Open the file and find its size.
2498         fstream file;
2499         file.open(filename, ios::in);
2500         if (not file)
2501         {
2502                 cerr << "ERROR: Could not open the file: " << filename << endl;
2503                 return SYSTEM_ERROR;
2504         }
2505         file.seekg(0, ios::end);
2506         if (not file)
2507         {
2508                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
2509                 return SYSTEM_ERROR;
2510         }
2511         bufferSize = file.tellg();
2512         if (not file)
2513         {
2514                 cerr << "ERROR: Could not get file size for the file: " <<
2515                         filename << endl;
2516                 return SYSTEM_ERROR;
2517         }
2518         file.seekg(0, ios::beg);
2519         if (not file)
2520         {
2521                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
2522                 return SYSTEM_ERROR;
2523         }
2524         
2525         // Allocate the memory for the file.
2526         try
2527         {
2528                 buffer = new char[bufferSize];
2529         }
2530         catch (const std::bad_alloc&)
2531         {
2532                 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
2533                         << " bytes." << endl;
2534                 return SYSTEM_ERROR;
2535         }
2536         
2537         file.read(buffer, bufferSize);
2538         if (not file)
2539         {
2540                 delete [] buffer;
2541                 buffer = NULL;
2542                 bufferSize = 0;
2543                 cerr << "ERROR: Could not read from file: " << filename << endl;
2544                 return SYSTEM_ERROR;
2545         }
2546         
2547         file.close();
2548         if (not file)
2549         {
2550                 delete [] buffer;
2551                 buffer = NULL;
2552                 bufferSize = 0;
2553                 cerr << "ERROR: Could not close the file: " << filename << endl;
2554                 return SYSTEM_ERROR;
2555         }
2556         
2557         return EXIT_SUCCESS;
2558 }
2559
2560 /**
2561  * Prints the command line usage of this program to standard error.
2562  */
2563 void PrintUsage(bool asError = true)
2564 {
2565         std::ostream& os = asError ? cerr : cout;
2566         os << "Usage: dHLTdumpraw [-help|-h] [-continue|-c] [-type|-t <typename>] [-check|-k]" << endl;
2567         os << "         [-debug|-d] [-dataspec|-s <number>] [-cdbpath|-p <url>] [-run|-r <number>]" << endl;
2568         os << "         <filename> [<filename> ...]" << endl;
2569         os << "Where <filename> is the name of a file containing a raw data block." << endl;
2570         os << "Options:" << endl;
2571         os << " -help | -h" << endl;
2572         os << "       Displays this message." << endl;
2573         os << " -continue | -c" << endl;
2574         os << "       If specified, the program will try to continue parsing the data block" << endl;
2575         os << "       as much as possible rather than stopping at the first error." << endl;
2576         os << " -type | -t <typename>" << endl;
2577         os << "       Forces the contents of the subsequent files specified on the command" << endl;
2578         os << "       line to be interpreted as a specific type of data block." << endl;
2579         os << "       Where <typename> can be one of:" << endl;
2580         os << "         rawtracker - raw DDL stream from tracker chambers." << endl;
2581         os << "         rawtrigger - raw DDL stream from trigger chambers." << endl;
2582         os << "         trigrecs - trigger records data." << endl;
2583         os << "         trigrecsdebug - debugging information about trigger records." << endl;
2584         os << "         rechits - reconstructed hits data." << endl;
2585         os << "         channels - channel debugging information from hit reconstruction." << endl;
2586         os << "         clusters - cluster debugging information from hit reconstruction." << endl;
2587         os << "         mansotracks - partial tracks from Manso algorithm." << endl;
2588         os << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
2589         os << "         singlesdecision - trigger decisions for single tracks." << endl;
2590         os << "         pairsdecision - trigger decisions for track pairs." << endl;
2591         os << "         autodetect - the type of the data block will be automatically" << endl;
2592         os << "                      detected." << endl;
2593         os << " -check | -k" << endl;
2594         os << "       If specified then data integrity checks are performed on the raw data." << endl;
2595         os << "       Warnings and errors are printed as problems are found with the data, but" << endl;
2596         os << "       the data will still be converted into ROOT objects as best as possible." << endl;
2597         os << " -debug | -d" << endl;
2598         os << "       If specified, then the all debug messages are printed by the AliHLTSystem." << endl;
2599         os << "       This is only useful if experiencing problems with the -check|-k option." << endl;
2600         os << " -dataspec | -s <number>" << endl;
2601         os << "       When specified, then <number> is used as the data specification for the" << endl;
2602         os << "       data file that follows. This option is only useful with the -check|-k option." << endl;
2603         os << " -cdbpath | -p <url>" << endl;
2604         os << "       The path to the CDB to use when running with the -check | -k option." << endl;
2605         os << " -run | -r <number>" << endl;
2606         os << "       The run number to use when running with the -check | -k option." << endl;
2607 }
2608
2609 /**
2610  * Parses the command line.
2611  * @param argc  Number of arguments as given in main().
2612  * @param argv  Array of arguments as given in main().
2613  * @param filenames  Pointer to buffer storing file name strings.
2614  * @param filetypes  Array that receives the type of the data block expected, i.e.
2615  *                   the value of the -type flag for the corresponding file.
2616  * @param dataspecs  Data specifications to use for the data files.
2617  * @param numOfFiles  Receives the number of file name strings that were found
2618  *                    and added to 'filenames'.
2619  * @param continueParse  Set to true if the user requested to continue to parse
2620  *                      after errors.
2621  * @param checkData  Set to true if data integrity checking was requested.
2622  * @param maxLogging  Set to true if maximal logging was requested.
2623  * @return  A status flag suitable for returning from main(), containing either
2624  *          EXIT_SUCCESS or CMDLINE_ERROR.
2625  */
2626 int ParseCommandLine(
2627                 int argc,
2628                 const char** argv,
2629                 const char** filenames,
2630                 int* filetypes,
2631                 const char** dataspecs,
2632                 int& numOfFiles,
2633                 bool& continueParse,
2634                 bool& checkData,
2635                 bool& maxLogging
2636         )
2637 {
2638         numOfFiles = 0;
2639         continueParse = false;
2640         maxLogging = false;
2641         checkData = false;
2642         int currentType = kUnknownDataBlock;
2643         const char* currentDataSpec = NULL;
2644         bool pathSet = false;
2645         bool runSet = false;
2646
2647         // Parse the command line.
2648         for (int i = 1; i < argc; i++)
2649         {
2650                 if (strcmp(argv[i], "-help") == 0 or strcmp(argv[i], "-h") == 0)
2651                 {
2652                         PrintUsage(false);
2653                         return EXIT_SUCCESS;
2654                 }
2655                 else if (strcmp(argv[i], "-continue") == 0 or strcmp(argv[i], "-c") == 0)
2656                 {
2657                         continueParse = true;
2658                 }
2659                 else if (strcmp(argv[i], "-type") == 0 or strcmp(argv[i], "-t") == 0)
2660                 {
2661                         if (++i >= argc)
2662                         {
2663                                 cerr << "ERROR: Missing a type specifier." << endl << endl;
2664                                 PrintUsage();
2665                                 return CMDLINE_ERROR;
2666                         }
2667                         // Now we need to parse the typename in the command line.
2668                         if (strcmp(argv[i], "autodetect") == 0)
2669                         {
2670                                 currentType = kUnknownDataBlock;
2671                         }
2672                         else if (strcmp(argv[i], "rawtracker") == 0)
2673                         {
2674                                 currentType = kTrackerDDLRawData;
2675                         }
2676                         else if (strcmp(argv[i], "rawtrigger") == 0)
2677                         {
2678                                 currentType = kTriggerDDLRawData;
2679                         }
2680                         else
2681                         {
2682                                 currentType = AliHLTMUONUtils::ParseCommandLineTypeString(argv[i]);
2683                                 if (currentType == kUnknownDataBlock)
2684                                 {
2685                                         cerr << "ERROR: Invalid type name '" << argv[i]
2686                                                 << "' specified for argument " << argv[i-1]
2687                                                 << "." << endl << endl;
2688                                         PrintUsage();
2689                                         return CMDLINE_ERROR;
2690                                 }
2691                         }
2692                 }
2693                 else if (strcmp(argv[i], "-debug") == 0 or strcmp(argv[i], "-d") == 0)
2694                 {
2695                         maxLogging = true;
2696                 }
2697                 else if (strcmp(argv[i], "-check") == 0 or strcmp(argv[i], "-k") == 0)
2698                 {
2699                         checkData = true;
2700                 }
2701                 else if (strcmp(argv[i], "-dataspec") == 0 or strcmp(argv[i], "-s") == 0)
2702                 {
2703                         if (++i >= argc)
2704                         {
2705                                 cerr << "ERROR: Missing a specification number." << endl << endl;
2706                                 PrintUsage();
2707                                 return CMDLINE_ERROR;
2708                         }
2709                         
2710                         char* errPos = NULL;
2711                         unsigned long num = strtoul(argv[i], &errPos, 0);
2712                         if (errPos == NULL or *errPos != '\0')
2713                         {
2714                                 cerr << "ERROR: Cannot convert '%s' to a data specification number."
2715                                         << argv[i] << endl;
2716                                 return CMDLINE_ERROR;
2717                         }
2718                         if (not AliHLTMUONUtils::IsSpecValid(num))
2719                         {
2720                                 cerr << "ERROR: The data specification number is not a valid format."
2721                                         << endl;
2722                                 return CMDLINE_ERROR;
2723                         }
2724                         currentDataSpec = argv[i];
2725                 }
2726                 else if (strcmp(argv[i], "-cdbpath") == 0 or strcmp(argv[i], "-p") == 0)
2727                 {
2728                         if (pathSet)
2729                         {
2730                                 cerr << "WARNING: Already used -cdbpath|-p with '" << gCDBPath
2731                                         << "' before. Will override it with the last value specified with -cdbpath|-p."
2732                                         << endl;
2733                         }
2734                         if (++i >= argc)
2735                         {
2736                                 cerr << "ERROR: Missing the URL for the CDB path." << endl << endl;
2737                                 PrintUsage();
2738                                 return CMDLINE_ERROR;
2739                         }
2740                         gCDBPath = argv[i];
2741                         pathSet = true;
2742                 }
2743                 else if (strcmp(argv[i], "-run") == 0 or strcmp(argv[i], "-r") == 0)
2744                 {
2745                         if (runSet)
2746                         {
2747                                 cerr << "WARNING: Already used -run|-r with " << gRunNumber
2748                                         << " before. Will override it with the last value specified with -run|-r."
2749                                         << endl;
2750                         }
2751                         if (++i >= argc)
2752                         {
2753                                 cerr << "ERROR: Missing the run number." << endl << endl;
2754                                 PrintUsage();
2755                                 return CMDLINE_ERROR;
2756                         }
2757                         
2758                         char* cpErr = NULL;
2759                         Int_t run = Int_t( strtol(argv[i], &cpErr, 0) );
2760                         if (cpErr == NULL or *cpErr != '\0' or run < 0)
2761                         {
2762                                 cerr << "ERROR: Cannot convert '" << argv[i] << "' to a valid run number."
2763                                         " Expected a positive integer value." << endl;
2764                                 return CMDLINE_ERROR;
2765                         }
2766
2767                         gRunNumber = run;
2768                         runSet = true;
2769                 }
2770                 else
2771                 {
2772                         assert( numOfFiles < argc );
2773                         filenames[numOfFiles] = argv[i];
2774                         filetypes[numOfFiles] = currentType;
2775                         dataspecs[numOfFiles] = currentDataSpec;
2776                         currentDataSpec = NULL;  // Reset because '-dataspec' option is only valid for one file.
2777                         numOfFiles++;
2778                 }
2779         }
2780         
2781         // Now check that we have at least one filename and all the flags we need.
2782         if (numOfFiles == 0)
2783         {
2784                 cerr << "ERROR: Missing a file name. You must specify at least one file to process."
2785                         << endl << endl;
2786                 PrintUsage();
2787                 return CMDLINE_ERROR;
2788         }
2789         
2790         return EXIT_SUCCESS;
2791 }
2792
2793
2794 int main(int argc, const char** argv)
2795 {
2796         // Test endianess of this machine during runtime and print warning if it is not
2797         // little endian.
2798         union
2799         {
2800                 int dword;
2801                 char byte[4];
2802         } endianTest;
2803         endianTest.dword = 0x1;
2804         if (endianTest.byte[0] != 0x1)
2805         {
2806                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2807                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2808                 cerr << "!!                                                                     !!" << endl;
2809                 cerr << "!! This is not a little endian machine, but dHLT raw data is normally  !!" << endl;
2810                 cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
2811                 cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
2812                 cerr << "!! output.                                                             !!" << endl;
2813                 cerr << "!!                                                                     !!" << endl;
2814                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2815                 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2816                 cerr << endl;
2817         }
2818
2819
2820         int numOfFiles = 0;
2821         bool continueParse = false;
2822         bool checkData = false;
2823         bool maxLogging = false;
2824         int returnCode = EXIT_SUCCESS;
2825         char* buffer = NULL;
2826         const char** filename = NULL;
2827         int* filetype = NULL;
2828         const char** dataspec = NULL;
2829
2830         try
2831         {
2832                 // Reduce logging now to get rid of informationals from AliHLTSystem constructor.
2833                 AliLog::SetGlobalLogLevel(AliLog::kWarning);
2834                 AliHLTSystem sys;
2835         
2836                 // There will be at least 'argc' number of filenames.
2837                 typedef const char* AnsiString;
2838                 filename = new AnsiString[argc];
2839                 filetype = new int[argc];
2840                 dataspec = new AnsiString[argc];
2841                 
2842                 returnCode = ParseCommandLine(
2843                                 argc, argv, filename, filetype, dataspec, numOfFiles,
2844                                 continueParse, checkData, maxLogging
2845                         );
2846
2847                 if (returnCode == EXIT_SUCCESS)
2848                 {
2849                         for (int i = 0; i < numOfFiles; i++)
2850                         {
2851                                 unsigned long bufferSize = 0;
2852                                 returnCode = ReadFile(filename[i], buffer, bufferSize);
2853                                 if (returnCode != EXIT_SUCCESS) break;
2854                                 if (numOfFiles > 1)
2855                                 {
2856                                         cout << "########## Start of dump for file: "
2857                                                 << filename[i] << " ##########" << endl;
2858                                 }
2859                                 int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]);
2860                                 if (buffer != NULL) delete [] buffer;
2861                                 if (result != EXIT_SUCCESS)
2862                                 {
2863                                         returnCode = result;
2864                                         if (not continueParse) break;
2865                                 }
2866                                 if (checkData)
2867                                 {
2868                                         result = CheckDataIntegrity(
2869                                                         sys, filename[i], filetype[i],
2870                                                         dataspec[i], maxLogging
2871                                                 );
2872                                         if (result != EXIT_SUCCESS)
2873                                         {
2874                                                 returnCode = result;
2875                                                 if (not continueParse) break;
2876                                         }
2877                                 }
2878                                 if (numOfFiles > 1)
2879                                 {
2880                                         cout << "##########   End of dump for file: " <<
2881                                                 filename[i] << " ##########" << endl;
2882                                 }
2883                         }
2884                 }
2885                 
2886                 delete [] filename;
2887                 delete [] filetype;
2888                 delete [] dataspec;
2889         }
2890         catch (...)
2891         {
2892                 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
2893                 returnCode = FATAL_ERROR;
2894                 if (buffer != NULL) delete [] buffer;
2895                 if (filename != NULL) delete [] filename;
2896                 if (filetype != NULL) delete [] filetype;
2897                 if (dataspec != NULL) delete [] dataspec;
2898         }
2899         
2900         return returnCode;
2901 }