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