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