1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 * @file dHLTdumpraw.cxx
20 * @author Artur Szostak <artursz@iafrica.com>,
21 * Seforo Mohlalisi <seforomohlalisi@yahoo.co.uk>
23 * @brief Command line utility to dump dHLT's internal raw data blocks.
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.
32 #include "AliHLTMUONDataBlockReader.h"
33 #if defined(DEBUG) && defined(NDEBUG)
37 #include "AliHLTMUONUtils.h"
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
41 * Handle this with #ifdef __APPLE__ ?
44 #error Handling of internal data for non little endian machines not yet implemented.
58 using std::noshowbase;
68 #define CMDLINE_ERROR 1
70 #define SYSTEM_ERROR 3
74 void PrintRubbishData(AliHLTUInt32_t offset, const char* padByte, AliHLTUInt32_t padCount)
76 if (padCount == 0) return;
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++)
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"
92 template <typename FieldType>
94 FieldType& field, const char* buffer, unsigned long bufferSize,
98 const char* fieldptr = reinterpret_cast<const char*>(&field);
99 const char* endptr = buffer + bufferSize;
100 AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
102 if (bufferRemaining < sizeof(field))
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;
108 AliHLTUInt32_t offset = fieldptr - buffer;
109 PrintRubbishData(offset, fieldptr, bufferRemaining);
117 template <typename FieldType>
119 FieldType& field, const char* buffer, unsigned long bufferSize,
123 const char* fieldptr = reinterpret_cast<const char*>(&field);
124 const char* endptr = buffer + bufferSize;
125 AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
127 if (bufferRemaining < sizeof(field))
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;
133 AliHLTUInt32_t offset = fieldptr - buffer;
134 PrintRubbishData(offset, fieldptr, bufferRemaining);
142 template <typename BlockType>
143 int CheckCommonHeader(
144 BlockType& block, const char* buffer, unsigned long bufferSize,
148 int result = EXIT_SUCCESS;
150 // Check the fRecordWidth field in the common header.
151 if (block.CommonBlockHeader().fRecordWidth !=
152 sizeof(typename BlockType::ElementType))
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;
163 if (not block.BufferSizeOk())
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;
177 template <typename BlockType>
178 AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize)
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)
186 nentries = block.Nentries();
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)
200 int DumpRecHitStruct(
201 const char* buffer, unsigned long bufferSize,
202 const AliHLTMUONRecHitStruct* hit,
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);
214 result = CheckField(hit->fY, buffer, bufferSize, continueParse);
215 if (result != EXIT_SUCCESS) return result;
216 cout << setw(13) << left << hit->fY << setw(0);
218 result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
219 if (result != EXIT_SUCCESS) return result;
220 cout << hit->fZ << setw(0) << endl;
226 int DumpRecHitsBlock(
227 const char* buffer, unsigned long bufferSize,
231 int result = EXIT_SUCCESS;
232 AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
234 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
235 if (result != EXIT_SUCCESS and not continueParse) return result;
237 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
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++)
245 int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
246 if (subResult != EXIT_SUCCESS) return subResult;
253 int DumpTriggerRecordStruct(
254 const char* buffer, unsigned long bufferSize,
255 const AliHLTMUONTriggerRecordStruct* record,
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;
267 result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
268 if (result != EXIT_SUCCESS) return result;
269 cout << "Flags: " << showbase << hex << record->fFlags << dec;
271 // Print the individual trigger bits.
272 AliHLTMUONParticleSign sign;
274 AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
275 cout << " [Sign: " << sign << ", Hits set on chambers: ";
277 for (AliHLTUInt32_t i = 0; i < 4; i++)
281 cout << (first ? "" : ", ") << i+11;
285 cout << (first ? "none]" : "]") << endl;
287 result = CheckField(record->fPx, buffer, bufferSize, continueParse);
288 if (result != EXIT_SUCCESS) return result;
289 cout << "Momentum: (px = " << record->fPx << ", ";
291 result = CheckField(record->fPy, buffer, bufferSize, continueParse);
292 if (result != EXIT_SUCCESS) return result;
293 cout << "py = " << record->fPy << ", ";
295 result = CheckField(record->fPz, buffer, bufferSize, continueParse);
296 if (result != EXIT_SUCCESS) return result;
297 cout << "pz = " << record->fPz << ") GeV/c"<<endl;
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++)
305 cout << setw(10) << left << ch + 11 << setw(0);
306 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
307 if (result != EXIT_SUCCESS) return result;
315 int DumpTriggerRecordsBlock(
316 const char* buffer, unsigned long bufferSize,
320 AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
322 int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
323 if (result != EXIT_SUCCESS and not continueParse) return result;
325 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
327 // Print the data block record entries.
328 const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
329 for(AliHLTUInt32_t i = 0; i < nentries; i++)
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;
341 int DumpTrigRecInfoStruct(const char* buffer, unsigned long bufferSize,
342 const AliHLTMUONTrigRecInfoStruct* debuginfo,
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);
354 result = CheckField(debuginfo->fDetElemId, buffer, bufferSize, continueParse);
355 if (result != EXIT_SUCCESS) return result;
356 cout << setw(20) << left << debuginfo->fDetElemId << setw(0);
358 result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
359 if(result != EXIT_SUCCESS) return result;
360 cout << setw(30) << left << debuginfo->fZmiddle << setw(0);
362 result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
363 if (result != EXIT_SUCCESS) return result;
364 cout <<debuginfo->fBl << setw(0) << endl;
370 int DumpTrigRecsDebugBlock(
371 const char* buffer, unsigned long bufferSize,
375 AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
377 int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
378 if (result != EXIT_SUCCESS and not continueParse) return result;
380 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
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++)
388 int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
389 if (subResult != EXIT_SUCCESS) return subResult;
396 int DumpTriggerChannelStruct(const char* buffer, unsigned long bufferSize,
397 const AliHLTMUONTriggerChannelStruct* triggerchannel,
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.
405 int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse);
406 if (result != EXIT_SUCCESS) return result;
407 cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0);
409 result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse);
410 if (result != EXIT_SUCCESS) return result;
411 cout << setw(13) << left << triggerchannel->fChamber << setw(0);
413 result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse);
414 if (result != EXIT_SUCCESS) return result;
415 cout << setw(10) << left << triggerchannel->fSignal << setw(0);
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;
424 int DumpTriggerChannelsBlock(
425 const char* buffer, unsigned long bufferSize,
429 int result = EXIT_SUCCESS;
430 AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
432 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
433 if (result != EXIT_SUCCESS and not continueParse) return result;
435 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
437 // Print the data block record entries.
438 cout << " Trigger Record ID | Chamber | Signal | Raw Data Word " << endl;
439 cout << "--------------------------------------------------------------" << endl;
440 const AliHLTMUONTriggerChannelStruct* entry = block.GetArray();
441 for(AliHLTUInt32_t i = 0; i < nentries; i++)
443 int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse);
444 if (subResult != EXIT_SUCCESS) return subResult;
451 int DumpClusterStruct(
452 const char* buffer, unsigned long bufferSize,
453 const AliHLTMUONClusterStruct* cluster,
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";
465 result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
466 if (result != EXIT_SUCCESS) return result;
467 cout << "cluster->fDetElemId: " << cluster->fDetElemId << "\t";
469 result = CheckField(cluster->fNchannels, buffer, bufferSize, continueParse);
470 if(result != EXIT_SUCCESS) return result;
471 cout << "cluster->fNchannels: " << cluster->fNchannels <<endl;
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);
483 int DumpClustersBlock(
484 const char* buffer, unsigned long bufferSize,
488 int result = EXIT_SUCCESS;
489 AliHLTMUONClustersBlockReader block(buffer, bufferSize);
491 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
492 if (result != EXIT_SUCCESS and not continueParse) return result;
494 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
496 // Print the data block record entries.
497 const AliHLTMUONClusterStruct* entry = block.GetArray();
498 for(AliHLTUInt32_t i = 0; i < nentries; i++)
500 cout << " ===================================================== Cluster Number "
501 << i+1 << "==================================================" << endl;
502 int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
503 if (subResult != EXIT_SUCCESS) return subResult;
510 int DumpChannelStruct(
511 const char* buffer, unsigned long bufferSize,
512 const AliHLTMUONChannelStruct* channel,
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);
524 result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
525 if (result != EXIT_SUCCESS) return result;
526 cout << setw(16) << left << channel->fManu << setw(0);
528 result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
529 if (result != EXIT_SUCCESS) return result;
530 cout << setw(19) << left << channel->fChannelAddress << setw(0);
532 result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
533 if(result != EXIT_SUCCESS) return result;
534 cout << setw(16) << left << channel->fSignal << setw(0);
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;
544 int DumpChannelsBlock(
545 const char* buffer, unsigned long bufferSize,
549 int result = EXIT_SUCCESS;
550 AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
552 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
553 if (result != EXIT_SUCCESS and not continueParse) return result;
555 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
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++)
563 int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
564 if (subResult != EXIT_SUCCESS) return subResult;
570 int DumpMansoTrackStruct(
571 const char* buffer, unsigned long bufferSize,
572 const AliHLTMUONMansoTrackStruct* track,
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";
584 result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
585 if (result != EXIT_SUCCESS) return result;
586 cout << "Trigger Record ID: " << track->fTrigRec << endl;
588 result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
589 if (result != EXIT_SUCCESS) return result;
590 cout << "Flags: " << showbase << hex << track->fFlags << dec;
592 // Print the individual trigger bits.
593 AliHLTMUONParticleSign sign;
595 AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset);
596 cout << " [Sign: " << sign << ", Hits set on chambers: ";
598 for (AliHLTUInt32_t i = 0; i < 4; i++)
602 cout << (first ? "" : ", ") << i+7;
606 cout << (first ? "none]" : "]") << endl;
608 result = CheckField(track->fPx, buffer, bufferSize, continueParse);
609 if (result != EXIT_SUCCESS) return result;
610 cout << "Momentum: (px = " << track->fPx << ", ";
612 result = CheckField(track->fPy, buffer, bufferSize, continueParse);
613 if (result != EXIT_SUCCESS) return result;
614 cout << "py = " << track->fPy << ", ";
616 result = CheckField(track->fPz, buffer, bufferSize, continueParse);
617 if (result != EXIT_SUCCESS) return result;
618 cout << "pz = " << track->fPz << ") GeV/c\t";
620 result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
621 if (result != EXIT_SUCCESS) return result;
622 cout << "Chi squared fit: " << track->fChi2 << endl;
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++)
630 cout << setw(10) << left << ch + 7 << setw(0);
631 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
632 if (result != EXIT_SUCCESS) return result;
639 int DumpMansoTracksBlock(
640 const char* buffer, unsigned long bufferSize,
644 int result = EXIT_SUCCESS;
645 AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize);
647 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
648 if (result != EXIT_SUCCESS and not continueParse) return result;
650 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
652 // Print the data block record entries.
653 const AliHLTMUONMansoTrackStruct* entry = block.GetArray();
654 for(AliHLTUInt32_t i = 0; i < nentries; i++)
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;
666 int DumpMansoRoIStruct(
667 const char* buffer, unsigned long bufferSize,
668 const AliHLTMUONMansoRoIStruct* roi,
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);
680 result = CheckField(roi->fY, buffer, bufferSize, continueParse);
681 if (result != EXIT_SUCCESS) return result;
682 cout << setw(13) << left << roi->fY << setw(0);
684 result = CheckField(roi->fZ, buffer, bufferSize, continueParse);
685 if (result != EXIT_SUCCESS) return result;
686 cout << setw(13) << left << roi->fZ << setw(0);
688 result = CheckField(roi->fRadius, buffer, bufferSize, continueParse);
689 if (result != EXIT_SUCCESS) return result;
690 cout << roi->fRadius << setw(0) << endl;
696 int DumpMansoCandidateStruct(
697 const char* buffer, unsigned long bufferSize,
698 const AliHLTMUONMansoCandidateStruct* candidate,
702 int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse);
703 if (result != EXIT_SUCCESS) return result;
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++)
711 cout << setw(10) << ch + 7;
712 result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse);
713 if (result != EXIT_SUCCESS) return result;
719 int DumpMansoCandidatesBlock(
720 const char* buffer, unsigned long bufferSize,
724 int result = EXIT_SUCCESS;
725 AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize);
727 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
728 if (result != EXIT_SUCCESS and not continueParse) return result;
730 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
732 // Print the data block record entries.
733 const AliHLTMUONMansoCandidateStruct* entry = block.GetArray();
734 for(AliHLTUInt32_t i = 0; i < nentries; i++)
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;
746 int DumpSinglesDecisionBlockHeader(
747 const char* buffer, unsigned long bufferSize,
748 const AliHLTMUONSinglesDecisionBlockStruct* header,
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;
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;
768 int DumpTrackDecisionStruct(
769 const char* buffer, unsigned long bufferSize,
770 const AliHLTMUONTrackDecisionStruct* decision,
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);
782 result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
783 if (result != EXIT_SUCCESS) return result;
784 cout << setw(12) << left << showbase << hex << decision->fTriggerBits
787 // Print the individual trigger bits.
789 AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
790 cout << setw(7) << left << (highPt ? "yes" : "no");
791 cout << setw(8) << left << (lowPt ? "yes" : "no");
792 cout << setw(0) << endl;
798 int DumpSinglesDecisionBlock(
799 const char* buffer, unsigned long bufferSize,
803 int result = EXIT_SUCCESS;
804 AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
806 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
807 if (result != EXIT_SUCCESS and not continueParse) return result;
809 // Dump the rest of the block header.
810 const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
811 int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
812 if (subResult != EXIT_SUCCESS) return subResult;
814 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
816 // Print the data block record entries.
817 cout << " | Trigger Bits" << endl;
818 cout << "Track ID | Raw HighPt LowPt" << endl;
819 cout << "--------------------------------------" << endl;
820 const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
821 for(AliHLTUInt32_t i = 0; i < nentries; i++)
823 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
824 if (subResult != EXIT_SUCCESS) return subResult;
831 int DumpPairsDecisionBlockHeader(
832 const char* buffer, unsigned long bufferSize,
833 const AliHLTMUONPairsDecisionBlockStruct* header,
837 // Step through the header fields trying to print them.
838 // At each step check if we have not overflowed the buffer, if we have
839 // not then we can print the field, otherwise we print the left over
840 // bytes assumed to be corrupted rubbish.
841 int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
842 if (result != EXIT_SUCCESS) return result;
843 cout << " Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
845 result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
846 if (result != EXIT_SUCCESS) return result;
847 cout << " Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
849 result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
850 if (result != EXIT_SUCCESS) return result;
851 cout << " Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
853 result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
854 if (result != EXIT_SUCCESS) return result;
855 cout << " Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
857 result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
858 if (result != EXIT_SUCCESS) return result;
859 cout << " Number of like low pt triggers: " << header->fNlikeLowPt << endl;
861 result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
862 if (result != EXIT_SUCCESS) return result;
863 cout << " Number of like high pt triggers: " << header->fNlikeHighPt << endl;
865 result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
866 if (result != EXIT_SUCCESS) return result;
867 cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
869 result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
870 if (result != EXIT_SUCCESS) return result;
871 cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
873 result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
874 if (result != EXIT_SUCCESS) return result;
875 cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
881 int DumpPairDecisionStruct(
882 const char* buffer, unsigned long bufferSize,
883 const AliHLTMUONPairDecisionStruct* decision,
887 // Step through the fields trying to print them.
888 // At each step check if we have not overflowed the buffer. If we have
889 // not, then we can print the field, otherwise we print the left over
890 // bytes assumed to be corrupted rubbish.
891 int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
892 if (result != EXIT_SUCCESS) return result;
893 cout << setw(13) << left << decision->fTrackAId << setw(0);
895 result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
896 if (result != EXIT_SUCCESS) return result;
897 cout << setw(13) << left << decision->fTrackBId << setw(0);
899 result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
900 if (result != EXIT_SUCCESS) return result;
901 cout << setw(12) << left << showbase << hex << decision->fTriggerBits
904 // Print the individual trigger bits.
905 bool highMass, lowMass, unlike;
906 AliHLTUInt8_t highPtCount, lowPtCount;
907 AliHLTMUONUtils::UnpackPairDecisionBits(
908 decision->fTriggerBits,
909 highMass, lowMass, unlike, highPtCount, lowPtCount
911 cout << setw(7) << left << (highMass ? "yes" : "no");
912 cout << setw(7) << left << (lowMass ? "yes" : "no");
913 cout << setw(7) << left << (unlike ? "yes" : "no");
914 cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
915 cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
918 result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
919 if (result != EXIT_SUCCESS) return result;
920 cout << decision->fInvMass << endl;
926 int DumpPairsDecisionBlock(
927 const char* buffer, unsigned long bufferSize,
931 int result = EXIT_SUCCESS;
932 AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
934 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
935 if (result != EXIT_SUCCESS and not continueParse) return result;
937 // Dump the rest of the block header.
938 const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
939 int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
940 if (subResult != EXIT_SUCCESS) return subResult;
942 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
944 // Print the data block record entries.
945 cout << " | | Trigger Bits |" << endl;
946 cout << "Track A ID | Track B ID | Raw HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
947 cout << "----------------------------------------------------------------------------------------" << endl;
948 const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
949 for(AliHLTUInt32_t i = 0; i < nentries; i++)
951 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
952 if (subResult != EXIT_SUCCESS) return subResult;
959 int DumpCommonHeader(
960 const char* buffer, unsigned long bufferSize,
961 const AliHLTMUONDataBlockHeader* header, bool continueParse
964 // Step through the header fields trying to print them.
965 // At each step check if we have not overflowed the buffer, if we have
966 // not then we can print the field, otherwise we print the left over
967 // bytes assumed to be corrupted rubbish.
968 int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
969 if (result != EXIT_SUCCESS) return result;
970 AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
971 cout << " Block type: " << type << endl;
973 result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
974 if (result != EXIT_SUCCESS) return result;
975 cout << " Record width: " << header->fRecordWidth << endl;
977 result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
978 if (result != EXIT_SUCCESS) return result;
979 cout << "Number of entries: " << header->fNrecords << endl;
986 const char* buffer, unsigned long bufferSize,
987 bool continueParse, AliHLTMUONDataBlockType type
990 assert( buffer != NULL );
991 int result = EXIT_SUCCESS;
993 if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
995 cerr << "ERROR: The size of the file is too small to contain a"
996 " valid data block." << endl;
997 result = PARSE_ERROR;
998 if (not continueParse) return result;
1000 const AliHLTMUONDataBlockHeader* header =
1001 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
1003 int subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
1004 if (subResult != EXIT_SUCCESS) return subResult;
1007 // Check if the block type in the header corresponds to the type given
1008 // by the '-type' command line parameter. If they do not then print an
1009 // error or big fat warning message and force interpretation of the data
1010 // block with the type given by '-type'.
1011 AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
1013 if (type == kUnknownDataBlock)
1015 // -type not used in the command line so just use what is given
1016 // by the data block header.
1019 else if (type != headerType)
1021 cerr << "WARNING: The data block header indicates a type"
1022 " different from what was specified on the command line."
1023 " The data could be corrupt."
1025 cerr << "WARNING: The type value in the file is "
1026 << showbase << hex << header->fType
1027 << " (" << headerType << "), but on the command line it is "
1028 << showbase << hex << int(type) << dec
1029 << " (" << type << ")."
1031 cerr << "WARNING: Will force the interpretation of the data block"
1032 " with a type of " << type << "." << endl;
1035 // Now we know what type the data block is supposed to be so we can
1036 // dump it to screen with the appropriate dump routine.
1039 case kTriggerRecordsDataBlock:
1040 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
1041 if (subResult != EXIT_SUCCESS) result = subResult;
1043 case kTrigRecsDebugDataBlock:
1044 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
1045 if (subResult != EXIT_SUCCESS) result = subResult;
1047 case kTriggerChannelsDataBlock:
1048 subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse);
1049 if (subResult != EXIT_SUCCESS) result = subResult;
1051 case kRecHitsDataBlock:
1052 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
1053 if (subResult != EXIT_SUCCESS) result = subResult;
1055 case kClustersDataBlock:
1056 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
1057 if (subResult != EXIT_SUCCESS) result = subResult;
1059 case kChannelsDataBlock:
1060 return DumpChannelsBlock(buffer, bufferSize, continueParse);
1061 if (subResult != EXIT_SUCCESS) result = subResult;
1063 case kMansoTracksDataBlock:
1064 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
1065 if (subResult != EXIT_SUCCESS) result = subResult;
1067 case kMansoCandidatesDataBlock:
1068 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
1069 if (subResult != EXIT_SUCCESS) result = subResult;
1071 case kSinglesDecisionDataBlock:
1072 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
1073 if (subResult != EXIT_SUCCESS) result = subResult;
1075 case kPairsDecisionDataBlock:
1076 return DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
1077 if (subResult != EXIT_SUCCESS) result = subResult;
1080 cout << "ERROR: Unknown data block type. Found a type number of "
1081 << showbase << hex << int(type) << dec
1082 << " (" << int(type) << ")." << endl;
1083 result = PARSE_ERROR;
1091 * The caller is responsible for freeing memory allocated for buffer with a call
1092 * to delete [] buffer.
1094 int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
1096 assert( filename != NULL );
1098 // Open the file and find its size.
1100 file.open(filename, ios::in);
1103 cerr << "ERROR: Could not open the file: " << filename << endl;
1104 return SYSTEM_ERROR;
1106 file.seekg(0, ios::end);
1109 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1110 return SYSTEM_ERROR;
1112 bufferSize = file.tellg();
1115 cerr << "ERROR: Could not get file size for the file: " <<
1117 return SYSTEM_ERROR;
1119 file.seekg(0, ios::beg);
1122 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1123 return SYSTEM_ERROR;
1126 // Allocate the memory for the file.
1129 buffer = new char[bufferSize];
1131 catch (const std::bad_alloc&)
1133 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
1134 << " bytes." << endl;
1135 return SYSTEM_ERROR;
1138 file.read(buffer, bufferSize);
1144 cerr << "ERROR: Could not read from file: " << filename << endl;
1145 return SYSTEM_ERROR;
1154 cerr << "ERROR: Could not close the file: " << filename << endl;
1155 return SYSTEM_ERROR;
1158 return EXIT_SUCCESS;
1162 * Prints the command line usage of this program to standard error.
1166 cerr << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
1167 cerr << "Where <filename> is the name of a file containing a raw data block." << endl;
1168 cerr << "Options:" << endl;
1169 cerr << " -help | -h" << endl;
1170 cerr << " Displays this message." << endl;
1171 cerr << " -continue" << endl;
1172 cerr << " If specified, the program will try to continue parsing the data block" << endl;
1173 cerr << " as much as possible rather than stopping at the first error." << endl;
1174 cerr << " -type <typename>" << endl;
1175 cerr << " Forces the contents of the file to be interpreted as a specific" << endl;
1176 cerr << " type of data block. Where <typename> can be one of:" << endl;
1177 cerr << " trigrecs - trigger records data." << endl;
1178 cerr << " trigrecsdebug - debugging information about trigger records." << endl;
1179 cerr << " trigchannels - channel debugging in." << endl;
1180 cerr << " rechits - reconstructed hits data." << endl;
1181 cerr << " channels - channel debugging information from hit reconstruction." << endl;
1182 cerr << " clusters - cluster debugging information from hit reconstruction." << endl;
1183 cerr << " mansotracks - partial tracks from Manso algorithm." << endl;
1184 cerr << " mansocandidates - track candidates considered in the Manso algorithm." << endl;
1185 cerr << " singlesdecision - trigger decisions for single tracks." << endl;
1186 cerr << " pairsdecision - trigger decisions for track pairs." << endl;
1190 * Parse the string passed as the type of the block and return the corresponding
1191 * AliHLTMUONDataBlockType value.
1193 AliHLTMUONDataBlockType ParseCommandLineType(const char* type)
1195 if (strcmp(type, "trigrecs") == 0)
1197 return kTriggerRecordsDataBlock;
1199 else if (strcmp(type, "trigrecsdebug") == 0)
1201 return kTrigRecsDebugDataBlock;
1203 else if (strcmp(type, "trigchannels") == 0)
1205 return kTriggerChannelsDataBlock;
1207 else if (strcmp(type, "rechits") == 0)
1209 return kRecHitsDataBlock;
1211 else if (strcmp(type,"channels") == 0)
1213 return kChannelsDataBlock;
1215 else if (strcmp(type,"clusters") == 0)
1217 return kClustersDataBlock;
1219 else if (strcmp(type, "mansotracks") == 0)
1221 return kMansoTracksDataBlock;
1223 else if (strcmp(type, "mansocandidates") == 0)
1225 return kMansoCandidatesDataBlock;
1227 else if (strcmp(type, "singlesdecision") == 0)
1229 return kSinglesDecisionDataBlock;
1231 else if (strcmp(type, "pairsdecision") == 0)
1233 return kPairsDecisionDataBlock;
1236 cerr << "ERROR: Invalid type name '" << type << "' specified for argument -type."
1239 return kUnknownDataBlock;
1243 * Parses the command line.
1244 * @param argc Number of arguments as given in main().
1245 * @param argv Array of arguments as given in main().
1246 * @param filename Receives the pointer to the file name string.
1247 * @param type Receives the type of the data block expected, i.e. the
1248 * value of the -type flag.
1249 * @return A status flag suitable for returning from main(), containing either
1250 * EXIT_SUCCESS or CMDLINE_ERROR.
1252 int ParseCommandLine(
1253 int argc, const char** argv,
1254 const char*& filename, bool& continueParse,
1255 AliHLTMUONDataBlockType& type
1259 continueParse = false;
1261 // Parse the command line.
1262 for (int i = 1; i < argc; i++)
1264 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0)
1267 return EXIT_SUCCESS;
1269 else if (strcmp(argv[i], "-continue") == 0)
1271 continueParse = true;
1273 else if (strcmp(argv[i], "-type") == 0)
1275 // Now we need to parse the typename in the command line.
1276 type = ParseCommandLineType(argv[++i]);
1277 if (type == kUnknownDataBlock) return CMDLINE_ERROR;
1281 if (filename != NULL)
1283 cerr << "ERROR: Only one file can be specified, but got '"
1284 << argv[i] << "', with '" << filename
1285 << "' specified earlier." << endl << endl;
1287 return CMDLINE_ERROR;
1294 // Now check that we have the filename and all the flags we need.
1295 if (filename == NULL)
1297 cerr << "ERROR: Missing a file name. You must specify a file to process."
1300 return CMDLINE_ERROR;
1303 return EXIT_SUCCESS;
1307 int main(int argc, const char** argv)
1309 const char* filename = NULL;
1310 bool continueParse = false;
1311 int returnCode = EXIT_SUCCESS;
1312 AliHLTMUONDataBlockType type = kUnknownDataBlock;
1313 char* buffer = NULL;
1317 returnCode = ParseCommandLine(argc, argv, filename, continueParse, type);
1319 if (returnCode == EXIT_SUCCESS and filename != NULL)
1321 unsigned long bufferSize = 0;
1322 returnCode = ReadFile(filename, buffer, bufferSize);
1323 if (returnCode == EXIT_SUCCESS)
1324 returnCode = ParseBuffer(buffer, bufferSize, continueParse, type);
1325 if (buffer != NULL) delete [] buffer;
1331 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
1332 returnCode = FATAL_ERROR;
1333 if (buffer != NULL) delete [] buffer;