Fixing bug when choosing -h | -help flag.
[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   
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 #define NDEBUG
30 #include "AliHLTMUONDataBlockReader.h"
31 #undef NDEBUG
32 #include "AliHLTMUONUtils.h"
33
34 #include <endian.h>
35 #ifndef LITTLE_ENDIAN
36 #error Handling of internal data for non little endian machines not yet implemented.
37 #endif
38
39 #include <stdlib.h>
40 #include <cassert>
41 #include <new>
42 #include <fstream>
43
44 #include <iostream>
45 using std::cout;
46 using std::cerr;
47 using std::endl;
48 using std::showbase;
49 using std::noshowbase;
50 using std::hex;
51 using std::dec;
52
53 #include <iomanip>
54 using std::setw;
55 using std::left;
56 using std::internal;
57
58
59 #define CMDLINE_ERROR 1
60 #define PARSE_ERROR 2
61 #define SYSTEM_ERROR 3
62 #define FATAL_ERROR 4
63
64
65 void PrintRubbishData(AliHLTUInt32_t offset, const char* padByte, AliHLTUInt32_t padCount)
66 {
67         if (padCount == 0) return;
68         
69         cerr << "ERROR: Found the following unexpected rubbish data at the"
70                 " end of the data block:" << endl;
71         cerr << "Byte #\tValue\tCharacter" << endl;
72         for (AliHLTUInt32_t i = 0; i < padCount; i++)
73         {
74                 short value = short(padByte[i]) & 0xFF;
75                 char character = padByte[i];
76                 cerr << offset + i + 1 << "\t"
77                         << noshowbase << hex << "0x" << value << dec << "\t"
78                         << character << endl;
79         }
80 }
81
82
83 template <typename FieldType>
84 int CheckHeaderField(
85                 FieldType& field, const char* buffer, unsigned long bufferSize,
86                 bool continueParse
87         )
88 {
89         const char* fieldptr = reinterpret_cast<const char*>(&field);
90         const char* endptr = buffer + bufferSize;
91         AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
92         
93         if (bufferRemaining < sizeof(field))
94         {
95                 cout << "..." << endl; // We may be half way through printing a line so end it.
96                 cerr << "ERROR: The data block is too short. The header is corrupt." << endl;
97                 if (continueParse)
98                 {
99                         AliHLTUInt32_t offset = fieldptr - buffer;
100                         PrintRubbishData(offset, fieldptr, bufferRemaining);
101                 }
102                 return PARSE_ERROR;
103         }
104         return EXIT_SUCCESS;
105 }
106
107
108 template <typename FieldType>
109 int CheckField(
110                 FieldType& field, const char* buffer, unsigned long bufferSize,
111                 bool continueParse
112         )
113 {
114         const char* fieldptr = reinterpret_cast<const char*>(&field);
115         const char* endptr = buffer + bufferSize;
116         AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
117         
118         if (bufferRemaining < sizeof(field))
119         {
120                 cout << "..." << endl; // We may be half way through printing a line so end it.
121                 cerr << "ERROR: The data block is too short. The data is corrupt." << endl;
122                 if (continueParse)
123                 {
124                         AliHLTUInt32_t offset = fieldptr - buffer;
125                         PrintRubbishData(offset, fieldptr, bufferRemaining);
126                 }
127                 return PARSE_ERROR;
128         }
129         return EXIT_SUCCESS;
130 }
131
132
133 template <typename BlockType>
134 int CheckCommonHeader(
135                 BlockType& block, const char* buffer, unsigned long bufferSize,
136                 bool continueParse
137         )
138 {
139         int result = EXIT_SUCCESS;
140
141         // Check the fRecordWidth field in the common header.
142         if (block.CommonBlockHeader().fRecordWidth !=
143                 sizeof(typename BlockType::ElementType))
144         {
145                 cerr << "ERROR: The record width found in the header is incorrect."
146                         " Found a record width of "
147                         << block.CommonBlockHeader().fRecordWidth << " bytes, but expected"
148                         " a value of " << sizeof(typename BlockType::ElementType)
149                         << " bytes." << endl;
150                 result = PARSE_ERROR;
151                 if (not continueParse) return result;
152         }
153         
154         if (not block.BufferSizeOk())
155         {
156                 cerr << "ERROR: The size of the file is incorrect. It is "
157                         << bufferSize << " bytes big, but according"
158                         " to the data block header it should be " << block.BytesUsed()
159                         << " bytes." << endl;
160                 result = PARSE_ERROR;
161                 if (not continueParse) return result;
162         }
163         
164         return result;
165 }
166
167
168 template <typename BlockType>
169 AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize)
170 {
171         // Calculate how many entries we can display. If the buffer size is correct
172         // we just use the number of entries the block specifies. Otherwise we need
173         // to calculate it from the buffer size.
174         AliHLTUInt32_t nentries;
175         if (block.BytesUsed() == bufferSize)
176         {
177                 nentries = block.Nentries();
178         }
179         else
180         {
181                 AliHLTInt32_t dataSize = bufferSize
182                         - sizeof(typename BlockType::HeaderType);
183                 nentries = dataSize / sizeof(typename BlockType::ElementType);
184                 if (dataSize % sizeof(typename BlockType::ElementType) > 0)
185                         nentries++;
186         }
187         return nentries;
188 }
189
190
191 int DumpRecHitStruct(
192                 const char* buffer, unsigned long bufferSize,
193                 const AliHLTMUONRecHitStruct* hit,
194                 bool continueParse
195         )
196 {
197         // Step through the fields trying to print them.
198         // At each step check if we have not overflowed the buffer. If we have
199         // not, then we can print the field, otherwise we print the left over
200         // bytes assumed to be corrupted rubbish.
201         int result = CheckField(hit->fX, buffer, bufferSize, continueParse);
202         if (result != EXIT_SUCCESS) return result;
203         cout << setw(13) << left << hit->fX << setw(0);
204
205         result = CheckField(hit->fY, buffer, bufferSize, continueParse);
206         if (result != EXIT_SUCCESS) return result;
207         cout << setw(13) << left << hit->fY << setw(0);
208
209         result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
210         if (result != EXIT_SUCCESS) return result;
211         cout << hit->fZ << setw(0) << endl;
212
213         return result;
214 }
215
216
217 int DumpRecHitsBlock(
218                 const char* buffer, unsigned long bufferSize,
219                 bool continueParse
220         )
221 {
222         int result = EXIT_SUCCESS;
223         AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
224         
225         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
226         if (result != EXIT_SUCCESS and not continueParse) return result;
227         
228         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
229         
230         // Print the data block record entries.
231         cout << " X (cm)     | Y (cm)     | Z (cm)" << endl;
232         cout << "---------------------------------------" << endl;
233         const AliHLTMUONRecHitStruct* entry = block.GetArray();
234         for(AliHLTUInt32_t i = 0; i < nentries; i++)
235         {
236                 int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
237                 if (subResult != EXIT_SUCCESS) return subResult;
238         }
239         
240         return result;
241 }
242
243
244 int DumpTriggerRecordStruct(
245                const char* buffer, unsigned long bufferSize, 
246                const AliHLTMUONTriggerRecordStruct* record,
247                bool continueParse
248        )
249 {
250         // Step through the fields trying to print them.
251         // At each step check if we have not overflowed the buffer. If we have
252         // not, then we can print the field, otherwise we print the left over
253         // bytes assumed to be corrupted rubbish.
254         int result = CheckField(record->fId, buffer, bufferSize, continueParse);
255         if (result != EXIT_SUCCESS) return result;
256         cout << "Trigger Record ID: " << record->fId <<endl;
257         
258         result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
259         if (result != EXIT_SUCCESS) return result;
260         cout << "Flags: " << showbase << hex << record->fFlags << dec;
261                 
262         // Print the individual trigger bits.
263         AliHLTMUONParticleSign sign;
264         bool hitset[4];
265         AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
266         cout << " [Sign: " << sign << ", Hits set on chambers: ";
267         bool first = true;
268         for (AliHLTUInt32_t i = 0; i < 4; i++)
269         {
270                 if (hitset[i])
271                 {
272                         cout << (first ? "" : ", ") << i+11;
273                         first = false;
274                 }
275         }
276         cout << (first ? "none]" : "]") << endl;
277
278         result = CheckField(record->fPx, buffer, bufferSize, continueParse);
279         if (result != EXIT_SUCCESS) return result;
280         cout << "Momentum: (px = " << record->fPx << ", ";
281
282         result = CheckField(record->fPy, buffer, bufferSize, continueParse);
283         if (result != EXIT_SUCCESS) return result;
284         cout << "py = " << record->fPy << ", ";
285
286         result = CheckField(record->fPz, buffer, bufferSize, continueParse);
287         if (result != EXIT_SUCCESS) return result;
288         cout << "pz = " << record->fPz << ") GeV/c"<<endl;
289         
290         cout << "Track hits:" << endl;
291         cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)" << endl;
292         cout << "------------------------------------------------" << endl;
293         const AliHLTMUONRecHitStruct* hit = &record->fHit[0];
294         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
295         {
296                 cout << setw(10) << left << ch + 11 << setw(0);
297                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
298                 if (result != EXIT_SUCCESS) return result;
299         }
300
301         return result;
302
303 }
304
305
306 int DumpTriggerRecordsBlock(
307                 const char* buffer, unsigned long bufferSize,
308                 bool continueParse
309         )
310 {
311         AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
312         
313         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
314         if (result != EXIT_SUCCESS and not continueParse) return result;
315         
316         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
317         
318         // Print the data block record entries.
319         const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
320         for(AliHLTUInt32_t i = 0; i < nentries; i++)
321         {
322                 cout << "============================== Trigger Record number " << i+1
323                         << " of " << nentries << " ==============================" << endl;
324                 int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse);
325                 if (subResult != EXIT_SUCCESS) return subResult;
326         }
327         
328         return EXIT_SUCCESS;
329 }
330
331
332 int DumpTrigRecInfoStruct(const char* buffer, unsigned long bufferSize, 
333                           const AliHLTMUONTrigRecInfoStruct* debuginfo, 
334                           bool continueParse
335                           )
336 {
337         // Step through the fields trying to print them.
338         // At each step check if we have not overflowed the buffer. If we have
339         // not, then we can print the field, otherwise we print the left over
340         // bytes assumed to be corrupted rubbish.
341         int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse);
342         if (result != EXIT_SUCCESS) return result;
343         cout << setw(22) << left << debuginfo->fTrigRecId << setw(0);
344
345         result = CheckField(debuginfo->fDetElemId, buffer, bufferSize, continueParse);
346         if (result != EXIT_SUCCESS) return result;
347         cout << setw(20) << left << debuginfo->fDetElemId << setw(0);
348         
349         result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
350         if(result != EXIT_SUCCESS) return result;
351         cout << setw(30) << left << debuginfo->fZmiddle << setw(0);
352
353         result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
354         if (result != EXIT_SUCCESS) return result;
355         cout <<debuginfo->fBl << setw(0) << endl;
356
357         return result;
358 }
359
360
361 int DumpTrigRecsDebugBlock(
362                 const char* buffer, unsigned long bufferSize,
363                 bool continueParse
364         )
365 {
366         AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
367         
368         int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
369         if (result != EXIT_SUCCESS and not continueParse) return result;
370         
371         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
372         
373         // Print the data block record entries.
374         cout << "Trigger Record ID  | Detector ID  | Momentum X Component (Gev/c) | Integrated Magnetic Field (T.m)" << endl;
375         cout << "--------------------------------------------------------------------------------------------------" << endl;
376         const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray();
377         for(AliHLTUInt32_t i = 0; i < nentries; i++)
378         {
379                 int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
380                 if (subResult != EXIT_SUCCESS) return subResult;
381         }
382         
383         return EXIT_SUCCESS;
384 }
385
386
387 int DumpTriggerChannelStruct(const char* buffer, unsigned long bufferSize, 
388                       const AliHLTMUONTriggerChannelStruct* triggerchannel, 
389                       bool continueParse
390                       )
391 {
392         // Step through the fields trying to print them.
393         // At each step check if we have not overflowed the buffer. If we have
394         // not, then we can print the field, otherwise we print the left over
395         // bytes assumed to be corrupted rubbish.
396         int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse);
397         if (result != EXIT_SUCCESS) return result;
398         cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0);
399
400         result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse);
401         if (result != EXIT_SUCCESS) return result;
402         cout << setw(13) << left << triggerchannel->fChamber << setw(0);
403
404         result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse);
405         if (result != EXIT_SUCCESS) return result;
406         cout << setw(10) << left << triggerchannel->fSignal << setw(0);
407
408         result = CheckField(triggerchannel->fRawDataWord, buffer, bufferSize, continueParse);
409         if(result != EXIT_SUCCESS) return result;
410         cout << showbase << hex << triggerchannel->fRawDataWord << dec << setw(0) << endl;
411         return result;
412 }
413
414
415 int DumpTriggerChannelsBlock(
416                 const char* buffer, unsigned long bufferSize,
417                 bool continueParse
418         )
419 {
420         int result = EXIT_SUCCESS;
421         AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
422         
423         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
424         if (result != EXIT_SUCCESS and not continueParse) return result;
425         
426         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
427         
428         // Print the data block record entries.
429         cout << " Trigger Record ID   | Chamber    | Signal   | Raw Data Word " << endl;
430         cout << "--------------------------------------------------------------" << endl;
431         const AliHLTMUONTriggerChannelStruct* entry = block.GetArray();
432         for(AliHLTUInt32_t i = 0; i < nentries; i++)
433         {
434                 int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse);
435                 if (subResult != EXIT_SUCCESS) return subResult;
436         }
437
438         return result;
439 }
440
441
442 int DumpClusterStruct(
443                       const char* buffer, unsigned long bufferSize,
444                       const AliHLTMUONClusterStruct* cluster,
445                       bool continueParse
446        )
447 {
448         // Step through the fields trying to print them.
449         // At each step check if we have not overflowed the buffer. If we have
450         // not, then we can print the field, otherwise we print the left over
451         // bytes assumed to be corrupted rubbish.
452         int result = CheckField(cluster->fId, buffer, bufferSize, continueParse);
453         if (result != EXIT_SUCCESS) return result;
454         cout << "cluster->fId: " << cluster->fId << "\t";
455
456         result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
457         if (result != EXIT_SUCCESS) return result;
458         cout << "cluster->fDetElemId: " << cluster->fDetElemId << "\t";
459
460         result = CheckField(cluster->fNchannels, buffer, bufferSize, continueParse);
461         if(result != EXIT_SUCCESS) return result;
462         cout << "cluster->fNchannels: " << cluster->fNchannels <<endl;
463
464         cout << " Corresponding Hit: "<< endl;
465         cout << " X (cm)     | Y (cm)     | Z (cm)" << endl;
466         cout << "---------------------------------------" << endl;
467         const AliHLTMUONRecHitStruct * hit = & cluster->fHit;
468         result = DumpRecHitStruct(buffer, bufferSize, hit, continueParse);
469
470         return result;
471 }
472
473
474 int DumpClustersBlock(
475                 const char* buffer, unsigned long bufferSize,
476                 bool continueParse
477         )
478 {
479         int result = EXIT_SUCCESS;
480         AliHLTMUONClustersBlockReader block(buffer, bufferSize);
481         
482         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
483         if (result != EXIT_SUCCESS and not continueParse) return result;
484         
485         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
486         
487         // Print the data block record entries.
488         const AliHLTMUONClusterStruct* entry = block.GetArray();
489         for(AliHLTUInt32_t i = 0; i < nentries; i++)
490         {
491                 cout << " ===================================================== Cluster Number "
492                         << i+1 << "==================================================" << endl; 
493                 int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
494                 if (subResult != EXIT_SUCCESS) return subResult;
495         }       
496
497         return result;
498 }
499
500
501 int DumpChannelStruct(
502                const char* buffer, unsigned long bufferSize,
503                const AliHLTMUONChannelStruct* channel,
504                bool continueParse                 
505        )
506 {
507         // Step through the fields trying to print them.
508         // At each step check if we have not overflowed the buffer. If we have
509         // not, then we can print the field, otherwise we print the left over
510         // bytes assumed to be corrupted rubbish.
511         int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse);
512         if (result != EXIT_SUCCESS) return result;
513         cout << setw(16) << left << channel->fClusterId << setw(0);
514
515         result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
516         if (result != EXIT_SUCCESS) return result;
517         cout << setw(16) << left << channel->fManu << setw(0);
518
519         result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
520         if (result != EXIT_SUCCESS) return result;
521         cout << setw(19) << left << channel->fChannelAddress << setw(0);
522
523         result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
524         if(result != EXIT_SUCCESS) return result;
525         cout << setw(16) << left << channel->fSignal << setw(0);
526
527         result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse);
528         if(result != EXIT_SUCCESS) return result;
529         cout << showbase << hex << channel->fRawDataWord << dec << setw(0) <<endl;
530
531         return result;
532 }
533
534
535 int DumpChannelsBlock(
536                 const char* buffer, unsigned long bufferSize,
537                 bool continueParse
538         )
539 {
540         int result = EXIT_SUCCESS;
541         AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
542         
543         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
544         if (result != EXIT_SUCCESS and not continueParse) return result;
545         
546         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
547         
548         // Print the data block record entries.
549         cout << "Cluster Id  | Manu Address  | Channel Address  | Signal Value  | Raw Data Word " <<endl;
550         cout << "-------------------------------------------------------------------------------" <<endl;
551         const AliHLTMUONChannelStruct* entry = block.GetArray();
552         for(AliHLTUInt32_t i = 0; i < nentries; i++)
553         { 
554                 int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
555                 if (subResult != EXIT_SUCCESS) return subResult;
556         }
557         return EXIT_SUCCESS;
558 }
559
560
561 int DumpMansoTrackStruct(
562                 const char* buffer, unsigned long bufferSize,
563                 const AliHLTMUONMansoTrackStruct* track,
564                 bool continueParse
565         )
566 {
567         // Step through the fields trying to print them.
568         // At each step check if we have not overflowed the buffer. If we have
569         // not, then we can print the field, otherwise we print the left over
570         // bytes assumed to be corrupted rubbish.
571         int result = CheckField(track->fId, buffer, bufferSize, continueParse);
572         if (result != EXIT_SUCCESS) return result;
573         cout << "Track ID: " << track->fId << "\t";
574
575         result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
576         if (result != EXIT_SUCCESS) return result;
577         cout << "Trigger Record ID: " << track->fTrigRec << endl;
578         
579         result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
580         if (result != EXIT_SUCCESS) return result;
581         cout << "Flags: " << showbase << hex << track->fFlags << dec;
582         
583         // Print the individual trigger bits.
584         AliHLTMUONParticleSign sign;
585         bool hitset[4];
586         AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset);
587         cout << " [Sign: " << sign << ", Hits set on chambers: ";
588         bool first = true;
589         for (AliHLTUInt32_t i = 0; i < 4; i++)
590         {
591                 if (hitset[i])
592                 {
593                         cout << (first ? "" : ", ") << i+7;
594                         first = false;
595                 }
596         }
597         cout << (first ? "none]" : "]") << endl;
598
599         result = CheckField(track->fPx, buffer, bufferSize, continueParse);
600         if (result != EXIT_SUCCESS) return result;
601         cout << "Momentum: (px = " << track->fPx << ", ";
602
603         result = CheckField(track->fPy, buffer, bufferSize, continueParse);
604         if (result != EXIT_SUCCESS) return result;
605         cout << "py = " << track->fPy << ", ";
606
607         result = CheckField(track->fPz, buffer, bufferSize, continueParse);
608         if (result != EXIT_SUCCESS) return result;
609         cout << "pz = " << track->fPz << ") GeV/c\t";
610
611         result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
612         if (result != EXIT_SUCCESS) return result;
613         cout << "Chi squared fit: " << track->fChi2 << endl;
614         
615         cout << "Track hits:" << endl;
616         cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)" << endl;
617         cout << "------------------------------------------------" << endl;
618         const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
619         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
620         {
621                 cout << setw(10) << left << ch + 7 << setw(0);
622                 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
623                 if (result != EXIT_SUCCESS) return result;
624         }
625
626         return result;
627 }
628
629
630 int DumpMansoTracksBlock(
631                 const char* buffer, unsigned long bufferSize,
632                 bool continueParse
633         )
634 {
635         int result = EXIT_SUCCESS;
636         AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize);
637         
638         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
639         if (result != EXIT_SUCCESS and not continueParse) return result;
640         
641         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
642         
643         // Print the data block record entries.
644         const AliHLTMUONMansoTrackStruct* entry = block.GetArray();
645         for(AliHLTUInt32_t i = 0; i < nentries; i++)
646         {
647                 cout << "============================== Manso track number " << i+1
648                         << " of " << nentries << " ==============================" << endl;
649                 int subResult = DumpMansoTrackStruct(buffer, bufferSize, entry++, continueParse);
650                 if (subResult != EXIT_SUCCESS) return subResult;
651         }
652         
653         return result;
654 }
655
656
657 int DumpMansoRoIStruct(
658                 const char* buffer, unsigned long bufferSize,
659                 const AliHLTMUONMansoRoIStruct* roi,
660                 bool continueParse
661         )
662 {
663         // Step through the fields trying to print them.
664         // At each step check if we have not overflowed the buffer. If we have
665         // not, then we can print the field, otherwise we print the left over
666         // bytes assumed to be corrupted rubbish.
667         int result = CheckField(roi->fX, buffer, bufferSize, continueParse);
668         if (result != EXIT_SUCCESS) return result;
669         cout << setw(13) << left << roi->fX << setw(0);
670
671         result = CheckField(roi->fY, buffer, bufferSize, continueParse);
672         if (result != EXIT_SUCCESS) return result;
673         cout << setw(13) << left << roi->fY << setw(0);
674
675         result = CheckField(roi->fZ, buffer, bufferSize, continueParse);
676         if (result != EXIT_SUCCESS) return result;
677         cout << setw(13) << left << roi->fZ << setw(0);
678
679         result = CheckField(roi->fRadius, buffer, bufferSize, continueParse);
680         if (result != EXIT_SUCCESS) return result;
681         cout << roi->fRadius << setw(0) << endl;
682
683         return result;
684 }
685
686
687 int DumpMansoCandidateStruct(
688                 const char* buffer, unsigned long bufferSize,
689                 const AliHLTMUONMansoCandidateStruct* candidate,
690                 bool continueParse
691         )
692 {
693         int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse);
694         if (result != EXIT_SUCCESS) return result;
695         
696         cout << "Regions of interest:" << endl;
697         cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)     | Radius (cm)" << endl;
698         cout << "-------------------------------------------------------------" << endl;
699         const AliHLTMUONMansoRoIStruct* roi = &candidate->fRoI[0];
700         for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
701         {
702                 cout << setw(10) << ch + 7;
703                 result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse);
704                 if (result != EXIT_SUCCESS) return result;
705         }
706         return result;
707 }
708
709
710 int DumpMansoCandidatesBlock(
711                 const char* buffer, unsigned long bufferSize,
712                 bool continueParse
713         )
714 {
715         int result = EXIT_SUCCESS;
716         AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize);
717         
718         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
719         if (result != EXIT_SUCCESS and not continueParse) return result;
720         
721         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
722         
723         // Print the data block record entries.
724         const AliHLTMUONMansoCandidateStruct* entry = block.GetArray();
725         for(AliHLTUInt32_t i = 0; i < nentries; i++)
726         {
727                 cout << "=========================== Manso track candidate number " << i+1
728                         << " of " << nentries << " ===========================" << endl;
729                 int subResult = DumpMansoCandidateStruct(buffer, bufferSize, entry++, continueParse);
730                 if (subResult != EXIT_SUCCESS) return subResult;
731         }
732         
733         return result;
734 }
735
736
737 int DumpSinglesDecisionBlockHeader(
738                 const char* buffer, unsigned long bufferSize,
739                 const AliHLTMUONSinglesDecisionBlockStruct* header,
740                 bool continueParse
741         )
742 {
743         // Step through the header fields trying to print them.
744         // At each step check if we have not overflowed the buffer, if we have
745         // not then we can print the field, otherwise we print the left over
746         // bytes assumed to be corrupted rubbish.
747         int result = CheckHeaderField(header->fNlowPt, buffer, bufferSize, continueParse);
748         if (result != EXIT_SUCCESS) return result;
749         cout << " Number of low pt triggers: " << header->fNlowPt << endl;
750         
751         result = CheckHeaderField(header->fNhighPt, buffer, bufferSize, continueParse);
752         if (result != EXIT_SUCCESS) return result;
753         cout << "Number of high pt triggers: " << header->fNhighPt << endl;
754
755         return result;
756 }
757
758
759 int DumpTrackDecisionStruct(
760                 const char* buffer, unsigned long bufferSize,
761                 const AliHLTMUONTrackDecisionStruct* decision,
762                 bool continueParse
763         )
764 {
765         // Step through the fields trying to print them.
766         // At each step check if we have not overflowed the buffer. If we have
767         // not, then we can print the field, otherwise we print the left over
768         // bytes assumed to be corrupted rubbish.
769         int result = CheckField(decision->fTrackId, buffer, bufferSize, continueParse);
770         if (result != EXIT_SUCCESS) return result;
771         cout << setw(13) << left << decision->fTrackId << setw(0);
772         
773         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
774         if (result != EXIT_SUCCESS) return result;
775         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
776                 << setw(0) << dec;
777                 
778         // Print the individual trigger bits.
779         bool highPt, lowPt;
780         AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
781         cout << setw(7) << left << (highPt ? "yes" : "no");
782         cout << setw(8) << left << (lowPt ? "yes" : "no");
783         cout << setw(0) << endl;
784
785         return result;
786 }
787
788
789 int DumpSinglesDecisionBlock(
790                 const char* buffer, unsigned long bufferSize,
791                 bool continueParse
792         )
793 {
794         int result = EXIT_SUCCESS;
795         AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
796         
797         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
798         if (result != EXIT_SUCCESS and not continueParse) return result;
799         
800         // Dump the rest of the block header.
801         const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
802         int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
803         if (subResult != EXIT_SUCCESS) return subResult;
804         
805         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
806         
807         // Print the data block record entries.
808         cout << "           |        Trigger Bits" << endl;
809         cout << "Track ID   | Raw         HighPt LowPt" << endl;
810         cout << "--------------------------------------" << endl;
811         const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
812         for(AliHLTUInt32_t i = 0; i < nentries; i++)
813         {
814                 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
815                 if (subResult != EXIT_SUCCESS) return subResult;
816         }
817         
818         return result;
819 }
820
821
822 int DumpPairsDecisionBlockHeader(
823                 const char* buffer, unsigned long bufferSize,
824                 const AliHLTMUONPairsDecisionBlockStruct* header,
825                 bool continueParse
826         )
827 {
828         // Step through the header fields trying to print them.
829         // At each step check if we have not overflowed the buffer, if we have
830         // not then we can print the field, otherwise we print the left over
831         // bytes assumed to be corrupted rubbish.
832         int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
833         if (result != EXIT_SUCCESS) return result;
834         cout << "      Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
835         
836         result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
837         if (result != EXIT_SUCCESS) return result;
838         cout << "      Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
839         
840         result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
841         if (result != EXIT_SUCCESS) return result;
842         cout << "     Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
843         
844         result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
845         if (result != EXIT_SUCCESS) return result;
846         cout << "        Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
847         
848         result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
849         if (result != EXIT_SUCCESS) return result;
850         cout << "        Number of like low pt triggers: " << header->fNlikeLowPt << endl;
851         
852         result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
853         if (result != EXIT_SUCCESS) return result;
854         cout << "       Number of like high pt triggers: " << header->fNlikeHighPt << endl;
855         
856         result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
857         if (result != EXIT_SUCCESS) return result;
858         cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
859         
860         result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
861         if (result != EXIT_SUCCESS) return result;
862         cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
863         
864         result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
865         if (result != EXIT_SUCCESS) return result;
866         cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
867         
868         return result;
869 }
870
871
872 int DumpPairDecisionStruct(
873                 const char* buffer, unsigned long bufferSize,
874                 const AliHLTMUONPairDecisionStruct* decision,
875                 bool continueParse
876         )
877 {
878         // Step through the fields trying to print them.
879         // At each step check if we have not overflowed the buffer. If we have
880         // not, then we can print the field, otherwise we print the left over
881         // bytes assumed to be corrupted rubbish.
882         int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
883         if (result != EXIT_SUCCESS) return result;
884         cout << setw(13) << left << decision->fTrackAId << setw(0);
885         
886         result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
887         if (result != EXIT_SUCCESS) return result;
888         cout << setw(13) << left << decision->fTrackBId << setw(0);
889         
890         result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
891         if (result != EXIT_SUCCESS) return result;
892         cout << setw(12) << left << showbase << hex << decision->fTriggerBits
893                 << setw(0) << dec;
894                 
895         // Print the individual trigger bits.
896         bool highMass, lowMass, unlike;
897         AliHLTUInt8_t highPtCount, lowPtCount;
898         AliHLTMUONUtils::UnpackPairDecisionBits(
899                         decision->fTriggerBits,
900                         highMass, lowMass, unlike, highPtCount, lowPtCount
901                 );
902         cout << setw(7) << left << (highMass ? "yes" : "no");
903         cout << setw(7) << left << (lowMass ? "yes" : "no");
904         cout << setw(7) << left << (unlike ? "yes" : "no");
905         cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
906         cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
907         cout << setw(0);
908         
909         result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
910         if (result != EXIT_SUCCESS) return result;
911         cout << decision->fInvMass << endl;
912         
913         return EXIT_SUCCESS;
914 }
915
916
917 int DumpPairsDecisionBlock(
918                 const char* buffer, unsigned long bufferSize,
919                 bool continueParse
920         )
921 {
922         int result = EXIT_SUCCESS;
923         AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
924         
925         result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
926         if (result != EXIT_SUCCESS and not continueParse) return result;
927         
928         // Dump the rest of the block header.
929         const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
930         int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
931         if (subResult != EXIT_SUCCESS) return subResult;
932         
933         AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
934         
935         // Print the data block record entries.
936         cout << "           |            |                Trigger Bits                  |" << endl;
937         cout << "Track A ID | Track B ID | Raw         HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
938         cout << "----------------------------------------------------------------------------------------" << endl;
939         const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
940         for(AliHLTUInt32_t i = 0; i < nentries; i++)
941         {
942                 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
943                 if (subResult != EXIT_SUCCESS) return subResult;
944         }
945         
946         return result;
947 }
948
949
950 int DumpCommonHeader(
951                 const char* buffer, unsigned long bufferSize,
952                 const AliHLTMUONDataBlockHeader* header, bool continueParse
953         )
954 {
955         // Step through the header fields trying to print them.
956         // At each step check if we have not overflowed the buffer, if we have
957         // not then we can print the field, otherwise we print the left over
958         // bytes assumed to be corrupted rubbish.
959         int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
960         if (result != EXIT_SUCCESS) return result;
961         AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
962         cout << "       Block type: " << type << endl;
963         
964         result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
965         if (result != EXIT_SUCCESS) return result;
966         cout << "     Record width: " << header->fRecordWidth << endl;
967         
968         result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
969         if (result != EXIT_SUCCESS) return result;
970         cout << "Number of entries: " << header->fNrecords << endl;
971         
972         return result;
973 }
974
975
976 int ParseBuffer(
977                 const char* buffer, unsigned long bufferSize,
978                 bool continueParse, AliHLTMUONDataBlockType type
979         )
980 {
981         assert( buffer != NULL );
982         int result = EXIT_SUCCESS;
983         
984         if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
985         {
986                 cerr << "ERROR: The size of the file is too small to contain a"
987                         " valid data block." << endl;
988                 result = PARSE_ERROR;
989                 if (not continueParse) return result;
990         }
991         const AliHLTMUONDataBlockHeader* header =
992                 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
993
994         int subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
995         if (subResult != EXIT_SUCCESS) return subResult;
996
997         
998         // Check if the block type in the header corresponds to the type given
999         // by the '-type' command line parameter. If they do not then print an
1000         // error or big fat warning message and force interpretation of the data
1001         // block with the type given by '-type'.
1002         AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
1003         
1004         if (type == kUnknownDataBlock)
1005         {
1006                 // -type not used in the command line so just use what is given
1007                 // by the data block header.
1008                 type = headerType;
1009         }
1010         else if (type != headerType)
1011         {
1012                 cerr << "WARNING: The data block header indicates a type"
1013                         " different from what was specified on the command line."
1014                         " The data could be corrupt."
1015                         << endl;
1016                 cerr << "WARNING: The type value in the file is "
1017                         << showbase << hex << header->fType
1018                         << " (" << headerType << "), but on the command line it is "
1019                         << showbase << hex << int(type) << dec
1020                         << " (" << type << ")."
1021                         << endl;
1022                 cerr << "WARNING: Will force the interpretation of the data block"
1023                         " with a type of " << type << "." << endl;
1024         }
1025         
1026         // Now we know what type the data block is supposed to be so we can
1027         // dump it to screen with the appropriate dump routine.
1028         switch (type)
1029         {
1030         case kTriggerRecordsDataBlock:
1031                 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
1032                 if (subResult != EXIT_SUCCESS) result = subResult;
1033                 break;
1034         case kTrigRecsDebugDataBlock:
1035                 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
1036                 if (subResult != EXIT_SUCCESS) result = subResult;
1037                 break;
1038         case kTriggerChannelsDataBlock:
1039                 subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse);
1040                 if (subResult != EXIT_SUCCESS) result = subResult;
1041                 break;
1042         case kRecHitsDataBlock:
1043                 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
1044                 if (subResult != EXIT_SUCCESS) result = subResult;
1045                 break;
1046         case kClustersDataBlock:
1047                 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
1048                 if (subResult != EXIT_SUCCESS) result = subResult;
1049                 break;
1050         case kChannelsDataBlock:
1051                 return DumpChannelsBlock(buffer, bufferSize, continueParse);
1052                 if (subResult != EXIT_SUCCESS) result = subResult;
1053                 break;
1054         case kMansoTracksDataBlock:
1055                 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
1056                 if (subResult != EXIT_SUCCESS) result = subResult;
1057                 break;
1058         case kMansoCandidatesDataBlock:
1059                 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
1060                 if (subResult != EXIT_SUCCESS) result = subResult;
1061                 break;
1062         case kSinglesDecisionDataBlock:
1063                 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
1064                 if (subResult != EXIT_SUCCESS) result = subResult;
1065                 break;
1066         case kPairsDecisionDataBlock:
1067                 return DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
1068                 if (subResult != EXIT_SUCCESS) result = subResult;
1069                 break;
1070         default :
1071                 cout << "ERROR: Unknown data block type. Found a type number of "
1072                         << showbase << hex << int(type) << dec
1073                         << " (" << int(type) << ")." << endl;
1074                 result = PARSE_ERROR;
1075         }
1076         
1077         return result;
1078 }
1079
1080
1081 /**
1082  * The caller is responsible for freeing memory allocated for buffer with a call
1083  * to delete [] buffer.
1084  */
1085 int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
1086 {
1087         assert( filename != NULL );
1088         
1089         // Open the file and find its size.
1090         fstream file;
1091         file.open(filename, ios::in);
1092         if (not file)
1093         {
1094                 cerr << "ERROR: Could not open the file: " << filename << endl;
1095                 return SYSTEM_ERROR;
1096         }
1097         file.seekg(0, ios::end);
1098         if (not file)
1099         {
1100                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1101                 return SYSTEM_ERROR;
1102         }
1103         bufferSize = file.tellg();
1104         if (not file)
1105         {
1106                 cerr << "ERROR: Could not get file size for the file: " <<
1107                         filename << endl;
1108                 return SYSTEM_ERROR;
1109         }
1110         file.seekg(0, ios::beg);
1111         if (not file)
1112         {
1113                 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1114                 return SYSTEM_ERROR;
1115         }
1116         
1117         // Allocate the memory for the file.
1118         try
1119         {
1120                 buffer = new char[bufferSize];
1121         }
1122         catch (const std::bad_alloc&)
1123         {
1124                 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
1125                         << " bytes." << endl;
1126                 return SYSTEM_ERROR;
1127         }
1128         
1129         file.read(buffer, bufferSize);
1130         if (not file)
1131         {
1132                 delete [] buffer;
1133                 buffer = NULL;
1134                 bufferSize = 0;
1135                 cerr << "ERROR: Could not read from file: " << filename << endl;
1136                 return SYSTEM_ERROR;
1137         }
1138         
1139         file.close();
1140         if (not file)
1141         {
1142                 delete [] buffer;
1143                 buffer = NULL;
1144                 bufferSize = 0;
1145                 cerr << "ERROR: Could not close the file: " << filename << endl;
1146                 return SYSTEM_ERROR;
1147         }
1148         
1149         return EXIT_SUCCESS;
1150 }
1151
1152 /**
1153  * Prints the command line usage of this program to standard error.
1154  */
1155 void PrintUsage()
1156 {
1157         cerr << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
1158         cerr << "Where <filename> is the name of a file containing a raw data block." << endl;
1159         cerr << "Options:" << endl;
1160         cerr << " -help | -h" << endl;
1161         cerr << "       Displays this message." << endl;
1162         cerr << " -continue" << endl;
1163         cerr << "       If specified, the program will try to continue parsing the data block" << endl;
1164         cerr << "       as much as possible rather than stopping at the first error." << endl;
1165         cerr << " -type <typename>" << endl;
1166         cerr << "       Forces the contents of the file to be interpreted as a specific" << endl;
1167         cerr << "       type of data block. Where <typename> can be one of:" << endl;
1168         cerr << "         trigrecs - trigger records data." << endl;
1169         cerr << "         trigrecsdebug - debugging information about trigger records." << endl;
1170         cerr << "         trigchannels - channel debugging in." << endl;
1171         cerr << "         rechits - reconstructed hits data." << endl;
1172         cerr << "         channels - channel debugging information from hit reconstruction." << endl;
1173         cerr << "         clusters - cluster debugging information from hit reconstruction." << endl;
1174         cerr << "         mansotracks - partial tracks from Manso algorithm." << endl;
1175         cerr << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
1176         cerr << "         singlesdecision - trigger decisions for single tracks." << endl;
1177         cerr << "         pairsdecision - trigger decisions for track pairs." << endl;
1178 }
1179
1180 /**
1181  * Parse the string passed as the type of the block and return the corresponding
1182  * AliHLTMUONDataBlockType value.
1183  */
1184 AliHLTMUONDataBlockType ParseCommandLineType(const char* type)
1185 {
1186         if (strcmp(type, "trigrecs") == 0)
1187         {
1188                 return kTriggerRecordsDataBlock;
1189         }
1190         else if (strcmp(type, "trigrecsdebug") == 0)
1191         {
1192                 return kTrigRecsDebugDataBlock;
1193         }
1194         else if (strcmp(type, "trigchannels") == 0)
1195         {
1196                 return kTriggerChannelsDataBlock;
1197         }
1198         else if (strcmp(type, "rechits") == 0)
1199         {      
1200                 return kRecHitsDataBlock;
1201         }
1202         else if (strcmp(type,"channels") == 0)
1203         {
1204                 return kChannelsDataBlock;
1205         }
1206         else if (strcmp(type,"clusters") == 0)
1207         {
1208                 return kClustersDataBlock;
1209         }
1210         else if (strcmp(type, "mansotracks") == 0)
1211         {
1212                 return kMansoTracksDataBlock;
1213         }
1214         else if (strcmp(type, "mansocandidates") == 0)
1215         {
1216                 return kMansoCandidatesDataBlock;
1217         }
1218         else if (strcmp(type, "singlesdecision") == 0)
1219         {
1220                 return kSinglesDecisionDataBlock;
1221         }
1222         else if (strcmp(type, "pairsdecision") == 0)
1223         {
1224                 return kPairsDecisionDataBlock;
1225         }
1226         
1227         cerr << "ERROR: Invalid type name '" << type << "' specified for argument -type."
1228                 << endl << endl;
1229         PrintUsage();
1230         return kUnknownDataBlock;
1231 }
1232
1233 /**
1234  * Parses the command line.
1235  * @param argc  Number of arguments as given in main().
1236  * @param argv  Array of arguments as given in main().
1237  * @param filename  Receives the pointer to the file name string.
1238  * @param type      Receives the type of the data block expected, i.e. the
1239  *                  value of the -type flag.
1240  * @return  A status flag suitable for returning from main(), containing either
1241  *          EXIT_SUCCESS or CMDLINE_ERROR.
1242  */
1243 int ParseCommandLine(
1244                 int argc, const char** argv,
1245                 const char*& filename, bool& continueParse,
1246                 AliHLTMUONDataBlockType& type
1247         )
1248 {
1249         filename = NULL;
1250         continueParse = false;
1251
1252         // Parse the command line.
1253         for (int i = 1; i < argc; i++)
1254         {
1255                 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0)
1256                 {
1257                         PrintUsage();
1258                         return EXIT_SUCCESS;
1259                 }
1260                 else if (strcmp(argv[i], "-continue") == 0)
1261                 {
1262                         continueParse = true;
1263                 }
1264                 else if (strcmp(argv[i], "-type") == 0)
1265                 {
1266                         // Now we need to parse the typename in the command line.
1267                         type = ParseCommandLineType(argv[++i]);
1268                         if (type == kUnknownDataBlock) return CMDLINE_ERROR;
1269                 }
1270                 else
1271                 {
1272                         if (filename != NULL)
1273                         {
1274                                 cerr << "ERROR: Only one file can be specified, but got '"
1275                                         << argv[i] << "', with '" << filename
1276                                         << "' specified earlier." << endl << endl;
1277                                 PrintUsage();
1278                                 return CMDLINE_ERROR;
1279                         }
1280                         else
1281                                 filename = argv[i];
1282                 }
1283         }
1284         
1285         // Now check that we have the filename and all the flags we need.
1286         if (filename == NULL)
1287         {
1288                 cerr << "ERROR: Missing a file name. You must specify a file to process."
1289                         << endl << endl;
1290                 PrintUsage();
1291                 return CMDLINE_ERROR;
1292         }
1293         
1294         return EXIT_SUCCESS;
1295 }
1296
1297
1298 int main(int argc, const char** argv)
1299 {
1300         const char* filename = NULL;
1301         bool continueParse = false;
1302         int returnCode = EXIT_SUCCESS;
1303         AliHLTMUONDataBlockType type = kUnknownDataBlock;
1304         char* buffer = NULL;
1305
1306         try
1307         {
1308                 returnCode = ParseCommandLine(argc, argv, filename, continueParse, type);
1309
1310                 if (returnCode == EXIT_SUCCESS and filename != NULL)
1311                 {
1312                         unsigned long bufferSize = 0;
1313                         returnCode = ReadFile(filename, buffer, bufferSize);
1314                         if (returnCode == EXIT_SUCCESS)
1315                                 returnCode = ParseBuffer(buffer, bufferSize, continueParse, type);
1316                         if (buffer != NULL) delete [] buffer;
1317                 }
1318                 
1319         }
1320         catch (...)
1321         {
1322                 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
1323                 returnCode = FATAL_ERROR;
1324                 if (buffer != NULL) delete [] buffer;
1325         }
1326
1327         return returnCode;
1328 }