Detecting endianess of platform at runtime and generating warning if not on a little...
[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#include <cstdlib>
3dad52b0 40#include <cassert>
41#include <new>
42#include <fstream>
43
44#include <iostream>
45using std::cout;
46using std::cerr;
47using std::endl;
48using std::showbase;
49using std::noshowbase;
50using std::hex;
51using std::dec;
52
53#include <iomanip>
54using std::setw;
55using std::left;
56using 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
65void 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
83template <typename FieldType>
84int 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
108template <typename FieldType>
109int 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
133template <typename BlockType>
134int CheckCommonHeader(
63ae97e0 135 BlockType& block, const char* /*buffer*/, unsigned long bufferSize,
3dad52b0 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
168template <typename BlockType>
169AliHLTUInt32_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
a68bc1e6 191int DumpRecHitStruct(
3dad52b0 192 const char* buffer, unsigned long bufferSize,
a68bc1e6 193 const AliHLTMUONRecHitStruct* hit,
3dad52b0 194 bool continueParse
195 )
196{
a68bc1e6 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;
3dad52b0 214}
215
216
a68bc1e6 217int DumpRecHitsBlock(
3dad52b0 218 const char* buffer, unsigned long bufferSize,
219 bool continueParse
220 )
221{
a68bc1e6 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;
3dad52b0 241}
242
243
a68bc1e6 244int 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
306int DumpTriggerRecordsBlock(
3dad52b0 307 const char* buffer, unsigned long bufferSize,
308 bool continueParse
309 )
310{
a68bc1e6 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
3dad52b0 328 return EXIT_SUCCESS;
329}
330
331
a68bc1e6 332int 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
361int DumpTrigRecsDebugBlock(
3dad52b0 362 const char* buffer, unsigned long bufferSize,
3dad52b0 363 bool continueParse
364 )
a68bc1e6 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
387int DumpTriggerChannelStruct(const char* buffer, unsigned long bufferSize,
388 const AliHLTMUONTriggerChannelStruct* triggerchannel,
389 bool continueParse
390 )
3dad52b0 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.
a68bc1e6 396 int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse);
3dad52b0 397 if (result != EXIT_SUCCESS) return result;
a68bc1e6 398 cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0);
3dad52b0 399
a68bc1e6 400 result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse);
3dad52b0 401 if (result != EXIT_SUCCESS) return result;
a68bc1e6 402 cout << setw(13) << left << triggerchannel->fChamber << setw(0);
3dad52b0 403
a68bc1e6 404 result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse);
3dad52b0 405 if (result != EXIT_SUCCESS) return result;
a68bc1e6 406 cout << setw(10) << left << triggerchannel->fSignal << setw(0);
3dad52b0 407
a68bc1e6 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;
3dad52b0 411 return result;
412}
413
414
a68bc1e6 415int DumpTriggerChannelsBlock(
3dad52b0 416 const char* buffer, unsigned long bufferSize,
417 bool continueParse
418 )
419{
a68bc1e6 420 int result = EXIT_SUCCESS;
421 AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
3dad52b0 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.
a68bc1e6 429 cout << " Trigger Record ID | Chamber | Signal | Raw Data Word " << endl;
430 cout << "--------------------------------------------------------------" << endl;
431 const AliHLTMUONTriggerChannelStruct* entry = block.GetArray();
3dad52b0 432 for(AliHLTUInt32_t i = 0; i < nentries; i++)
433 {
a68bc1e6 434 int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse);
3dad52b0 435 if (subResult != EXIT_SUCCESS) return subResult;
436 }
a68bc1e6 437
438 return result;
439}
440
441
442int 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
3dad52b0 470 return result;
471}
472
473
474int DumpClustersBlock(
475 const char* buffer, unsigned long bufferSize,
476 bool continueParse
477 )
478{
a68bc1e6 479 int result = EXIT_SUCCESS;
3dad52b0 480 AliHLTMUONClustersBlockReader block(buffer, bufferSize);
a68bc1e6 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
501int 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;
3dad52b0 532}
533
534
535int DumpChannelsBlock(
536 const char* buffer, unsigned long bufferSize,
537 bool continueParse
538 )
539{
a68bc1e6 540 int result = EXIT_SUCCESS;
3dad52b0 541 AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
a68bc1e6 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 }
3dad52b0 557 return EXIT_SUCCESS;
558}
559
560
561int 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;
a68bc1e6 582
3dad52b0 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 {
a68bc1e6 621 cout << setw(10) << left << ch + 7 << setw(0);
3dad52b0 622 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
623 if (result != EXIT_SUCCESS) return result;
624 }
625
626 return result;
627}
628
629
630int 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
657int 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
687int 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
710int 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
737int 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
759int 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");
c9537879 783
784 result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
785 if (result != EXIT_SUCCESS) return result;
786 cout << setw(0) << decision->fPt << endl;
3dad52b0 787
788 return result;
789}
790
791
792int DumpSinglesDecisionBlock(
793 const char* buffer, unsigned long bufferSize,
794 bool continueParse
795 )
796{
797 int result = EXIT_SUCCESS;
798 AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
799
800 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
801 if (result != EXIT_SUCCESS and not continueParse) return result;
802
803 // Dump the rest of the block header.
804 const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
805 int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
806 if (subResult != EXIT_SUCCESS) return subResult;
807
808 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
809
810 // Print the data block record entries.
c9537879 811 cout << " | Trigger Bits |" << endl;
812 cout << "Track ID | Raw HighPt LowPt | pT" << endl;
813 cout << "----------------------------------------------------" << endl;
3dad52b0 814 const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
815 for(AliHLTUInt32_t i = 0; i < nentries; i++)
816 {
817 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
818 if (subResult != EXIT_SUCCESS) return subResult;
819 }
820
821 return result;
822}
823
824
825int DumpPairsDecisionBlockHeader(
826 const char* buffer, unsigned long bufferSize,
827 const AliHLTMUONPairsDecisionBlockStruct* header,
828 bool continueParse
829 )
830{
831 // Step through the header fields trying to print them.
832 // At each step check if we have not overflowed the buffer, if we have
833 // not then we can print the field, otherwise we print the left over
834 // bytes assumed to be corrupted rubbish.
835 int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
836 if (result != EXIT_SUCCESS) return result;
837 cout << " Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
838
839 result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
840 if (result != EXIT_SUCCESS) return result;
841 cout << " Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
842
843 result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
844 if (result != EXIT_SUCCESS) return result;
845 cout << " Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
846
847 result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
848 if (result != EXIT_SUCCESS) return result;
849 cout << " Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
850
851 result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
852 if (result != EXIT_SUCCESS) return result;
853 cout << " Number of like low pt triggers: " << header->fNlikeLowPt << endl;
854
855 result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
856 if (result != EXIT_SUCCESS) return result;
857 cout << " Number of like high pt triggers: " << header->fNlikeHighPt << endl;
858
859 result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
860 if (result != EXIT_SUCCESS) return result;
861 cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
862
863 result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
864 if (result != EXIT_SUCCESS) return result;
865 cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
866
867 result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
868 if (result != EXIT_SUCCESS) return result;
869 cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
870
871 return result;
872}
873
874
875int DumpPairDecisionStruct(
876 const char* buffer, unsigned long bufferSize,
877 const AliHLTMUONPairDecisionStruct* decision,
878 bool continueParse
879 )
880{
881 // Step through the fields trying to print them.
882 // At each step check if we have not overflowed the buffer. If we have
883 // not, then we can print the field, otherwise we print the left over
884 // bytes assumed to be corrupted rubbish.
885 int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
886 if (result != EXIT_SUCCESS) return result;
887 cout << setw(13) << left << decision->fTrackAId << setw(0);
888
889 result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
890 if (result != EXIT_SUCCESS) return result;
891 cout << setw(13) << left << decision->fTrackBId << setw(0);
892
893 result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
894 if (result != EXIT_SUCCESS) return result;
895 cout << setw(12) << left << showbase << hex << decision->fTriggerBits
896 << setw(0) << dec;
897
898 // Print the individual trigger bits.
899 bool highMass, lowMass, unlike;
900 AliHLTUInt8_t highPtCount, lowPtCount;
901 AliHLTMUONUtils::UnpackPairDecisionBits(
902 decision->fTriggerBits,
903 highMass, lowMass, unlike, highPtCount, lowPtCount
904 );
905 cout << setw(7) << left << (highMass ? "yes" : "no");
906 cout << setw(7) << left << (lowMass ? "yes" : "no");
907 cout << setw(7) << left << (unlike ? "yes" : "no");
908 cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
909 cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
910 cout << setw(0);
911
912 result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
913 if (result != EXIT_SUCCESS) return result;
914 cout << decision->fInvMass << endl;
915
916 return EXIT_SUCCESS;
917}
918
919
920int DumpPairsDecisionBlock(
921 const char* buffer, unsigned long bufferSize,
922 bool continueParse
923 )
924{
925 int result = EXIT_SUCCESS;
926 AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
927
928 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
929 if (result != EXIT_SUCCESS and not continueParse) return result;
930
931 // Dump the rest of the block header.
932 const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
933 int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
934 if (subResult != EXIT_SUCCESS) return subResult;
935
936 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
937
938 // Print the data block record entries.
939 cout << " | | Trigger Bits |" << endl;
940 cout << "Track A ID | Track B ID | Raw HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
941 cout << "----------------------------------------------------------------------------------------" << endl;
942 const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
943 for(AliHLTUInt32_t i = 0; i < nentries; i++)
944 {
945 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
946 if (subResult != EXIT_SUCCESS) return subResult;
947 }
948
949 return result;
950}
951
952
953int DumpCommonHeader(
954 const char* buffer, unsigned long bufferSize,
955 const AliHLTMUONDataBlockHeader* header, bool continueParse
956 )
957{
958 // Step through the header fields trying to print them.
959 // At each step check if we have not overflowed the buffer, if we have
960 // not then we can print the field, otherwise we print the left over
961 // bytes assumed to be corrupted rubbish.
962 int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
963 if (result != EXIT_SUCCESS) return result;
964 AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
965 cout << " Block type: " << type << endl;
966
967 result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
968 if (result != EXIT_SUCCESS) return result;
969 cout << " Record width: " << header->fRecordWidth << endl;
970
971 result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
972 if (result != EXIT_SUCCESS) return result;
973 cout << "Number of entries: " << header->fNrecords << endl;
974
975 return result;
976}
977
978
979int ParseBuffer(
980 const char* buffer, unsigned long bufferSize,
981 bool continueParse, AliHLTMUONDataBlockType type
982 )
983{
984 assert( buffer != NULL );
985 int result = EXIT_SUCCESS;
986
987 if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
988 {
989 cerr << "ERROR: The size of the file is too small to contain a"
990 " valid data block." << endl;
991 result = PARSE_ERROR;
992 if (not continueParse) return result;
993 }
994 const AliHLTMUONDataBlockHeader* header =
995 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
996
997 int subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
998 if (subResult != EXIT_SUCCESS) return subResult;
999
1000
1001 // Check if the block type in the header corresponds to the type given
1002 // by the '-type' command line parameter. If they do not then print an
1003 // error or big fat warning message and force interpretation of the data
1004 // block with the type given by '-type'.
1005 AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
1006
1007 if (type == kUnknownDataBlock)
1008 {
1009 // -type not used in the command line so just use what is given
1010 // by the data block header.
1011 type = headerType;
1012 }
1013 else if (type != headerType)
1014 {
1015 cerr << "WARNING: The data block header indicates a type"
1016 " different from what was specified on the command line."
1017 " The data could be corrupt."
1018 << endl;
1019 cerr << "WARNING: The type value in the file is "
1020 << showbase << hex << header->fType
1021 << " (" << headerType << "), but on the command line it is "
1022 << showbase << hex << int(type) << dec
1023 << " (" << type << ")."
1024 << endl;
1025 cerr << "WARNING: Will force the interpretation of the data block"
1026 " with a type of " << type << "." << endl;
1027 }
1028
1029 // Now we know what type the data block is supposed to be so we can
1030 // dump it to screen with the appropriate dump routine.
1031 switch (type)
1032 {
1033 case kTriggerRecordsDataBlock:
1034 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
1035 if (subResult != EXIT_SUCCESS) result = subResult;
1036 break;
1037 case kTrigRecsDebugDataBlock:
1038 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
1039 if (subResult != EXIT_SUCCESS) result = subResult;
1040 break;
1041 case kTriggerChannelsDataBlock:
1042 subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse);
1043 if (subResult != EXIT_SUCCESS) result = subResult;
1044 break;
1045 case kRecHitsDataBlock:
1046 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
1047 if (subResult != EXIT_SUCCESS) result = subResult;
1048 break;
1049 case kClustersDataBlock:
1050 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
1051 if (subResult != EXIT_SUCCESS) result = subResult;
1052 break;
1053 case kChannelsDataBlock:
1054 return DumpChannelsBlock(buffer, bufferSize, continueParse);
1055 if (subResult != EXIT_SUCCESS) result = subResult;
1056 break;
1057 case kMansoTracksDataBlock:
1058 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
1059 if (subResult != EXIT_SUCCESS) result = subResult;
1060 break;
1061 case kMansoCandidatesDataBlock:
1062 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
1063 if (subResult != EXIT_SUCCESS) result = subResult;
1064 break;
1065 case kSinglesDecisionDataBlock:
1066 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
1067 if (subResult != EXIT_SUCCESS) result = subResult;
1068 break;
1069 case kPairsDecisionDataBlock:
1070 return DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
1071 if (subResult != EXIT_SUCCESS) result = subResult;
1072 break;
1073 default :
1074 cout << "ERROR: Unknown data block type. Found a type number of "
1075 << showbase << hex << int(type) << dec
1076 << " (" << int(type) << ")." << endl;
1077 result = PARSE_ERROR;
1078 }
1079
1080 return result;
1081}
1082
1083
1084/**
1085 * The caller is responsible for freeing memory allocated for buffer with a call
1086 * to delete [] buffer.
1087 */
1088int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
1089{
1090 assert( filename != NULL );
1091
1092 // Open the file and find its size.
1093 fstream file;
1094 file.open(filename, ios::in);
1095 if (not file)
1096 {
1097 cerr << "ERROR: Could not open the file: " << filename << endl;
1098 return SYSTEM_ERROR;
1099 }
1100 file.seekg(0, ios::end);
1101 if (not file)
1102 {
1103 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1104 return SYSTEM_ERROR;
1105 }
1106 bufferSize = file.tellg();
1107 if (not file)
1108 {
1109 cerr << "ERROR: Could not get file size for the file: " <<
1110 filename << endl;
1111 return SYSTEM_ERROR;
1112 }
1113 file.seekg(0, ios::beg);
1114 if (not file)
1115 {
1116 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1117 return SYSTEM_ERROR;
1118 }
1119
1120 // Allocate the memory for the file.
1121 try
1122 {
1123 buffer = new char[bufferSize];
1124 }
1125 catch (const std::bad_alloc&)
1126 {
1127 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
1128 << " bytes." << endl;
1129 return SYSTEM_ERROR;
1130 }
1131
1132 file.read(buffer, bufferSize);
1133 if (not file)
1134 {
1135 delete [] buffer;
1136 buffer = NULL;
1137 bufferSize = 0;
1138 cerr << "ERROR: Could not read from file: " << filename << endl;
1139 return SYSTEM_ERROR;
1140 }
1141
1142 file.close();
1143 if (not file)
1144 {
1145 delete [] buffer;
1146 buffer = NULL;
1147 bufferSize = 0;
1148 cerr << "ERROR: Could not close the file: " << filename << endl;
1149 return SYSTEM_ERROR;
1150 }
1151
1152 return EXIT_SUCCESS;
1153}
1154
1155/**
1156 * Prints the command line usage of this program to standard error.
1157 */
c9537879 1158void PrintUsage(bool asError = true)
3dad52b0 1159{
c9537879 1160 std::ostream& os = asError ? cerr : cout;
1161 os << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
1162 os << "Where <filename> is the name of a file containing a raw data block." << endl;
1163 os << "Options:" << endl;
1164 os << " -help | -h" << endl;
1165 os << " Displays this message." << endl;
1166 os << " -continue" << endl;
1167 os << " If specified, the program will try to continue parsing the data block" << endl;
1168 os << " as much as possible rather than stopping at the first error." << endl;
1169 os << " -type <typename>" << endl;
1170 os << " Forces the contents of the subsequent files specified on the command" << endl;
1171 os << " line to be interpreted as a specific type of data block." << endl;
1172 os << " Where <typename> can be one of:" << endl;
1173 os << " trigrecs - trigger records data." << endl;
1174 os << " trigrecsdebug - debugging information about trigger records." << endl;
1175 os << " trigchannels - channel debugging in." << endl;
1176 os << " rechits - reconstructed hits data." << endl;
1177 os << " channels - channel debugging information from hit reconstruction." << endl;
1178 os << " clusters - cluster debugging information from hit reconstruction." << endl;
1179 os << " mansotracks - partial tracks from Manso algorithm." << endl;
1180 os << " mansocandidates - track candidates considered in the Manso algorithm." << endl;
1181 os << " singlesdecision - trigger decisions for single tracks." << endl;
1182 os << " pairsdecision - trigger decisions for track pairs." << endl;
1183 os << " autodetect - the type of the data block will be automatically" << endl;
1184 os << " detected." << endl;
3dad52b0 1185}
1186
1187/**
1188 * Parse the string passed as the type of the block and return the corresponding
1189 * AliHLTMUONDataBlockType value.
1190 */
1191AliHLTMUONDataBlockType ParseCommandLineType(const char* type)
1192{
1193 if (strcmp(type, "trigrecs") == 0)
1194 {
1195 return kTriggerRecordsDataBlock;
1196 }
1197 else if (strcmp(type, "trigrecsdebug") == 0)
1198 {
1199 return kTrigRecsDebugDataBlock;
1200 }
1201 else if (strcmp(type, "trigchannels") == 0)
1202 {
1203 return kTriggerChannelsDataBlock;
1204 }
1205 else if (strcmp(type, "rechits") == 0)
1206 {
1207 return kRecHitsDataBlock;
1208 }
1209 else if (strcmp(type,"channels") == 0)
1210 {
1211 return kChannelsDataBlock;
1212 }
1213 else if (strcmp(type,"clusters") == 0)
1214 {
1215 return kClustersDataBlock;
1216 }
1217 else if (strcmp(type, "mansotracks") == 0)
1218 {
1219 return kMansoTracksDataBlock;
1220 }
1221 else if (strcmp(type, "mansocandidates") == 0)
1222 {
1223 return kMansoCandidatesDataBlock;
1224 }
1225 else if (strcmp(type, "singlesdecision") == 0)
1226 {
1227 return kSinglesDecisionDataBlock;
1228 }
1229 else if (strcmp(type, "pairsdecision") == 0)
1230 {
1231 return kPairsDecisionDataBlock;
1232 }
1233
1234 cerr << "ERROR: Invalid type name '" << type << "' specified for argument -type."
1235 << endl << endl;
1236 PrintUsage();
1237 return kUnknownDataBlock;
1238}
1239
1240/**
1241 * Parses the command line.
1242 * @param argc Number of arguments as given in main().
1243 * @param argv Array of arguments as given in main().
c9537879 1244 * @param filenames Pointer to buffer storing file name strings.
1245 * @param numOfFiles Receives the number of file name strings that were found
1246 * and added to 'filenames'.
1247 * @param filetypes Array that receives the type of the data block expected, i.e.
1248 * the value of the -type flag for the corresponding file.
3dad52b0 1249 * @return A status flag suitable for returning from main(), containing either
1250 * EXIT_SUCCESS or CMDLINE_ERROR.
1251 */
1252int ParseCommandLine(
c9537879 1253 int argc,
1254 const char** argv,
1255 const char** filenames,
1256 int& numOfFiles,
1257 bool& continueParse,
1258 AliHLTMUONDataBlockType* filetypes
3dad52b0 1259 )
1260{
c9537879 1261 numOfFiles = 0;
3dad52b0 1262 continueParse = false;
c9537879 1263 AliHLTMUONDataBlockType currentType = kUnknownDataBlock;
3dad52b0 1264
1265 // Parse the command line.
1266 for (int i = 1; i < argc; i++)
1267 {
1268 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0)
1269 {
c9537879 1270 PrintUsage(false);
3dad52b0 1271 return EXIT_SUCCESS;
1272 }
1273 else if (strcmp(argv[i], "-continue") == 0)
1274 {
1275 continueParse = true;
1276 }
1277 else if (strcmp(argv[i], "-type") == 0)
1278 {
c9537879 1279 if (++i >= argc)
3dad52b0 1280 {
c9537879 1281 cerr << "ERROR: Missing a type specifier" << endl;
3dad52b0 1282 PrintUsage();
1283 return CMDLINE_ERROR;
1284 }
c9537879 1285 // Now we need to parse the typename in the command line.
1286 if (strcmp(argv[i], "autodetect") == 0)
1287 {
1288 currentType = kUnknownDataBlock;
1289 }
3dad52b0 1290 else
c9537879 1291 {
1292 currentType = ParseCommandLineType(argv[i]);
1293 if (currentType == kUnknownDataBlock) return CMDLINE_ERROR;
1294 }
1295 }
1296 else
1297 {
1298 assert( numOfFiles < argc );
1299 filenames[numOfFiles] = argv[i];
1300 filetypes[numOfFiles] = currentType;
1301 numOfFiles++;
3dad52b0 1302 }
1303 }
1304
c9537879 1305 // Now check that we have at least one filename and all the flags we need.
1306 if (numOfFiles == 0)
3dad52b0 1307 {
c9537879 1308 cerr << "ERROR: Missing a file name. You must specify at least one file to process."
3dad52b0 1309 << endl << endl;
1310 PrintUsage();
1311 return CMDLINE_ERROR;
1312 }
1313
1314 return EXIT_SUCCESS;
1315}
1316
1317
1318int main(int argc, const char** argv)
1319{
1120d5de 1320 // Test endianess of this machine during runtime and print warning if it is not
1321 // little endian.
1322 union
1323 {
1324 int dword;
1325 char byte[4];
1326 } endianTest;
1327 endianTest.dword = 0x1;
1328 if (endianTest.byte[0] != 0x1)
1329 {
1330 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
1331 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
1332 cerr << "!! !!" << endl;
1333 cerr << "!! This is not a little endian machine, but dHLT raw data is normally !!" << endl;
1334 cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
1335 cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
1336 cerr << "!! output. !!" << endl;
1337 cerr << "!! !!" << endl;
1338 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
1339 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
1340 cerr << endl;
1341 }
1342
1343
c9537879 1344 int numOfFiles = 0;
3dad52b0 1345 bool continueParse = false;
1346 int returnCode = EXIT_SUCCESS;
3dad52b0 1347 char* buffer = NULL;
1348
1349 try
1350 {
c9537879 1351 // There will be at least 'argc' number of filenames.
1352 typedef const char* AnsiString;
1353 const char** filename = new AnsiString[argc];
1354 AliHLTMUONDataBlockType* filetype = new AliHLTMUONDataBlockType[argc];
1355
1356 returnCode = ParseCommandLine(argc, argv, filename, numOfFiles, continueParse, filetype);
3dad52b0 1357
c9537879 1358 if (returnCode == EXIT_SUCCESS)
3dad52b0 1359 {
c9537879 1360 for (int i = 0; i < numOfFiles; i++)
1361 {
1362 unsigned long bufferSize = 0;
1363 returnCode = ReadFile(filename[i], buffer, bufferSize);
1364 if (returnCode != EXIT_SUCCESS) break;
a2be583d 1365 if (numOfFiles > 1)
1366 {
1367 cout << "########## Start of dump for file: " << filename[i] << " ##########" << endl;
1368 }
c9537879 1369 int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]);
1370 if (buffer != NULL) delete [] buffer;
1371 if (result != EXIT_SUCCESS)
1372 {
1373 returnCode = result;
1374 if (not continueParse) break;
1375 }
a2be583d 1376 if (numOfFiles > 1)
1377 {
1378 cout << "########## End of dump for file: " << filename[i] << " ##########" << endl;
1379 }
c9537879 1380 }
3dad52b0 1381 }
1382
c9537879 1383 delete [] filename;
1384 delete [] filetype;
3dad52b0 1385 }
1386 catch (...)
1387 {
1388 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
1389 returnCode = FATAL_ERROR;
1390 if (buffer != NULL) delete [] buffer;
1391 }
c9537879 1392
3dad52b0 1393 return returnCode;
1394}