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