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"
38 #include "AliHLTMUONConstants.h"
40 #include "AliRawDataHeader.h"
41 #include "AliMUONTrackerDDLDecoder.h"
42 #include "AliMUONTriggerDDLDecoder.h"
43 #include "AliHLTSystem.h"
44 #include "AliHLTConfiguration.h"
46 #include "TClassTable.h"
62 using std::noshowbase;
73 #define CMDLINE_ERROR 1
75 #define SYSTEM_ERROR 3
77 #define HLTSYSTEM_ERROR 5
80 // Adding enum types for extending AliHLTMUONDataBlockType with the
81 // raw DDL data types.
82 enum AliHLTMUONDDLRawDataType
84 kTrackerDDLRawData = 10,
85 kTriggerDDLRawData = 11
89 void PrintRubbishData(AliHLTUInt32_t offset, const char* padByte, AliHLTUInt32_t padCount)
91 if (padCount == 0) return;
93 cerr << "ERROR: Found the following unexpected rubbish data at the"
94 " end of the data block:" << endl;
95 cerr << "Byte #\tValue\tCharacter" << endl;
96 for (AliHLTUInt32_t i = 0; i < padCount; i++)
98 short value = short(padByte[i]) & 0xFF;
99 char character = padByte[i];
100 cerr << offset + i + 1 << "\t"
101 << noshowbase << hex << "0x" << value << dec << "\t"
102 << character << endl;
107 template <typename FieldType>
108 int CheckHeaderField(
109 FieldType& field, const char* buffer, unsigned long bufferSize,
113 const char* fieldptr = reinterpret_cast<const char*>(&field);
114 const char* endptr = buffer + bufferSize;
115 AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
117 if (bufferRemaining < sizeof(field))
119 cout << "..." << endl; // We may be half way through printing a line so end it.
120 cerr << "ERROR: The data block is too short. The header is corrupt." << endl;
123 AliHLTUInt32_t offset = fieldptr - buffer;
124 PrintRubbishData(offset, fieldptr, bufferRemaining);
132 template <typename FieldType>
134 FieldType& field, const char* buffer, unsigned long bufferSize,
138 const char* fieldptr = reinterpret_cast<const char*>(&field);
139 const char* endptr = buffer + bufferSize;
140 AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0;
142 if (bufferRemaining < sizeof(field))
144 cout << "..." << endl; // We may be half way through printing a line so end it.
145 cerr << "ERROR: The data block is too short. The data is corrupt." << endl;
148 AliHLTUInt32_t offset = fieldptr - buffer;
149 PrintRubbishData(offset, fieldptr, bufferRemaining);
157 template <typename BlockType>
158 int CheckCommonHeader(
159 BlockType& block, const char* /*buffer*/, unsigned long bufferSize,
163 int result = EXIT_SUCCESS;
165 // Check the fRecordWidth field in the common header.
166 if (block.CommonBlockHeader().fRecordWidth !=
167 sizeof(typename BlockType::ElementType))
169 cerr << "ERROR: The record width found in the header is incorrect."
170 " Found a record width of "
171 << block.CommonBlockHeader().fRecordWidth << " bytes, but expected"
172 " a value of " << sizeof(typename BlockType::ElementType)
173 << " bytes." << endl;
174 result = PARSE_ERROR;
175 if (not continueParse) return result;
178 if (not block.BufferSizeOk())
180 cerr << "ERROR: The size of the file is incorrect. It is "
181 << bufferSize << " bytes big, but according"
182 " to the data block header it should be " << block.BytesUsed()
183 << " bytes." << endl;
184 result = PARSE_ERROR;
185 if (not continueParse) return result;
192 template <typename BlockType>
193 AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize)
195 // Calculate how many entries we can display. If the buffer size is correct
196 // we just use the number of entries the block specifies. Otherwise we need
197 // to calculate it from the buffer size.
198 AliHLTUInt32_t nentries;
199 if (block.BytesUsed() == bufferSize)
201 nentries = block.Nentries();
205 AliHLTInt32_t dataSize = bufferSize
206 - sizeof(typename BlockType::HeaderType);
207 nentries = dataSize / sizeof(typename BlockType::ElementType);
208 if (dataSize % sizeof(typename BlockType::ElementType) > 0)
218 * Common methods for DDL decoder event handlers.
220 class AliDecoderHandler
223 AliDecoderHandler() :
230 virtual ~AliDecoderHandler() {}
234 // Do not allow copying of this class.
235 AliDecoderHandler(const AliDecoderHandler& obj);
236 AliDecoderHandler& operator = (const AliDecoderHandler& obj);
239 const char* errorMessage, int errorCode,
240 const char* errorCodeString, const void* location
243 unsigned long offset = (unsigned long)location - (unsigned long)fBufferStart
244 + sizeof(AliRawDataHeader);
246 cerr << "ERROR: " << errorMessage
247 << " [Error code = " << errorCode << " ("
248 << errorCodeString << "), at byte "
249 << offset << " (" << noshowbase << hex << "0x"
250 << offset << dec << ")]" << endl;
252 if (fDumpStart == NULL) fDumpStart = location;
256 void TryDumpCorruptData(const void* dumpEnd)
258 if (dumpEnd < fDumpStart) return;
259 if (not fDumpData) return;
261 unsigned long startOffset = (unsigned long)fDumpStart - (unsigned long)fBufferStart
262 + sizeof(AliRawDataHeader);
263 unsigned long endOffset = (unsigned long)dumpEnd - (unsigned long)fBufferStart
264 + sizeof(AliRawDataHeader);
265 if (endOffset - startOffset > 264)
267 endOffset = startOffset + 264;
268 dumpEnd = reinterpret_cast<const char*>(fBufferStart) + endOffset;
270 cerr << "Dumping corrupt data words from byte " << startOffset
271 << " (" << noshowbase << hex << "0x" << startOffset
272 << dec << "), to byte " << endOffset << " (" << noshowbase
273 << hex << "0x" << endOffset << dec << "):" << endl;
274 const UInt_t* start = reinterpret_cast<const UInt_t*>(fDumpStart);
275 const UInt_t* end = reinterpret_cast<const UInt_t*>(dumpEnd);
276 cerr << " Start byte | Data words" << endl;
277 for (const UInt_t* current = start; current < end; current++)
279 unsigned long currentByte = (unsigned long)current
280 - (unsigned long)fBufferStart + sizeof(AliRawDataHeader);
281 cerr << right << setw(9) << dec << currentByte << setw(0)
282 << " 0x" << left << setw(7) << noshowbase << hex
283 << currentByte << setw(0) << right << " | ";
284 char fillChar = cerr.fill();
286 for (int i = 0; i < 4 and current < end; i++, current++)
288 cerr << noshowbase << hex << "0x" << setw(8)
289 << (*current) << setw(0) << dec << " ";
298 const void* fBufferStart; ///< Start location of buffer.
299 const void* fDumpStart; ///< Start location of corrupt data to dump.
300 bool fDumpData; ///< Flag indicating if fDumpStart points to corrupt data and should be dumped.
304 * Event handler for the tracker DDL decoder.
305 * It simply prints the structure to standard output.
307 class AliTrackerDecoderHandler :
308 public AliMUONTrackerDDLDecoderEventHandler, public AliDecoderHandler
311 AliTrackerDecoderHandler() :
312 AliMUONTrackerDDLDecoderEventHandler(),
316 virtual ~AliTrackerDecoderHandler() {}
318 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
320 fBufferStart = buffer;
323 void OnEndOfBuffer(const void* buffer, UInt_t bufferSize)
325 const char* bufferEnd =
326 reinterpret_cast<const char*>(buffer) + bufferSize;
327 TryDumpCorruptData(bufferEnd);
330 void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/)
332 TryDumpCorruptData(header);
335 cout << "block: " << header << endl;
338 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/)
340 TryDumpCorruptData(header);
343 cout << "DSP: " << header << endl;
346 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
348 TryDumpCorruptData(header);
351 cout << "buspatch: " << header << endl;
354 void OnData(UInt_t data, bool parityError)
359 cerr << "Raw data word with parity error" << data << endl;
364 cout << "data word: 0x" << hex << data << dec << endl;
368 void OnError(ErrorCode error, const void* location)
370 TryDumpCorruptData(location);
372 ErrorCodeToMessage(error), error,
373 ErrorCodeToString(error), location
379 * Event handler for the trigger DDL decoder.
380 * It simply prints the structure to standard output.
382 class AliTriggerDecoderHandler :
383 public AliMUONTriggerDDLDecoderEventHandler, public AliDecoderHandler
386 AliTriggerDecoderHandler() :
387 AliMUONTriggerDDLDecoderEventHandler(),
391 virtual ~AliTriggerDecoderHandler() {}
393 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
395 fBufferStart = buffer;
398 void OnEndOfBuffer(const void* buffer, UInt_t bufferSize)
400 const char* bufferEnd =
401 reinterpret_cast<const char*>(buffer) + bufferSize;
402 TryDumpCorruptData(bufferEnd);
407 const AliMUONDarcScalarsStruct* scalars,
412 TryDumpCorruptData(scalars);
414 TryDumpCorruptData(data);
417 cout << "DARC header: " << header << endl;
421 const AliMUONGlobalHeaderStruct* header,
422 const AliMUONGlobalScalarsStruct* /*scalars*/,
426 TryDumpCorruptData(header);
429 cout << "global header: " << header << endl;
432 void OnNewRegionalStruct(
433 const AliMUONRegionalHeaderStruct* regionalStruct,
434 const AliMUONRegionalScalarsStruct* /*scalars*/,
438 TryDumpCorruptData(regionalStruct);
441 cout << "regional struct: " << regionalStruct << endl;
445 const AliMUONLocalInfoStruct* localStruct,
446 const AliMUONLocalScalarsStruct* /*scalars*/
449 TryDumpCorruptData(localStruct);
452 cout << "local struct: " << localStruct << endl;
455 void OnError(ErrorCode error, const void* location)
457 TryDumpCorruptData(location);
459 ErrorCodeToMessage(error), error,
460 ErrorCodeToString(error), location
465 } // end of namespace
468 int DumpTrackerDDLRawStream(
469 const char* buffer, unsigned long bufferSize,
473 // TODO dump the CDH header.
475 // Setup the decoder for the DDL payload.
476 AliMUONTrackerDDLDecoder<AliTrackerDecoderHandler> decoder;
477 decoder.ExitOnError(not continueParse);
478 decoder.SendDataOnParityError(false);
479 decoder.TryRecover(false);
480 decoder.AutoDetectTrailer(true);
481 decoder.CheckForTrailer(true);
482 const char* payload = buffer + sizeof(AliRawDataHeader);
483 UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
484 if (decoder.Decode(payload, payloadSize))
495 int DumpTriggerDDLRawStream(
496 const char* buffer, unsigned long bufferSize,
500 // TODO dump the CDH header.
502 const AliRawDataHeader* header =
503 reinterpret_cast<const AliRawDataHeader*>(buffer);
504 bool scalarEvent = header->GetL1TriggerMessage() == 0x1;
506 AliMUONTriggerDDLDecoder<AliTriggerDecoderHandler> decoder;
507 decoder.ExitOnError(not continueParse);
508 decoder.TryRecover(false);
509 decoder.AutoDetectScalars(false);
510 const char* payload = buffer + sizeof(AliRawDataHeader);
511 UInt_t payloadSize = bufferSize - sizeof(AliRawDataHeader);
512 if (decoder.Decode(payload, payloadSize, scalarEvent))
523 int DumpRecHitStruct(
524 const char* buffer, unsigned long bufferSize,
525 const AliHLTMUONRecHitStruct* hit,
529 // Step through the fields trying to print them.
530 // At each step check if we have not overflowed the buffer. If we have
531 // not, then we can print the field, otherwise we print the left over
532 // bytes assumed to be corrupted rubbish.
533 int result = CheckField(hit->fX, buffer, bufferSize, continueParse);
534 if (result != EXIT_SUCCESS) return result;
535 cout << setw(13) << left << hit->fX << setw(0);
537 result = CheckField(hit->fY, buffer, bufferSize, continueParse);
538 if (result != EXIT_SUCCESS) return result;
539 cout << setw(13) << left << hit->fY << setw(0);
541 result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
542 if (result != EXIT_SUCCESS) return result;
543 cout << hit->fZ << setw(0) << endl;
549 int DumpRecHitsBlock(
550 const char* buffer, unsigned long bufferSize,
554 int result = EXIT_SUCCESS;
555 AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
557 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
558 if (result != EXIT_SUCCESS and not continueParse) return result;
560 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
562 // Print the data block record entries.
563 cout << " X (cm) | Y (cm) | Z (cm)" << endl;
564 cout << "---------------------------------------" << endl;
565 const AliHLTMUONRecHitStruct* entry = block.GetArray();
566 for(AliHLTUInt32_t i = 0; i < nentries; i++)
568 int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
569 if (subResult != EXIT_SUCCESS) return subResult;
576 int DumpTriggerRecordStruct(
577 const char* buffer, unsigned long bufferSize,
578 const AliHLTMUONTriggerRecordStruct* record,
582 // Step through the fields trying to print them.
583 // At each step check if we have not overflowed the buffer. If we have
584 // not, then we can print the field, otherwise we print the left over
585 // bytes assumed to be corrupted rubbish.
586 int result = CheckField(record->fId, buffer, bufferSize, continueParse);
587 if (result != EXIT_SUCCESS) return result;
588 cout << "Trigger Record ID: " << record->fId <<endl;
590 result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
591 if (result != EXIT_SUCCESS) return result;
592 cout << "Flags: " << showbase << hex << record->fFlags << dec;
594 // Print the individual trigger bits.
595 AliHLTMUONParticleSign sign;
597 AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
598 cout << " [Sign: " << sign << ", Hits set on chambers: ";
600 for (AliHLTUInt32_t i = 0; i < 4; i++)
604 cout << (first ? "" : ", ") << i+11;
608 cout << (first ? "none]" : "]") << endl;
610 result = CheckField(record->fPx, buffer, bufferSize, continueParse);
611 if (result != EXIT_SUCCESS) return result;
612 cout << "Momentum: (px = " << record->fPx << ", ";
614 result = CheckField(record->fPy, buffer, bufferSize, continueParse);
615 if (result != EXIT_SUCCESS) return result;
616 cout << "py = " << record->fPy << ", ";
618 result = CheckField(record->fPz, buffer, bufferSize, continueParse);
619 if (result != EXIT_SUCCESS) return result;
620 cout << "pz = " << record->fPz << ") GeV/c"<<endl;
622 cout << "Track hits:" << endl;
623 cout << "Chamber | X (cm) | Y (cm) | Z (cm)" << endl;
624 cout << "------------------------------------------------" << endl;
625 const AliHLTMUONRecHitStruct* hit = &record->fHit[0];
626 for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
628 cout << setw(10) << left << ch + 11 << setw(0);
629 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
630 if (result != EXIT_SUCCESS) return result;
638 int DumpTriggerRecordsBlock(
639 const char* buffer, unsigned long bufferSize,
643 AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
645 int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
646 if (result != EXIT_SUCCESS and not continueParse) return result;
648 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
650 // Print the data block record entries.
651 const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
652 for(AliHLTUInt32_t i = 0; i < nentries; i++)
654 cout << "============================== Trigger Record number " << i+1
655 << " of " << nentries << " ==============================" << endl;
656 int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse);
657 if (subResult != EXIT_SUCCESS) return subResult;
664 int DumpTrigRecInfoStruct(
665 const char* buffer, unsigned long bufferSize,
666 const AliHLTMUONTrigRecInfoStruct* debuginfo,
670 // Step through the fields trying to print them.
671 // At each step check if we have not overflowed the buffer. If we have
672 // not, then we can print the field, otherwise we print the left over
673 // bytes assumed to be corrupted rubbish.
674 int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse);
675 if (result != EXIT_SUCCESS) return result;
676 cout << setw(22) << left << debuginfo->fTrigRecId << setw(0);
678 result = CheckField(debuginfo->fDetElemId, buffer, bufferSize, continueParse);
679 if (result != EXIT_SUCCESS) return result;
680 cout << setw(20) << left << debuginfo->fDetElemId << setw(0);
682 result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
683 if(result != EXIT_SUCCESS) return result;
684 cout << setw(30) << left << debuginfo->fZmiddle << setw(0);
686 result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
687 if (result != EXIT_SUCCESS) return result;
688 cout <<debuginfo->fBl << setw(0) << endl;
694 int DumpTrigRecsDebugBlock(
695 const char* buffer, unsigned long bufferSize,
699 AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
701 int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
702 if (result != EXIT_SUCCESS and not continueParse) return result;
704 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
706 // Print the data block record entries.
707 cout << "Trigger Record ID | Detector ID | Momentum X Component (Gev/c) | Integrated Magnetic Field (T.m)" << endl;
708 cout << "--------------------------------------------------------------------------------------------------" << endl;
709 const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray();
710 for(AliHLTUInt32_t i = 0; i < nentries; i++)
712 int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
713 if (subResult != EXIT_SUCCESS) return subResult;
720 int DumpTriggerChannelStruct(
721 const char* buffer, unsigned long bufferSize,
722 const AliHLTMUONTriggerChannelStruct* triggerchannel,
726 // Step through the fields trying to print them.
727 // At each step check if we have not overflowed the buffer. If we have
728 // not, then we can print the field, otherwise we print the left over
729 // bytes assumed to be corrupted rubbish.
730 int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse);
731 if (result != EXIT_SUCCESS) return result;
732 cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0);
734 result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse);
735 if (result != EXIT_SUCCESS) return result;
736 cout << setw(13) << left << triggerchannel->fChamber << setw(0);
738 result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse);
739 if (result != EXIT_SUCCESS) return result;
740 cout << setw(10) << left << triggerchannel->fSignal << setw(0);
742 result = CheckField(triggerchannel->fRawDataWord, buffer, bufferSize, continueParse);
743 if(result != EXIT_SUCCESS) return result;
744 cout << showbase << hex << triggerchannel->fRawDataWord << dec << setw(0) << endl;
749 int DumpTriggerChannelsBlock(
750 const char* buffer, unsigned long bufferSize,
754 int result = EXIT_SUCCESS;
755 AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
757 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
758 if (result != EXIT_SUCCESS and not continueParse) return result;
760 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
762 // Print the data block record entries.
763 cout << " Trigger Record ID | Chamber | Signal | Raw Data Word " << endl;
764 cout << "--------------------------------------------------------------" << endl;
765 const AliHLTMUONTriggerChannelStruct* entry = block.GetArray();
766 for(AliHLTUInt32_t i = 0; i < nentries; i++)
768 int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse);
769 if (subResult != EXIT_SUCCESS) return subResult;
776 int DumpClusterStruct(
777 const char* buffer, unsigned long bufferSize,
778 const AliHLTMUONClusterStruct* cluster,
782 // Step through the fields trying to print them.
783 // At each step check if we have not overflowed the buffer. If we have
784 // not, then we can print the field, otherwise we print the left over
785 // bytes assumed to be corrupted rubbish.
786 int result = CheckField(cluster->fId, buffer, bufferSize, continueParse);
787 if (result != EXIT_SUCCESS) return result;
788 cout << "cluster->fId: " << cluster->fId << "\t";
790 result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
791 if (result != EXIT_SUCCESS) return result;
792 cout << "cluster->fDetElemId: " << cluster->fDetElemId << "\t";
794 result = CheckField(cluster->fNchannels, buffer, bufferSize, continueParse);
795 if(result != EXIT_SUCCESS) return result;
796 cout << "cluster->fNchannels: " << cluster->fNchannels <<endl;
798 cout << " Corresponding Hit: "<< endl;
799 cout << " X (cm) | Y (cm) | Z (cm)" << endl;
800 cout << "---------------------------------------" << endl;
801 const AliHLTMUONRecHitStruct * hit = & cluster->fHit;
802 result = DumpRecHitStruct(buffer, bufferSize, hit, continueParse);
808 int DumpClustersBlock(
809 const char* buffer, unsigned long bufferSize,
813 int result = EXIT_SUCCESS;
814 AliHLTMUONClustersBlockReader block(buffer, bufferSize);
816 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
817 if (result != EXIT_SUCCESS and not continueParse) return result;
819 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
821 // Print the data block record entries.
822 const AliHLTMUONClusterStruct* entry = block.GetArray();
823 for(AliHLTUInt32_t i = 0; i < nentries; i++)
825 cout << " ===================================================== Cluster Number "
826 << i+1 << "==================================================" << endl;
827 int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
828 if (subResult != EXIT_SUCCESS) return subResult;
835 int DumpChannelStruct(
836 const char* buffer, unsigned long bufferSize,
837 const AliHLTMUONChannelStruct* channel,
841 // Step through the fields trying to print them.
842 // At each step check if we have not overflowed the buffer. If we have
843 // not, then we can print the field, otherwise we print the left over
844 // bytes assumed to be corrupted rubbish.
845 int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse);
846 if (result != EXIT_SUCCESS) return result;
847 cout << setw(16) << left << channel->fClusterId << setw(0);
849 result = CheckField(channel->fBusPatch, buffer, bufferSize, continueParse);
850 if (result != EXIT_SUCCESS) return result;
851 cout << setw(16) << left << channel->fBusPatch << setw(0);
853 result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
854 if (result != EXIT_SUCCESS) return result;
855 cout << setw(16) << left << channel->fManu << setw(0);
857 result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
858 if (result != EXIT_SUCCESS) return result;
859 cout << setw(16) << left << channel->fChannelAddress << setw(0);
861 result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
862 if(result != EXIT_SUCCESS) return result;
863 cout << setw(16) << left << channel->fSignal << setw(0);
865 result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse);
866 if(result != EXIT_SUCCESS) return result;
867 cout << showbase << hex << channel->fRawDataWord << dec << setw(0) <<endl;
873 int DumpChannelsBlock(
874 const char* buffer, unsigned long bufferSize,
878 int result = EXIT_SUCCESS;
879 AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
881 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
882 if (result != EXIT_SUCCESS and not continueParse) return result;
884 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
886 // Print the data block record entries.
887 cout << "Cluster Id | Bus Patch | Manu Address | Channel Addr | Signal Value | Raw Data Word " << endl;
888 cout << "----------------------------------------------------------------------------------------------" << endl;
889 const AliHLTMUONChannelStruct* entry = block.GetArray();
890 for(AliHLTUInt32_t i = 0; i < nentries; i++)
892 int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
893 if (subResult != EXIT_SUCCESS) return subResult;
899 int DumpMansoTrackStruct(
900 const char* buffer, unsigned long bufferSize,
901 const AliHLTMUONMansoTrackStruct* track,
905 // Step through the fields trying to print them.
906 // At each step check if we have not overflowed the buffer. If we have
907 // not, then we can print the field, otherwise we print the left over
908 // bytes assumed to be corrupted rubbish.
909 int result = CheckField(track->fId, buffer, bufferSize, continueParse);
910 if (result != EXIT_SUCCESS) return result;
911 cout << "Track ID: " << track->fId << "\t";
913 result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse);
914 if (result != EXIT_SUCCESS) return result;
915 cout << "Trigger Record ID: " << track->fTrigRec << endl;
917 result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
918 if (result != EXIT_SUCCESS) return result;
919 cout << "Flags: " << showbase << hex << track->fFlags << dec;
921 // Print the individual trigger bits.
922 AliHLTMUONParticleSign sign;
924 AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset);
925 cout << " [Sign: " << sign << ", Hits set on chambers: ";
927 for (AliHLTUInt32_t i = 0; i < 4; i++)
931 cout << (first ? "" : ", ") << i+7;
935 cout << (first ? "none]" : "]") << endl;
937 result = CheckField(track->fPx, buffer, bufferSize, continueParse);
938 if (result != EXIT_SUCCESS) return result;
939 cout << "Momentum: (px = " << track->fPx << ", ";
941 result = CheckField(track->fPy, buffer, bufferSize, continueParse);
942 if (result != EXIT_SUCCESS) return result;
943 cout << "py = " << track->fPy << ", ";
945 result = CheckField(track->fPz, buffer, bufferSize, continueParse);
946 if (result != EXIT_SUCCESS) return result;
947 cout << "pz = " << track->fPz << ") GeV/c\t";
949 result = CheckField(track->fChi2, buffer, bufferSize, continueParse);
950 if (result != EXIT_SUCCESS) return result;
951 cout << "Chi squared fit: " << track->fChi2 << endl;
953 cout << "Track hits:" << endl;
954 cout << "Chamber | X (cm) | Y (cm) | Z (cm)" << endl;
955 cout << "------------------------------------------------" << endl;
956 const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
957 for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
959 cout << setw(10) << left << ch + 7 << setw(0);
960 result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
961 if (result != EXIT_SUCCESS) return result;
968 int DumpMansoTracksBlock(
969 const char* buffer, unsigned long bufferSize,
973 int result = EXIT_SUCCESS;
974 AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize);
976 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
977 if (result != EXIT_SUCCESS and not continueParse) return result;
979 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
981 // Print the data block record entries.
982 const AliHLTMUONMansoTrackStruct* entry = block.GetArray();
983 for(AliHLTUInt32_t i = 0; i < nentries; i++)
985 cout << "============================== Manso track number " << i+1
986 << " of " << nentries << " ==============================" << endl;
987 int subResult = DumpMansoTrackStruct(buffer, bufferSize, entry++, continueParse);
988 if (subResult != EXIT_SUCCESS) return subResult;
995 int DumpMansoRoIStruct(
996 const char* buffer, unsigned long bufferSize,
997 const AliHLTMUONMansoRoIStruct* roi,
1001 // Step through the fields trying to print them.
1002 // At each step check if we have not overflowed the buffer. If we have
1003 // not, then we can print the field, otherwise we print the left over
1004 // bytes assumed to be corrupted rubbish.
1005 int result = CheckField(roi->fX, buffer, bufferSize, continueParse);
1006 if (result != EXIT_SUCCESS) return result;
1007 cout << setw(13) << left << roi->fX << setw(0);
1009 result = CheckField(roi->fY, buffer, bufferSize, continueParse);
1010 if (result != EXIT_SUCCESS) return result;
1011 cout << setw(13) << left << roi->fY << setw(0);
1013 result = CheckField(roi->fZ, buffer, bufferSize, continueParse);
1014 if (result != EXIT_SUCCESS) return result;
1015 cout << setw(13) << left << roi->fZ << setw(0);
1017 result = CheckField(roi->fRadius, buffer, bufferSize, continueParse);
1018 if (result != EXIT_SUCCESS) return result;
1019 cout << roi->fRadius << setw(0) << endl;
1025 int DumpMansoCandidateStruct(
1026 const char* buffer, unsigned long bufferSize,
1027 const AliHLTMUONMansoCandidateStruct* candidate,
1031 int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse);
1032 if (result != EXIT_SUCCESS) return result;
1034 cout << "Regions of interest:" << endl;
1035 cout << "Chamber | X (cm) | Y (cm) | Z (cm) | Radius (cm)" << endl;
1036 cout << "-------------------------------------------------------------" << endl;
1037 const AliHLTMUONMansoRoIStruct* roi = &candidate->fRoI[0];
1038 for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
1040 cout << setw(10) << ch + 7;
1041 result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse);
1042 if (result != EXIT_SUCCESS) return result;
1048 int DumpMansoCandidatesBlock(
1049 const char* buffer, unsigned long bufferSize,
1053 int result = EXIT_SUCCESS;
1054 AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize);
1056 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1057 if (result != EXIT_SUCCESS and not continueParse) return result;
1059 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1061 // Print the data block record entries.
1062 const AliHLTMUONMansoCandidateStruct* entry = block.GetArray();
1063 for(AliHLTUInt32_t i = 0; i < nentries; i++)
1065 cout << "=========================== Manso track candidate number " << i+1
1066 << " of " << nentries << " ===========================" << endl;
1067 int subResult = DumpMansoCandidateStruct(buffer, bufferSize, entry++, continueParse);
1068 if (subResult != EXIT_SUCCESS) return subResult;
1075 int DumpSinglesDecisionBlockHeader(
1076 const char* buffer, unsigned long bufferSize,
1077 const AliHLTMUONSinglesDecisionBlockStruct* header,
1081 // Step through the header fields trying to print them.
1082 // At each step check if we have not overflowed the buffer, if we have
1083 // not then we can print the field, otherwise we print the left over
1084 // bytes assumed to be corrupted rubbish.
1085 int result = CheckHeaderField(header->fNlowPt, buffer, bufferSize, continueParse);
1086 if (result != EXIT_SUCCESS) return result;
1087 cout << " Number of low pt triggers: " << header->fNlowPt << endl;
1089 result = CheckHeaderField(header->fNhighPt, buffer, bufferSize, continueParse);
1090 if (result != EXIT_SUCCESS) return result;
1091 cout << "Number of high pt triggers: " << header->fNhighPt << endl;
1097 int DumpTrackDecisionStruct(
1098 const char* buffer, unsigned long bufferSize,
1099 const AliHLTMUONTrackDecisionStruct* decision,
1103 // Step through the fields trying to print them.
1104 // At each step check if we have not overflowed the buffer. If we have
1105 // not, then we can print the field, otherwise we print the left over
1106 // bytes assumed to be corrupted rubbish.
1107 int result = CheckField(decision->fTrackId, buffer, bufferSize, continueParse);
1108 if (result != EXIT_SUCCESS) return result;
1109 cout << setw(13) << left << decision->fTrackId << setw(0);
1111 result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
1112 if (result != EXIT_SUCCESS) return result;
1113 cout << setw(12) << left << showbase << hex << decision->fTriggerBits
1116 // Print the individual trigger bits.
1118 AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
1119 cout << setw(7) << left << (highPt ? "yes" : "no");
1120 cout << setw(8) << left << (lowPt ? "yes" : "no");
1122 result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
1123 if (result != EXIT_SUCCESS) return result;
1124 cout << setw(0) << decision->fPt << endl;
1130 int DumpSinglesDecisionBlock(
1131 const char* buffer, unsigned long bufferSize,
1135 int result = EXIT_SUCCESS;
1136 AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize);
1138 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1139 if (result != EXIT_SUCCESS and not continueParse) return result;
1141 // Dump the rest of the block header.
1142 const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader();
1143 int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse);
1144 if (subResult != EXIT_SUCCESS) return subResult;
1146 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1148 // Print the data block record entries.
1149 cout << " | Trigger Bits |" << endl;
1150 cout << "Track ID | Raw HighPt LowPt | pT" << endl;
1151 cout << "----------------------------------------------------" << endl;
1152 const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
1153 for(AliHLTUInt32_t i = 0; i < nentries; i++)
1155 subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse);
1156 if (subResult != EXIT_SUCCESS) return subResult;
1163 int DumpPairsDecisionBlockHeader(
1164 const char* buffer, unsigned long bufferSize,
1165 const AliHLTMUONPairsDecisionBlockStruct* header,
1169 // Step through the header fields trying to print them.
1170 // At each step check if we have not overflowed the buffer, if we have
1171 // not then we can print the field, otherwise we print the left over
1172 // bytes assumed to be corrupted rubbish.
1173 int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse);
1174 if (result != EXIT_SUCCESS) return result;
1175 cout << " Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl;
1177 result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse);
1178 if (result != EXIT_SUCCESS) return result;
1179 cout << " Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl;
1181 result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse);
1182 if (result != EXIT_SUCCESS) return result;
1183 cout << " Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl;
1185 result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse);
1186 if (result != EXIT_SUCCESS) return result;
1187 cout << " Number of like any pt triggers: " << header->fNlikeAnyPt << endl;
1189 result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse);
1190 if (result != EXIT_SUCCESS) return result;
1191 cout << " Number of like low pt triggers: " << header->fNlikeLowPt << endl;
1193 result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse);
1194 if (result != EXIT_SUCCESS) return result;
1195 cout << " Number of like high pt triggers: " << header->fNlikeHighPt << endl;
1197 result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse);
1198 if (result != EXIT_SUCCESS) return result;
1199 cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl;
1201 result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse);
1202 if (result != EXIT_SUCCESS) return result;
1203 cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl;
1205 result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse);
1206 if (result != EXIT_SUCCESS) return result;
1207 cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl;
1213 int DumpPairDecisionStruct(
1214 const char* buffer, unsigned long bufferSize,
1215 const AliHLTMUONPairDecisionStruct* decision,
1219 // Step through the fields trying to print them.
1220 // At each step check if we have not overflowed the buffer. If we have
1221 // not, then we can print the field, otherwise we print the left over
1222 // bytes assumed to be corrupted rubbish.
1223 int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse);
1224 if (result != EXIT_SUCCESS) return result;
1225 cout << setw(13) << left << decision->fTrackAId << setw(0);
1227 result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse);
1228 if (result != EXIT_SUCCESS) return result;
1229 cout << setw(13) << left << decision->fTrackBId << setw(0);
1231 result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse);
1232 if (result != EXIT_SUCCESS) return result;
1233 cout << setw(12) << left << showbase << hex << decision->fTriggerBits
1236 // Print the individual trigger bits.
1237 bool highMass, lowMass, unlike;
1238 AliHLTUInt8_t highPtCount, lowPtCount;
1239 AliHLTMUONUtils::UnpackPairDecisionBits(
1240 decision->fTriggerBits,
1241 highMass, lowMass, unlike, highPtCount, lowPtCount
1243 cout << setw(7) << left << (highMass ? "yes" : "no");
1244 cout << setw(7) << left << (lowMass ? "yes" : "no");
1245 cout << setw(7) << left << (unlike ? "yes" : "no");
1246 cout << setw(6) << left << AliHLTUInt16_t(highPtCount);
1247 cout << setw(8) << left << AliHLTUInt16_t(lowPtCount);
1250 result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse);
1251 if (result != EXIT_SUCCESS) return result;
1252 cout << decision->fInvMass << endl;
1254 return EXIT_SUCCESS;
1258 int DumpPairsDecisionBlock(
1259 const char* buffer, unsigned long bufferSize,
1263 int result = EXIT_SUCCESS;
1264 AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize);
1266 result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
1267 if (result != EXIT_SUCCESS and not continueParse) return result;
1269 // Dump the rest of the block header.
1270 const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader();
1271 int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse);
1272 if (subResult != EXIT_SUCCESS) return subResult;
1274 AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
1276 // Print the data block record entries.
1277 cout << " | | Trigger Bits |" << endl;
1278 cout << "Track A ID | Track B ID | Raw HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl;
1279 cout << "----------------------------------------------------------------------------------------" << endl;
1280 const AliHLTMUONPairDecisionStruct* entry = block.GetArray();
1281 for(AliHLTUInt32_t i = 0; i < nentries; i++)
1283 subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse);
1284 if (subResult != EXIT_SUCCESS) return subResult;
1291 int DumpCommonHeader(
1292 const char* buffer, unsigned long bufferSize,
1293 const AliHLTMUONDataBlockHeader* header, bool continueParse
1296 // Step through the header fields trying to print them.
1297 // At each step check if we have not overflowed the buffer, if we have
1298 // not then we can print the field, otherwise we print the left over
1299 // bytes assumed to be corrupted rubbish.
1300 int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse);
1301 if (result != EXIT_SUCCESS) return result;
1302 AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType);
1303 cout << " Block type: " << type << endl;
1305 result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse);
1306 if (result != EXIT_SUCCESS) return result;
1307 cout << " Record width: " << header->fRecordWidth << endl;
1309 result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse);
1310 if (result != EXIT_SUCCESS) return result;
1311 cout << "Number of entries: " << header->fNrecords << endl;
1317 * Method to look for a certain data word key in the buffer.
1318 * \param buffer The start location in the buffer to search.
1319 * \param end The end of the buffer.
1320 * \returns the pointer position just past the word found or
1321 * NULL if the word was not found in the buffer.
1323 const char* FindDataWord(const char* buffer, const char* end, UInt_t word)
1325 for (const char* current = buffer; (current+1) <= end; current += sizeof(UInt_t))
1327 const UInt_t* currentWord = reinterpret_cast<const UInt_t*>(current);
1328 if (*currentWord == word) return current + sizeof(UInt_t);
1334 * Method to check if the data buffer is really a raw DDL stream.
1335 * \returns kUnknownDataBlock if this does not look like a raw DDL stream.
1336 * kTrackerDDLRawData if this looks like a raw DDL stream from the tracker.
1337 * kTriggerDDLRawData if this looks like a raw DDL stream from the trigger.
1339 int CheckIfDDLStream(const char* buffer, unsigned long bufferSize)
1341 if (bufferSize < sizeof(AliRawDataHeader)) return kUnknownDataBlock;
1343 const AliRawDataHeader* cdhHeader =
1344 reinterpret_cast<const AliRawDataHeader*>(buffer);
1346 // Keep scores of indicators / tests that show this is a raw DDL stream
1347 // either from the trigger or tracker. We will decide if the stream is
1348 // indeed a raw DDL stream if the largest of the two scores is above a
1349 // minimum threshold.
1350 int trackerScore = 0;
1351 int triggerScore = 0;
1353 if (cdhHeader->fSize == UInt_t(-1) or cdhHeader->fSize == bufferSize)
1359 if (cdhHeader->GetVersion() == 2)
1365 const char* payload = buffer + sizeof(AliRawDataHeader);
1366 const char* payloadEnd = buffer + bufferSize;
1368 typedef AliMUONTrackerDDLDecoder<AliMUONTrackerDDLDecoderEventHandler> AliTrkDecoder;
1369 typedef AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler> AliTrgDecoder;
1371 // See if the DDL data has a payload with data word keys as expected by
1372 // AliMUONTrackerDDLDecoder.
1373 const char* current = payload;
1374 while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BlockDataKeyWord())) != NULL )
1379 while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::DspDataKeyWord())) != NULL )
1384 while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::BusPatchDataKeyWord())) != NULL )
1389 while ( (current = FindDataWord(current, payloadEnd, AliTrkDecoder::EndOfDDLWord())) != NULL )
1394 // See if the DDL data has a payload with data word keys as expected by
1395 // AliMUONTriggerDDLDecoder.
1397 while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfDarcWord())) != NULL )
1402 while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfGlobalWord())) != NULL )
1407 while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfRegionalWord())) != NULL )
1412 while ( (current = FindDataWord(current, payloadEnd, AliTrgDecoder::EndOfLocalWord())) != NULL )
1417 if (triggerScore > trackerScore)
1419 if (triggerScore >= 6) return kTriggerDDLRawData;
1423 if (trackerScore >= 6) return kTrackerDDLRawData;
1425 return kUnknownDataBlock;
1429 * Parses the buffer and prints the contents to screen.
1430 * [in] \param buffer The pointer to the buffer to parse.
1431 * [in] \param bufferSize The size of the buffer in bytes.
1432 * [in] \param continueParse If specified then the we try to continue parsing the
1433 * buffer as much as possible.
1434 * [in/out] \param type Initialy this should indicate the type of the data block
1435 * or kUnknownDataBlock if not known. On exit it will be filled with
1436 * the type of the data block as discovered by this routine if type
1437 * initially contained kUnknownDataBlock.
1438 * \returns The error code indicating the problem. EXIT_SUCCESS is returned
1442 const char* buffer, unsigned long bufferSize,
1443 bool continueParse, int& type
1446 assert( buffer != NULL );
1447 int result = EXIT_SUCCESS;
1448 int subResult = EXIT_FAILURE;
1450 // If the -type|-t option was not used in the command line then we need to
1451 // figure out what type of data block this is from the data itself.
1452 bool ddlStream = false;
1453 if (type == kUnknownDataBlock)
1455 // First check if this is a raw DDL stream, if not then assume it is
1456 // some kind of internal dHLT raw data block.
1457 int streamType = CheckIfDDLStream(buffer, bufferSize);
1458 if (streamType == kTrackerDDLRawData or streamType == kTriggerDDLRawData)
1464 else if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
1471 if (bufferSize < sizeof(AliHLTMUONDataBlockHeader))
1473 cerr << "ERROR: The size of the file is too small to contain a"
1474 " valid data block." << endl;
1475 result = PARSE_ERROR;
1476 if (not continueParse) return result;
1478 const AliHLTMUONDataBlockHeader* header =
1479 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer);
1481 subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse);
1482 if (subResult != EXIT_SUCCESS) return subResult;
1485 // Check if the block type in the header corresponds to the type given
1486 // by the '-type' command line parameter. If they do not then print an
1487 // error or big fat warning message and force interpretation of the data
1488 // block with the type given by '-type'.
1489 AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType);
1491 if (type == kUnknownDataBlock)
1493 // -type not used in the command line so just use what is given
1494 // by the data block header.
1497 else if (type != headerType)
1499 cerr << "WARNING: The data block header indicates a type"
1500 " different from what was specified on the command line."
1501 " The data could be corrupt."
1503 cerr << "WARNING: The type value in the file is "
1504 << showbase << hex << header->fType
1505 << " (" << headerType << "), but on the command line it is "
1506 << showbase << hex << int(type) << dec
1507 << " (" << type << ")."
1509 cerr << "WARNING: Will force the interpretation of the data block"
1510 " with a type of " << type << "." << endl;
1514 // Now we know what type the data block is supposed to be, so we can
1515 // dump it to screen with the appropriate dump routine.
1518 case kTrackerDDLRawData:
1519 subResult = DumpTrackerDDLRawStream(buffer, bufferSize, continueParse);
1520 if (subResult != EXIT_SUCCESS) result = subResult;
1522 case kTriggerDDLRawData:
1523 subResult = DumpTriggerDDLRawStream(buffer, bufferSize, continueParse);
1524 if (subResult != EXIT_SUCCESS) result = subResult;
1526 case kTriggerRecordsDataBlock:
1527 subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse);
1528 if (subResult != EXIT_SUCCESS) result = subResult;
1530 case kTrigRecsDebugDataBlock:
1531 subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse);
1532 if (subResult != EXIT_SUCCESS) result = subResult;
1534 case kTriggerChannelsDataBlock:
1535 subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse);
1536 if (subResult != EXIT_SUCCESS) result = subResult;
1538 case kRecHitsDataBlock:
1539 subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse);
1540 if (subResult != EXIT_SUCCESS) result = subResult;
1542 case kClustersDataBlock:
1543 subResult = DumpClustersBlock(buffer, bufferSize, continueParse);
1544 if (subResult != EXIT_SUCCESS) result = subResult;
1546 case kChannelsDataBlock:
1547 return DumpChannelsBlock(buffer, bufferSize, continueParse);
1548 if (subResult != EXIT_SUCCESS) result = subResult;
1550 case kMansoTracksDataBlock:
1551 subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse);
1552 if (subResult != EXIT_SUCCESS) result = subResult;
1554 case kMansoCandidatesDataBlock:
1555 subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse);
1556 if (subResult != EXIT_SUCCESS) result = subResult;
1558 case kSinglesDecisionDataBlock:
1559 subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse);
1560 if (subResult != EXIT_SUCCESS) result = subResult;
1562 case kPairsDecisionDataBlock:
1563 return DumpPairsDecisionBlock(buffer, bufferSize, continueParse);
1564 if (subResult != EXIT_SUCCESS) result = subResult;
1567 cout << "ERROR: Unknown data block type. Found a type number of "
1568 << showbase << hex << int(type) << dec
1569 << " (" << int(type) << ")." << endl;
1570 result = PARSE_ERROR;
1577 * Convert the type code to a string.
1579 const char* TypeToString(int type)
1581 if (type == kTrackerDDLRawData or type == kTriggerDDLRawData)
1583 static char str[kAliHLTComponentDataTypefIDsize+1];
1584 AliHLTComponentDataType t = AliHLTMUONConstants::DDLRawDataType();
1585 memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
1586 // Must insert the NULL character to make this an ANSI C string.
1587 str[kAliHLTComponentDataTypefIDsize] = '\0';
1592 return AliHLTMUONUtils::DataBlockTypeToString(AliHLTMUONDataBlockType(type));
1597 * Find the data specification from the filename and return it in string format.
1599 const char* TryDecodeDataSpec(const char* filename)
1601 TString name = filename;
1603 TRegexp re1("MUONTR[GK]_[0123456789]+\\.ddl$");
1605 Ssiz_t pos = re1.Index(name, &length);
1609 for (Ssiz_t i = 0; i < length; i++)
1610 substr += name[pos+i];
1611 TRegexp re("[0123456789]+");
1612 pos = re.Index(substr, &length);
1614 for (Ssiz_t i = 0; i < length; i++)
1615 num += substr[pos+i];
1616 AliHLTUInt32_t spec = AliHLTMUONUtils::EquipIdToSpec(num.Atoi());
1617 static char strbuf[32];
1618 sprintf(&strbuf[0], "0x%8.8X", spec);
1622 TRegexp re2("_MUON\\:.+_0x[0123456789abscefABCDEF]+\\.dat$");
1623 pos = re2.Index(name, &length);
1627 for (Ssiz_t i = 0; i < length; i++)
1628 substr += name[pos+i];
1629 TRegexp re("0x[0123456789abscefABCDEF]+");
1630 pos = re.Index(substr, &length);
1632 for (Ssiz_t i = 0; i < length; i++)
1633 num += substr[pos+i];
1634 static TString result = num;
1635 return result.Data();
1642 * Performs basic data integrity checks of the data block using the
1643 * AliHLTMUONDataCheckerComponent.
1644 * [in] \param sys The HLT system framework.
1645 * [in] \param filename The name of the file containing the data block to check.
1646 * [in] \param type Must indicate the type of the data block.
1647 * [in] \param dataspec The data specification of the data block. NULL if none.
1648 * [in] \param maxLogging If set to true then full logging is turned on for AliHLTSystem.
1649 * \returns The error code indicating the problem. EXIT_SUCCESS is returned
1652 int CheckDataIntegrity(
1653 AliHLTSystem& sys, const char* filename, int type,
1654 const char* dataspec, bool maxLogging
1659 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
1660 sys.SetGlobalLoggingLevel(kHLTLogAll);
1664 AliLog::SetGlobalLogLevel(AliLog::kWarning);
1665 int level = kHLTLogWarning | kHLTLogError | kHLTLogFatal;
1666 sys.SetGlobalLoggingLevel(AliHLTComponentLogSeverity(level));
1669 // Check if required libraries are there and load them if not.
1670 if (gClassTable->GetID("AliHLTAgentUtil") < 0)
1672 sys.LoadComponentLibraries("libAliHLTUtil.so");
1674 if (gClassTable->GetID("AliHLTMUONAgent") < 0)
1676 sys.LoadComponentLibraries("libAliHLTMUON.so");
1679 // Setup the component parameter lists and then the components.
1680 TString dcparams = "-return_error -warn_on_unexpected_block -no_global_check";
1681 TString fpparams = "-datatype '";
1682 fpparams += TypeToString(type);
1683 fpparams += "' 'MUON'";
1684 if (dataspec != NULL)
1686 fpparams += " -dataspec ";
1687 fpparams += dataspec;
1691 const char* spec = TryDecodeDataSpec(filename);
1694 fpparams += " -dataspec ";
1699 dcparams += " -ignorespec";
1702 fpparams += " -datafile ";
1703 fpparams += filename;
1704 TString fpname = "filePublisher_";
1706 TString dcname = "checker_";
1711 cout << "DEBUG: Using the following flags for FilePublisher: \""
1712 << fpparams.Data() << "\""<< endl;
1713 cout << "DEBUG: Using the following flags for "
1714 << AliHLTMUONConstants::DataCheckerComponentId()
1715 << ": \"" << dcparams.Data() << "\""<< endl;
1718 AliHLTConfiguration(fpname.Data(), "FilePublisher", NULL, fpparams.Data());
1719 AliHLTConfiguration checker(
1720 dcname.Data(), AliHLTMUONConstants::DataCheckerComponentId(),
1721 fpname.Data(), dcparams.Data()
1724 // Build and run the HLT tasks.
1725 if (sys.BuildTaskList(dcname.Data()) != 0) return HLTSYSTEM_ERROR;
1726 if (maxLogging) sys.PrintTaskList();
1727 if (sys.Run() != 1) return HLTSYSTEM_ERROR;
1730 if (sys.CleanTaskList() != 0) return HLTSYSTEM_ERROR;
1732 return EXIT_SUCCESS;
1737 * The caller is responsible for freeing memory allocated for buffer with a call
1738 * to delete [] buffer.
1740 int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
1742 assert( filename != NULL );
1744 // Open the file and find its size.
1746 file.open(filename, ios::in);
1749 cerr << "ERROR: Could not open the file: " << filename << endl;
1750 return SYSTEM_ERROR;
1752 file.seekg(0, ios::end);
1755 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1756 return SYSTEM_ERROR;
1758 bufferSize = file.tellg();
1761 cerr << "ERROR: Could not get file size for the file: " <<
1763 return SYSTEM_ERROR;
1765 file.seekg(0, ios::beg);
1768 cerr << "ERROR: Could not seek in the file: " << filename << endl;
1769 return SYSTEM_ERROR;
1772 // Allocate the memory for the file.
1775 buffer = new char[bufferSize];
1777 catch (const std::bad_alloc&)
1779 cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize
1780 << " bytes." << endl;
1781 return SYSTEM_ERROR;
1784 file.read(buffer, bufferSize);
1790 cerr << "ERROR: Could not read from file: " << filename << endl;
1791 return SYSTEM_ERROR;
1800 cerr << "ERROR: Could not close the file: " << filename << endl;
1801 return SYSTEM_ERROR;
1804 return EXIT_SUCCESS;
1808 * Prints the command line usage of this program to standard error.
1810 void PrintUsage(bool asError = true)
1812 std::ostream& os = asError ? cerr : cout;
1813 os << "Usage: dHLTdumpraw [-help|-h] [-continue|-c] [-type|-t <typename>] [-check|-k]" << endl;
1814 os << " [-debug|-d] [-dataspec|-s <number>] <filename> [<filename> ...]" << endl;
1815 os << "Where <filename> is the name of a file containing a raw data block." << endl;
1816 os << "Options:" << endl;
1817 os << " -help | -h" << endl;
1818 os << " Displays this message." << endl;
1819 os << " -continue | -c" << endl;
1820 os << " If specified, the program will try to continue parsing the data block" << endl;
1821 os << " as much as possible rather than stopping at the first error." << endl;
1822 os << " -type | -t <typename>" << endl;
1823 os << " Forces the contents of the subsequent files specified on the command" << endl;
1824 os << " line to be interpreted as a specific type of data block." << endl;
1825 os << " Where <typename> can be one of:" << endl;
1826 os << " rawtracker - raw DDL stream from tracker chambers." << endl;
1827 os << " rawtrigger - raw DDL stream from trigger chambers." << endl;
1828 os << " trigrecs - trigger records data." << endl;
1829 os << " trigrecsdebug - debugging information about trigger records." << endl;
1830 os << " trigchannels - channel debugging in." << endl;
1831 os << " rechits - reconstructed hits data." << endl;
1832 os << " channels - channel debugging information from hit reconstruction." << endl;
1833 os << " clusters - cluster debugging information from hit reconstruction." << endl;
1834 os << " mansotracks - partial tracks from Manso algorithm." << endl;
1835 os << " mansocandidates - track candidates considered in the Manso algorithm." << endl;
1836 os << " singlesdecision - trigger decisions for single tracks." << endl;
1837 os << " pairsdecision - trigger decisions for track pairs." << endl;
1838 os << " autodetect - the type of the data block will be automatically" << endl;
1839 os << " detected." << endl;
1840 os << " -check | -k" << endl;
1841 os << " If specified then data integrity checks are performed on the raw data." << endl;
1842 os << " Warnings and errors are printed as problems are found with the data, but" << endl;
1843 os << " the data will still be converted into ROOT objects as best as possible." << endl;
1844 os << " -debug | -d" << endl;
1845 os << " If specified, then the all debug messages are printed by the AliHLTSystem." << endl;
1846 os << " This is only useful if experiencing problems with the -check|-k option." << endl;
1847 os << " -dataspec | -s <number>" << endl;
1848 os << " When specified, then <number> is used as the data specification for the" << endl;
1849 os << " data file that follows. This option is only useful with the -check|-k option." << endl;
1853 * Parses the command line.
1854 * @param argc Number of arguments as given in main().
1855 * @param argv Array of arguments as given in main().
1856 * @param filenames Pointer to buffer storing file name strings.
1857 * @param filetypes Array that receives the type of the data block expected, i.e.
1858 * the value of the -type flag for the corresponding file.
1859 * @param dataspecs Data specifications to use for the data files.
1860 * @param numOfFiles Receives the number of file name strings that were found
1861 * and added to 'filenames'.
1862 * @param continueParse Set to true if the user requested to continue to parse
1864 * @param checkData Set to true if data integrity checking was requested.
1865 * @param maxLogging Set to true if maximal logging was requested.
1866 * @return A status flag suitable for returning from main(), containing either
1867 * EXIT_SUCCESS or CMDLINE_ERROR.
1869 int ParseCommandLine(
1872 const char** filenames,
1874 const char** dataspecs,
1876 bool& continueParse,
1882 continueParse = false;
1885 int currentType = kUnknownDataBlock;
1886 const char* currentDataSpec = NULL;
1888 // Parse the command line.
1889 for (int i = 1; i < argc; i++)
1891 if (strcmp(argv[i], "-help") == 0 or strcmp(argv[i], "-h") == 0)
1894 return EXIT_SUCCESS;
1896 else if (strcmp(argv[i], "-continue") == 0 or strcmp(argv[i], "-c") == 0)
1898 continueParse = true;
1900 else if (strcmp(argv[i], "-type") == 0 or strcmp(argv[i], "-t") == 0)
1904 cerr << "ERROR: Missing a type specifier." << endl << endl;
1906 return CMDLINE_ERROR;
1908 // Now we need to parse the typename in the command line.
1909 if (strcmp(argv[i], "autodetect") == 0)
1911 currentType = kUnknownDataBlock;
1913 else if (strcmp(argv[i], "rawtracker") == 0)
1915 currentType = kTrackerDDLRawData;
1917 else if (strcmp(argv[i], "rawtrigger") == 0)
1919 currentType = kTriggerDDLRawData;
1923 currentType = AliHLTMUONUtils::ParseCommandLineTypeString(argv[i]);
1924 if (currentType == kUnknownDataBlock)
1926 cerr << "ERROR: Invalid type name '" << argv[i]
1927 << "' specified for argument " << argv[i-1]
1928 << "." << endl << endl;
1930 return CMDLINE_ERROR;
1934 else if (strcmp(argv[i], "-debug") == 0 or strcmp(argv[i], "-d") == 0)
1938 else if (strcmp(argv[i], "-check") == 0 or strcmp(argv[i], "-k") == 0)
1942 else if (strcmp(argv[i], "-dataspec") == 0 or strcmp(argv[i], "-s") == 0)
1946 cerr << "ERROR: Missing a specification number." << endl << endl;
1948 return CMDLINE_ERROR;
1951 char* errPos = NULL;
1952 unsigned long num = strtoul(argv[i], &errPos, 0);
1953 if (errPos == NULL or *errPos != '\0')
1955 cerr << "ERROR: Cannot convert '%s' to a data specification number."
1957 return CMDLINE_ERROR;
1959 if (not AliHLTMUONUtils::IsSpecValid(num))
1961 cerr << "ERROR: The data specification number is not a valid format."
1963 return CMDLINE_ERROR;
1965 currentDataSpec = argv[i];
1969 assert( numOfFiles < argc );
1970 filenames[numOfFiles] = argv[i];
1971 filetypes[numOfFiles] = currentType;
1972 dataspecs[numOfFiles] = currentDataSpec;
1973 currentDataSpec = NULL; // Reset because '-dataspec' option is only valid for one file.
1978 // Now check that we have at least one filename and all the flags we need.
1979 if (numOfFiles == 0)
1981 cerr << "ERROR: Missing a file name. You must specify at least one file to process."
1984 return CMDLINE_ERROR;
1987 return EXIT_SUCCESS;
1991 int main(int argc, const char** argv)
1993 // Test endianess of this machine during runtime and print warning if it is not
2000 endianTest.dword = 0x1;
2001 if (endianTest.byte[0] != 0x1)
2003 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2004 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2005 cerr << "!! !!" << endl;
2006 cerr << "!! This is not a little endian machine, but dHLT raw data is normally !!" << endl;
2007 cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
2008 cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
2009 cerr << "!! output. !!" << endl;
2010 cerr << "!! !!" << endl;
2011 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2012 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
2018 bool continueParse = false;
2019 bool checkData = false;
2020 bool maxLogging = false;
2021 int returnCode = EXIT_SUCCESS;
2022 char* buffer = NULL;
2023 const char** filename = NULL;
2024 int* filetype = NULL;
2025 const char** dataspec = NULL;
2029 // Reduce logging now to get rid of informationals from AliHLTSystem constructor.
2030 AliLog::SetGlobalLogLevel(AliLog::kWarning);
2033 // There will be at least 'argc' number of filenames.
2034 typedef const char* AnsiString;
2035 filename = new AnsiString[argc];
2036 filetype = new int[argc];
2037 dataspec = new AnsiString[argc];
2039 returnCode = ParseCommandLine(
2040 argc, argv, filename, filetype, dataspec, numOfFiles,
2041 continueParse, checkData, maxLogging
2044 if (returnCode == EXIT_SUCCESS)
2046 for (int i = 0; i < numOfFiles; i++)
2048 unsigned long bufferSize = 0;
2049 returnCode = ReadFile(filename[i], buffer, bufferSize);
2050 if (returnCode != EXIT_SUCCESS) break;
2053 cout << "########## Start of dump for file: "
2054 << filename[i] << " ##########" << endl;
2056 int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]);
2057 if (buffer != NULL) delete [] buffer;
2058 if (result != EXIT_SUCCESS)
2060 returnCode = result;
2061 if (not continueParse) break;
2065 result = CheckDataIntegrity(
2066 sys, filename[i], filetype[i],
2067 dataspec[i], maxLogging
2069 if (result != EXIT_SUCCESS)
2071 returnCode = result;
2072 if (not continueParse) break;
2077 cout << "########## End of dump for file: " <<
2078 filename[i] << " ##########" << endl;
2089 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
2090 returnCode = FATAL_ERROR;
2091 if (buffer != NULL) delete [] buffer;
2092 if (filename != NULL) delete [] filename;
2093 if (filetype != NULL) delete [] filetype;
2094 if (dataspec != NULL) delete [] dataspec;